diff --git a/.github/workflows/demo.yml b/.github/workflows/demo.yml new file mode 100644 index 00000000..55e055ee --- /dev/null +++ b/.github/workflows/demo.yml @@ -0,0 +1,114 @@ +name: Demo - Build & Deploy to Scaleway + +on: + push: + branches: [legacy_dev] + +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 }} + diff --git a/.github/workflows/ppd.yml b/.github/workflows/ppd.yml index 97e04f25..8cb3d90a 100644 --- a/.github/workflows/ppd.yml +++ b/.github/workflows/ppd.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: diff --git a/src/app/api/notary/OfficeFolderAnchorsController.ts b/src/app/api/notary/OfficeFolderAnchorsController.ts index bf8141ed..8cedd895 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); @@ -230,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");