From 8b636dadd39a3b20d6b2cdfc2cfe60efd9eb6a17 Mon Sep 17 00:00:00 2001 From: Maxime Sallerin <97036207+maxime-sallerin@users.noreply.github.com> Date: Wed, 21 Aug 2024 11:32:36 +0200 Subject: [PATCH 01/15] :bug: Cant delete a document with archived file in it (#203) --- src/services/admin/DocumentsService/DocumentsService.ts | 4 +++- src/services/notary/DocumentsService/DocumentsService.ts | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/services/admin/DocumentsService/DocumentsService.ts b/src/services/admin/DocumentsService/DocumentsService.ts index ce3f4242..8983e442 100644 --- a/src/services/admin/DocumentsService/DocumentsService.ts +++ b/src/services/admin/DocumentsService/DocumentsService.ts @@ -62,7 +62,9 @@ export default class DocumentsService extends BaseService { if (!documentEntity) throw new Error("document not found"); const document = Document.hydrate(documentEntity, { strategy: "excludeAll" }); - if (document.files && document.files.length !== 0) { + const isDocumentEmpty = document.files && !document!.files.find((file) => file.archived_at === null); + + if (!isDocumentEmpty) { throw new Error("Can't delete a document with file"); } return this.documentsRepository.delete(uid); diff --git a/src/services/notary/DocumentsService/DocumentsService.ts b/src/services/notary/DocumentsService/DocumentsService.ts index 0dce86dc..6fefc6ea 100644 --- a/src/services/notary/DocumentsService/DocumentsService.ts +++ b/src/services/notary/DocumentsService/DocumentsService.ts @@ -62,7 +62,9 @@ export default class DocumentsService extends BaseService { if (!documentEntity) throw new Error("document not found"); const document = Document.hydrate(documentEntity, { strategy: "excludeAll" }); - if (document.files && document.files.length !== 0 && document.document_status !== "REFUSED") { + const isDocumentEmpty = document.files && !document!.files.find((file) => file.archived_at === null); + + if (!isDocumentEmpty && document.document_status !== "REFUSED") { throw new Error("Can't delete a document with file"); } return this.documentsRepository.delete(uid); From c489138479b6b9fa67a5577acf701cf73a4e46fe Mon Sep 17 00:00:00 2001 From: Max S Date: Fri, 27 Sep 2024 16:28:06 +0200 Subject: [PATCH 02/15] add log bug fix --- .../common/IdNotService/IdNotService.ts | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/services/common/IdNotService/IdNotService.ts b/src/services/common/IdNotService/IdNotService.ts index b108aed5..26ad9cb7 100644 --- a/src/services/common/IdNotService/IdNotService.ts +++ b/src/services/common/IdNotService/IdNotService.ts @@ -124,12 +124,19 @@ export default class IdNotService extends BaseService { const token = await fetch(this.variables.IDNOT_BASE_URL + this.variables.IDNOT_CONNEXION_URL + "?" + query, { method: "POST" }); + console.log("URL"); + console.log(this.variables.IDNOT_BASE_URL + this.variables.IDNOT_CONNEXION_URL + "?" + query, { method: "POST" }); + if (token.status !== 200) console.error(await token.text()); const decodedToken = (await token.json()) as IIdNotToken; + console.log({ decodedToken }); + const decodedIdToken = jwt.decode(decodedToken.id_token) as IdNotJwtPayload; + console.log({ decodedIdToken }); + return decodedIdToken; } @@ -181,11 +188,16 @@ export default class IdNotService extends BaseService { const searchParams = new URLSearchParams({ key: this.variables.IDNOT_API_KEY, }); - return (await ( - await fetch(`${this.variables.IDNOT_API_BASE_URL}/api/pp/v2/entites/${office.idNot}/personnes?` + searchParams, { - method: "GET", - }) - ).json()) as any; + console.log("URL: getOfficeMemberships"); + + const URl = `${this.variables.IDNOT_API_BASE_URL}/api/pp/v2/entites/${office.idNot}/personnes?` + searchParams; + console.log(URl); + + const response = await fetch(URl, { + method: "GET", + }); + + return (await response.json()) as any; } public getOfficeStatus(statusName: string) { @@ -289,7 +301,7 @@ export default class IdNotService extends BaseService { await this.userService.updateCheckedAt(user.uid!); } - public async updateOffice(officeId: string) { + public async updateOffice(officeId: string) { const officeInfos = await this.officeService.getByUid(officeId); const office = Office.hydrate(officeInfos!); const searchParams = new URLSearchParams({ From a599548d4a5c756257d22deb59e9a513afe491b1 Mon Sep 17 00:00:00 2001 From: Max S Date: Fri, 27 Sep 2024 16:46:44 +0200 Subject: [PATCH 03/15] add loggs idNotService --- .../common/IdNotService/IdNotService.ts | 45 +++++++++++-------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/src/services/common/IdNotService/IdNotService.ts b/src/services/common/IdNotService/IdNotService.ts index 26ad9cb7..74b9a233 100644 --- a/src/services/common/IdNotService/IdNotService.ts +++ b/src/services/common/IdNotService/IdNotService.ts @@ -122,22 +122,25 @@ export default class IdNotService extends BaseService { grant_type: "authorization_code", }); - const token = await fetch(this.variables.IDNOT_BASE_URL + this.variables.IDNOT_CONNEXION_URL + "?" + query, { method: "POST" }); + const url = this.variables.IDNOT_BASE_URL + this.variables.IDNOT_CONNEXION_URL + "?" + query; - console.log("URL"); - console.log(this.variables.IDNOT_BASE_URL + this.variables.IDNOT_CONNEXION_URL + "?" + query, { method: "POST" }); + console.log("getIdNotToken"); + console.log("Tentative de connexion à l'URL :", url); - if (token.status !== 200) console.error(await token.text()); + try { + const token = await fetch(url, { method: "POST" }); + console.log("Réponse du fetch :", token); + if (token.status !== 200) console.error(await token.text()); - const decodedToken = (await token.json()) as IIdNotToken; + const decodedToken = (await token.json()) as IIdNotToken; - console.log({ decodedToken }); + const decodedIdToken = jwt.decode(decodedToken.id_token) as IdNotJwtPayload; - const decodedIdToken = jwt.decode(decodedToken.id_token) as IdNotJwtPayload; - - console.log({ decodedIdToken }); - - return decodedIdToken; + return decodedIdToken; + } catch (error) { + console.error("Erreur lors de l'appel à fetch :", error); + return null; + } } public async getRole(roleName: string): Promise { @@ -188,16 +191,22 @@ export default class IdNotService extends BaseService { const searchParams = new URLSearchParams({ key: this.variables.IDNOT_API_KEY, }); - console.log("URL: getOfficeMemberships"); - const URl = `${this.variables.IDNOT_API_BASE_URL}/api/pp/v2/entites/${office.idNot}/personnes?` + searchParams; - console.log(URl); + console.log("getOfficeMemberships"); - const response = await fetch(URl, { - method: "GET", - }); + const url = `${this.variables.IDNOT_API_BASE_URL}/api/pp/v2/entites/${office.idNot}/personnes?` + searchParams; - return (await response.json()) as any; + try { + console.log("Tentative de connexion à l'URL :", url); + const response = await fetch(url, { + method: "GET", + }); + + return (await response.json()) as any; + } catch (error) { + console.error("Erreur lors de l'appel à fetch :", error); + return null; + } } public getOfficeStatus(statusName: string) { From 404640052fa6877973ffe08e0abd1db21196a624 Mon Sep 17 00:00:00 2001 From: Max S Date: Fri, 27 Sep 2024 17:38:22 +0200 Subject: [PATCH 04/15] add executablePath in browser generate anchoring proof --- .../common/AnchoringProofService/AnchoringProofService.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/services/common/AnchoringProofService/AnchoringProofService.ts b/src/services/common/AnchoringProofService/AnchoringProofService.ts index 7077ce45..65fc543c 100644 --- a/src/services/common/AnchoringProofService/AnchoringProofService.ts +++ b/src/services/common/AnchoringProofService/AnchoringProofService.ts @@ -22,8 +22,9 @@ export default class AnchoringProofService extends BaseService { public async generate(data: AnchoringProofData): Promise { const browser = await puppeteer.launch({ headless: "new", + executablePath: `/usr/bin/chromium`, args: ["--no-sandbox", "--disable-setuid-sandbox"], - }); + }); const page = await browser.newPage(); From a4080d3f82c59d108ce43ea14d568e0f45268cac Mon Sep 17 00:00:00 2001 From: Maxime Sallerin <97036207+maxime-sallerin@users.noreply.github.com> Date: Fri, 8 Nov 2024 16:26:48 +0100 Subject: [PATCH 05/15] hotfix (#204) --- src/services/customer/CustomersService/CustomersService.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/customer/CustomersService/CustomersService.ts b/src/services/customer/CustomersService/CustomersService.ts index fcc02d17..7d64e0aa 100644 --- a/src/services/customer/CustomersService/CustomersService.ts +++ b/src/services/customer/CustomersService/CustomersService.ts @@ -358,7 +358,7 @@ export default class CustomersService extends BaseService { } private async sendSmsCodeToCustomer(totpPin: number, customer: Customer) { - const message = "Votre code de vérification LEcoffre.io est : " + totpPin.toString(); + const message = "Votre code de vérification LeCoffre est : " + totpPin.toString(); // Sélectionnez le fournisseur de SMS en fonction de la variable d'environnement //const selectedProvider = this.variables.SMS_PROVIDER === "OVH" ? this.ovhService : this.smsFactorService; From 003798fcfadb9ef625727a87bbf85167ff4f175f Mon Sep 17 00:00:00 2001 From: Omar Date: Tue, 17 Jun 2025 13:54:38 +0000 Subject: [PATCH 06/15] Actualiser Dockerfile --- Dockerfile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index e98bde33..15f33c12 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,10 +8,10 @@ COPY package.json ./ RUN apk update && apk add openssh-client git -COPY id_rsa /root/.ssh/id_rsa -RUN chmod 600 ~/.ssh/id_rsa -RUN eval "$(ssh-agent -s)" && ssh-add /root/.ssh/id_rsa -RUN ssh-keyscan github.com smart-chain-fr/leCoffre-resources.git >> /root/.ssh/known_hosts +#COPY id_rsa /root/.ssh/id_rsa +#RUN chmod 600 ~/.ssh/id_rsa +#RUN eval "$(ssh-agent -s)" && ssh-add /root/.ssh/id_rsa +#RUN ssh-keyscan github.com smart-chain-fr/leCoffre-resources.git >> /root/.ssh/known_hosts RUN npm install --frozen-lockfile From 2b59de3778bb6ea3ffb0d38461b2fd7ef46c516e Mon Sep 17 00:00:00 2001 From: Omar Date: Tue, 17 Jun 2025 13:55:27 +0000 Subject: [PATCH 07/15] Actualiser Dockerfile-Cron --- Dockerfile-Cron | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile-Cron b/Dockerfile-Cron index 77780e6f..86a71ada 100644 --- a/Dockerfile-Cron +++ b/Dockerfile-Cron @@ -8,10 +8,10 @@ COPY package.json ./ RUN apk update && apk add openssh-client git -COPY id_rsa /root/.ssh/id_rsa -RUN chmod 600 ~/.ssh/id_rsa -RUN eval "$(ssh-agent -s)" && ssh-add /root/.ssh/id_rsa -RUN ssh-keyscan github.com smart-chain-fr/leCoffre-resources.git >> /root/.ssh/known_hosts +#COPY id_rsa /root/.ssh/id_rsa +#RUN chmod 600 ~/.ssh/id_rsa +#RUN eval "$(ssh-agent -s)" && ssh-add /root/.ssh/id_rsa +#RUN ssh-keyscan github.com smart-chain-fr/leCoffre-resources.git >> /root/.ssh/known_hosts RUN npm install --frozen-lockfile From eebccebec12207ead041669ab30d1f84d78bfa9f Mon Sep 17 00:00:00 2001 From: Omar Date: Tue, 17 Jun 2025 13:58:17 +0000 Subject: [PATCH 08/15] Actualiser package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 82f0b42a..e1353da9 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "file-type-checker": "^1.0.8", "fp-ts": "^2.16.1", "jsonwebtoken": "^9.0.0", - "le-coffre-resources": "git@github.com:smart-chain-fr/leCoffre-resources.git#v2.167", + "le-coffre-resources": "git+https://git.4nkweb.com/4nk/lecoffre-ressources.git#dev", "module-alias": "^2.2.2", "monocle-ts": "^2.3.13", "multer": "^1.4.5-lts.1", From cb4d1eea1ed0463fc85f8ecd3bda5eca513c6549 Mon Sep 17 00:00:00 2001 From: Omar Date: Tue, 17 Jun 2025 14:27:45 +0000 Subject: [PATCH 09/15] Actualiser package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e1353da9..65e8fa23 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "file-type-checker": "^1.0.8", "fp-ts": "^2.16.1", "jsonwebtoken": "^9.0.0", - "le-coffre-resources": "git+https://git.4nkweb.com/4nk/lecoffre-ressources.git#dev", + "le-coffre-resources": "git+https://git.4nkweb.com/4nk/lecoffre-ressources.git#v2.167", "module-alias": "^2.2.2", "monocle-ts": "^2.3.13", "multer": "^1.4.5-lts.1", From 45765cfbeaacc5ad3d1318fbbb6bc120a42d5e78 Mon Sep 17 00:00:00 2001 From: Omar Date: Tue, 17 Jun 2025 14:39:29 +0000 Subject: [PATCH 10/15] Actualiser .github/workflows/prd.yml --- .github/workflows/prd.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/prd.yml b/.github/workflows/prd.yml index 1937379a..1dee1bde 100644 --- a/.github/workflows/prd.yml +++ b/.github/workflows/prd.yml @@ -18,16 +18,16 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Setup SSH - run: | - mkdir -p ~/.ssh - echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa - chmod 600 ~/.ssh/id_rsa - ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts - env: - SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} - - name: Copy SSH - run: cp ~/.ssh/id_rsa id_rsa + #- name: Setup SSH + # run: | + # mkdir -p ~/.ssh + # echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa + # chmod 600 ~/.ssh/id_rsa + # ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts + # env: + # SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + #- name: Copy SSH + # run: cp ~/.ssh/id_rsa id_rsa - name: Login to Scaleway Container Registry uses: docker/login-action@v3 with: From d62cd0f7fd2d49fc122ce1cc06664a69cc4677c8 Mon Sep 17 00:00:00 2001 From: Omar Date: Fri, 20 Jun 2025 13:24:38 +0000 Subject: [PATCH 11/15] Ajouter .github/workflows/test.yml --- .github/workflows/test.yml | 118 +++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 .github/workflows/test.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..12e16fc9 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,118 @@ +name: Prod - Build & Deploy to Scaleway + +on: + push: + branches: [test] + +env: + + PROJECT_ID_LECOFFRE: 72d08499-37c2-412b-877e-f8af0471654a + NAMESPACE_ID_LECOFFRE: 3829c5cd-9fb0-4871-97a1-eb33e4bc1114 + CONTAINER_REGISTRY_ENDPOINT_LECOFFRE: rg.fr-par.scw.cloud/funcscwlecoffretestouylprmj + + IMAGE_NAME: back + CONTAINER_NAME: back + +jobs: + build-and-push-images-lecoffre: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + #- name: Setup SSH + # run: | + # mkdir -p ~/.ssh + # echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa + # chmod 600 ~/.ssh/id_rsa + # ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts + # env: + # SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + #- name: Copy SSH + # run: cp ~/.ssh/id_rsa id_rsa + - name: Login to Scaleway Container Registry + uses: docker/login-action@v3 + with: + username: nologin + password: ${{ secrets.SCW_SECRET_KEY_LECOFFRE }} + registry: ${{ env.CONTAINER_REGISTRY_ENDPOINT_LECOFFRE }} + - name: Build the Back Image + run: docker build . -t ${{ env.CONTAINER_REGISTRY_ENDPOINT_LECOFFRE }}/${{ env.IMAGE_NAME }} + - name: Push the Back Image to Scaleway Container Registry + run: docker push ${{ env.CONTAINER_REGISTRY_ENDPOINT_LECOFFRE }}/${{ env.IMAGE_NAME }} + - name: Build the Cron Image + run: docker build -f Dockerfile-Cron . -t ${{ env.CONTAINER_REGISTRY_ENDPOINT_LECOFFRE }}/cron + - name: Push the Cron Image to Scaleway Container Registry + run: docker push ${{ env.CONTAINER_REGISTRY_ENDPOINT_LECOFFRE }}/cron + + deploy-back-lecoffre: + needs: build-and-push-images-lecoffre + runs-on: ubuntu-latest + environment: prod + steps: + - name: Install CLI + uses: scaleway/action-scw@v0 + - name: Get container ID + run: | + echo "CONTAINER_ID=$(scw container container list namespace-id=${{ env.NAMESPACE_ID_LECOFFRE }} -o json | jq -r '.[] | select(.name == "${{ env.CONTAINER_NAME }}") | .id')" >> $GITHUB_ENV + env: + SCW_ACCESS_KEY: ${{ secrets.SCW_ACCESS_KEY_LECOFFRE }} + SCW_SECRET_KEY: ${{ secrets.SCW_SECRET_KEY_LECOFFRE }} + SCW_DEFAULT_PROJECT_ID: ${{ env.PROJECT_ID_LECOFFRE }} + SCW_DEFAULT_ORGANIZATION_ID: ${{ secrets.SCW_ORGANIZATION_ID_LECOFFRE }} + - name: Deploy the container based on the new image + run: | + env_string="" + while IFS= read -r line; do + if [[ "$line" == *"="* ]]; then + key=$(echo "$line" | cut -d '=' -f 1) + value=$(echo "$line" | cut -d '=' -f 2-) + if [[ -n "$key" ]]; then + env_string+="environment-variables.$key=$value " + fi + fi + done <<< "$ENV_VARS" + env_string=$(echo $env_string | sed 's/ $//') + scw container container update ${{ env.CONTAINER_ID }} $env_string + env: + ENV_VARS: ${{ secrets.ENV }} + SCW_ACCESS_KEY: ${{ secrets.SCW_ACCESS_KEY_LECOFFRE }} + SCW_SECRET_KEY: ${{ secrets.SCW_SECRET_KEY_LECOFFRE }} + SCW_DEFAULT_PROJECT_ID: ${{ env.PROJECT_ID_LECOFFRE }} + SCW_DEFAULT_ORGANIZATION_ID: ${{ secrets.SCW_ORGANIZATION_ID_LECOFFRE }} + + deploy-cron-lecoffre: + needs: build-and-push-images-lecoffre + runs-on: ubuntu-latest + environment: prod + steps: + - name: Install CLI + uses: scaleway/action-scw@v0 + - name: Get container ID + run: | + echo "CONTAINER_ID=$(scw container container list namespace-id=${{env.NAMESPACE_ID_LECOFFRE}} -o json | jq -r '.[] | select(.name == "cron") | .id')" >> $GITHUB_ENV + env: + SCW_ACCESS_KEY: ${{ secrets.SCW_ACCESS_KEY_LECOFFRE }} + SCW_SECRET_KEY: ${{ secrets.SCW_SECRET_KEY_LECOFFRE }} + SCW_DEFAULT_PROJECT_ID: ${{ env.PROJECT_ID_LECOFFRE }} + SCW_DEFAULT_ORGANIZATION_ID: ${{ secrets.SCW_ORGANIZATION_ID_LECOFFRE }} + - name: Deploy the container based on the new image + run: | + env_string="" + while IFS= read -r line; do + if [[ "$line" == *"="* ]]; then + key=$(echo "$line" | cut -d '=' -f 1) + value=$(echo "$line" | cut -d '=' -f 2-) + if [[ -n "$key" ]]; then + env_string+="environment-variables.$key=$value " + fi + fi + done <<< "$ENV_VARS" + env_string=$(echo $env_string | sed 's/ $//') + scw container container update ${{ env.CONTAINER_ID }} $env_string + env: + ENV_VARS: ${{ secrets.ENV }} + + SCW_ACCESS_KEY: ${{ secrets.SCW_ACCESS_KEY_LECOFFRE }} + SCW_SECRET_KEY: ${{ secrets.SCW_SECRET_KEY_LECOFFRE }} + SCW_DEFAULT_PROJECT_ID: ${{ env.PROJECT_ID_LECOFFRE }} + SCW_DEFAULT_ORGANIZATION_ID: ${{ secrets.SCW_ORGANIZATION_ID_LECOFFRE }} + \ No newline at end of file From 5eff333aed309c7fa05baa0f06a62aee0cb148fe Mon Sep 17 00:00:00 2001 From: Omar Oughriss Date: Fri, 18 Jul 2025 12:48:36 +0200 Subject: [PATCH 12/15] Add Demo CICD for back --- .github/workflows/demo.yml | 114 +++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 .github/workflows/demo.yml diff --git a/.github/workflows/demo.yml b/.github/workflows/demo.yml new file mode 100644 index 00000000..9ddfb981 --- /dev/null +++ b/.github/workflows/demo.yml @@ -0,0 +1,114 @@ +name: Demo - Build & Deploy to Scaleway + +on: + push: + branches: [legacy_demo] + +env: + PROJECT_ID_LECOFFRE: 72d08499-37c2-412b-877e-f8af0471654a + NAMESPACE_ID_LECOFFRE: c992c042-bdb6-4974-becf-aa5039b9ec58 + CONTAINER_REGISTRY_ENDPOINT_LECOFFRE: rg.fr-par.scw.cloud/funcscwlecoffredemovts5gdxg + + IMAGE_NAME: back + CONTAINER_NAME: back + +jobs: + build-and-push-images-lecoffre: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup SSH + run: | + mkdir -p ~/.ssh + echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts + env: + SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} + - name: Copy SSH + run: cp ~/.ssh/id_rsa id_rsa + - name: Login to Scaleway Container Registry + uses: docker/login-action@v3 + with: + username: nologin + password: ${{ secrets.SCW_SECRET_KEY_LECOFFRE }} + registry: ${{ env.CONTAINER_REGISTRY_ENDPOINT_LECOFFRE }} + - name: Build the Back Image + run: docker build . -t ${{ env.CONTAINER_REGISTRY_ENDPOINT_LECOFFRE }}/${{ env.IMAGE_NAME }} + - name: Push the Back Image to Scaleway Container Registry + run: docker push ${{ env.CONTAINER_REGISTRY_ENDPOINT_LECOFFRE }}/${{ env.IMAGE_NAME }} + - name: Build the Cron Image + run: docker build -f Dockerfile-Cron . -t ${{ env.CONTAINER_REGISTRY_ENDPOINT_LECOFFRE }}/cron + - name: Push the Cron Image to Scaleway Container Registry + run: docker push ${{ env.CONTAINER_REGISTRY_ENDPOINT_LECOFFRE }}/cron + deploy-back-lecoffre: + needs: build-and-push-images-lecoffre + runs-on: ubuntu-latest + environment: demo + steps: + - name: Install CLI + uses: scaleway/action-scw@v0 + - name: Get container ID + run: | + echo "CONTAINER_ID=$(scw container container list namespace-id=${{ env.NAMESPACE_ID_LECOFFRE }} -o json | jq -r '.[] | select(.name == "${{ env.CONTAINER_NAME }}") | .id')" >> $GITHUB_ENV + env: + SCW_ACCESS_KEY: ${{ secrets.SCW_ACCESS_KEY_LECOFFRE }} + SCW_SECRET_KEY: ${{ secrets.SCW_SECRET_KEY_LECOFFRE }} + SCW_DEFAULT_PROJECT_ID: ${{ env.PROJECT_ID_LECOFFRE }} + SCW_DEFAULT_ORGANIZATION_ID: ${{ secrets.SCW_ORGANIZATION_ID_LECOFFRE }} + - name: Deploy the container based on the new image + run: | + env_string="" + while IFS= read -r line; do + if [[ "$line" == *"="* ]]; then + key=$(echo "$line" | cut -d '=' -f 1) + value=$(echo "$line" | cut -d '=' -f 2-) + if [[ -n "$key" ]]; then + env_string+="environment-variables.$key=$value " + fi + fi + done <<< "$ENV_VARS" + env_string=$(echo $env_string | sed 's/ $//') + scw container container update ${{ env.CONTAINER_ID }} $env_string + env: + ENV_VARS: ${{ secrets.ENV }} + SCW_ACCESS_KEY: ${{ secrets.SCW_ACCESS_KEY_LECOFFRE }} + SCW_SECRET_KEY: ${{ secrets.SCW_SECRET_KEY_LECOFFRE }} + SCW_DEFAULT_PROJECT_ID: ${{ env.PROJECT_ID_LECOFFRE }} + SCW_DEFAULT_ORGANIZATION_ID: ${{ secrets.SCW_ORGANIZATION_ID_LECOFFRE }} + deploy-cron-lecoffre: + needs: build-and-push-images-lecoffre + runs-on: ubuntu-latest + environment: demo + steps: + - name: Install CLI + uses: scaleway/action-scw@v0 + - name: Get container ID + run: | + echo "CONTAINER_ID=$(scw container container list namespace-id=${{env.NAMESPACE_ID_LECOFFRE}} -o json | jq -r '.[] | select(.name == "cron") | .id')" >> $GITHUB_ENV + env: + SCW_ACCESS_KEY: ${{ secrets.SCW_ACCESS_KEY_LECOFFRE }} + SCW_SECRET_KEY: ${{ secrets.SCW_SECRET_KEY_LECOFFRE }} + SCW_DEFAULT_PROJECT_ID: ${{ env.PROJECT_ID_LECOFFRE }} + SCW_DEFAULT_ORGANIZATION_ID: ${{ secrets.SCW_ORGANIZATION_ID_LECOFFRE }} + - name: Deploy the container based on the new image + run: | + env_string="" + while IFS= read -r line; do + if [[ "$line" == *"="* ]]; then + key=$(echo "$line" | cut -d '=' -f 1) + value=$(echo "$line" | cut -d '=' -f 2-) + if [[ -n "$key" ]]; then + env_string+="environment-variables.$key=$value " + fi + fi + done <<< "$ENV_VARS" + env_string=$(echo $env_string | sed 's/ $//') + scw container container update ${{ env.CONTAINER_ID }} $env_string + env: + ENV_VARS: ${{ secrets.ENV }} + SCW_ACCESS_KEY: ${{ secrets.SCW_ACCESS_KEY_LECOFFRE }} + SCW_SECRET_KEY: ${{ secrets.SCW_SECRET_KEY_LECOFFRE }} + SCW_DEFAULT_PROJECT_ID: ${{ env.PROJECT_ID_LECOFFRE }} + SCW_DEFAULT_ORGANIZATION_ID: ${{ secrets.SCW_ORGANIZATION_ID_LECOFFRE }} + From a2fef18b82afc3851249c7c8f815bdcdd2e0b57c Mon Sep 17 00:00:00 2001 From: Omar Date: Fri, 18 Jul 2025 10:47:41 +0000 Subject: [PATCH 13/15] Fix branche name --- .github/workflows/demo.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/demo.yml b/.github/workflows/demo.yml index 9ddfb981..55e055ee 100644 --- a/.github/workflows/demo.yml +++ b/.github/workflows/demo.yml @@ -2,7 +2,7 @@ name: Demo - Build & Deploy to Scaleway on: push: - branches: [legacy_demo] + branches: [legacy_dev] env: PROJECT_ID_LECOFFRE: 72d08499-37c2-412b-877e-f8af0471654a From b70dee2afebd1a5333db8ac6657d71c2065203b5 Mon Sep 17 00:00:00 2001 From: Sosthene Date: Fri, 18 Jul 2025 14:30:06 +0200 Subject: [PATCH 14/15] [bug] Don't count refused documents when anchoring --- .../notary/OfficeFolderAnchorsController.ts | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/app/api/notary/OfficeFolderAnchorsController.ts b/src/app/api/notary/OfficeFolderAnchorsController.ts index bf8141ed..3f84a5bd 100644 --- a/src/app/api/notary/OfficeFolderAnchorsController.ts +++ b/src/app/api/notary/OfficeFolderAnchorsController.ts @@ -2,7 +2,7 @@ import { Response, Request } from "express"; import { Controller, Get, Post } from "@ControllerPattern/index"; import ApiController from "@Common/system/controller-pattern/ApiController"; import { Service } from "typedi"; -import { Document, OfficeFolder } from "le-coffre-resources/dist/Notary"; +import { Document, OfficeFolder, File } from "le-coffre-resources/dist/Notary"; import { getFolderHashes, getFolderFilesUid } from "@Common/optics/notary"; import OfficeFoldersService from "@Services/notary/OfficeFoldersService/OfficeFoldersService"; import OfficeFolderAnchorsRepository from "@Repositories/OfficeFolderAnchorsRepository"; @@ -162,24 +162,34 @@ export default class OfficeFoldersController extends ApiController { const officeFolder = OfficeFolder.hydrate(officeFolderFound, { strategy: "excludeAll" }); - // Check if every document is validated in a folder const documents = officeFolder.documents ?? []; - const documentsValidated = documents.filter((document) => { - let documentHydrated = Document.hydrate(document, { strategy: "excludeAll" }); - return documentHydrated.document_status === "VALIDATED"; + + if (documents.length === 0) { + this.httpBadRequest(response, "OfficeFolder has no documents at all"); + return; + } + + const hasInvalidDocument = documents.some((document: any) => { + const documentHydrated = Document.hydrate(document, { strategy: "excludeAll" }); + return documentHydrated.document_status !== "VALIDATED" && + documentHydrated.document_status !== "REFUSED"; }); - if (documentsValidated.length !== documents.length && documents.length !== 0) { - this.httpBadRequest(response, "Cannot anchor a folder with non validated documents"); + if (hasInvalidDocument) { + this.httpBadRequest(response, "OfficeFolder has non validated documents"); return; } - const folderHashes = getFolderHashes(officeFolder); - - if (folderHashes.length === 0) { - this.httpNotFoundRequest(response, "No file hash to anchor"); - return; - } + const folderHashes: string[] = []; + documents.forEach((document: any) => { + const documentHydrated = Document.hydrate(document, { strategy: "excludeAll" }); + if (documentHydrated.document_status === "VALIDATED") { + documentHydrated.files?.forEach((file: any) => { + const fileHydrated = File.hydrate(file, { strategy: "excludeAll" }); + folderHashes.push(fileHydrated.hash); + }); + } + }); const sortedHashes = [...folderHashes].sort(); const data = await this.secureService.anchor(sortedHashes); From 86725b53fe1d181495349c6b9319b67f39b70b63 Mon Sep 17 00:00:00 2001 From: Sosthene Date: Fri, 18 Jul 2025 19:15:42 +0200 Subject: [PATCH 15/15] Only take VALIDATED documents hash in get --- .../notary/OfficeFolderAnchorsController.ts | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/app/api/notary/OfficeFolderAnchorsController.ts b/src/app/api/notary/OfficeFolderAnchorsController.ts index 3f84a5bd..8cedd895 100644 --- a/src/app/api/notary/OfficeFolderAnchorsController.ts +++ b/src/app/api/notary/OfficeFolderAnchorsController.ts @@ -240,7 +240,24 @@ export default class OfficeFoldersController extends ApiController { } const officeFolder = OfficeFolder.hydrate(officeFolderFound, { strategy: "excludeAll" }); - const folderHashes = getFolderHashes(officeFolder); + + const documents = officeFolder.documents ?? []; + + if (documents.length === 0) { + this.httpNotFoundRequest(response, "Office folder has no documents"); + return; + } + + const folderHashes: string[] = []; + documents.forEach((document: any) => { + const documentHydrated = Document.hydrate(document, { strategy: "excludeAll" }); + if (documentHydrated.document_status === "VALIDATED") { + documentHydrated.files?.forEach((file: any) => { + const fileHydrated = File.hydrate(file, { strategy: "excludeAll" }); + folderHashes.push(fileHydrated.hash); + }); + } + }); if (folderHashes.length === 0) { this.httpNotFoundRequest(response, "No file hash to anchor");