From ebe3813b76e1e5a34f0e895ba6db28eeaefff4e5 Mon Sep 17 00:00:00 2001 From: IshaVenikar Date: Wed, 29 Jan 2025 11:19:06 +0530 Subject: [PATCH] Implement functionality to encrypt env --- packages/backend/package.json | 3 +++ packages/backend/src/entity/Deployer.ts | 17 +++++++----- packages/backend/src/registry.ts | 35 ++++++++++++++++++++++--- packages/backend/src/service.ts | 22 +++++++++++++--- yarn.lock | 10 +++++++ 5 files changed, 74 insertions(+), 13 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index a7a5d34b..0ffc07dd 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -23,10 +23,12 @@ "express-session": "^1.18.0", "fs-extra": "^11.2.0", "graphql": "^16.8.1", + "js-yaml": "^4.1.0", "luxon": "^3.4.4", "nanoid": "3", "nanoid-dictionary": "^5.0.0-beta.1", "octokit": "^3.1.2", + "openpgp": "^6.0.1", "reflect-metadata": "^0.2.1", "semver": "^7.6.0", "toml": "^3.0.0", @@ -53,6 +55,7 @@ "@types/cookie-session": "^2.0.49", "@types/express-session": "^1.17.10", "@types/fs-extra": "^11.0.4", + "@types/js-yaml": "^4.0.9", "better-sqlite3": "^9.2.2", "copyfiles": "^2.4.1", "prettier": "^3.1.1", diff --git a/packages/backend/src/entity/Deployer.ts b/packages/backend/src/entity/Deployer.ts index d9e1b600..e6c2a904 100644 --- a/packages/backend/src/entity/Deployer.ts +++ b/packages/backend/src/entity/Deployer.ts @@ -4,23 +4,26 @@ import { Project } from './Project'; @Entity() export class Deployer { @PrimaryColumn('varchar') - deployerLrn!: string; + deployerLrn!: string; @Column('varchar') - deployerId!: string; + deployerId!: string; @Column('varchar') - deployerApiUrl!: string; + deployerApiUrl!: string; @Column('varchar') - baseDomain!: string; + baseDomain!: string; + + @Column('varchar') + publicKey!: string; @Column('varchar', { nullable: true }) - minimumPayment!: string | null; + minimumPayment!: string | null; @Column('varchar', { nullable: true }) - paymentAddress!: string | null; + paymentAddress!: string | null; @ManyToMany(() => Project, (project) => project.deployers) - projects!: Project[]; + projects!: Project[]; } diff --git a/packages/backend/src/registry.ts b/packages/backend/src/registry.ts index 43d9c988..689a5cac 100644 --- a/packages/backend/src/registry.ts +++ b/packages/backend/src/registry.ts @@ -4,6 +4,8 @@ import { DateTime } from 'luxon'; import { Octokit } from 'octokit'; import { inc as semverInc } from 'semver'; import { DeepPartial } from 'typeorm'; +import * as openpgp from 'openpgp'; +import yaml from 'js-yaml'; import { Account, DEFAULT_GAS_ESTIMATION_MULTIPLIER, Registry as LaconicRegistry, getGasPrice, parseGasAndFees } from '@cerc-io/registry-sdk'; import { DeliverTxResponse, IndexedTx } from '@cosmjs/stargate'; @@ -246,8 +248,11 @@ export class Registry { repository: string, auctionId?: string | null, lrn: string, + apiUrl: string, environmentVariables: { [key: string]: string }, dns: string, + address: string, + publicKey: string, payment?: string | null }): Promise<{ applicationDeploymentRequestId: string; @@ -261,6 +266,32 @@ export class Registry { throw new Error(`No record found for ${lrn}`); } + // Config to be encrypted + const config = { + "authorized": [data.address], + "config": { "env": data.environmentVariables }, + } + + const serialized = yaml.dump(config) + + const publicKey = await openpgp.readKey({ armoredKey: data.publicKey }); + + const encrypted = await openpgp.encrypt({ + message: await openpgp.createMessage({ text: serialized }), + encryptionKeys: publicKey + }); + + // To get the hash after uploading encrypted env + const response = await fetch(`${data.apiUrl}/upload/config`, { + method: 'POST', + headers: { + 'Content-Type': 'application/octet-stream' + }, + body: encrypted + }); + + const envHash = await response.json(); + // Create record of type ApplicationDeploymentRequest and publish const applicationDeploymentRequest = { type: APP_DEPLOYMENT_REQUEST_TYPE, @@ -270,9 +301,7 @@ export class Registry { dns: data.dns, // https://git.vdb.to/cerc-io/laconic-registry-cli/commit/129019105dfb93bebcea02fde0ed64d0f8e5983b - config: JSON.stringify({ - env: data.environmentVariables - }), + config: { ref: envHash }, meta: JSON.stringify({ note: `Added by Snowball @ ${DateTime.utc().toFormat( "EEE LLL dd HH:mm:ss 'UTC' yyyy" diff --git a/packages/backend/src/service.ts b/packages/backend/src/service.ts index 5da16954..a5cf0b28 100644 --- a/packages/backend/src/service.ts +++ b/packages/backend/src/service.ts @@ -641,6 +641,7 @@ export class Service { const newDeployment = await this.createDeploymentFromData(userId, data, deployer!.deployerLrn!, applicationRecordId, applicationRecordData); + const address = await this.getAddress(); const { repo, repoUrl } = await getRepoDetails(octokit, data.project.repository, data.commitHash); const environmentVariablesObj = await this.getEnvVariables(data.project!.id!); // To set project DNS @@ -654,8 +655,11 @@ export class Service { environmentVariables: environmentVariablesObj, dns: `${newDeployment.project.name}`, lrn: deployer!.deployerLrn!, + apiUrl: deployer!.deployerApiUrl!, payment: data.project.txHash, - auctionId: data.project.auctionId + auctionId: data.project.auctionId, + address, + publicKey: deployer!.publicKey! }); } @@ -665,10 +669,13 @@ export class Service { appName: repo, repository: repoUrl, lrn: deployer!.deployerLrn!, + apiUrl: deployer!.deployerApiUrl!, environmentVariables: environmentVariablesObj, dns: `${newDeployment.project.name}-${newDeployment.id}`, payment: data.project.txHash, - auctionId: data.project.auctionId + auctionId: data.project.auctionId, + address, + publicKey: deployer!.publicKey! }); await this.db.updateDeploymentById(newDeployment.id, { @@ -720,6 +727,7 @@ export class Service { }; const newDeployment = await this.createDeploymentFromData(project.ownerId!, deploymentData, deployerLrn, applicationRecordId, applicationRecordData); + const address = await this.getAddress(); const environmentVariablesObj = await this.getEnvVariables(project!.id!); // To set project DNS @@ -734,6 +742,9 @@ export class Service { dns: `${newDeployment.project.name}`, auctionId: project.auctionId!, lrn: deployerLrn, + apiUrl: deployer!.deployerApiUrl!, + address, + publicKey: deployer!.publicKey! }); } @@ -745,8 +756,11 @@ export class Service { repository: repoUrl, auctionId: project.auctionId!, lrn: deployerLrn, + apiUrl: deployer!.deployerApiUrl!, environmentVariables: environmentVariablesObj, dns: `${newDeployment.project.name}-${newDeployment.id}`, + address, + publicKey: deployer!.publicKey! }); await this.db.updateDeploymentById(newDeployment.id, { @@ -1434,6 +1448,7 @@ export class Service { const deployerApiUrl = record.attributes.apiUrl; const minimumPayment = record.attributes.minimumPayment; const paymentAddress = record.attributes.paymentAddress; + const publicKey = record.attributes.publicKey; const baseDomain = deployerApiUrl.substring(deployerApiUrl.indexOf('.') + 1); const deployerData = { @@ -1442,7 +1457,8 @@ export class Service { deployerApiUrl, baseDomain, minimumPayment, - paymentAddress + paymentAddress, + publicKey }; // TODO: Update deployers table in a separate job diff --git a/yarn.lock b/yarn.lock index 46f83374..4ade2cb1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6793,6 +6793,11 @@ jest-matcher-utils "^27.0.0" pretty-format "^27.0.0" +"@types/js-yaml@^4.0.9": + version "4.0.9" + resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.9.tgz#cd82382c4f902fed9691a2ed79ec68c5898af4c2" + integrity sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg== + "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" @@ -14407,6 +14412,11 @@ open@^8.0.4, open@^8.4.0: is-docker "^2.1.1" is-wsl "^2.2.0" +openpgp@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/openpgp/-/openpgp-6.0.1.tgz#ab3a2c08a3e23ac7f85c4fc62a3e715d50dc08fb" + integrity sha512-3lReDKjgWsKFArZT4Y/yj7/Q0q6/VhXarn4WqKEkyiBWckNjrThSGoB1t0IKo3Ke0ClvBpyQfTwumkGUkxOwww== + optimism@^0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.18.0.tgz#e7bb38b24715f3fdad8a9a7fc18e999144bbfa63"