Skip to content

Commit

Permalink
add support for cache-signatures (#10)
Browse files Browse the repository at this point in the history
* cache signatures

* mnemonic

---------

Co-authored-by: nomo-fe <[email protected]>
  • Loading branch information
nomo-app and dev2-nomo authored Mar 5, 2024
1 parent e433b4a commit 840ad2c
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 29 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ The `nomo-webon-cli` is configured with a file `nomo_cli.config.cjs`.
See the following example for configuring your deployTargets:

```JavaScript
const mnemonic = process.env.CACHE_SIGN_MNEMONIC;

const nomoCliConfig = {
deployTargets: {
production: {
Expand All @@ -79,6 +81,11 @@ const nomoCliConfig = {
* If true, the WebOn will be deployed both as a tar.gz as well as a normal website.
*/
hybrid: true,

/**
* If set, the cli will generate a signature of the tar.gz-cache.
*/
mnemonic,
},
},
staging: {
Expand Down
94 changes: 92 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nomo-webon-cli",
"version": "0.1.9",
"version": "0.1.10",
"description": "A CLI for building and deploying Nomo WebOns",
"repository": {
"type": "git",
Expand All @@ -25,6 +25,7 @@
},
"dependencies": {
"commander": "^6.1.0",
"ethers": "^6.11.1",
"inquirer": "^7.3.3",
"semver": "^7.5.4",
"tar": "^6.2.0",
Expand Down
13 changes: 5 additions & 8 deletions src/init/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,11 @@ export interface NomoManifest {
* See https://semver.org/ for details.
*/
webon_version: string;
/**
* If true, then the WebOn could be displayed in both card-mode and fullscreen-mode.
* If false, then the WebOn will only be displayed in fullscreen-mode.
*/
card_mode?: boolean;
/**
* If defined, then the WebOn can decide whether a navigation bar should be shown or not.
/**
* If set, the Nomo App will reject a cache if the signature cannot be verified.
* cache_sig should be an Ethereum-styled message signature of a tar.gz-cache.
*/
show_navbar?: boolean;
cache_sig?: string;
}

export interface GeneratedFile {
Expand All @@ -47,6 +43,7 @@ export interface RawSSHConfig {
publicBaseUrl: string;
sshPort?: number;
hybrid?: boolean;
mnemonic?: string;
}

export interface DeployTargetConfig {
Expand Down
41 changes: 41 additions & 0 deletions src/services/sign-webon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { resolve } from "path";
import { readFileSync, existsSync, writeFileSync } from "fs";
import { logFatal } from "../util/util";
import { NomoManifest } from "../init/interface";
import { Wallet } from "ethers";
import { ethers } from "ethers";

export async function signWebOn(args: {
manifestPath: string;
tarFilePath: string;
mnemonic: string;
}): Promise<void> {
console.log("Mnemonic found in config. Creating a signature of the cache...");

const manifestPath = resolve(args.manifestPath);
if (!existsSync(manifestPath)) {
logFatal(`Manifest does not exist: ${manifestPath}`);
}
const tarFilePath = resolve(args.manifestPath);
if (!existsSync(tarFilePath)) {
logFatal(`tar.gz file to sign does not exist: ${tarFilePath}`);
}

const nomoManifestContent = readFileSync(manifestPath, "utf-8");
const nomoManifest: NomoManifest = JSON.parse(nomoManifestContent);

const tarFileContent = readFileSync(tarFilePath);

const ethersSigner = Wallet.fromPhrase(args.mnemonic);
const cache_sig = await ethersSigner.signMessage(tarFileContent);
const signerAddress = ethers.verifyMessage(tarFileContent, cache_sig);

nomoManifest.cache_sig = cache_sig;

const newManifestContent = JSON.stringify(nomoManifest, null, 2);

writeFileSync(manifestPath, newManifestContent);
console.log(
`Wrote a cache-signature for address ${signerAddress} to ${manifestPath}`
);
}
9 changes: 9 additions & 0 deletions src/services/ssh-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { manifestChecks } from "../util/validate-manifest";

import { SSHOperations } from "./ssh-operations";
import { RawSSHConfig } from "../init/interface";
import { signWebOn } from "./sign-webon";
import path from "path";

const manifestPath = getCachedNomoManifestPath();
Expand All @@ -24,6 +25,14 @@ export async function connectAndDeploy(args: {
await extractAndCache({
tarFilePath: args.archive,
});
const mnemonic = args.rawSSH.mnemonic;
if (mnemonic) {
await signWebOn({ manifestPath, tarFilePath: args.archive, mnemonic });
} else {
console.log(
"No mnemonic found in config. Skipping the creation of a cache-signature..."
);
}

const { sshOperations, sshBaseDir, publicBaseUrl } =
await validateDeploymentConfig(args.deployTarget, args.rawSSH);
Expand Down
4 changes: 2 additions & 2 deletions src/services/ssh-operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ export class SSHOperations {
filePath,
sshConfig,
});
// Rename the file to "manifest" on the remote server
const renameManifestCommand = `${this.sshConnect} "mv ${path.join(
// Copy the "nomo_manifest.json" to "manifest" to comply with the deploy-system-V2
const renameManifestCommand = `${this.sshConnect} "cp ${path.join(
sshConfig.sshBaseDir,
path.basename(filePath)
)} ${path.join(sshConfig.sshBaseDir, "manifest")}"`;
Expand Down
11 changes: 0 additions & 11 deletions src/util/extract-tar-gz.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,6 @@ export async function extractAndCache(args: {
cwd: resolve(destinationDir),
});

/* Maybe possible to fetch fileNames as stream before extracting:
const getEntryFilenamesSync = (tarFilePath as any) => {
const filenames = requiredFiles;
tar.t({
file: tarFilePath,
onentry: (entry) => filenames.push(entry.path),
sync: true,
});
return filenames
};*/

const missingFiles = requiredFiles.filter((file) => {
const filePath = join(resolve(destinationDir), "/out/", file);
return !existsSync(filePath);
Expand Down
6 changes: 1 addition & 5 deletions src/util/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,7 @@ export function readCliConfig(): NomoCliConfigs {
return nomoCliConfig;
} catch (e) {
console.error(e);
logFatal(
"Could not find " +
getDebugPath(cliPath) +
", run nomo-webon-cli init <assetDir> to create one. "
);
logFatal("Could not load " + getDebugPath(cliPath));
}
}

Expand Down

0 comments on commit 840ad2c

Please sign in to comment.