From 59fe0b3df9cd3b52f7be08a041e59f2b16f881d9 Mon Sep 17 00:00:00 2001 From: Brian Botha Date: Mon, 1 Nov 2021 14:38:15 +1100 Subject: [PATCH 01/29] Fixing tests/bin/sessions, removed nested describes and concurrent test, using pkAgent --- tests/bin/sessions.test.ts | 480 ++++++++++++++++++++++--------------- 1 file changed, 293 insertions(+), 187 deletions(-) diff --git a/tests/bin/sessions.test.ts b/tests/bin/sessions.test.ts index 96741f898..ab8283f72 100644 --- a/tests/bin/sessions.test.ts +++ b/tests/bin/sessions.test.ts @@ -1,215 +1,321 @@ -import type { VaultName } from '@/vaults/types'; import type { SessionToken } from '@/sessions/types'; import os from 'os'; import path from 'path'; import fs from 'fs'; -import lock from 'fd-lock'; +import { mocked } from 'ts-jest/utils'; +import prompts from 'prompts'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; -import PolykeyAgent from '@/PolykeyAgent'; +import { Session } from '@/sessions'; import { sleep } from '@/utils'; -import * as testUtils from './utils'; - -jest.mock('@/keys/utils', () => ({ - ...jest.requireActual('@/keys/utils'), - generateDeterministicKeyPair: - jest.requireActual('@/keys/utils').generateKeyPair, -})); +import config from '@/config'; +import * as clientErrors from '@/client/errors'; +import * as testBinUtils from './utils'; /** - * This test file has been optimised to use only one instance of PolykeyAgent where posible. - * Setting up the PolykeyAgent has been done in a beforeAll block. - * Keep this in mind when adding or editing tests. - * Any side effects need to be undone when the test has completed. - * Preferably within a `afterEach()` since any cleanup will be skipped inside a failing test. - * - * - left over state can cause a test to fail in certain cases. - * - left over state can cause similar tests to succeed when they should fail. - * - starting or stopping the agent within tests should be done on a new instance of the polykey agent. - * - when in doubt test each modified or added test on it's own as well as the whole file. - * - Looking into adding a way to safely clear each domain's DB information with out breaking modules. + * Mock prompts module which is used prompt for password */ +jest.mock('prompts'); +const mockedPrompts = mocked(prompts); -describe('Session Token Refreshing', () => { - const logger = new Logger('pkStdio Test', LogLevel.WARN, [ +describe('CLI Sessions', () => { + const logger = new Logger('sessions test', LogLevel.WARN, [ new StreamHandler(), ]); let dataDir: string; - let nodePath: string; - let passwordFile: string; - let sessionFile: string; - let polykeyAgent: PolykeyAgent; - - let tokenBuffer: Buffer; - let token: SessionToken; - let command: string[]; - const vaultName = 'TestVault' as VaultName; - + let pkAgentClose; + const sessionTokenPath = path.join(global.binAgentDir, config.defaults.tokenBase); beforeAll(async () => { - // This handles the expensive setting up of the polykey agent. + pkAgentClose = await testBinUtils.pkAgent(); + }, global.maxTimeout); + afterAll(async () => { + await pkAgentClose(); + }); + beforeEach(async () => { dataDir = await fs.promises.mkdtemp( path.join(os.tmpdir(), 'polykey-test-'), ); - nodePath = path.join(dataDir, 'keynode'); - command = ['vaults', 'list', '-np', nodePath]; - passwordFile = path.join(dataDir, 'passwordFile'); - sessionFile = path.join(nodePath, 'token'); - await fs.promises.writeFile(passwordFile, 'password'); - polykeyAgent = await PolykeyAgent.createPolykeyAgent({ - password: 'password', - nodePath: nodePath, - logger: logger, + // Invalidate all active sessions + await testBinUtils.pkStdio( + ['agent', 'lock'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); + }); + afterEach(async () => { + await fs.promises.rm(dataDir, { + force: true, + recursive: true, }); - await polykeyAgent.vaultManager.createVault(vaultName); }); - - afterAll(async () => { - await polykeyAgent.stop(); - await polykeyAgent.destroy(); - await fs.promises.rmdir(dataDir, { recursive: true }); + test('processes should store session token in session file', async () => { + // Run command to set token + let exitCode, stdout; + ({ exitCode, stdout } = await testBinUtils.pkStdio( + ['agent', 'status', '--format', 'json', '--verbose'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + )); + expect(exitCode).toBe(0); + expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); + await sleep(1100); + // Try again without password + ({ exitCode, stdout } = await testBinUtils.pkStdio( + ['agent', 'status', '--format', 'json', '--verbose'], + { + PK_NODE_PATH: global.binAgentDir, + }, + global.binAgentDir, + )); + expect(exitCode).toBe(0); + expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); }); - - test('Process should store session token in session file', async () => { - // Agent has not been unlocked yet - const result = await testUtils.pkStdio( - command, - { PK_PASSWORD: 'password' }, - dataDir, - ); - expect(result.exitCode).toBe(0); - expect(result.stdout).toContain(vaultName); - - const buff = await fs.promises.readFile(sessionFile); - const newToken = buff.toString() as SessionToken; - expect( - async () => await polykeyAgent.sessionManager.verifyToken(newToken), - ).not.toThrow(); + test('processes should refresh the session token', async () => { + const session = await Session.createSession({ + sessionTokenPath, + fs, + logger, + }); + // Generate new token + await testBinUtils.pkStdio( + ['agent', 'unlock'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); + await sleep(1100); + const token1 = await session.readToken(); + // New command should refresh token + const { exitCode, stdout } = await testBinUtils.pkStdio( + ['agent', 'status', '--format', 'json', '--verbose'], + { + PK_NODE_PATH: global.binAgentDir, + }, + global.binAgentDir, + ); + expect(exitCode).toBe(0); + expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); + await sleep(1100); + const token2 = await session.readToken(); + expect(token1).not.toBe(token2); }); - - describe('After session has been unlocked', () => { - beforeAll(async () => { - // Authorize session - await testUtils.pkStdio( - ['agent', 'unlock', '-np', nodePath, '--password-file', passwordFile], - {}, - dataDir, - ); - }, global.polykeyStartupTimeout); - - test('Process should refresh the session token', async () => { - tokenBuffer = await fs.promises.readFile(sessionFile); - token = tokenBuffer.toString() as SessionToken; - const prevToken = token; - - // At least 1 second of delay - // Expiry time resolution is in seconds - await sleep(1100); - const result = await testUtils.pkStdio(command, {}, dataDir); - expect(result.exitCode).toBe(0); - expect(result.stdout).toContain(vaultName); - - const buff = await fs.promises.readFile(sessionFile); - const newToken = buff.toString() as SessionToken; - expect( - async () => await polykeyAgent.sessionManager.verifyToken(newToken), - ).not.toThrow(); - // Make sure the first and second tokens are not the same - expect(newToken).not.toEqual(prevToken); + test('serial processes should both refresh the session token', async () => { + const session = await Session.createSession({ + sessionTokenPath, + fs, + logger, }); - - test('Serial processes should refresh the session token', async () => { - let result = await testUtils.pkStdio(command, {}, dataDir); - expect(result.exitCode).toBe(0); - expect(result.stdout).toContain(vaultName); - - tokenBuffer = await fs.promises.readFile(sessionFile); - const token1 = tokenBuffer.toString() as SessionToken; - expect( - async () => await polykeyAgent.sessionManager.verifyToken(token1), - ).not.toThrow(); - - // At least 1 second of delay - // Expiry time resolution is in seconds - await sleep(1100); - result = await testUtils.pkStdio(command, {}, dataDir); - expect(result.exitCode).toBe(0); - expect(result.stdout).toContain(vaultName); - - tokenBuffer = await fs.promises.readFile(sessionFile); - const token2 = tokenBuffer.toString() as SessionToken; - expect( - async () => await polykeyAgent.sessionManager.verifyToken(token2), - ).not.toThrow(); - - // Make sure the first and second tokens are not the same - expect(token1).not.toEqual(token2); + // Run first command + let exitCode, stdout; + ({ exitCode, stdout } = await testBinUtils.pkStdio( + ['agent', 'status', '--format', 'json', '--verbose'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + )); + expect(exitCode).toBe(0); + expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); + await sleep(1100); + const token1 = await session.readToken(); + // Run second command + ({ exitCode, stdout } = await testBinUtils.pkStdio( + ['agent', 'status', '--format', 'json', '--verbose'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + )); + expect(exitCode).toBe(0); + expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); + await sleep(1100); + const token2 = await session.readToken(); + // Assert different + expect(token1).not.toBe(token2); + }); + test('failing processes should unlock the session file', async () => { + const session = await Session.createSession({ + sessionTokenPath, + fs, + logger, }); - - test( - 'Failing processes should unlock the session file', - async () => { - const result = await testUtils.pkStdio( - ['vaults', 'delete', 'NotAVault', '-np', nodePath], - {}, - dataDir, - ); - expect(result.exitCode).not.toBe(0); - - tokenBuffer = await fs.promises.readFile(sessionFile); - token = tokenBuffer.toString() as SessionToken; - expect( - async () => await polykeyAgent.sessionManager.verifyToken(token), - ).not.toThrow(); - - // Try to lock the session file to ensure it's unlocked - const fd = fs.openSync(sessionFile, 'r'); - expect(lock(fd)).toBeTruthy(); - lock.unlock(fd); - fs.closeSync(fd); + // Run command that will fail + const { exitCode } = await testBinUtils.pkStdio( + ['identities', 'search', 'InvalidProvider'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, }, - global.failedConnectionTimeout, + global.binAgentDir, ); - - test('Parallel processes should not refresh the session token', async () => { - let tokenP1 = 'token1' as SessionToken; - let tokenP2 = 'token2' as SessionToken; - - tokenBuffer = await fs.promises.readFile(sessionFile); - const prevTokenParallel = tokenBuffer.toString() as SessionToken; - - async function runListCommand(): Promise { - // At least 1 second of delay - // Expiry time resolution is in seconds - await sleep(1000); - await testUtils.pkStdio(command, {}, dataDir); - const buffer = await fs.promises.readFile(sessionFile); - return buffer.toString() as SessionToken; - } - - [tokenP1, tokenP2] = await Promise.all([ - runListCommand(), - runListCommand(), - ]); - - // Verify both tokens - expect( - async () => await polykeyAgent.sessionManager.verifyToken(tokenP1), - ).not.toThrow(); - expect( - async () => await polykeyAgent.sessionManager.verifyToken(tokenP2), - ).not.toThrow(); - - // Check that both commands were completed - expect(tokenP1).not.toEqual('token1'); - expect(tokenP2).not.toEqual('token2'); - - // Check that the session token was refreshed exactly one time - if (tokenP1 === prevTokenParallel) { - expect(tokenP2).not.toEqual(prevTokenParallel); - } else if (tokenP2 === prevTokenParallel) { - expect(tokenP1).not.toEqual(prevTokenParallel); - } else { - expect(tokenP1).toEqual(tokenP2); - } + expect(exitCode).not.toBe(0); + await sleep(1100); + // Write to session file to ensure it's unlocked + await session.writeToken('abc' as SessionToken); + const token = await session.readToken(); + expect(token).toEqual('abc'); + }); + test('agent lock should remove the token from the client and delete the token', async () => { + const { exitCode } = await testBinUtils.pkStdio( + ['agent', 'lock'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); + expect(exitCode).toBe(0); + await expect( + fs.promises.readdir(path.join(global.binAgentDir)), + ).resolves.not.toContain('token'); + }); + test('cause old sessions to fail when locking all sessions', async () => { + // Generate new token + await testBinUtils.pkStdio( + ['agent', 'unlock'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); + await sleep(1100); + // Lockall + await testBinUtils.pkStdio( + ['agent', 'lockall'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); + // Call should fail because token is invalidated + const { exitCode, stderr } = await testBinUtils.pkStdio( + ['agent', 'status', '--verbose'], + { + PK_NODE_PATH: global.binAgentDir, + }, + global.binAgentDir, + ); + testBinUtils.expectProcessError( + exitCode, + stderr, + new clientErrors.ErrorClientAuthDenied(), + ); + }); + test('unattended calls with invalid auth should fail', async () => { + let exitCode, stderr; + // Password and Token set + ({ exitCode, stderr } = await testBinUtils.pkStdio( + ['agent', 'status'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: 'invalid', + PK_TOKEN: 'token', + }, + global.binAgentDir, + )); + testBinUtils.expectProcessError( + exitCode, + stderr, + new clientErrors.ErrorClientAuthDenied(), + ); + // Password set + ({ exitCode, stderr } = await testBinUtils.pkStdio( + ['agent', 'status'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: 'invalid', + PK_TOKEN: undefined, + }, + global.binAgentDir, + )); + testBinUtils.expectProcessError( + exitCode, + stderr, + new clientErrors.ErrorClientAuthDenied(), + ); + // Token set + ({ exitCode, stderr } = await testBinUtils.pkStdio( + ['agent', 'status'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: undefined, + PK_TOKEN: 'token', + }, + global.binAgentDir, + )); + testBinUtils.expectProcessError( + exitCode, + stderr, + new clientErrors.ErrorClientAuthDenied(), + ); + }); + test('password can be used to authenticate attended calls', async () => { + const password = global.binAgentPassword; + mockedPrompts.mockClear(); + mockedPrompts.mockImplementation(async (_opts: any) => { + return { password }; }); + const { exitCode, stdout } = await testBinUtils.pkStdio( + ['agent', 'status', '--format', 'json', '--verbose'], + { + PK_NODE_PATH: global.binAgentDir, + }, + global.binAgentDir, + ); + expect(exitCode).toBe(0); + expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); + // Prompted for password 1 time + expect(mockedPrompts.mock.calls.length).toBe(1); + mockedPrompts.mockClear(); + }); + test('re-prompt for password if unable to authenticate call', async () => { + const validPassword = global.binAgentPassword; + const invalidPassword = 'invalid'; + mockedPrompts.mockClear(); + mockedPrompts + .mockResolvedValueOnce({ password: invalidPassword }) + .mockResolvedValue({ password: validPassword }); + const { exitCode, stdout } = await testBinUtils.pkStdio( + ['agent', 'status', '--format', 'json', '--verbose'], + { + PK_NODE_PATH: global.binAgentDir, + }, + global.binAgentDir, + ); + expect(exitCode).toBe(0); + expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); + // Prompted for password 2 times + expect(mockedPrompts.mock.calls.length).toBe(2); + mockedPrompts.mockClear(); + }); + test('will not prompt for password reauthentication on generic error', async () => { + const validPassword = global.binAgentPassword; + const invalidPassword = 'invalid'; + mockedPrompts.mockClear(); + mockedPrompts + .mockResolvedValueOnce({ password: invalidPassword }) + .mockResolvedValue({ password: validPassword }); + const { exitCode } = await testBinUtils.pkStdio( + ['identities', 'search', 'InvalidProvider'], + { + PK_NODE_PATH: global.binAgentDir, + }, + global.binAgentDir, + ); + expect(exitCode).not.toBe(0); + // Prompted for password 2 times + expect(mockedPrompts.mock.calls.length).toBe(2); + mockedPrompts.mockClear(); }); }); From b7e5978bb352d12c90e249b00503c156993ee9a3 Mon Sep 17 00:00:00 2001 From: Joshua Karp Date: Thu, 9 Dec 2021 12:54:09 +1100 Subject: [PATCH 02/29] Adding typescript-cache-transpile for faster test execution with processes (usage with pkExec, pkSpawn, pkExpect) --- package-lock.json | 45 +++++++++++++++ package.json | 5 +- src/bin/agent/CommandLockAll.ts | 15 +++-- src/bin/agent/CommandStatus.ts | 8 +-- src/bin/agent/CommandUnlock.ts | 42 ++++---------- src/client/GRPCClientClient.ts | 12 +--- src/client/rpcSessions.ts | 42 ++++---------- .../js/polykey/v1/client_service_grpc_pb.d.ts | 57 +++++++------------ .../js/polykey/v1/client_service_grpc_pb.js | 34 ++--------- .../schemas/polykey/v1/client_service.proto | 5 +- tests/bin/sessions.test.ts | 26 ++++----- tests/bin/utils.ts | 21 ++++++- 12 files changed, 141 insertions(+), 171 deletions(-) diff --git a/package-lock.json b/package-lock.json index f82faf934..9b42e0824 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9308,6 +9308,51 @@ "integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==", "dev": true }, + "typescript-cached-transpile": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typescript-cached-transpile/-/typescript-cached-transpile-0.0.6.tgz", + "integrity": "sha512-bfPc7YUW0PrVkQHU0xN0ANRuxdPgoYYXtZEW6PNkH5a97/AOM+kPPxSTMZbpWA3BG1do22JUkfC60KoCKJ9VZQ==", + "dev": true, + "requires": { + "@types/node": "^12.12.7", + "fs-extra": "^8.1.0", + "tslib": "^1.10.0" + }, + "dependencies": { + "@types/node": { + "version": "12.20.37", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.37.tgz", + "integrity": "sha512-i1KGxqcvJaLQali+WuypQnXwcplhtNtjs66eNsZpp2P2FL/trJJxx/VWsM0YCL2iMoIJrbXje48lvIQAQ4p2ZA==", + "dev": true + }, + "fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, "uglify-js": { "version": "3.14.2", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.14.2.tgz", diff --git a/package.json b/package.json index 084fcc48f..baf818195 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "lintfix": "eslint '{src,tests}/**/*.{js,ts}' --fix", "docs": "rm -r ./docs || true; typedoc --gitRevision master --tsconfig ./tsconfig.build.json --out ./docs src && touch ./docs/.nojekyll", "proto-generate": "scripts/proto-generate.sh", - "polykey": "ts-node --require tsconfig-paths/register --transpile-only src/bin/polykey.ts" + "polykey": "ts-node --require tsconfig-paths/register --compiler typescript-cached-transpile --transpile-only src/bin/polykey.ts" }, "dependencies": { "@grpc/grpc-js": "1.3.7", @@ -130,6 +130,7 @@ "ts-node": "^10.4.0", "tsconfig-paths": "^3.9.0", "typedoc": "^0.21.5", - "typescript": "^4.1.3" + "typescript": "^4.1.3", + "typescript-cached-transpile": "0.0.6" } } diff --git a/src/bin/agent/CommandLockAll.ts b/src/bin/agent/CommandLockAll.ts index d0c532049..f18ad7dc6 100644 --- a/src/bin/agent/CommandLockAll.ts +++ b/src/bin/agent/CommandLockAll.ts @@ -23,7 +23,11 @@ class CommandLockAll extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -35,18 +39,13 @@ class CommandLockAll extends CommandPolykey { nodePath: options.nodePath, logger: this.logger.getChild(PolykeyClient.name), }); - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const emptyMessage = new utilsPB.EmptyMessage(); await binUtils.retryAuthentication( - (auth) => grpcClient.sessionsLockAll(emptyMessage, auth), + (auth) => pkClient.grpcClient.sessionsLockAll(emptyMessage, auth), meta, ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/agent/CommandStatus.ts b/src/bin/agent/CommandStatus.ts index d38921522..ea15fb6e7 100644 --- a/src/bin/agent/CommandStatus.ts +++ b/src/bin/agent/CommandStatus.ts @@ -38,6 +38,10 @@ class CommandStatus extends CommandPolykey { }), ); } else { + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); @@ -51,10 +55,6 @@ class CommandStatus extends CommandPolykey { nodePath: options.nodePath, logger: this.logger.getChild(PolykeyClient.name), }); - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); const emptyMessage = new utilsPB.EmptyMessage(); response = await binUtils.retryAuthentication( (auth) => pkClient.grpcClient.agentStatus(emptyMessage, auth), diff --git a/src/bin/agent/CommandUnlock.ts b/src/bin/agent/CommandUnlock.ts index c4467804e..278c2292d 100644 --- a/src/bin/agent/CommandUnlock.ts +++ b/src/bin/agent/CommandUnlock.ts @@ -1,6 +1,3 @@ -import type { SessionToken } from '../../sessions/types'; -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -17,10 +14,7 @@ class CommandUnlock extends CommandPolykey { this.addOption(binOptions.clientPort); this.action(async (options) => { const { default: PolykeyClient } = await import('../../PolykeyClient'); - const sessionsPB = await import( - '../../proto/js/polykey/v1/sessions/sessions_pb' - ); - + const utilsPB = await import('../../proto/js/polykey/v1/utils/utils_pb'); const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -29,41 +23,29 @@ class CommandUnlock extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); try { pkClient = await PolykeyClient.createPolykeyClient({ - nodePath: options.nodePath, nodeId: clientOptions.nodeId, host: clientOptions.clientHost, port: clientOptions.clientPort, + nodePath: options.nodePath, logger: this.logger.getChild(PolykeyClient.name), }); - - const password = await binProcessors.processPassword( - options.passwordFile, - this.fs, + const emptyMessage = new utilsPB.EmptyMessage(); + await binUtils.retryAuthentication( + (auth) => pkClient.grpcClient.sessionsUnlock(emptyMessage, auth), + meta ); - const grpcClient = pkClient.grpcClient; - const passwordMessage = new sessionsPB.Password(); - passwordMessage.setPassword(password); - const responseMessage = await binUtils.retryAuthentication( - (metaRetried?: Metadata) => { - return metaRetried != null - ? grpcClient.sessionsUnlock(passwordMessage, metaRetried) - : grpcClient.sessionsUnlock(passwordMessage); - }, - ); - const token: SessionToken = responseMessage.getToken() as SessionToken; - - // Write token to file - await pkClient.session.writeToken(token); - process.stdout.write('Client session started'); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/client/GRPCClientClient.ts b/src/client/GRPCClientClient.ts index 9beec1423..7833d91ef 100644 --- a/src/client/GRPCClientClient.ts +++ b/src/client/GRPCClientClient.ts @@ -103,23 +103,15 @@ class GRPCClientClient extends GRPCClient { @ready(new clientErrors.ErrorClientClientDestroyed()) public sessionsUnlock(...args) { - return grpcUtils.promisifyUnaryCall( + return grpcUtils.promisifyUnaryCall( this.client, this.client.sessionsUnlock, )(...args); } - @ready(new clientErrors.ErrorClientClientDestroyed()) - public sessionsRefresh(...args) { - return grpcUtils.promisifyUnaryCall( - this.client, - this.client.sessionsRefresh, - )(...args); - } - @ready(new clientErrors.ErrorClientClientDestroyed()) public sessionsLockAll(...args) { - return grpcUtils.promisifyUnaryCall( + return grpcUtils.promisifyUnaryCall( this.client, this.client.sessionsLockAll, )(...args); diff --git a/src/client/rpcSessions.ts b/src/client/rpcSessions.ts index 5f541b540..891482444 100644 --- a/src/client/rpcSessions.ts +++ b/src/client/rpcSessions.ts @@ -3,10 +3,8 @@ import type { KeyManager } from '../keys'; import type * as grpc from '@grpc/grpc-js'; import type * as utils from './utils'; -import * as clientUtils from '../client/utils'; import * as grpcUtils from '../grpc/utils'; import * as utilsPB from '../proto/js/polykey/v1/utils/utils_pb'; -import * as sessionsPB from '../proto/js/polykey/v1/sessions/sessions_pb'; const createSessionsRPC = ({ authenticate, @@ -19,49 +17,31 @@ const createSessionsRPC = ({ }) => { return { sessionsUnlock: async ( - call: grpc.ServerUnaryCall, - callback: grpc.sendUnaryData, + call: grpc.ServerUnaryCall, + callback: grpc.sendUnaryData, ): Promise => { - const response = new sessionsPB.Token(); - try { - const password = call.request.getPassword(); - await keyManager.checkPassword(password); - const token = await sessionManager.createToken(); - response.setToken(token); - call.sendMetadata(clientUtils.encodeAuthFromSession(token)); - } catch (err) { - callback(grpcUtils.fromError(err), null); - } - callback(null, response); - }, - sessionsRefresh: async ( - call: grpc.ServerUnaryCall, - callback: grpc.sendUnaryData, - ): Promise => { - const response = new sessionsPB.Token(); + const response = new utilsPB.EmptyMessage(); try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - response.setToken(await sessionManager.createToken()); - } catch (err) { - callback(grpcUtils.fromError(err), null); + return callback(null, response); + } catch (e) { + return callback(grpcUtils.fromError(e), null); } - callback(null, response); }, sessionsLockAll: async ( - call: grpc.ServerUnaryCall, - callback: grpc.sendUnaryData, + call: grpc.ServerUnaryCall, + callback: grpc.sendUnaryData, ): Promise => { - const response = new utilsPB.StatusMessage(); + const response = new utilsPB.EmptyMessage(); try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); await sessionManager.resetKey(); - response.setSuccess(true); + return callback(null, response); } catch (err) { - callback(grpcUtils.fromError(err), null); + return callback(grpcUtils.fromError(err), null); } - callback(null, response); }, }; }; diff --git a/src/proto/js/polykey/v1/client_service_grpc_pb.d.ts b/src/proto/js/polykey/v1/client_service_grpc_pb.d.ts index 3e5a38052..152afa5b2 100644 --- a/src/proto/js/polykey/v1/client_service_grpc_pb.d.ts +++ b/src/proto/js/polykey/v1/client_service_grpc_pb.d.ts @@ -22,7 +22,6 @@ interface IClientServiceService extends grpc.ServiceDefinition; responseDeserialize: grpc.deserialize; } -interface IClientServiceService_ISessionsUnlock extends grpc.MethodDefinition { +interface IClientServiceService_ISessionsUnlock extends grpc.MethodDefinition { path: "/polykey.v1.ClientService/SessionsUnlock"; requestStream: false; responseStream: false; - requestSerialize: grpc.serialize; - requestDeserialize: grpc.deserialize; - responseSerialize: grpc.serialize; - responseDeserialize: grpc.deserialize; -} -interface IClientServiceService_ISessionsRefresh extends grpc.MethodDefinition { - path: "/polykey.v1.ClientService/SessionsRefresh"; - requestStream: false; - responseStream: false; requestSerialize: grpc.serialize; requestDeserialize: grpc.deserialize; - responseSerialize: grpc.serialize; - responseDeserialize: grpc.deserialize; + responseSerialize: grpc.serialize; + responseDeserialize: grpc.deserialize; } -interface IClientServiceService_ISessionsLockAll extends grpc.MethodDefinition { +interface IClientServiceService_ISessionsLockAll extends grpc.MethodDefinition { path: "/polykey.v1.ClientService/SessionsLockAll"; requestStream: false; responseStream: false; requestSerialize: grpc.serialize; requestDeserialize: grpc.deserialize; - responseSerialize: grpc.serialize; - responseDeserialize: grpc.deserialize; + responseSerialize: grpc.serialize; + responseDeserialize: grpc.deserialize; } interface IClientServiceService_INodesAdd extends grpc.MethodDefinition { path: "/polykey.v1.ClientService/NodesAdd"; @@ -647,9 +637,8 @@ export const ClientServiceService: IClientServiceService; export interface IClientServiceServer extends grpc.UntypedServiceImplementation { agentStatus: grpc.handleUnaryCall; agentStop: grpc.handleUnaryCall; - sessionsUnlock: grpc.handleUnaryCall; - sessionsRefresh: grpc.handleUnaryCall; - sessionsLockAll: grpc.handleUnaryCall; + sessionsUnlock: grpc.handleUnaryCall; + sessionsLockAll: grpc.handleUnaryCall; nodesAdd: grpc.handleUnaryCall; nodesPing: grpc.handleUnaryCall; nodesClaim: grpc.handleUnaryCall; @@ -716,15 +705,12 @@ export interface IClientServiceClient { agentStop(request: polykey_v1_utils_utils_pb.EmptyMessage, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; agentStop(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; agentStop(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; - sessionsUnlock(request: polykey_v1_sessions_sessions_pb.Password, callback: (error: grpc.ServiceError | null, response: polykey_v1_sessions_sessions_pb.Token) => void): grpc.ClientUnaryCall; - sessionsUnlock(request: polykey_v1_sessions_sessions_pb.Password, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: polykey_v1_sessions_sessions_pb.Token) => void): grpc.ClientUnaryCall; - sessionsUnlock(request: polykey_v1_sessions_sessions_pb.Password, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: polykey_v1_sessions_sessions_pb.Token) => void): grpc.ClientUnaryCall; - sessionsRefresh(request: polykey_v1_utils_utils_pb.EmptyMessage, callback: (error: grpc.ServiceError | null, response: polykey_v1_sessions_sessions_pb.Token) => void): grpc.ClientUnaryCall; - sessionsRefresh(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: polykey_v1_sessions_sessions_pb.Token) => void): grpc.ClientUnaryCall; - sessionsRefresh(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: polykey_v1_sessions_sessions_pb.Token) => void): grpc.ClientUnaryCall; - sessionsLockAll(request: polykey_v1_utils_utils_pb.EmptyMessage, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.StatusMessage) => void): grpc.ClientUnaryCall; - sessionsLockAll(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.StatusMessage) => void): grpc.ClientUnaryCall; - sessionsLockAll(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.StatusMessage) => void): grpc.ClientUnaryCall; + sessionsUnlock(request: polykey_v1_utils_utils_pb.EmptyMessage, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; + sessionsUnlock(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; + sessionsUnlock(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; + sessionsLockAll(request: polykey_v1_utils_utils_pb.EmptyMessage, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; + sessionsLockAll(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; + sessionsLockAll(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; nodesAdd(request: polykey_v1_nodes_nodes_pb.NodeAddress, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; nodesAdd(request: polykey_v1_nodes_nodes_pb.NodeAddress, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; nodesAdd(request: polykey_v1_nodes_nodes_pb.NodeAddress, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; @@ -897,15 +883,12 @@ export class ClientServiceClient extends grpc.Client implements IClientServiceCl public agentStop(request: polykey_v1_utils_utils_pb.EmptyMessage, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; public agentStop(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; public agentStop(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; - public sessionsUnlock(request: polykey_v1_sessions_sessions_pb.Password, callback: (error: grpc.ServiceError | null, response: polykey_v1_sessions_sessions_pb.Token) => void): grpc.ClientUnaryCall; - public sessionsUnlock(request: polykey_v1_sessions_sessions_pb.Password, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: polykey_v1_sessions_sessions_pb.Token) => void): grpc.ClientUnaryCall; - public sessionsUnlock(request: polykey_v1_sessions_sessions_pb.Password, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: polykey_v1_sessions_sessions_pb.Token) => void): grpc.ClientUnaryCall; - public sessionsRefresh(request: polykey_v1_utils_utils_pb.EmptyMessage, callback: (error: grpc.ServiceError | null, response: polykey_v1_sessions_sessions_pb.Token) => void): grpc.ClientUnaryCall; - public sessionsRefresh(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: polykey_v1_sessions_sessions_pb.Token) => void): grpc.ClientUnaryCall; - public sessionsRefresh(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: polykey_v1_sessions_sessions_pb.Token) => void): grpc.ClientUnaryCall; - public sessionsLockAll(request: polykey_v1_utils_utils_pb.EmptyMessage, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.StatusMessage) => void): grpc.ClientUnaryCall; - public sessionsLockAll(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.StatusMessage) => void): grpc.ClientUnaryCall; - public sessionsLockAll(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.StatusMessage) => void): grpc.ClientUnaryCall; + public sessionsUnlock(request: polykey_v1_utils_utils_pb.EmptyMessage, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; + public sessionsUnlock(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; + public sessionsUnlock(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; + public sessionsLockAll(request: polykey_v1_utils_utils_pb.EmptyMessage, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; + public sessionsLockAll(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; + public sessionsLockAll(request: polykey_v1_utils_utils_pb.EmptyMessage, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; public nodesAdd(request: polykey_v1_nodes_nodes_pb.NodeAddress, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; public nodesAdd(request: polykey_v1_nodes_nodes_pb.NodeAddress, metadata: grpc.Metadata, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; public nodesAdd(request: polykey_v1_nodes_nodes_pb.NodeAddress, metadata: grpc.Metadata, options: Partial, callback: (error: grpc.ServiceError | null, response: polykey_v1_utils_utils_pb.EmptyMessage) => void): grpc.ClientUnaryCall; diff --git a/src/proto/js/polykey/v1/client_service_grpc_pb.js b/src/proto/js/polykey/v1/client_service_grpc_pb.js index 103b234a6..397a11162 100644 --- a/src/proto/js/polykey/v1/client_service_grpc_pb.js +++ b/src/proto/js/polykey/v1/client_service_grpc_pb.js @@ -278,17 +278,6 @@ function deserialize_polykey_v1_sessions_Password(buffer_arg) { return polykey_v1_sessions_sessions_pb.Password.deserializeBinary(new Uint8Array(buffer_arg)); } -function serialize_polykey_v1_sessions_Token(arg) { - if (!(arg instanceof polykey_v1_sessions_sessions_pb.Token)) { - throw new Error('Expected argument of type polykey.v1.sessions.Token'); - } - return Buffer.from(arg.serializeBinary()); -} - -function deserialize_polykey_v1_sessions_Token(buffer_arg) { - return polykey_v1_sessions_sessions_pb.Token.deserializeBinary(new Uint8Array(buffer_arg)); -} - function serialize_polykey_v1_utils_EmptyMessage(arg) { if (!(arg instanceof polykey_v1_utils_utils_pb.EmptyMessage)) { throw new Error('Expected argument of type polykey.v1.utils.EmptyMessage'); @@ -506,34 +495,23 @@ sessionsUnlock: { path: '/polykey.v1.ClientService/SessionsUnlock', requestStream: false, responseStream: false, - requestType: polykey_v1_sessions_sessions_pb.Password, - responseType: polykey_v1_sessions_sessions_pb.Token, - requestSerialize: serialize_polykey_v1_sessions_Password, - requestDeserialize: deserialize_polykey_v1_sessions_Password, - responseSerialize: serialize_polykey_v1_sessions_Token, - responseDeserialize: deserialize_polykey_v1_sessions_Token, - }, - sessionsRefresh: { - path: '/polykey.v1.ClientService/SessionsRefresh', - requestStream: false, - responseStream: false, requestType: polykey_v1_utils_utils_pb.EmptyMessage, - responseType: polykey_v1_sessions_sessions_pb.Token, + responseType: polykey_v1_utils_utils_pb.EmptyMessage, requestSerialize: serialize_polykey_v1_utils_EmptyMessage, requestDeserialize: deserialize_polykey_v1_utils_EmptyMessage, - responseSerialize: serialize_polykey_v1_sessions_Token, - responseDeserialize: deserialize_polykey_v1_sessions_Token, + responseSerialize: serialize_polykey_v1_utils_EmptyMessage, + responseDeserialize: deserialize_polykey_v1_utils_EmptyMessage, }, sessionsLockAll: { path: '/polykey.v1.ClientService/SessionsLockAll', requestStream: false, responseStream: false, requestType: polykey_v1_utils_utils_pb.EmptyMessage, - responseType: polykey_v1_utils_utils_pb.StatusMessage, + responseType: polykey_v1_utils_utils_pb.EmptyMessage, requestSerialize: serialize_polykey_v1_utils_EmptyMessage, requestDeserialize: deserialize_polykey_v1_utils_EmptyMessage, - responseSerialize: serialize_polykey_v1_utils_StatusMessage, - responseDeserialize: deserialize_polykey_v1_utils_StatusMessage, + responseSerialize: serialize_polykey_v1_utils_EmptyMessage, + responseDeserialize: deserialize_polykey_v1_utils_EmptyMessage, }, // Nodes nodesAdd: { diff --git a/src/proto/schemas/polykey/v1/client_service.proto b/src/proto/schemas/polykey/v1/client_service.proto index 03dffd7b3..d27cd8562 100644 --- a/src/proto/schemas/polykey/v1/client_service.proto +++ b/src/proto/schemas/polykey/v1/client_service.proto @@ -20,9 +20,8 @@ service ClientService { rpc AgentStop(polykey.v1.utils.EmptyMessage) returns (polykey.v1.utils.EmptyMessage); // Session - rpc SessionsUnlock (polykey.v1.sessions.Password) returns (polykey.v1.sessions.Token); - rpc SessionsRefresh (polykey.v1.utils.EmptyMessage) returns (polykey.v1.sessions.Token); - rpc SessionsLockAll (polykey.v1.utils.EmptyMessage) returns (polykey.v1.utils.StatusMessage); + rpc SessionsUnlock (polykey.v1.utils.EmptyMessage) returns (polykey.v1.utils.EmptyMessage); + rpc SessionsLockAll (polykey.v1.utils.EmptyMessage) returns (polykey.v1.utils.EmptyMessage); // Nodes rpc NodesAdd(polykey.v1.nodes.NodeAddress) returns (polykey.v1.utils.EmptyMessage); diff --git a/tests/bin/sessions.test.ts b/tests/bin/sessions.test.ts index ab8283f72..c3cf4a1a5 100644 --- a/tests/bin/sessions.test.ts +++ b/tests/bin/sessions.test.ts @@ -53,7 +53,7 @@ describe('CLI Sessions', () => { test('processes should store session token in session file', async () => { // Run command to set token let exitCode, stdout; - ({ exitCode, stdout } = await testBinUtils.pkStdio( + ({ exitCode, stdout } = await testBinUtils.pkExec( ['agent', 'status', '--format', 'json', '--verbose'], { PK_NODE_PATH: global.binAgentDir, @@ -63,9 +63,8 @@ describe('CLI Sessions', () => { )); expect(exitCode).toBe(0); expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); - await sleep(1100); // Try again without password - ({ exitCode, stdout } = await testBinUtils.pkStdio( + ({ exitCode, stdout } = await testBinUtils.pkExec( ['agent', 'status', '--format', 'json', '--verbose'], { PK_NODE_PATH: global.binAgentDir, @@ -82,7 +81,9 @@ describe('CLI Sessions', () => { logger, }); // Generate new token - await testBinUtils.pkStdio( + // Using pkExec such that the asynchronous session token write operation is + // ensured to have been completed at conclusion of command. + await testBinUtils.pkExec( ['agent', 'unlock'], { PK_NODE_PATH: global.binAgentDir, @@ -90,10 +91,9 @@ describe('CLI Sessions', () => { }, global.binAgentDir, ); - await sleep(1100); const token1 = await session.readToken(); // New command should refresh token - const { exitCode, stdout } = await testBinUtils.pkStdio( + const { exitCode, stdout } = await testBinUtils.pkExec( ['agent', 'status', '--format', 'json', '--verbose'], { PK_NODE_PATH: global.binAgentDir, @@ -102,7 +102,6 @@ describe('CLI Sessions', () => { ); expect(exitCode).toBe(0); expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); - await sleep(1100); const token2 = await session.readToken(); expect(token1).not.toBe(token2); }); @@ -114,7 +113,7 @@ describe('CLI Sessions', () => { }); // Run first command let exitCode, stdout; - ({ exitCode, stdout } = await testBinUtils.pkStdio( + ({ exitCode, stdout } = await testBinUtils.pkExec( ['agent', 'status', '--format', 'json', '--verbose'], { PK_NODE_PATH: global.binAgentDir, @@ -124,10 +123,9 @@ describe('CLI Sessions', () => { )); expect(exitCode).toBe(0); expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); - await sleep(1100); const token1 = await session.readToken(); // Run second command - ({ exitCode, stdout } = await testBinUtils.pkStdio( + ({ exitCode, stdout } = await testBinUtils.pkExec( ['agent', 'status', '--format', 'json', '--verbose'], { PK_NODE_PATH: global.binAgentDir, @@ -137,7 +135,6 @@ describe('CLI Sessions', () => { )); expect(exitCode).toBe(0); expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); - await sleep(1100); const token2 = await session.readToken(); // Assert different expect(token1).not.toBe(token2); @@ -180,7 +177,7 @@ describe('CLI Sessions', () => { }); test('cause old sessions to fail when locking all sessions', async () => { // Generate new token - await testBinUtils.pkStdio( + await testBinUtils.pkExec( ['agent', 'unlock'], { PK_NODE_PATH: global.binAgentDir, @@ -188,9 +185,8 @@ describe('CLI Sessions', () => { }, global.binAgentDir, ); - await sleep(1100); // Lockall - await testBinUtils.pkStdio( + await testBinUtils.pkExec( ['agent', 'lockall'], { PK_NODE_PATH: global.binAgentDir, @@ -199,7 +195,7 @@ describe('CLI Sessions', () => { global.binAgentDir, ); // Call should fail because token is invalidated - const { exitCode, stderr } = await testBinUtils.pkStdio( + const { exitCode, stderr } = await testBinUtils.pkExec( ['agent', 'status', '--verbose'], { PK_NODE_PATH: global.binAgentDir, diff --git a/tests/bin/utils.ts b/tests/bin/utils.ts index f196e6157..36e551205 100644 --- a/tests/bin/utils.ts +++ b/tests/bin/utils.ts @@ -127,7 +127,10 @@ async function pkExec( }> { cwd = cwd ?? (await fs.promises.mkdtemp(path.join(os.tmpdir(), 'polykey-test-'))); - env = { ...process.env, ...env }; + env = { + ...process.env, + ...env, + }; const tsConfigPath = path.resolve( path.join(global.projectDir, 'tsconfig.json'), ); @@ -145,6 +148,8 @@ async function pkExec( tsConfigPath, '--require', tsConfigPathsRegisterPath, + '--compiler', + 'typescript-cached-transpile', '--transpile-only', polykeyPath, ...args, @@ -186,7 +191,10 @@ async function pkSpawn( ): Promise { cwd = cwd ?? (await fs.promises.mkdtemp(path.join(os.tmpdir(), 'polykey-test-'))); - env = { ...process.env, ...env }; + env = { + ...process.env, + ...env, + }; const tsConfigPath = path.resolve( path.join(global.projectDir, 'tsconfig.json'), ); @@ -203,6 +211,8 @@ async function pkSpawn( tsConfigPath, '--require', tsConfigPathsRegisterPath, + '--compiler', + 'typescript-cached-transpile', '--transpile-only', polykeyPath, ...args, @@ -243,7 +253,10 @@ async function pkExpect({ }> { cwd = cwd ?? (await fs.promises.mkdtemp(path.join(os.tmpdir(), 'polykey-test-'))); - env = { ...process.env, ...env }; + env = { + ...process.env, + ...env, + }; const tsConfigPath = path.resolve( path.join(global.projectDir, 'tsconfig.json'), ); @@ -261,6 +274,8 @@ async function pkExpect({ tsConfigPath, '--require', tsConfigPathsRegisterPath, + '--compiler', + 'typescript-cached-transpile', '--transpile-only', polykeyPath, ...args, From 7789a4873e6b611c5de45b7e3c9e09539e71dc01 Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Thu, 9 Dec 2021 14:24:39 +1100 Subject: [PATCH 03/29] Session fixes: correct authentication usage for CLI commands, exceptions thrown, deletion of session token on lock --- src/bin/agent/CommandLock.ts | 2 +- src/bin/agent/CommandLockAll.ts | 14 ++++++++++++++ src/bin/agent/CommandStop.ts | 11 +++++------ src/bin/utils/utils.ts | 13 ++++++------- src/client/utils.ts | 2 +- 5 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/bin/agent/CommandLock.ts b/src/bin/agent/CommandLock.ts index 5c408fd8e..60a2cf141 100644 --- a/src/bin/agent/CommandLock.ts +++ b/src/bin/agent/CommandLock.ts @@ -9,7 +9,6 @@ class CommandLock extends CommandPolykey { this.description('Lock the Client and Clear the Existing Token'); this.action(async (options) => { const { default: Session } = await import('../../sessions/Session'); - // Just delete the session token const session = new Session({ sessionTokenPath: path.join( options.nodePath, @@ -18,6 +17,7 @@ class CommandLock extends CommandPolykey { fs: this.fs, logger: this.logger.getChild(Session.name), }); + // Destroy local session await session.destroy(); }); } diff --git a/src/bin/agent/CommandLockAll.ts b/src/bin/agent/CommandLockAll.ts index f18ad7dc6..faa154072 100644 --- a/src/bin/agent/CommandLockAll.ts +++ b/src/bin/agent/CommandLockAll.ts @@ -1,8 +1,10 @@ import type PolykeyClient from '../../PolykeyClient'; +import path from 'path'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; import * as binOptions from '../utils/options'; import * as binProcessors from '../utils/processors'; +import config from '../../config'; class CommandLockAll extends CommandPolykey { constructor(...args: ConstructorParameters) { @@ -14,7 +16,9 @@ class CommandLockAll extends CommandPolykey { this.addOption(binOptions.clientPort); this.action(async (options) => { const { default: PolykeyClient } = await import('../../PolykeyClient'); + const { default: Session } = await import('../../sessions/Session'); const utilsPB = await import('../../proto/js/polykey/v1/utils/utils_pb'); + const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -27,6 +31,14 @@ class CommandLockAll extends CommandPolykey { options.passwordFile, this.fs, ); + const session = new Session({ + sessionTokenPath: path.join( + options.nodePath, + config.defaults.tokenBase, + ), + fs: this.fs, + logger: this.logger.getChild(Session.name), + }); let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); @@ -44,6 +56,8 @@ class CommandLockAll extends CommandPolykey { (auth) => pkClient.grpcClient.sessionsLockAll(emptyMessage, auth), meta, ); + // Destroy local session + await session.destroy(); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/agent/CommandStop.ts b/src/bin/agent/CommandStop.ts index 9c3f78111..80705dd58 100644 --- a/src/bin/agent/CommandStop.ts +++ b/src/bin/agent/CommandStop.ts @@ -34,6 +34,10 @@ class CommandStop extends CommandPolykey { } else if (statusInfo?.status === 'STARTING') { throw new binErrors.ErrorCLIStatusStarting(); } + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); // Either the statusInfo is undefined or LIVE // Either way, the connection parameters now exist let pkClient: PolykeyClient; @@ -48,14 +52,9 @@ class CommandStop extends CommandPolykey { port: clientStatus.clientPort!, logger: this.logger.getChild(PolykeyClient.name), }); - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); const emptyMessage = new utilsPB.EmptyMessage(); - const grpcClient = pkClient.grpcClient; await binUtils.retryAuthentication( - (auth) => grpcClient.agentStop(emptyMessage, auth), + (auth) => pkClient.grpcClient.agentStop(emptyMessage, auth), meta, ); this.logger.info('Stopping Agent'); diff --git a/src/bin/utils/utils.ts b/src/bin/utils/utils.ts index 2978341ee..a5d6f9075 100644 --- a/src/bin/utils/utils.ts +++ b/src/bin/utils/utils.ts @@ -97,14 +97,13 @@ async function retryAuthentication( try { return await f(meta); } catch (e) { - // If it is any exception other than ErrorClientAuthMissing, throw the exception - // If it is ErrorClientAuthMissing and unattended, throw the exception + // If it is unattended, throw the exception + // Don't enter into a retry loop when unattended // Unattended means that either the `PK_PASSWORD` or `PK_TOKEN` was set - if ( - !(e instanceof clientErrors.ErrorClientAuthMissing) || - 'PK_PASSWORD' in process.env || - 'PK_TOKEN' in process.env - ) { + if ('PK_PASSWORD' in process.env || 'PK_TOKEN' in process.env) { + throw e; + } + if (!(e instanceof clientErrors.ErrorClientAuthDenied)) { throw e; } } diff --git a/src/client/utils.ts b/src/client/utils.ts index 1ed23ea1b..64b4f66c0 100644 --- a/src/client/utils.ts +++ b/src/client/utils.ts @@ -76,7 +76,7 @@ function authenticator( const encoded = auth.substring(6); const decoded = base64.base64pad.baseDecode(encoded); const decodedString = String.fromCharCode(...decoded); - const match = decodedString.match(/:(.+)/); + const match = decodedString.match(/:(.*)/); if (match == null) { throw new clientErrors.ErrorClientAuthFormat(); } From b170935cfb9f04df012e1b14500ed39af0c04692 Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Thu, 9 Dec 2021 18:13:03 +1100 Subject: [PATCH 04/29] Integration FlowCountInterceptor to GRPCClient, enabling pkStdio --- package-lock.json | 12 ++- package.json | 1 + src/agent/GRPCClientAgent.ts | 22 +++--- src/bin/agent/CommandUnlock.ts | 2 +- src/bin/utils/utils.ts | 7 +- src/client/GRPCClientClient.ts | 25 +++--- src/client/rpcSessions.ts | 4 - src/client/utils/index.ts | 1 + src/client/{ => utils}/utils.ts | 9 +-- src/grpc/GRPCClient.ts | 44 ++++++++++- src/grpc/utils/FlowCountInterceptor.ts | 105 +++++++++++++++++++++++++ src/grpc/utils/index.ts | 2 + src/grpc/{ => utils}/utils.ts | 10 +-- tests/bin/sessions.test.ts | 7 +- tests/grpc/utils/testService.ts | 2 +- 15 files changed, 201 insertions(+), 52 deletions(-) create mode 100644 src/client/utils/index.ts rename src/client/{ => utils}/utils.ts (95%) create mode 100644 src/grpc/utils/FlowCountInterceptor.ts create mode 100644 src/grpc/utils/index.ts rename src/grpc/{ => utils}/utils.ts (98%) diff --git a/package-lock.json b/package-lock.json index 9b42e0824..758918abc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2446,13 +2446,6 @@ "requires": { "core-js": "^2.4.0", "regenerator-runtime": "^0.11.0" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" - } } }, "balanced-match": { @@ -7955,6 +7948,11 @@ "regenerate": "^1.4.2" } }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, "regenerator-transform": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.5.tgz", diff --git a/package.json b/package.json index baf818195..93a57f7c8 100644 --- a/package.json +++ b/package.json @@ -95,6 +95,7 @@ "pako": "^1.0.11", "prompts": "^2.4.1", "readable-stream": "^3.6.0", + "resource-counter": "^1.2.4", "threads": "^1.6.5", "ts-custom-error": "^3.2.0", "utp-native": "^2.5.3", diff --git a/src/agent/GRPCClientAgent.ts b/src/agent/GRPCClientAgent.ts index 25d5432a7..ce9a22c9a 100644 --- a/src/agent/GRPCClientAgent.ts +++ b/src/agent/GRPCClientAgent.ts @@ -38,16 +38,17 @@ class GRPCClientAgent extends GRPCClient { logger?: Logger; }): Promise { logger.info(`Creating ${this.name}`); - const { client, serverCertChain } = await super.createClient({ - clientConstructor: AgentServiceClient, - nodeId, - host, - port, - tlsConfig, - proxyConfig, - timeout, - logger, - }); + const { client, serverCertChain, flowCountInterceptor } = + await super.createClient({ + clientConstructor: AgentServiceClient, + nodeId, + host, + port, + tlsConfig, + proxyConfig, + timeout, + logger, + }); const grpcClientAgent = new GRPCClientAgent({ client, nodeId, @@ -56,6 +57,7 @@ class GRPCClientAgent extends GRPCClient { tlsConfig, proxyConfig, serverCertChain, + flowCountInterceptor, logger, }); logger.info(`Created ${this.name}`); diff --git a/src/bin/agent/CommandUnlock.ts b/src/bin/agent/CommandUnlock.ts index 278c2292d..3215253a5 100644 --- a/src/bin/agent/CommandUnlock.ts +++ b/src/bin/agent/CommandUnlock.ts @@ -42,7 +42,7 @@ class CommandUnlock extends CommandPolykey { const emptyMessage = new utilsPB.EmptyMessage(); await binUtils.retryAuthentication( (auth) => pkClient.grpcClient.sessionsUnlock(emptyMessage, auth), - meta + meta, ); } finally { if (pkClient! != null) await pkClient.stop(); diff --git a/src/bin/utils/utils.ts b/src/bin/utils/utils.ts index a5d6f9075..fcddf74f3 100644 --- a/src/bin/utils/utils.ts +++ b/src/bin/utils/utils.ts @@ -103,7 +103,11 @@ async function retryAuthentication( if ('PK_PASSWORD' in process.env || 'PK_TOKEN' in process.env) { throw e; } - if (!(e instanceof clientErrors.ErrorClientAuthDenied)) { + // If it is exception is not missing or denied, then throw the exception + if ( + !(e instanceof clientErrors.ErrorClientAuthMissing) && + !(e instanceof clientErrors.ErrorClientAuthDenied) + ) { throw e; } } @@ -119,6 +123,7 @@ async function retryAuthentication( try { return await f(meta); } catch (e) { + // The auth cannot be missing, so when it is denied do we retry if (!(e instanceof clientErrors.ErrorClientAuthDenied)) { throw e; } diff --git a/src/client/GRPCClientClient.ts b/src/client/GRPCClientClient.ts index 7833d91ef..0eb4e5659 100644 --- a/src/client/GRPCClientClient.ts +++ b/src/client/GRPCClientClient.ts @@ -8,7 +8,6 @@ import type * as agentPB from '../proto/js/polykey/v1/agent/agent_pb'; import type * as vaultsPB from '../proto/js/polykey/v1/vaults/vaults_pb'; import type * as nodesPB from '../proto/js/polykey/v1/nodes/nodes_pb'; import type * as notificationsPB from '../proto/js/polykey/v1/notifications/notifications_pb'; -import type * as sessionsPB from '../proto/js/polykey/v1/sessions/sessions_pb'; import type * as gestaltsPB from '../proto/js/polykey/v1/gestalts/gestalts_pb'; import type * as identitiesPB from '../proto/js/polykey/v1/identities/identities_pb'; import type * as keysPB from '../proto/js/polykey/v1/keys/keys_pb'; @@ -54,17 +53,18 @@ class GRPCClientClient extends GRPCClient { if (session != null) { interceptors.push(clientUtils.sessionInterceptor(session)); } - const { client, serverCertChain } = await super.createClient({ - clientConstructor: ClientServiceClient, - nodeId, - host, - port, - tlsConfig, - proxyConfig, - timeout, - interceptors, - logger, - }); + const { client, serverCertChain, flowCountInterceptor } = + await super.createClient({ + clientConstructor: ClientServiceClient, + nodeId, + host, + port, + tlsConfig, + proxyConfig, + timeout, + interceptors, + logger, + }); const grpcClientClient = new GRPCClientClient({ client, nodeId, @@ -73,6 +73,7 @@ class GRPCClientClient extends GRPCClient { tlsConfig, proxyConfig, serverCertChain, + flowCountInterceptor, logger, }); logger.info(`Created ${this.name}`); diff --git a/src/client/rpcSessions.ts b/src/client/rpcSessions.ts index 891482444..25126ba09 100644 --- a/src/client/rpcSessions.ts +++ b/src/client/rpcSessions.ts @@ -1,6 +1,4 @@ import type { SessionManager } from '../sessions'; -import type { KeyManager } from '../keys'; - import type * as grpc from '@grpc/grpc-js'; import type * as utils from './utils'; import * as grpcUtils from '../grpc/utils'; @@ -9,11 +7,9 @@ import * as utilsPB from '../proto/js/polykey/v1/utils/utils_pb'; const createSessionsRPC = ({ authenticate, sessionManager, - keyManager, }: { authenticate: utils.Authenticate; sessionManager: SessionManager; - keyManager: KeyManager; }) => { return { sessionsUnlock: async ( diff --git a/src/client/utils/index.ts b/src/client/utils/index.ts new file mode 100644 index 000000000..04bca77e0 --- /dev/null +++ b/src/client/utils/index.ts @@ -0,0 +1 @@ +export * from './utils'; diff --git a/src/client/utils.ts b/src/client/utils/utils.ts similarity index 95% rename from src/client/utils.ts rename to src/client/utils/utils.ts index 64b4f66c0..581d511e0 100644 --- a/src/client/utils.ts +++ b/src/client/utils/utils.ts @@ -3,13 +3,12 @@ import type { Interceptor, InterceptorOptions, } from '@grpc/grpc-js/build/src/client-interceptors'; -import type { KeyManager } from '../keys'; -import type { Session, SessionManager } from '../sessions'; -import type { SessionToken } from '../sessions/types'; - +import type { KeyManager } from '../../keys'; +import type { Session, SessionManager } from '../../sessions'; +import type { SessionToken } from '../../sessions/types'; import * as grpc from '@grpc/grpc-js'; import * as base64 from 'multiformats/bases/base64'; -import * as clientErrors from './errors'; +import * as clientErrors from '../errors'; /** * Session interceptor middleware for authenticatio diff --git a/src/grpc/GRPCClient.ts b/src/grpc/GRPCClient.ts index 98097bf11..1c2e02bd4 100644 --- a/src/grpc/GRPCClient.ts +++ b/src/grpc/GRPCClient.ts @@ -16,7 +16,7 @@ import * as grpcUtils from './utils'; import * as grpcErrors from './errors'; import { utils as keysUtils } from '../keys'; import { utils as networkUtils, errors as networkErrors } from '../network'; -import { promisify } from '../utils'; +import { promisify, promise, timerStart, timerStop } from '../utils'; abstract class GRPCClient { /** @@ -55,6 +55,7 @@ abstract class GRPCClient { logger?: Logger; }): Promise<{ client: T; + flowCountInterceptor: grpcUtils.FlowCountInterceptor; serverCertChain?: Array; }> { const address = networkUtils.buildAddress(host, port); @@ -80,9 +81,10 @@ abstract class GRPCClient { // Prevents complaints with having an ip address as the server name 'grpc.ssl_target_name_override': nodeId, }; + const flowCountInterceptor = new grpcUtils.FlowCountInterceptor(); const clientOptions: ClientOptions = { // Interceptor middleware on every call - interceptors, + interceptors: [flowCountInterceptor.interceptor, ...interceptors], }; let client: T; if (proxyConfig == null) { @@ -147,7 +149,7 @@ abstract class GRPCClient { } } logger.info(`Created ${this.name} connecting to ${address}`); - return { client, serverCertChain }; + return { client, serverCertChain, flowCountInterceptor }; } public readonly nodeId: NodeId; @@ -159,6 +161,7 @@ abstract class GRPCClient { protected logger: Logger; protected client: T; protected serverCertChain?: Array; + protected flowCountInterceptor?: grpcUtils.FlowCountInterceptor; protected _secured: boolean = false; constructor({ @@ -169,6 +172,7 @@ abstract class GRPCClient { tlsConfig, proxyConfig, serverCertChain, + flowCountInterceptor, logger, }: { client: T; @@ -178,6 +182,7 @@ abstract class GRPCClient { tlsConfig?: Partial; proxyConfig?: ProxyConfig; serverCertChain?: Array; + flowCountInterceptor?: grpcUtils.FlowCountInterceptor; logger: Logger; }) { this.logger = logger; @@ -188,6 +193,7 @@ abstract class GRPCClient { this.tlsConfig = tlsConfig; this.proxyConfig = proxyConfig; this.serverCertChain = serverCertChain; + this.flowCountInterceptor = flowCountInterceptor; if (tlsConfig != null) { this._secured = true; } @@ -197,7 +203,11 @@ abstract class GRPCClient { return this._secured; } - public async destroy(): Promise { + public async destroy({ + timeout, + }: { + timeout?: number; + } = {}): Promise { const address = `${this.host}:${this.port}`; this.logger.info( `Destroying ${this.constructor.name} connected to ${address}`, @@ -205,6 +215,32 @@ abstract class GRPCClient { // This currently doesn't stop all inflight requests // https://github.com/grpc/grpc-node/issues/1340 this.client.close(); + // Block until all flow count is empty + // This ensures asynchronous interceptors are completed + // Before this function returns + if ( + this.flowCountInterceptor != null && + this.flowCountInterceptor.flowCount !== 0 + ) { + const { p: flowEmptyP, resolveP: resolveFlowEmptyP } = promise(); + this.flowCountInterceptor.once('empty', () => { + resolveFlowEmptyP(); + }); + const timer = timeout != null ? timerStart(timeout) : undefined; + try { + await Promise.race([ + flowEmptyP, + ...(timer != null ? [timer.timerP] : []), + ]); + } finally { + if (timer != null) timerStop(timer); + } + if (timer?.timedOut) { + this.logger.info( + `Timed out stopping ${this.constructor.name}, forcing destroy`, + ); + } + } this.logger.info( `Destroyed ${this.constructor.name} connected to ${address}`, ); diff --git a/src/grpc/utils/FlowCountInterceptor.ts b/src/grpc/utils/FlowCountInterceptor.ts new file mode 100644 index 000000000..b4aefb57e --- /dev/null +++ b/src/grpc/utils/FlowCountInterceptor.ts @@ -0,0 +1,105 @@ +import type { + NextCall, + Interceptor, + InterceptorOptions, +} from '@grpc/grpc-js/build/src/client-interceptors'; +import EventEmitter from 'events'; +import Counter from 'resource-counter'; +import * as grpc from '@grpc/grpc-js'; + +/** + * Client-side flow count interceptor + * A flow count is a count of the number flows + * A flow is the entire asynchronous GRPC call including asynchronous interceptor operations + * Except for onReceiveMessage, any asynchronous operations in the inteceptors counts towards an active flow + * Must be used as the FIRST interceptor in the interceptor list + * This is only necessary while GRPC doesn't support awaiting asynchronous interceptors + */ +class FlowCountInterceptor extends EventEmitter { + /** + * This is the actual interceptor needed by GRPC + * It is an arrow function property so that `this` is bound + */ + public readonly interceptor: Interceptor = ( + options: InterceptorOptions, + nextCall: NextCall, + ) => { + const flowId = this.createFlow(); + const requester = { + start: (metadata, _, next) => { + next(metadata, { + onReceiveMetadata: (metadata, next) => { + // On leading metadata, subtract the flow count + // Leading metadata is always received first before messages + // Or steam data chunks + // And before the trailing status + this.subtractFlow(flowId); + next(metadata); + }, + onReceiveStatus: (status, next) => { + // Trailing status occurs at the end of responses and streams + if (status.code !== grpc.status.OK) { + // On trailing status, the leading metadata may or may not have executed + // For example exceeding the deadline results in a local + // deadline status which can occur before leading metadata is sent + // If the flow count is 1, then leading metadata has been received + // If the flow count is 2, then the leading metadata has not been received + const flowCount = this.flows.get(flowId); + if (flowCount === 1) { + this.subtractFlow(flowId); + } else if (flowCount === 2) { + this.destroyFlow(flowId); + } + } else { + // Under normal conditions, we woulde expect the leading metadata to have been sent + this.subtractFlow(flowId); + } + next(status); + return; + }, + }); + }, + cancel: (next) => { + // If the client cancels, destroy the flow + this.destroyFlow(flowId); + next(); + return; + }, + }; + return new grpc.InterceptingCall(nextCall(options), requester); + }; + protected flows: Map = new Map(); + protected counter: Counter = new Counter(); + + get flowCount(): number { + return this.flows.size; + } + + protected createFlow(): number { + const flowId = this.counter.allocate(); + // Only 2 asynchronous inbound interceptors have to be tracked + // leading metadata and trailing status interceptors + const flowCount = 2; + this.flows.set(flowId, flowCount); + return flowId; + } + + protected subtractFlow(flowId: number): void { + let count = this.flows.get(flowId)!; + if (--count > 0) { + this.flows.set(flowId, count); + } else { + this.destroyFlow(flowId); + } + } + + protected destroyFlow(flowId: number): void { + this.flows.delete(flowId); + this.counter.deallocate(flowId); + if (this.flows.size === 0) { + this.emit('empty'); + } + } +} + +export default FlowCountInterceptor; diff --git a/src/grpc/utils/index.ts b/src/grpc/utils/index.ts new file mode 100644 index 000000000..73125dbb8 --- /dev/null +++ b/src/grpc/utils/index.ts @@ -0,0 +1,2 @@ +export { default as FlowCountInterceptor } from './FlowCountInterceptor'; +export * from './utils'; diff --git a/src/grpc/utils.ts b/src/grpc/utils/utils.ts similarity index 98% rename from src/grpc/utils.ts rename to src/grpc/utils/utils.ts index f14aeddb3..1dbb4f6bf 100644 --- a/src/grpc/utils.ts +++ b/src/grpc/utils/utils.ts @@ -25,14 +25,14 @@ import type { AsyncGeneratorWritableStreamClient, AsyncGeneratorDuplexStream, AsyncGeneratorDuplexStreamClient, -} from './types'; -import type { CertificatePemChain, PrivateKeyPem } from '../keys/types'; +} from '../types'; +import type { CertificatePemChain, PrivateKeyPem } from '../../keys/types'; import { Buffer } from 'buffer'; import * as grpc from '@grpc/grpc-js'; -import * as grpcErrors from './errors'; -import * as errors from '../errors'; -import { promisify, promise, never } from '../utils'; +import * as grpcErrors from '../errors'; +import * as errors from '../../errors'; +import { promisify, promise, never } from '../../utils'; /** * GRPC insecure credentials for the client diff --git a/tests/bin/sessions.test.ts b/tests/bin/sessions.test.ts index c3cf4a1a5..c6ad65077 100644 --- a/tests/bin/sessions.test.ts +++ b/tests/bin/sessions.test.ts @@ -23,7 +23,10 @@ describe('CLI Sessions', () => { ]); let dataDir: string; let pkAgentClose; - const sessionTokenPath = path.join(global.binAgentDir, config.defaults.tokenBase); + const sessionTokenPath = path.join( + global.binAgentDir, + config.defaults.tokenBase, + ); beforeAll(async () => { pkAgentClose = await testBinUtils.pkAgent(); }, global.maxTimeout); @@ -82,7 +85,7 @@ describe('CLI Sessions', () => { }); // Generate new token // Using pkExec such that the asynchronous session token write operation is - // ensured to have been completed at conclusion of command. + // ensured to have been completed at conclusion of command. await testBinUtils.pkExec( ['agent', 'unlock'], { diff --git a/tests/grpc/utils/testService.ts b/tests/grpc/utils/testService.ts index 20e2002f1..b6ee75236 100644 --- a/tests/grpc/utils/testService.ts +++ b/tests/grpc/utils/testService.ts @@ -75,7 +75,7 @@ function createTestService({ new grpcErrors.ErrorGRPC('test error', { grpc: true }), ); } else { - // Will send back a number of messsage + // Will send back a number of message // equal to the character length of the challenge string for (let i = 0; i < messageFrom.getChallenge().length; i++) { messageTo.setChallenge(messageFrom.getChallenge()); From bdc263386c228277bbda17783e12b76712d6f290 Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Fri, 10 Dec 2021 12:23:25 +1100 Subject: [PATCH 05/29] Ensure proper return for callback for `agentStop` and `sessionsUnlock` and `sessionsLockAll` --- src/client/clientService.ts | 4 +++- src/client/rpcSessions.ts | 12 ++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/client/clientService.ts b/src/client/clientService.ts index 5b4a7ef6d..dccde74a5 100644 --- a/src/client/clientService.ts +++ b/src/client/clientService.ts @@ -128,7 +128,8 @@ function createClientService({ ): Promise => { const response = new utilsPB.EmptyMessage(); if (!polykeyAgent.running) { - return callback(null, response); + callback(null, response); + return; } try { const metadata = await authenticate(call.metadata); @@ -137,6 +138,7 @@ function createClientService({ callback(null, response); } catch (err) { callback(grpcUtils.fromError(err), null); + return; } // Stop is called after GRPC resources are cleared await polykeyAgent.stop(); diff --git a/src/client/rpcSessions.ts b/src/client/rpcSessions.ts index 25126ba09..0d4f72231 100644 --- a/src/client/rpcSessions.ts +++ b/src/client/rpcSessions.ts @@ -20,9 +20,11 @@ const createSessionsRPC = ({ try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); - return callback(null, response); + callback(null, response); + return; } catch (e) { - return callback(grpcUtils.fromError(e), null); + callback(grpcUtils.fromError(e), null); + return; } }, sessionsLockAll: async ( @@ -34,9 +36,11 @@ const createSessionsRPC = ({ const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); await sessionManager.resetKey(); - return callback(null, response); + callback(null, response); + return; } catch (err) { - return callback(grpcUtils.fromError(err), null); + callback(grpcUtils.fromError(err), null); + return; } }, }; From 8c530c01807b3eeebd4bf61ad9cf595935fc3a69 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Fri, 10 Dec 2021 13:00:43 +1100 Subject: [PATCH 06/29] Adding returns to all GRPC handlers Parsing new password seperately from existing password Agent lock, unlock and lockall tests --- src/bin/keys/CommandPassword.ts | 18 +++-- src/bin/keys/CommandRenew.ts | 18 +++-- src/bin/keys/CommandReset.ts | 18 +++-- src/client/clientService.ts | 2 +- src/client/rpcGestalts.ts | 50 ++++++++++---- src/client/rpcIdentities.ts | 44 ++++++++---- src/client/rpcKeys.ts | 56 ++++++++++----- src/client/rpcNodes.ts | 24 ++++--- src/client/rpcNotifications.ts | 18 +++-- src/client/rpcSessions.ts | 4 +- src/client/rpcStatus.ts | 2 + src/client/rpcVaults.ts | 50 ++++++++++++-- tests/bin/agent/lock.test.ts | 58 ++++++++++++++++ tests/bin/agent/lockall.test.ts | 117 ++++++++++++++++++++++++++++++++ tests/bin/agent/unlock.test.ts | 92 +++++++++++++++++++++++++ tests/bin/sessions.test.ts | 106 ++--------------------------- 16 files changed, 496 insertions(+), 181 deletions(-) create mode 100644 tests/bin/agent/lock.test.ts create mode 100644 tests/bin/agent/lockall.test.ts create mode 100644 tests/bin/agent/unlock.test.ts diff --git a/src/bin/keys/CommandPassword.ts b/src/bin/keys/CommandPassword.ts index 3532f8fa5..9600615e7 100644 --- a/src/bin/keys/CommandPassword.ts +++ b/src/bin/keys/CommandPassword.ts @@ -1,6 +1,7 @@ import type { Metadata } from '@grpc/grpc-js'; import type PolykeyClient from '../../PolykeyClient'; +import * as binErrors from '../errors'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; import * as binOptions from '../utils/options'; @@ -53,10 +54,19 @@ class CommandPassword extends CommandPolykey { const grpcClient = pkClient.grpcClient; const passwordMessage = new sessionsPB.Password(); - const password = await binProcessors.processPassword( - passwordPath, - this.fs, - ); + let password: string | undefined; + try { + password = ( + await this.fs.promises.readFile(passwordPath, 'utf-8') + ).trim(); + } catch (e) { + throw new binErrors.ErrorCLIPasswordFileRead(e.message, { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }); + } passwordMessage.setPassword(password); await binUtils.retryAuthentication( diff --git a/src/bin/keys/CommandRenew.ts b/src/bin/keys/CommandRenew.ts index d3472f51e..83019a656 100644 --- a/src/bin/keys/CommandRenew.ts +++ b/src/bin/keys/CommandRenew.ts @@ -1,6 +1,7 @@ import type { Metadata } from '@grpc/grpc-js'; import type PolykeyClient from '../../PolykeyClient'; +import * as binErrors from '../errors'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; import * as binOptions from '../utils/options'; @@ -51,10 +52,19 @@ class CommandRenew extends CommandPolykey { const grpcClient = pkClient.grpcClient; const keyMessage = new keysPB.Key(); - const password = await binProcessors.processPassword( - passwordPath, - this.fs, - ); + let password: string | undefined; + try { + password = ( + await this.fs.promises.readFile(passwordPath, 'utf-8') + ).trim(); + } catch (e) { + throw new binErrors.ErrorCLIPasswordFileRead(e.message, { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }); + } keyMessage.setName(password); await binUtils.retryAuthentication( diff --git a/src/bin/keys/CommandReset.ts b/src/bin/keys/CommandReset.ts index d8b4b0f47..59b7f9f1b 100644 --- a/src/bin/keys/CommandReset.ts +++ b/src/bin/keys/CommandReset.ts @@ -1,6 +1,7 @@ import type { Metadata } from '@grpc/grpc-js'; import type PolykeyClient from '../../PolykeyClient'; +import * as binErrors from '../errors'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; import * as binOptions from '../utils/options'; @@ -51,10 +52,19 @@ class CommandReset extends CommandPolykey { const grpcClient = pkClient.grpcClient; const keyMessage = new keysPB.Key(); - const password = await binProcessors.processPassword( - passwordPath, - this.fs, - ); + let password: string | undefined; + try { + password = ( + await this.fs.promises.readFile(passwordPath, 'utf-8') + ).trim(); + } catch (e) { + throw new binErrors.ErrorCLIPasswordFileRead(e.message, { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }); + } keyMessage.setName(password); await binUtils.retryAuthentication( diff --git a/src/client/clientService.ts b/src/client/clientService.ts index dccde74a5..ec3946311 100644 --- a/src/client/clientService.ts +++ b/src/client/clientService.ts @@ -77,7 +77,6 @@ function createClientService({ ...createSessionsRPC({ authenticate, sessionManager, - keyManager, }), ...createVaultRPC({ vaultManager, @@ -121,6 +120,7 @@ function createClientService({ const write = promisify(call.write).bind(call); await write(nodeMessage); call.end(); + return; }, agentStop: async ( call: grpc.ServerUnaryCall, diff --git a/src/client/rpcGestalts.ts b/src/client/rpcGestalts.ts index ef0731f72..afbe69ac6 100644 --- a/src/client/rpcGestalts.ts +++ b/src/client/rpcGestalts.ts @@ -42,10 +42,12 @@ const createGestaltsRPC = ({ if (gestalt != null) { response.setGestaltGraph(JSON.stringify(gestalt)); } + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, gestaltsGestaltGetByIdentity: async ( call: grpc.ServerUnaryCall, @@ -63,10 +65,12 @@ const createGestaltsRPC = ({ if (gestalt != null) { response.setGestaltGraph(JSON.stringify(gestalt)); } + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, gestaltsGestaltList: async ( call: grpc.ServerWritableStream, @@ -84,8 +88,10 @@ const createGestaltsRPC = ({ await genWritable.next(gestaltMessage); } await genWritable.next(null); + return; } catch (err) { await genWritable.throw(err); + return; } }, gestaltsDiscoveryByNode: async ( @@ -93,7 +99,7 @@ const createGestaltsRPC = ({ callback: grpc.sendUnaryData, ): Promise => { const info = call.request; - const emptyMessage = new utilsPB.EmptyMessage(); + const response = new utilsPB.EmptyMessage(); try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); @@ -104,17 +110,19 @@ const createGestaltsRPC = ({ for await (const _ of gen) { // Empty } + callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } - callback(null, emptyMessage); }, gestaltsDiscoveryByIdentity: async ( call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData, ): Promise => { const info = call.request; - const emptyMessage = new utilsPB.EmptyMessage(); + const response = new utilsPB.EmptyMessage(); try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); @@ -126,10 +134,12 @@ const createGestaltsRPC = ({ for await (const _ of gen) { // Empty } + callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } - callback(null, emptyMessage); }, gestaltsActionsGetByNode: async ( call: grpc.ServerUnaryCall, @@ -152,10 +162,12 @@ const createGestaltsRPC = ({ const actions = Object.keys(result); response.setActionList(actions); } + callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, gestaltsActionsGetByIdentity: async ( call: grpc.ServerUnaryCall, @@ -181,10 +193,12 @@ const createGestaltsRPC = ({ const actions = Object.keys(result); response.setActionList(actions); } + callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, gestaltsActionsSetByNode: async ( call: grpc.ServerUnaryCall, @@ -212,10 +226,12 @@ const createGestaltsRPC = ({ const action = makeGestaltAction(info.getAction()); const nodeId = makeNodeId(info.getNode()?.getNodeId()); await gestaltGraph.setGestaltActionByNode(nodeId, action); + callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, gestaltsActionsSetByIdentity: async ( call: grpc.ServerUnaryCall, @@ -248,10 +264,12 @@ const createGestaltsRPC = ({ identityId, action, ); + callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, gestaltsActionsUnsetByNode: async ( call: grpc.ServerUnaryCall, @@ -279,10 +297,12 @@ const createGestaltsRPC = ({ const action = makeGestaltAction(info.getAction()); const nodeId = makeNodeId(info.getNode()?.getNodeId()); await gestaltGraph.unsetGestaltActionByNode(nodeId, action); + callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, gestaltsActionsUnsetByIdentity: async ( call: grpc.ServerUnaryCall, @@ -315,10 +335,12 @@ const createGestaltsRPC = ({ identityId, action, ); + callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, }; }; diff --git a/src/client/rpcIdentities.ts b/src/client/rpcIdentities.ts index 5ac508d58..2810208df 100644 --- a/src/client/rpcIdentities.ts +++ b/src/client/rpcIdentities.ts @@ -62,8 +62,10 @@ const createIdentitiesRPC = ({ response.setMessage(userName); await genWritable.next(response); await genWritable.next(null); + return; } catch (err) { await genWritable.throw(err); + return; } }, identitiesTokenPut: async ( @@ -84,10 +86,12 @@ const createIdentitiesRPC = ({ provider?.getMessage() as IdentityId, { accessToken: call.request.getToken() } as TokenData, ); + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, identitiesTokenGet: async ( call: grpc.ServerUnaryCall, @@ -103,10 +107,12 @@ const createIdentitiesRPC = ({ call.request.getMessage() as IdentityId, ); response.setToken(JSON.stringify(tokens)); + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, identitiesTokenDelete: async ( call: grpc.ServerUnaryCall, @@ -121,10 +127,12 @@ const createIdentitiesRPC = ({ call.request.getProviderId() as ProviderId, call.request.getMessage() as IdentityId, ); + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, identitiesProvidersList: async ( call: grpc.ServerUnaryCall, @@ -137,10 +145,12 @@ const createIdentitiesRPC = ({ const providers = identitiesManager.getProviders(); response.setProviderId(JSON.stringify(Object.keys(providers))); + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, identitiesInfoGetConnected: async ( call: grpc.ServerWritableStream< @@ -182,8 +192,10 @@ const createIdentitiesRPC = ({ await genWritable.next(identityInfoMessage); } await genWritable.next(null); + return; } catch (err) { await genWritable.throw(err); + return; } }, /** @@ -193,22 +205,24 @@ const createIdentitiesRPC = ({ call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData, ): Promise => { + const response = new identitiesPB.Provider(); try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); // Get's an identity out of all identities. - const providerMessage = new identitiesPB.Provider(); const providerId = call.request.getProviderId() as ProviderId; const provider = identitiesManager.getProvider(providerId); if (provider == null) throw Error(`Invalid provider: ${providerId}`); const identities = await provider.getAuthIdentityIds(); if (identities.length !== 0) { - providerMessage.setProviderId(providerId); - providerMessage.setMessage(identities[0]); + response.setProviderId(providerId); + response.setMessage(identities[0]); } else throw Error(`No identities found for provider: ${providerId}`); - callback(null, providerMessage); + callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } }, /** @@ -220,6 +234,7 @@ const createIdentitiesRPC = ({ ): Promise => { // To augment a keynode we need a provider, generate an oauthkey and then const info = call.request; + const response = new utilsPB.EmptyMessage(); try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); @@ -239,11 +254,12 @@ const createIdentitiesRPC = ({ await gestaltGraph.linkNodeAndIdentity(nodeInfo, identityInfo); // Need to call this // it takes NodeInfo and IdentityInfo. // Getting and creating NodeInfo is blocked by + callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } - const emptyMessage = new utilsPB.EmptyMessage(); - callback(null, emptyMessage); }, }; }; diff --git a/src/client/rpcKeys.ts b/src/client/rpcKeys.ts index a52ca16b9..3363dd326 100644 --- a/src/client/rpcKeys.ts +++ b/src/client/rpcKeys.ts @@ -39,10 +39,12 @@ const createKeysRPC = ({ const keyPair = keyManager.getRootKeyPairPem(); response.setPublic(keyPair.publicKey); response.setPrivate(keyPair.privateKey); + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, keysKeyPairReset: async ( call: grpc.ServerUnaryCall, @@ -67,10 +69,12 @@ const createKeysRPC = ({ // Finally, refresh the node buckets await nodeManager.refreshBuckets(); }); + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, keysKeyPairRenew: async ( call: grpc.ServerUnaryCall, @@ -94,10 +98,12 @@ const createKeysRPC = ({ // Finally, refresh the node buckets await nodeManager.refreshBuckets(); }); + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, keysEncrypt: async ( call: grpc.ServerUnaryCall, @@ -112,10 +118,12 @@ const createKeysRPC = ({ Buffer.from(call.request.getData(), 'binary'), ); response.setData(data.toString('binary')); + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, keysDecrypt: async ( call: grpc.ServerUnaryCall, @@ -130,10 +138,12 @@ const createKeysRPC = ({ Buffer.from(call.request.getData(), 'binary'), ); response.setData(data.toString('binary')); + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, keysSign: async ( call: grpc.ServerUnaryCall, @@ -148,10 +158,12 @@ const createKeysRPC = ({ Buffer.from(call.request.getData(), 'binary'), ); response.setSignature(signature.toString('binary')); + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, keysVerify: async ( call: grpc.ServerUnaryCall, @@ -167,10 +179,12 @@ const createKeysRPC = ({ Buffer.from(call.request.getSignature(), 'binary'), ); response.setSuccess(status); + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, keysPasswordChange: async ( call: grpc.ServerUnaryCall, @@ -182,10 +196,12 @@ const createKeysRPC = ({ call.sendMetadata(metadata); await keyManager.changePassword(call.request.getPassword()); + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, keysCertsGet: async ( call: grpc.ServerUnaryCall, @@ -198,10 +214,12 @@ const createKeysRPC = ({ const cert = keyManager.getRootCertPem(); response.setCert(cert); + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, keysCertsChainGet: async ( call: grpc.ServerWritableStream, @@ -219,8 +237,10 @@ const createKeysRPC = ({ await genWritable.next(certMessage); } await genWritable.next(null); + return; } catch (err) { await genWritable.throw(err); + return; } }, }; diff --git a/src/client/rpcNodes.ts b/src/client/rpcNodes.ts index 2a0c9ed17..6579a59d1 100644 --- a/src/client/rpcNodes.ts +++ b/src/client/rpcNodes.ts @@ -50,10 +50,12 @@ const createNodesRPC = ({ ip: call.request.getAddress()!.getHost(), port: call.request.getAddress()!.getPort(), } as NodeAddress); + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, /** * Checks if a remote node is online. @@ -71,10 +73,12 @@ const createNodesRPC = ({ makeNodeId(call.request.getNodeId()), ); response.setSuccess(status); + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, /** * Checks whether there is an existing Gestalt Invitation from the other node. @@ -108,10 +112,12 @@ const createNodesRPC = ({ await nodeManager.claimNode(remoteNodeId); response.setSuccess(true); } + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, /** * Attempts to get the node address of a provided node ID (by contacting @@ -134,10 +140,12 @@ const createNodesRPC = ({ .setAddress( new nodesPB.Address().setHost(address.ip).setPort(address.port), ); + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, }; }; diff --git a/src/client/rpcNotifications.ts b/src/client/rpcNotifications.ts index 0376b6077..62507d444 100644 --- a/src/client/rpcNotifications.ts +++ b/src/client/rpcNotifications.ts @@ -20,6 +20,7 @@ const createNotificationsRPC = ({ call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData, ): Promise => { + const response = new utilsPB.EmptyMessage(); try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); @@ -32,11 +33,12 @@ const createNotificationsRPC = ({ const validatedData = notificationsUtils.validateGeneralNotification(data); await notificationsManager.sendNotification(receivingId, validatedData); + callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } - const emptyMessage = new utilsPB.EmptyMessage(); - callback(null, emptyMessage); }, notificationsRead: async ( call: grpc.ServerUnaryCall, @@ -91,25 +93,29 @@ const createNotificationsRPC = ({ notifMessages.push(notificationsMessage); } response.setNotificationList(notifMessages); + callback(null, response); + return; } catch (err) { - callback(grpcUtils.fromError(err), response); + callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, notificationsClear: async ( call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData, ): Promise => { + const response = new utilsPB.EmptyMessage(); try { const metadata = await authenticate(call.metadata); call.sendMetadata(metadata); await notificationsManager.clearNotifications(); + callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } - const emptyMessage = new utilsPB.EmptyMessage(); - callback(null, emptyMessage); }, }; }; diff --git a/src/client/rpcSessions.ts b/src/client/rpcSessions.ts index 0d4f72231..e535c5f67 100644 --- a/src/client/rpcSessions.ts +++ b/src/client/rpcSessions.ts @@ -22,8 +22,8 @@ const createSessionsRPC = ({ call.sendMetadata(metadata); callback(null, response); return; - } catch (e) { - callback(grpcUtils.fromError(e), null); + } catch (err) { + callback(grpcUtils.fromError(err), null); return; } }, diff --git a/src/client/rpcStatus.ts b/src/client/rpcStatus.ts index 1d939ead1..d0d1e5480 100644 --- a/src/client/rpcStatus.ts +++ b/src/client/rpcStatus.ts @@ -48,8 +48,10 @@ const createStatusRPC = ({ response.setRootCertPem(keyManager.getRootCertPem()); response.setRootCertChainPem(await keyManager.getRootCertChainPem()); callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } }, }; diff --git a/src/client/rpcVaults.ts b/src/client/rpcVaults.ts index 15158edef..16be5875b 100644 --- a/src/client/rpcVaults.ts +++ b/src/client/rpcVaults.ts @@ -51,8 +51,10 @@ const createVaultRPC = ({ await genWritable.next(((_) => vaultListMessage)()); } await genWritable.next(null); + return; } catch (err) { await genWritable.throw(err); + return; } }, vaultsCreate: async ( @@ -69,10 +71,12 @@ const createVaultRPC = ({ call.request.getNameOrId() as VaultName, ); response.setNameOrId(vaultsUtils.makeVaultIdPretty(vault.vaultId)); + callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } - callback(null, response); }, vaultsRename: async ( call: grpc.ServerUnaryCall, @@ -96,8 +100,10 @@ const createVaultRPC = ({ await vaultManager.renameVault(vaultId, newName); response.setNameOrId(vaultsUtils.makeVaultIdPretty(vaultId)); callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } }, vaultsDelete: async ( @@ -117,8 +123,10 @@ const createVaultRPC = ({ await vaultManager.destroyVault(vaultId); response.setSuccess(true); callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } }, vaultsClone: async ( @@ -150,8 +158,10 @@ const createVaultRPC = ({ // await vaultManager.cloneVault(vaultId, id); response.setSuccess(true); callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } }, vaultsPull: async ( @@ -181,8 +191,10 @@ const createVaultRPC = ({ // Await vaultManager.pullVault(vaultId, id); response.setSuccess(true); callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } }, vaultsScan: async ( @@ -203,8 +215,10 @@ const createVaultRPC = ({ await genWritable.next(vaultListMessage); }); await genWritable.next(null); + return; } catch (err) { await genWritable.throw(err); + return; } }, vaultsSecretsList: async ( @@ -230,8 +244,10 @@ const createVaultRPC = ({ await genWritable.next(secretMessage); } await genWritable.next(null); + return; } catch (err) { await genWritable.throw(err); + return; } }, vaultsSecretsMkdir: async ( @@ -259,8 +275,10 @@ const createVaultRPC = ({ }); response.setSuccess(true); callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } }, vaultsSecretsStat: async ( @@ -280,8 +298,10 @@ const createVaultRPC = ({ // Const stats = await vaultManager.vaultStats(id); // response.setStats(JSON.stringify(stats));); callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } }, vaultsSecretsDelete: async ( @@ -307,8 +327,10 @@ const createVaultRPC = ({ await vaultOps.deleteSecret(vault, secretName); response.setSuccess(true); callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } }, vaultsSecretsEdit: async ( @@ -340,8 +362,10 @@ const createVaultRPC = ({ await vaultOps.updateSecret(vault, secretName, secretContent); response.setSuccess(true); callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } }, vaultsSecretsGet: async ( @@ -368,8 +392,10 @@ const createVaultRPC = ({ response.setSecretContent(secretContent); callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } }, vaultsSecretsRename: async ( @@ -401,8 +427,10 @@ const createVaultRPC = ({ await vaultOps.renameSecret(vault, oldSecret, newSecret); response.setSuccess(true); callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } }, vaultsSecretsNew: async ( @@ -429,8 +457,10 @@ const createVaultRPC = ({ await vaultOps.addSecret(vault, secret, content); response.setSuccess(true); callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } }, vaultsSecretsNewDir: async ( @@ -456,8 +486,10 @@ const createVaultRPC = ({ await vaultOps.addSecretDirectory(vault, secretsPath, fs); response.setSuccess(true); callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } }, vaultsPermissionsSet: async ( @@ -485,8 +517,10 @@ const createVaultRPC = ({ const response = new utilsPB.StatusMessage(); response.setSuccess(true); callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } }, vaultsPermissionsUnset: async ( @@ -514,8 +548,10 @@ const createVaultRPC = ({ const response = new utilsPB.StatusMessage(); response.setSuccess(true); callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } }, vaultsPermissions: async ( @@ -556,14 +592,17 @@ const createVaultRPC = ({ // await genWritable.next(permissionMessage); // } await genWritable.next(null); + return; } catch (err) { await genWritable.throw(err); + return; } }, vaultsVersion: async ( call: grpc.ServerUnaryCall, callback: grpc.sendUnaryData, ): Promise => { + const response = new vaultsPB.VersionResult(); try { // Checking session token const metadata = await authenticate(call.metadata); @@ -594,13 +633,14 @@ const createVaultRPC = ({ const isLatestVersion = latestOid === currentVersionId; // Creating message - const vaultsVersionResultMessage = new vaultsPB.VersionResult(); - vaultsVersionResultMessage.setIsLatestVersion(isLatestVersion); + response.setIsLatestVersion(isLatestVersion); // Sending message - callback(null, vaultsVersionResultMessage); + callback(null, response); + return; } catch (err) { callback(grpcUtils.fromError(err), null); + return; } }, vaultsLog: async ( @@ -638,8 +678,10 @@ const createVaultRPC = ({ await genWritable.next(vaultsLogEntryMessage); } await genWritable.next(null); + return; } catch (err) { await genWritable.throw(err); + return; } }, }; diff --git a/tests/bin/agent/lock.test.ts b/tests/bin/agent/lock.test.ts new file mode 100644 index 000000000..92507181e --- /dev/null +++ b/tests/bin/agent/lock.test.ts @@ -0,0 +1,58 @@ +import type { SessionToken } from '@/sessions/types'; +import os from 'os'; +import path from 'path'; +import fs from 'fs'; +import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; +import { Session } from '@/sessions'; +import config from '@/config'; +import * as testBinUtils from '../utils'; + +describe('lock', () => { + const logger = new Logger('lock test', LogLevel.WARN, [new StreamHandler()]); + let dataDir: string; + let pkAgentClose; + const sessionTokenPath = path.join( + global.binAgentDir, + config.defaults.tokenBase, + ); + beforeAll(async () => { + pkAgentClose = await testBinUtils.pkAgent(); + }, global.maxTimeout); + afterAll(async () => { + await pkAgentClose(); + }); + beforeEach(async () => { + dataDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'polykey-test-'), + ); + }); + afterEach(async () => { + await fs.promises.rm(dataDir, { + force: true, + recursive: true, + }); + }); + test('should delete the session file', async () => { + // Ensure session file exists + const session = await Session.createSession({ + sessionTokenPath, + fs, + logger, + }); + await session.writeToken('abc' as SessionToken); + // Run command + const { exitCode } = await testBinUtils.pkStdio( + ['agent', 'lock'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); + expect(exitCode).toBe(0); + // Check file does not exist + await expect( + fs.promises.readdir(path.join(global.binAgentDir)), + ).resolves.not.toContain('token'); + }); +}); diff --git a/tests/bin/agent/lockall.test.ts b/tests/bin/agent/lockall.test.ts new file mode 100644 index 000000000..48648a389 --- /dev/null +++ b/tests/bin/agent/lockall.test.ts @@ -0,0 +1,117 @@ +import os from 'os'; +import path from 'path'; +import fs from 'fs'; +import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; +import { Session } from '@/sessions'; +import config from '@/config'; +import * as clientErrors from '@/client/errors'; +import * as testBinUtils from '../utils'; + +describe('lockall', () => { + const logger = new Logger('lockall test', LogLevel.WARN, [ + new StreamHandler(), + ]); + let dataDir: string; + let pkAgentClose; + const sessionTokenPath = path.join( + global.binAgentDir, + config.defaults.tokenBase, + ); + beforeAll(async () => { + pkAgentClose = await testBinUtils.pkAgent(); + }, global.maxTimeout); + afterAll(async () => { + await pkAgentClose(); + }); + beforeEach(async () => { + dataDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'polykey-test-'), + ); + // Invalidate all active sessions + await testBinUtils.pkStdio( + ['agent', 'lock'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); + }); + afterEach(async () => { + await fs.promises.rm(dataDir, { + force: true, + recursive: true, + }); + }); + test('cause old sessions to fail when locking all sessions', async () => { + // Generate new token + await testBinUtils.pkStdio( + ['agent', 'unlock'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); + // Read token + const session = await Session.createSession({ + sessionTokenPath, + fs, + logger, + }); + const token = await session.readToken(); + // Run command + await testBinUtils.pkStdio( + ['agent', 'lockall'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); + // Call should fail because token is invalidated + const { exitCode, stderr } = await testBinUtils.pkStdio( + ['agent', 'status', '--verbose'], + { + PK_NODE_PATH: global.binAgentDir, + PK_TOKEN: token, + }, + global.binAgentDir, + ); + testBinUtils.expectProcessError( + exitCode, + stderr, + new clientErrors.ErrorClientAuthDenied(), + ); + }); + test('should fail to lock all sessions if agent stopped', async () => { + // Stop agent + await testBinUtils.pkStdio( + ['agent', 'stop'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); + // Run unlock command + const { exitCode } = await testBinUtils.pkStdio( + ['agent', 'lockall'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); + expect(exitCode).toBe(64); + // Undo side-effects + await testBinUtils.pkStdio( + ['agent', 'start'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); + }); +}); diff --git a/tests/bin/agent/unlock.test.ts b/tests/bin/agent/unlock.test.ts new file mode 100644 index 000000000..ab0514138 --- /dev/null +++ b/tests/bin/agent/unlock.test.ts @@ -0,0 +1,92 @@ +import os from 'os'; +import path from 'path'; +import fs from 'fs'; +import * as testBinUtils from '../utils'; + +describe('unlock', () => { + let dataDir: string; + let pkAgentClose; + beforeAll(async () => { + pkAgentClose = await testBinUtils.pkAgent(); + }, global.maxTimeout); + afterAll(async () => { + await pkAgentClose(); + }); + beforeEach(async () => { + dataDir = await fs.promises.mkdtemp( + path.join(os.tmpdir(), 'polykey-test-'), + ); + // Invalidate all active sessions + await testBinUtils.pkStdio( + ['agent', 'lock'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); + }); + afterEach(async () => { + await fs.promises.rm(dataDir, { + force: true, + recursive: true, + }); + }); + test('should store session token in session file', async () => { + // Assert no existing session file + await expect( + fs.promises.readdir(path.join(global.binAgentDir)), + ).resolves.not.toContain('token'); + // Run command to set token + let exitCode, stdout; + ({ exitCode, stdout } = await testBinUtils.pkStdio( + ['agent', 'unlock'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + )); + expect(exitCode).toBe(0); + // Run a command without password to check token is valid + ({ exitCode, stdout } = await testBinUtils.pkStdio( + ['agent', 'status', '--format', 'json', '--verbose'], + { + PK_NODE_PATH: global.binAgentDir, + }, + global.binAgentDir, + )); + expect(exitCode).toBe(0); + expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); + }); + test('should fail to unlock if agent stopped', async () => { + // Stop agent + await testBinUtils.pkStdio( + ['agent', 'stop'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); + // Run unlock command + const { exitCode } = await testBinUtils.pkStdio( + ['agent', 'unlock'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); + expect(exitCode).toBe(64); + // Undo side-effects + await testBinUtils.pkStdio( + ['agent', 'start'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); + }); +}); diff --git a/tests/bin/sessions.test.ts b/tests/bin/sessions.test.ts index c6ad65077..4ab720e77 100644 --- a/tests/bin/sessions.test.ts +++ b/tests/bin/sessions.test.ts @@ -1,4 +1,3 @@ -import type { SessionToken } from '@/sessions/types'; import os from 'os'; import path from 'path'; import fs from 'fs'; @@ -6,7 +5,6 @@ import { mocked } from 'ts-jest/utils'; import prompts from 'prompts'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import { Session } from '@/sessions'; -import { sleep } from '@/utils'; import config from '@/config'; import * as clientErrors from '@/client/errors'; import * as testBinUtils from './utils'; @@ -53,40 +51,13 @@ describe('CLI Sessions', () => { recursive: true, }); }); - test('processes should store session token in session file', async () => { - // Run command to set token - let exitCode, stdout; - ({ exitCode, stdout } = await testBinUtils.pkExec( - ['agent', 'status', '--format', 'json', '--verbose'], - { - PK_NODE_PATH: global.binAgentDir, - PK_PASSWORD: global.binAgentPassword, - }, - global.binAgentDir, - )); - expect(exitCode).toBe(0); - expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); - // Try again without password - ({ exitCode, stdout } = await testBinUtils.pkExec( - ['agent', 'status', '--format', 'json', '--verbose'], - { - PK_NODE_PATH: global.binAgentDir, - }, - global.binAgentDir, - )); - expect(exitCode).toBe(0); - expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); - }); test('processes should refresh the session token', async () => { const session = await Session.createSession({ sessionTokenPath, fs, logger, }); - // Generate new token - // Using pkExec such that the asynchronous session token write operation is - // ensured to have been completed at conclusion of command. - await testBinUtils.pkExec( + await testBinUtils.pkStdio( ['agent', 'unlock'], { PK_NODE_PATH: global.binAgentDir, @@ -96,7 +67,7 @@ describe('CLI Sessions', () => { ); const token1 = await session.readToken(); // New command should refresh token - const { exitCode, stdout } = await testBinUtils.pkExec( + const { exitCode, stdout } = await testBinUtils.pkStdio( ['agent', 'status', '--format', 'json', '--verbose'], { PK_NODE_PATH: global.binAgentDir, @@ -116,7 +87,7 @@ describe('CLI Sessions', () => { }); // Run first command let exitCode, stdout; - ({ exitCode, stdout } = await testBinUtils.pkExec( + ({ exitCode, stdout } = await testBinUtils.pkStdio( ['agent', 'status', '--format', 'json', '--verbose'], { PK_NODE_PATH: global.binAgentDir, @@ -128,7 +99,7 @@ describe('CLI Sessions', () => { expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); const token1 = await session.readToken(); // Run second command - ({ exitCode, stdout } = await testBinUtils.pkExec( + ({ exitCode, stdout } = await testBinUtils.pkStdio( ['agent', 'status', '--format', 'json', '--verbose'], { PK_NODE_PATH: global.binAgentDir, @@ -142,75 +113,6 @@ describe('CLI Sessions', () => { // Assert different expect(token1).not.toBe(token2); }); - test('failing processes should unlock the session file', async () => { - const session = await Session.createSession({ - sessionTokenPath, - fs, - logger, - }); - // Run command that will fail - const { exitCode } = await testBinUtils.pkStdio( - ['identities', 'search', 'InvalidProvider'], - { - PK_NODE_PATH: global.binAgentDir, - PK_PASSWORD: global.binAgentPassword, - }, - global.binAgentDir, - ); - expect(exitCode).not.toBe(0); - await sleep(1100); - // Write to session file to ensure it's unlocked - await session.writeToken('abc' as SessionToken); - const token = await session.readToken(); - expect(token).toEqual('abc'); - }); - test('agent lock should remove the token from the client and delete the token', async () => { - const { exitCode } = await testBinUtils.pkStdio( - ['agent', 'lock'], - { - PK_NODE_PATH: global.binAgentDir, - PK_PASSWORD: global.binAgentPassword, - }, - global.binAgentDir, - ); - expect(exitCode).toBe(0); - await expect( - fs.promises.readdir(path.join(global.binAgentDir)), - ).resolves.not.toContain('token'); - }); - test('cause old sessions to fail when locking all sessions', async () => { - // Generate new token - await testBinUtils.pkExec( - ['agent', 'unlock'], - { - PK_NODE_PATH: global.binAgentDir, - PK_PASSWORD: global.binAgentPassword, - }, - global.binAgentDir, - ); - // Lockall - await testBinUtils.pkExec( - ['agent', 'lockall'], - { - PK_NODE_PATH: global.binAgentDir, - PK_PASSWORD: global.binAgentPassword, - }, - global.binAgentDir, - ); - // Call should fail because token is invalidated - const { exitCode, stderr } = await testBinUtils.pkExec( - ['agent', 'status', '--verbose'], - { - PK_NODE_PATH: global.binAgentDir, - }, - global.binAgentDir, - ); - testBinUtils.expectProcessError( - exitCode, - stderr, - new clientErrors.ErrorClientAuthDenied(), - ); - }); test('unattended calls with invalid auth should fail', async () => { let exitCode, stderr; // Password and Token set From b0e4a82401b6141c8060f4ce8063319d208ba99b Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Sun, 12 Dec 2021 18:29:13 +1100 Subject: [PATCH 07/29] `pk keys password`, `pk keys renew` and `pk keys reset` all take `--password-new-file` now --- src/bin/keys/CommandPassword.ts | 57 ++++++---------------- src/bin/keys/CommandRenew.ts | 55 ++++++--------------- src/bin/keys/CommandReset.ts | 56 ++++++---------------- src/bin/utils/options.ts | 8 +++- src/bin/utils/processors.ts | 84 ++++++++++++++++++++++++++++++--- 5 files changed, 127 insertions(+), 133 deletions(-) diff --git a/src/bin/keys/CommandPassword.ts b/src/bin/keys/CommandPassword.ts index 9600615e7..e4f8baf05 100644 --- a/src/bin/keys/CommandPassword.ts +++ b/src/bin/keys/CommandPassword.ts @@ -1,7 +1,4 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; -import * as binErrors from '../errors'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; import * as binOptions from '../utils/options'; @@ -12,19 +9,15 @@ class CommandPassword extends CommandPolykey { super(...args); this.name('password'); this.description('Change the Password for the Root Keypair'); - this.argument( - '', - 'Path to the password for the new root key', - ); this.addOption(binOptions.nodeId); this.addOption(binOptions.clientHost); this.addOption(binOptions.clientPort); - this.action(async (passwordPath, options) => { + this.addOption(binOptions.passwordNewFile); + this.action(async (options) => { const { default: PolykeyClient } = await import('../../PolykeyClient'); const sessionsPB = await import( '../../proto/js/polykey/v1/sessions/sessions_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -33,8 +26,15 @@ class CommandPassword extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + const passwordNew = await binProcessors.processNewPassword( + options.passwordNewFile, + this.fs + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -46,43 +46,14 @@ class CommandPassword extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const passwordMessage = new sessionsPB.Password(); - - let password: string | undefined; - try { - password = ( - await this.fs.promises.readFile(passwordPath, 'utf-8') - ).trim(); - } catch (e) { - throw new binErrors.ErrorCLIPasswordFileRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, - }); - } - passwordMessage.setPassword(password); - + passwordMessage.setPassword(passwordNew); await binUtils.retryAuthentication( - (auth?: Metadata) => - grpcClient.keysPasswordChange(passwordMessage, auth), + (auth) => pkClient.grpcClient.keysPasswordChange(passwordMessage, auth), meta, ); - - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [`Password to root keypair changed`], - }), - ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/keys/CommandRenew.ts b/src/bin/keys/CommandRenew.ts index 83019a656..126764968 100644 --- a/src/bin/keys/CommandRenew.ts +++ b/src/bin/keys/CommandRenew.ts @@ -1,7 +1,4 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; -import * as binErrors from '../errors'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; import * as binOptions from '../utils/options'; @@ -12,17 +9,13 @@ class CommandRenew extends CommandPolykey { super(...args); this.name('renew'); this.description('Renew the Root Keypair'); - this.argument( - '', - 'Path to the password for the new root key', - ); this.addOption(binOptions.nodeId); this.addOption(binOptions.clientHost); this.addOption(binOptions.clientPort); - this.action(async (passwordPath, options) => { + this.addOption(binOptions.passwordNewFile); + this.action(async (options) => { const { default: PolykeyClient } = await import('../../PolykeyClient'); const keysPB = await import('../../proto/js/polykey/v1/keys/keys_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -31,8 +24,16 @@ class CommandRenew extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + const passwordNew = await binProcessors.processNewPassword( + options.passwordNewFile, + this.fs + ); - let pkClient: PolykeyClient | undefined; + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -44,42 +45,14 @@ class CommandRenew extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const keyMessage = new keysPB.Key(); - - let password: string | undefined; - try { - password = ( - await this.fs.promises.readFile(passwordPath, 'utf-8') - ).trim(); - } catch (e) { - throw new binErrors.ErrorCLIPasswordFileRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, - }); - } - keyMessage.setName(password); - + keyMessage.setName(passwordNew); await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.keysKeyPairRenew(keyMessage, auth), + (auth) => pkClient.grpcClient.keysKeyPairRenew(keyMessage, auth), meta, ); - - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [`Renewed root keypair successfully`], - }), - ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/keys/CommandReset.ts b/src/bin/keys/CommandReset.ts index 59b7f9f1b..1a594a750 100644 --- a/src/bin/keys/CommandReset.ts +++ b/src/bin/keys/CommandReset.ts @@ -1,7 +1,4 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; -import * as binErrors from '../errors'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; import * as binOptions from '../utils/options'; @@ -12,17 +9,13 @@ class CommandReset extends CommandPolykey { super(...args); this.name('reset'); this.description('Reset the Root Keypair'); - this.argument( - '', - 'Path to the password for the new root key', - ); this.addOption(binOptions.nodeId); this.addOption(binOptions.clientHost); this.addOption(binOptions.clientPort); - this.action(async (passwordPath, options) => { + this.addOption(binOptions.passwordNewFile); + this.action(async (options) => { const { default: PolykeyClient } = await import('../../PolykeyClient'); const keysPB = await import('../../proto/js/polykey/v1/keys/keys_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -31,8 +24,15 @@ class CommandReset extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + const passwordNew = await binProcessors.processNewPassword( + options.passwordNewFile, + this.fs + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -44,42 +44,14 @@ class CommandReset extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const keyMessage = new keysPB.Key(); - - let password: string | undefined; - try { - password = ( - await this.fs.promises.readFile(passwordPath, 'utf-8') - ).trim(); - } catch (e) { - throw new binErrors.ErrorCLIPasswordFileRead(e.message, { - errno: e.errno, - syscall: e.syscall, - code: e.code, - path: e.path, - }); - } - keyMessage.setName(password); - + keyMessage.setName(passwordNew); await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.keysKeyPairReset(keyMessage, auth), + (auth) => pkClient.grpcClient.keysKeyPairReset(keyMessage, auth), meta, ); - - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [`Reset root keypair successfully`], - }), - ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/utils/options.ts b/src/bin/utils/options.ts index 56d350432..68e508e78 100644 --- a/src/bin/utils/options.ts +++ b/src/bin/utils/options.ts @@ -88,6 +88,11 @@ const passwordFile = new commander.Option( 'Path to Password', ); +const passwordNewFile = new commander.Option( + '-pnf, --password-new-file ', + 'Path to new Password' +); + const recoveryCodeFile = new commander.Option( '-rcf, --recovery-code-file ', 'Path to Recovery Code', @@ -123,8 +128,9 @@ export { clientPort, ingressHost, ingressPort, - recoveryCodeFile, passwordFile, + passwordNewFile, + recoveryCodeFile, background, backgroundOutFile, backgroundErrFile, diff --git a/src/bin/utils/processors.ts b/src/bin/utils/processors.ts index 1b6e5ba4b..ec067e5cc 100644 --- a/src/bin/utils/processors.ts +++ b/src/bin/utils/processors.ts @@ -19,21 +19,58 @@ import { Status } from '../../status'; import config from '../../config'; /** - * Prompts for password + * Prompts for existing password * This masks SIGINT handling * When SIGINT is received this will return undefined */ async function promptPassword(): Promise { - const response = await prompts({ - type: 'password', + const { password } = await prompts({ name: 'password', - message: 'Please enter your password', + type: 'password', + message: 'Please enter the password', }); - return response.password; + return password; } /** - * Processes password + * Prompts for new password + * This masks SIGINT handling + * When SIGINT is received this will return undefined + */ +async function promptNewPassword(): Promise { + let password: string | undefined; + while (true) { + ({ password } = await prompts({ + name: 'password', + type: 'password', + message: 'Enter new password', + })); + // If undefined, then SIGINT was sent + // Break the loop and return undefined password + if (password == null) { + break; + } + const { passwordConfirm }= await prompts({ + name: 'passwordConfirm', + type: 'password', + message: 'Confirm new password', + }); + // If undefined, then SIGINT was sent + // Break the loop and return undefined password + if (passwordConfirm == null) { + break; + } + if (password === passwordConfirm) { + break; + } + // Interactive message + process.stderr.write('Passwords do not match!\n'); + } + return password; +} + +/** + * Processes existing password * Use this when password is necessary * Order of operations are: * 1. Reads --password-file @@ -68,6 +105,39 @@ async function processPassword( return password; } +/** + * Processes new password + * Use this when a new password is necessary + * Order of operations are: + * 1. Reads --password-new-file + * 2. Prompts for password + * This may return an empty string + */ +async function processNewPassword( + passwordNewFile?: string, + fs: FileSystem = require('fs'), +): Promise { + let passwordNew: string | undefined; + if (passwordNewFile != null) { + try { + passwordNew = (await fs.promises.readFile(passwordNewFile, 'utf-8')).trim(); + } catch (e) { + throw new binErrors.ErrorCLIPasswordFileRead(e.message, { + errno: e.errno, + syscall: e.syscall, + code: e.code, + path: e.path, + }); + } + } else { + passwordNew = await promptNewPassword(); + if (passwordNew === undefined) { + throw new binErrors.ErrorCLIPasswordMissing(); + } + } + return passwordNew; +} + /** * Process recovery code * Order of operations are: @@ -266,7 +336,9 @@ async function processAuthentication( export { promptPassword, + promptNewPassword, processPassword, + processNewPassword, processRecoveryCode, processClientOptions, processClientStatus, From 720d3459061ddecd5f6776b660aa2a805c07a486 Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Sun, 12 Dec 2021 18:42:35 +1100 Subject: [PATCH 08/29] `pk agent start` and `pk bootstrap` are also using `processNewPassword`, `processPassword` is only used by `pk agent start` --- src/bin/agent/CommandStart.ts | 37 ++++++++++++++++++++++----- src/bin/bootstrap/CommandBootstrap.ts | 2 +- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/bin/agent/CommandStart.ts b/src/bin/agent/CommandStart.ts index ce802125d..1b8e55008 100644 --- a/src/bin/agent/CommandStart.ts +++ b/src/bin/agent/CommandStart.ts @@ -33,12 +33,37 @@ class CommandStart extends CommandPolykey { options.clientPort = options.clientPort ?? config.defaults.networkConfig.clientPort; const { default: PolykeyAgent } = await import('../../PolykeyAgent'); - // Password is necessary - // If recovery code is supplied, then this is the new password - const password = await binProcessors.processPassword( - options.passwordFile, - this.fs, - ); + let password: string | undefined; + if (options.fresh) { + // If fresh, then get a new password + password = await binProcessors.processNewPassword( + options.passwordFile, + this.fs, + ); + } else if (options.recoveryCodeFile != null) { + // If recovery code is supplied, then this is the new password + password = await binProcessors.processNewPassword( + options.passwordFile, + this.fs, + ); + } else if ( + (await this.fs.promises.readdir(options.nodePath)).length === 0 + ) { + // If the node path is empty, get a new password + password = await binProcessors.processNewPassword( + options.passwordFile, + this.fs, + ); + } else { + // Otherwise this is the existing password + // however, the code is capable of doing partial bootstrapping + // so it's possible that this is also a new password + // if the root key isn't setup + password = await binProcessors.processPassword( + options.passwordFile, + this.fs, + ); + } const recoveryCodeIn = await binProcessors.processRecoveryCode( options.recoveryCodeFile, this.fs, diff --git a/src/bin/bootstrap/CommandBootstrap.ts b/src/bin/bootstrap/CommandBootstrap.ts index 93387465c..9842653c0 100644 --- a/src/bin/bootstrap/CommandBootstrap.ts +++ b/src/bin/bootstrap/CommandBootstrap.ts @@ -13,7 +13,7 @@ class CommandBootstrap extends CommandPolykey { this.addOption(binOptions.fresh); this.action(async (options) => { const bootstrapUtils = await import('../../bootstrap/utils'); - const password = await binProcessors.processPassword( + const password = await binProcessors.processNewPassword( options.passwordFile, this.fs, ); From 76d433873f8d84403d6aee58b8bf58fedc63912c Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Sun, 12 Dec 2021 20:32:16 +1100 Subject: [PATCH 09/29] Added test for stopping agent while unauthenticated, fixed `pk agent start` when starting with non-existing node path --- src/bin/agent/CommandStart.ts | 4 +-- src/utils/utils.ts | 32 ++++++++++---------- tests/bin/agent/stop.test.ts | 55 +++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 17 deletions(-) diff --git a/src/bin/agent/CommandStart.ts b/src/bin/agent/CommandStart.ts index 1b8e55008..ea3c1a802 100644 --- a/src/bin/agent/CommandStart.ts +++ b/src/bin/agent/CommandStart.ts @@ -9,7 +9,7 @@ import CommandPolykey from '../CommandPolykey'; import * as binOptions from '../utils/options'; import * as binProcessors from '../utils/processors'; import * as binErrors from '../errors'; -import { promise } from '../../utils'; +import { promise, dirEmpty } from '../../utils'; import config from '../../config'; class CommandStart extends CommandPolykey { @@ -47,7 +47,7 @@ class CommandStart extends CommandPolykey { this.fs, ); } else if ( - (await this.fs.promises.readdir(options.nodePath)).length === 0 + await dirEmpty(this.fs, options.nodePath) ) { // If the node path is empty, get a new password password = await binProcessors.processNewPassword( diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 2e53f3fc6..7ac87e633 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -47,6 +47,22 @@ async function mkdirExists(fs: FileSystem, path, ...args) { } } +/** + * Checks if a directory is empty + * If the path does not exist, also returns true + */ +async function dirEmpty(fs: FileSystem, path): Promise { + try { + const entries = await fs.promises.readdir(path); + return entries.length === 0; + } catch (e) { + if (e.code === 'ENOENT') { + return false; + } + throw e; + } +} + /** * Test whether a path includes another path * This will return true when path 1 is the same as path 2 @@ -60,15 +76,6 @@ function pathIncludes(p1: string, p2: string): boolean { ); } -function pidIsRunning(pid: number) { - try { - process.kill(pid, 0); - return true; - } catch (e) { - return false; - } -} - async function sleep(ms: number) { return await new Promise((r) => setTimeout(r, ms)); } @@ -93,10 +100,6 @@ function getUnixtime(date: Date = new Date()) { return Math.round(date.getTime() / 1000); } -function getRandomInt(max = Number.MAX_SAFE_INTEGER) { - return Math.floor(Math.random() * max); -} - /** * Poll execution and use condition to accept or reject the results */ @@ -204,13 +207,12 @@ export { getDefaultNodePath, never, mkdirExists, + dirEmpty, pathIncludes, - pidIsRunning, sleep, isEmptyObject, filterEmptyObject, getUnixtime, - getRandomInt, poll, promisify, promise, diff --git a/tests/bin/agent/stop.test.ts b/tests/bin/agent/stop.test.ts index 8bf594171..bc797dac2 100644 --- a/tests/bin/agent/stop.test.ts +++ b/tests/bin/agent/stop.test.ts @@ -5,7 +5,9 @@ import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import { Status } from '@/status'; import config from '@/config'; import * as binErrors from '@/bin/errors'; +import * as clientErrors from '@/client/errors'; import * as testBinUtils from '../utils'; +import { sleep } from '@/utils'; describe('stop', () => { const logger = new Logger('stop test', LogLevel.WARN, [new StreamHandler()]); @@ -174,4 +176,57 @@ describe('stop', () => { }, global.defaultTimeout * 2, ); + test( + 'stopping while unauthenticated does not stop', + async () => { + const password = 'abc123'; + await testBinUtils.pkStdio( + [ + 'agent', + 'start', + // 1024 is the smallest size and is faster to start + '--root-key-pair-bits', + '1024', + ], + { + PK_NODE_PATH: path.join(dataDir, 'polykey'), + PK_PASSWORD: password, + }, + dataDir, + ); + const status = new Status({ + statusPath: path.join(dataDir, 'polykey', config.defaults.statusBase), + fs, + logger, + }); + const { exitCode, stderr } = await testBinUtils.pkStdio( + ['agent', 'stop'], + { + PK_NODE_PATH: path.join(dataDir, 'polykey'), + PK_PASSWORD: 'wrong password', + }, + dataDir, + ); + testBinUtils.expectProcessError( + exitCode, + stderr, + new clientErrors.ErrorClientAuthDenied() + ); + // Should still be LIVE + await sleep(500); + const statusInfo = await status.readStatus(); + expect(statusInfo).toBeDefined(); + expect(statusInfo?.status).toBe('LIVE'); + await testBinUtils.pkStdio( + ['agent', 'stop'], + { + PK_NODE_PATH: path.join(dataDir, 'polykey'), + PK_PASSWORD: password, + }, + dataDir, + ); + await status.waitFor('DEAD'); + }, + global.defaultTimeout * 2 + ); }); From a46d74e40ac859501d82c62b982d5765d8534bd7 Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Mon, 13 Dec 2021 10:39:19 +1100 Subject: [PATCH 10/29] Reading `PK_PASSWORD` should be in `processNewPassword` --- src/bin/utils/processors.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bin/utils/processors.ts b/src/bin/utils/processors.ts index ec067e5cc..daf6c971a 100644 --- a/src/bin/utils/processors.ts +++ b/src/bin/utils/processors.ts @@ -94,8 +94,6 @@ async function processPassword( path: e.path, }); } - } else if (typeof process.env['PK_PASSWORD'] === 'string') { - password = process.env['PK_PASSWORD']; } else { password = await promptPassword(); if (password === undefined) { @@ -129,6 +127,8 @@ async function processNewPassword( path: e.path, }); } + } else if (typeof process.env['PK_PASSWORD'] === 'string') { + passwordNew = process.env['PK_PASSWORD']; } else { passwordNew = await promptNewPassword(); if (passwordNew === undefined) { From a35ad9943509282fa6b45977c9ae340850af5bec Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Mon, 13 Dec 2021 10:59:11 +1100 Subject: [PATCH 11/29] Fixing password env --- src/bin/keys/CommandPassword.ts | 3 ++- src/bin/keys/CommandRenew.ts | 4 ++-- src/bin/keys/CommandReset.ts | 3 ++- src/bin/utils/processors.ts | 11 +++++++++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/bin/keys/CommandPassword.ts b/src/bin/keys/CommandPassword.ts index e4f8baf05..aa452abc6 100644 --- a/src/bin/keys/CommandPassword.ts +++ b/src/bin/keys/CommandPassword.ts @@ -32,7 +32,8 @@ class CommandPassword extends CommandPolykey { ); const passwordNew = await binProcessors.processNewPassword( options.passwordNewFile, - this.fs + this.fs, + true ); let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { diff --git a/src/bin/keys/CommandRenew.ts b/src/bin/keys/CommandRenew.ts index 126764968..362c0c472 100644 --- a/src/bin/keys/CommandRenew.ts +++ b/src/bin/keys/CommandRenew.ts @@ -30,9 +30,9 @@ class CommandRenew extends CommandPolykey { ); const passwordNew = await binProcessors.processNewPassword( options.passwordNewFile, - this.fs + this.fs, + true ); - let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); diff --git a/src/bin/keys/CommandReset.ts b/src/bin/keys/CommandReset.ts index 1a594a750..83eeb7d4d 100644 --- a/src/bin/keys/CommandReset.ts +++ b/src/bin/keys/CommandReset.ts @@ -30,7 +30,8 @@ class CommandReset extends CommandPolykey { ); const passwordNew = await binProcessors.processNewPassword( options.passwordNewFile, - this.fs + this.fs, + true ); let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { diff --git a/src/bin/utils/processors.ts b/src/bin/utils/processors.ts index daf6c971a..24f0c23e9 100644 --- a/src/bin/utils/processors.ts +++ b/src/bin/utils/processors.ts @@ -94,6 +94,8 @@ async function processPassword( path: e.path, }); } + } else if (typeof process.env['PK_PASSWORD'] === 'string') { + password = process.env['PK_PASSWORD']; } else { password = await promptPassword(); if (password === undefined) { @@ -108,12 +110,17 @@ async function processPassword( * Use this when a new password is necessary * Order of operations are: * 1. Reads --password-new-file - * 2. Prompts for password + * 2. Reads PK_PASSWORD + * 3. Prompts and confirms password + * If processNewPassword is used when an existing password is needed + * for authentication, then the existing boolean should be set to true + * This ensures that this call does not read `PK_PASSWORD` * This may return an empty string */ async function processNewPassword( passwordNewFile?: string, fs: FileSystem = require('fs'), + existing: boolean = false ): Promise { let passwordNew: string | undefined; if (passwordNewFile != null) { @@ -127,7 +134,7 @@ async function processNewPassword( path: e.path, }); } - } else if (typeof process.env['PK_PASSWORD'] === 'string') { + } else if (!existing && (typeof process.env['PK_PASSWORD'] === 'string')) { passwordNew = process.env['PK_PASSWORD']; } else { passwordNew = await promptNewPassword(); From 25d9654db9db4e50e9b33b9da644a5506041db82 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 13 Dec 2021 11:00:32 +1100 Subject: [PATCH 12/29] sessions tests passing --- tests/bin/sessions.test.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/bin/sessions.test.ts b/tests/bin/sessions.test.ts index 4ab720e77..98e2a3433 100644 --- a/tests/bin/sessions.test.ts +++ b/tests/bin/sessions.test.ts @@ -5,6 +5,7 @@ import { mocked } from 'ts-jest/utils'; import prompts from 'prompts'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import { Session } from '@/sessions'; +import { sleep } from '@/utils'; import config from '@/config'; import * as clientErrors from '@/client/errors'; import * as testBinUtils from './utils'; @@ -67,6 +68,8 @@ describe('CLI Sessions', () => { ); const token1 = await session.readToken(); // New command should refresh token + // Need to wait for 1100ms to ensure refreshed token will be different from previous one + await sleep(1100); const { exitCode, stdout } = await testBinUtils.pkStdio( ['agent', 'status', '--format', 'json', '--verbose'], { @@ -99,6 +102,8 @@ describe('CLI Sessions', () => { expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); const token1 = await session.readToken(); // Run second command + // Need to wait for 1100ms to ensure refreshed token will be different from previous one + await sleep(1100); ({ exitCode, stdout } = await testBinUtils.pkStdio( ['agent', 'status', '--format', 'json', '--verbose'], { From bd3ca048c5f490b7a30e41984656784d3e7a8697 Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Mon, 13 Dec 2021 11:41:58 +1100 Subject: [PATCH 13/29] Close the testLockFile for `pkAgent` after unlocking --- tests/bin/utils.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/bin/utils.ts b/tests/bin/utils.ts index 36e551205..a18ccc3d2 100644 --- a/tests/bin/utils.ts +++ b/tests/bin/utils.ts @@ -378,6 +378,7 @@ async function pkAgent( path.join(global.binAgentDir, 'references', reference), ); lock.unlock(testLockFile.fd); + await testLockFile.close(); // If the pids directory is not empty, there are other processes still running try { await fs.promises.rmdir(path.join(global.binAgentDir, 'references')); From c7eaaa95f0e0c89b62db0a5cb9dc2cc0e07782f0 Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Mon, 13 Dec 2021 12:05:18 +1100 Subject: [PATCH 14/29] Fixing up `pk agent lock` tests --- tests/bin/agent/lock.test.ts | 57 +++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/tests/bin/agent/lock.test.ts b/tests/bin/agent/lock.test.ts index 92507181e..82f78192f 100644 --- a/tests/bin/agent/lock.test.ts +++ b/tests/bin/agent/lock.test.ts @@ -2,25 +2,33 @@ import type { SessionToken } from '@/sessions/types'; import os from 'os'; import path from 'path'; import fs from 'fs'; +import prompts from 'prompts'; +import { mocked } from 'ts-jest/utils'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import { Session } from '@/sessions'; import config from '@/config'; import * as testBinUtils from '../utils'; +/** + * Mock prompts module which is used prompt for password + */ +jest.mock('prompts'); +const mockedPrompts = mocked(prompts); + describe('lock', () => { const logger = new Logger('lock test', LogLevel.WARN, [new StreamHandler()]); - let dataDir: string; - let pkAgentClose; const sessionTokenPath = path.join( global.binAgentDir, config.defaults.tokenBase, ); + let pkAgentClose; beforeAll(async () => { pkAgentClose = await testBinUtils.pkAgent(); }, global.maxTimeout); afterAll(async () => { await pkAgentClose(); }); + let dataDir: string; beforeEach(async () => { dataDir = await fs.promises.mkdtemp( path.join(os.tmpdir(), 'polykey-test-'), @@ -32,27 +40,56 @@ describe('lock', () => { recursive: true, }); }); - test('should delete the session file', async () => { - // Ensure session file exists + test('lock deletes the session token', async () => { const session = await Session.createSession({ sessionTokenPath, fs, logger, }); await session.writeToken('abc' as SessionToken); - // Run command const { exitCode } = await testBinUtils.pkStdio( ['agent', 'lock'], { PK_NODE_PATH: global.binAgentDir, - PK_PASSWORD: global.binAgentPassword, }, global.binAgentDir, ); expect(exitCode).toBe(0); - // Check file does not exist - await expect( - fs.promises.readdir(path.join(global.binAgentDir)), - ).resolves.not.toContain('token'); + expect(await session.readToken()).toBeUndefined(); + }); + test('lock ensures reauthentication is required', async () => { + const password = global.binAgentPassword; + mockedPrompts.mockClear(); + mockedPrompts.mockImplementation(async (_opts: any) => { + return { password }; + }); + // Session token is set + await testBinUtils.pkStdio( + ['agent', 'status'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir + ); + // Session token is deleted + await testBinUtils.pkStdio( + ['agent', 'lock'], + { + PK_NODE_PATH: global.binAgentDir, + }, + global.binAgentDir, + ); + // Will prompt to reauthenticate + await testBinUtils.pkStdio( + ['agent', 'status'], + { + PK_NODE_PATH: global.binAgentDir, + }, + global.binAgentDir + ); + // Prompted for password 1 time + expect(mockedPrompts.mock.calls.length).toBe(1); + mockedPrompts.mockClear(); }); }); From 308c7846f331cc606772a7f810f1e8531eb6a514 Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Mon, 13 Dec 2021 12:25:46 +1100 Subject: [PATCH 15/29] Fixing `pk agent lock` and `pk agent lockall` tests --- tests/bin/agent/lock.test.ts | 25 +++++---- tests/bin/agent/lockall.test.ts | 95 ++++++++++++++++++++------------- 2 files changed, 74 insertions(+), 46 deletions(-) diff --git a/tests/bin/agent/lock.test.ts b/tests/bin/agent/lock.test.ts index 82f78192f..7d2c68479 100644 --- a/tests/bin/agent/lock.test.ts +++ b/tests/bin/agent/lock.test.ts @@ -1,4 +1,3 @@ -import type { SessionToken } from '@/sessions/types'; import os from 'os'; import path from 'path'; import fs from 'fs'; @@ -41,12 +40,14 @@ describe('lock', () => { }); }); test('lock deletes the session token', async () => { - const session = await Session.createSession({ - sessionTokenPath, - fs, - logger, - }); - await session.writeToken('abc' as SessionToken); + await testBinUtils.pkStdio( + ['agent', 'unlock'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); const { exitCode } = await testBinUtils.pkStdio( ['agent', 'lock'], { @@ -55,6 +56,11 @@ describe('lock', () => { global.binAgentDir, ); expect(exitCode).toBe(0); + const session = await Session.createSession({ + sessionTokenPath, + fs, + logger, + }); expect(await session.readToken()).toBeUndefined(); }); test('lock ensures reauthentication is required', async () => { @@ -63,14 +69,13 @@ describe('lock', () => { mockedPrompts.mockImplementation(async (_opts: any) => { return { password }; }); - // Session token is set await testBinUtils.pkStdio( - ['agent', 'status'], + ['agent', 'unlock'], { PK_NODE_PATH: global.binAgentDir, PK_PASSWORD: global.binAgentPassword, }, - global.binAgentDir + global.binAgentDir, ); // Session token is deleted await testBinUtils.pkStdio( diff --git a/tests/bin/agent/lockall.test.ts b/tests/bin/agent/lockall.test.ts index 48648a389..93b0a520e 100644 --- a/tests/bin/agent/lockall.test.ts +++ b/tests/bin/agent/lockall.test.ts @@ -1,41 +1,40 @@ import os from 'os'; import path from 'path'; import fs from 'fs'; +import prompts from 'prompts'; +import { mocked } from 'ts-jest/utils'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import { Session } from '@/sessions'; import config from '@/config'; import * as clientErrors from '@/client/errors'; import * as testBinUtils from '../utils'; +/** + * Mock prompts module which is used prompt for password + */ +jest.mock('prompts'); +const mockedPrompts = mocked(prompts); + describe('lockall', () => { const logger = new Logger('lockall test', LogLevel.WARN, [ new StreamHandler(), ]); - let dataDir: string; - let pkAgentClose; const sessionTokenPath = path.join( global.binAgentDir, config.defaults.tokenBase, ); + let pkAgentClose; beforeAll(async () => { pkAgentClose = await testBinUtils.pkAgent(); }, global.maxTimeout); afterAll(async () => { await pkAgentClose(); }); + let dataDir: string; beforeEach(async () => { dataDir = await fs.promises.mkdtemp( path.join(os.tmpdir(), 'polykey-test-'), ); - // Invalidate all active sessions - await testBinUtils.pkStdio( - ['agent', 'lock'], - { - PK_NODE_PATH: global.binAgentDir, - PK_PASSWORD: global.binAgentPassword, - }, - global.binAgentDir, - ); }); afterEach(async () => { await fs.promises.rm(dataDir, { @@ -43,8 +42,7 @@ describe('lockall', () => { recursive: true, }); }); - test('cause old sessions to fail when locking all sessions', async () => { - // Generate new token + test('lockall deletes the session token', async () => { await testBinUtils.pkStdio( ['agent', 'unlock'], { @@ -53,49 +51,70 @@ describe('lockall', () => { }, global.binAgentDir, ); - // Read token + const { exitCode } = await testBinUtils.pkStdio( + ['agent', 'lockall'], + { + PK_NODE_PATH: global.binAgentDir, + }, + global.binAgentDir, + ); + expect(exitCode).toBe(0); const session = await Session.createSession({ sessionTokenPath, fs, logger, }); - const token = await session.readToken(); - // Run command + expect(await session.readToken()).toBeUndefined(); + }); + test('lockall ensures reauthentication is required', async () => { + const password = global.binAgentPassword; await testBinUtils.pkStdio( - ['agent', 'lockall'], + ['agent', 'unlock'], { PK_NODE_PATH: global.binAgentDir, PK_PASSWORD: global.binAgentPassword, }, global.binAgentDir, ); - // Call should fail because token is invalidated - const { exitCode, stderr } = await testBinUtils.pkStdio( - ['agent', 'status', '--verbose'], + await testBinUtils.pkStdio( + ['agent', 'lockall'], { - PK_NODE_PATH: global.binAgentDir, - PK_TOKEN: token, + PK_NODE_PATH: global.binAgentDir }, global.binAgentDir, ); - testBinUtils.expectProcessError( - exitCode, - stderr, - new clientErrors.ErrorClientAuthDenied(), + // Token is deleted, reauthentication is required + mockedPrompts.mockClear(); + mockedPrompts.mockImplementation(async (_opts: any) => { + return { password }; + }); + await testBinUtils.pkStdio( + ['agent', 'status'], + { + PK_NODE_PATH: global.binAgentDir, + }, + global.binAgentDir, ); + // Prompted for password 1 time + expect(mockedPrompts.mock.calls.length).toBe(1); + mockedPrompts.mockClear(); }); - test('should fail to lock all sessions if agent stopped', async () => { - // Stop agent + test('lockall causes old session tokens to fail', async () => { await testBinUtils.pkStdio( - ['agent', 'stop'], + ['agent', 'unlock'], { PK_NODE_PATH: global.binAgentDir, PK_PASSWORD: global.binAgentPassword, }, global.binAgentDir, ); - // Run unlock command - const { exitCode } = await testBinUtils.pkStdio( + const session = await Session.createSession({ + sessionTokenPath, + fs, + logger, + }); + const token = await session.readToken(); + await testBinUtils.pkStdio( ['agent', 'lockall'], { PK_NODE_PATH: global.binAgentDir, @@ -103,15 +122,19 @@ describe('lockall', () => { }, global.binAgentDir, ); - expect(exitCode).toBe(64); - // Undo side-effects - await testBinUtils.pkStdio( - ['agent', 'start'], + // Old token is invalid + const { exitCode, stderr } = await testBinUtils.pkStdio( + ['agent', 'status'], { PK_NODE_PATH: global.binAgentDir, - PK_PASSWORD: global.binAgentPassword, + PK_TOKEN: token, }, global.binAgentDir, ); + testBinUtils.expectProcessError( + exitCode, + stderr, + new clientErrors.ErrorClientAuthDenied(), + ); }); }); From 130d3dae2739e401ec0d381e7a9e422309a551ae Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 13 Dec 2021 12:22:35 +1100 Subject: [PATCH 16/29] test fixes for keys + sessions --- tests/bin/keys.test.ts | 6 +- tests/client/rpcSessions.test.ts | 94 ++++---------------------------- tests/client/utils.ts | 3 +- 3 files changed, 17 insertions(+), 86 deletions(-) diff --git a/tests/bin/keys.test.ts b/tests/bin/keys.test.ts index 0e79fe64b..970eb9348 100644 --- a/tests/bin/keys.test.ts +++ b/tests/bin/keys.test.ts @@ -154,7 +154,7 @@ describe('CLI keys', () => { const passPath = path.join(dataDir, 'passwordNew'); await fs.promises.writeFile(passPath, 'password-new'); - command = ['keys', 'renew', '-np', nodePath, passPath]; + command = ['keys', 'renew', '-np', nodePath, '-pnf', passPath]; const result = await utils.pkStdio([...command], {}, dataDir); expect(result.exitCode).toBe(0); @@ -183,7 +183,7 @@ describe('CLI keys', () => { const passPath = path.join(dataDir, 'passwordNewNew'); await fs.promises.writeFile(passPath, 'password-new-new'); - command = ['keys', 'reset', '-np', nodePath, passPath]; + command = ['keys', 'reset', '-np', nodePath, '-pnf', passPath]; const result = await utils.pkStdio([...command], {}, dataDir); expect(result.exitCode).toBe(0); @@ -211,7 +211,7 @@ describe('CLI keys', () => { const passPath = path.join(dataDir, 'passwordChange'); await fs.promises.writeFile(passPath, 'password-change'); - command = ['keys', 'password', '-np', nodePath, passPath]; + command = ['keys', 'password', '-np', nodePath, '-pnf', passPath]; const result2 = await utils.pkStdio([...command], {}, dataDir); expect(result2.exitCode).toBe(0); diff --git a/tests/client/rpcSessions.test.ts b/tests/client/rpcSessions.test.ts index 96a149a3a..15d58284c 100644 --- a/tests/client/rpcSessions.test.ts +++ b/tests/client/rpcSessions.test.ts @@ -1,5 +1,4 @@ import type * as grpc from '@grpc/grpc-js'; -import type { SessionToken } from '@/sessions/types'; import type { ClientServiceClient } from '@/proto/js/polykey/v1/client_service_grpc_pb'; import os from 'os'; import path from 'path'; @@ -7,12 +6,10 @@ import fs from 'fs'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import { PolykeyAgent } from '@'; import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; -import * as sessionsPB from '@/proto/js/polykey/v1/sessions/sessions_pb'; import { KeyManager } from '@/keys'; import { ForwardProxy } from '@/network'; import * as grpcUtils from '@/grpc/utils'; -import { sleep } from '@/utils'; -import * as errors from '@/errors'; +import * as clientUtils from '@/client/utils'; import * as testUtils from './utils'; // Mocks. @@ -22,19 +19,6 @@ jest.mock('@/keys/utils', () => ({ jest.requireActual('@/keys/utils').generateKeyPair, })); -/** - * This test file has been optimised to use only one instance of PolykeyAgent where posible. - * Setting up the PolykeyAgent has been done in a beforeAll block. - * Keep this in mind when adding or editing tests. - * Any side effects need to be undone when the test has completed. - * Preferably within a `afterEach()` since any cleanup will be skipped inside a failing test. - * - * - left over state can cause a test to fail in certain cases. - * - left over state can cause similar tests to succeed when they should fail. - * - starting or stopping the agent within tests should be done on a new instance of the polykey agent. - * - when in doubt test each modified or added test on it's own as well as the whole file. - * - Looking into adding a way to safely clear each domain's DB information with out breaking modules. - */ describe('Sessions client service', () => { const password = 'password'; const logger = new Logger('SessionsClientServerTest', LogLevel.WARN, [ @@ -101,81 +85,27 @@ describe('Sessions client service', () => { const sessionToken = await polykeyAgent.sessionManager.createToken(); callCredentials = testUtils.createCallCredentials(sessionToken); }); - test('can request a session', async () => { - const requestJWT = grpcUtils.promisifyUnaryCall( + const requestJWT = grpcUtils.promisifyUnaryCall( client, client.sessionsUnlock, ); - const passwordMessage = new sessionsPB.Password(); - passwordMessage.setPassword(passwordFile); - - const res = await requestJWT(passwordMessage); - expect(typeof res.getToken()).toBe('string'); - const result = await polykeyAgent.sessionManager.verifyToken( - res.getToken() as SessionToken, - ); + const pCall = requestJWT(new utilsPB.EmptyMessage(), callCredentials); + const meta = await pCall.meta; + const token = clientUtils.decodeAuthToSession(meta); + const result = await polykeyAgent.sessionManager.verifyToken(token!); expect(result).toBeTruthy(); }); - test('can refresh session', async () => { - const requestJWT = grpcUtils.promisifyUnaryCall( - client, - client.sessionsUnlock, - ); - - const passwordMessage = new sessionsPB.Password(); - passwordMessage.setPassword(passwordFile); - - const res1 = await requestJWT(passwordMessage); - const token1 = res1.getToken() as SessionToken; - const callCredentialsRefresh = testUtils.createCallCredentials(token1); - - const sessionRefresh = grpcUtils.promisifyUnaryCall( - client, - client.sessionsRefresh, - ); - - await sleep(1100); - const emptyMessage = new utilsPB.EmptyMessage(); - const res2 = await sessionRefresh(emptyMessage, callCredentialsRefresh); - expect(typeof res2.getToken()).toBe('string'); - const token2 = res2.getToken() as SessionToken; - const result = await polykeyAgent.sessionManager.verifyToken(token2); - expect(result).toBeTruthy(); - expect(token1).not.toEqual(token2); - }); - test('actions over GRPC refresh the session', async () => { - // Since we refresh the token when metadata is sent, check that - // metadata is sent and that we can do something when it happens - const agentStatus = grpcUtils.promisifyUnaryCall( - client, - client.agentStatus, - ); - const emptyMessage = new utilsPB.EmptyMessage(); - const res = agentStatus(emptyMessage, callCredentials); - let check = 0; - res.call.on('metadata', () => (check = 1)); - await res; - expect(check).toEqual(1); - }); - test('session can lock all', async () => { - const agentStatus = grpcUtils.promisifyUnaryCall( - client, - client.agentStatus, - ); - - // Locking the session. - const sessionLockAll = grpcUtils.promisifyUnaryCall( + test('can lock all sessions', async () => { + const requestJWT = grpcUtils.promisifyUnaryCall( client, client.sessionsLockAll, ); - const emptyMessage = new utilsPB.EmptyMessage(); - await sessionLockAll(emptyMessage, callCredentials); - // Should reject the session token. - await expect(() => agentStatus(emptyMessage)).rejects.toThrow( - errors.ErrorClientAuthMissing, - ); + await requestJWT(new utilsPB.EmptyMessage(), callCredentials); + const prevToken = clientUtils.decodeAuthToSession(callCredentials); + const result = await polykeyAgent.sessionManager.verifyToken(prevToken!); + expect(result).toBeFalsy(); }); }); diff --git a/tests/client/utils.ts b/tests/client/utils.ts index 6aa9f0c43..6ca47d3af 100644 --- a/tests/client/utils.ts +++ b/tests/client/utils.ts @@ -35,7 +35,8 @@ async function openTestClientServer({ discovery: polykeyAgent.discovery, fwdProxy: polykeyAgent.fwdProxy, revProxy: polykeyAgent.revProxy, - clientGrpcServer: polykeyAgent.grpcServerClient, + grpcServerClient: polykeyAgent.grpcServerClient, + grpcServerAgent: polykeyAgent.grpcServerAgent, fs: polykeyAgent.fs, }); From 98b29167ff840e538a06c0295ca477c81849464c Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Mon, 13 Dec 2021 12:46:07 +1100 Subject: [PATCH 17/29] Fixed tests/bin/agent concurrent testing --- tests/bin/agent/lock.test.ts | 10 +- tests/bin/agent/lockall.test.ts | 14 ++- tests/bin/agent/status.test.ts | 200 ++++++++++++++++---------------- tests/bin/agent/unlock.test.ts | 70 +++++------ tests/bin/utils.ts | 5 + 5 files changed, 145 insertions(+), 154 deletions(-) diff --git a/tests/bin/agent/lock.test.ts b/tests/bin/agent/lock.test.ts index 7d2c68479..f19a16a73 100644 --- a/tests/bin/agent/lock.test.ts +++ b/tests/bin/agent/lock.test.ts @@ -16,10 +16,6 @@ const mockedPrompts = mocked(prompts); describe('lock', () => { const logger = new Logger('lock test', LogLevel.WARN, [new StreamHandler()]); - const sessionTokenPath = path.join( - global.binAgentDir, - config.defaults.tokenBase, - ); let pkAgentClose; beforeAll(async () => { pkAgentClose = await testBinUtils.pkAgent(); @@ -57,11 +53,15 @@ describe('lock', () => { ); expect(exitCode).toBe(0); const session = await Session.createSession({ - sessionTokenPath, + sessionTokenPath: path.join( + global.binAgentDir, + config.defaults.tokenBase, + ), fs, logger, }); expect(await session.readToken()).toBeUndefined(); + await session.stop(); }); test('lock ensures reauthentication is required', async () => { const password = global.binAgentPassword; diff --git a/tests/bin/agent/lockall.test.ts b/tests/bin/agent/lockall.test.ts index 93b0a520e..f8f1dfcc0 100644 --- a/tests/bin/agent/lockall.test.ts +++ b/tests/bin/agent/lockall.test.ts @@ -19,10 +19,6 @@ describe('lockall', () => { const logger = new Logger('lockall test', LogLevel.WARN, [ new StreamHandler(), ]); - const sessionTokenPath = path.join( - global.binAgentDir, - config.defaults.tokenBase, - ); let pkAgentClose; beforeAll(async () => { pkAgentClose = await testBinUtils.pkAgent(); @@ -60,7 +56,10 @@ describe('lockall', () => { ); expect(exitCode).toBe(0); const session = await Session.createSession({ - sessionTokenPath, + sessionTokenPath: path.join( + global.binAgentDir, + config.defaults.tokenBase, + ), fs, logger, }); @@ -109,7 +108,10 @@ describe('lockall', () => { global.binAgentDir, ); const session = await Session.createSession({ - sessionTokenPath, + sessionTokenPath: path.join( + global.binAgentDir, + config.defaults.tokenBase, + ), fs, logger, }); diff --git a/tests/bin/agent/status.test.ts b/tests/bin/agent/status.test.ts index c5daa9fbf..4c31502e8 100644 --- a/tests/bin/agent/status.test.ts +++ b/tests/bin/agent/status.test.ts @@ -11,14 +11,7 @@ describe('status', () => { const logger = new Logger('status test', LogLevel.WARN, [ new StreamHandler(), ]); - let pkAgentClose; let dataDir: string; - beforeAll(async () => { - pkAgentClose = await testBinUtils.pkAgent(); - }, global.maxTimeout); - afterAll(async () => { - await pkAgentClose(); - }); beforeEach(async () => { dataDir = await fs.promises.mkdtemp( path.join(os.tmpdir(), 'polykey-test-'), @@ -30,98 +23,6 @@ describe('status', () => { recursive: true, }); }); - test('status on LIVE agent', async () => { - const status = new Status({ - statusPath: path.join(global.binAgentDir, config.defaults.statusBase), - fs, - logger, - }); - const statusInfo = (await status.readStatus())!; - const { exitCode, stdout } = await testBinUtils.pkStdio( - ['agent', 'status', '--format', 'json', '--verbose'], - { - PK_NODE_PATH: global.binAgentDir, - PK_PASSWORD: global.binAgentPassword, - }, - global.binAgentDir, - ); - expect(exitCode).toBe(0); - expect(JSON.parse(stdout)).toMatchObject({ - status: 'LIVE', - pid: expect.any(Number), - nodeId: statusInfo.data.nodeId, - clientHost: statusInfo.data.clientHost, - clientPort: statusInfo.data.clientPort, - ingressHost: statusInfo.data.ingressHost, - ingressPort: statusInfo.data.ingressPort, - egressHost: expect.any(String), - egressPort: expect.any(Number), - agentHost: expect.any(String), - agentPort: expect.any(Number), - proxyHost: expect.any(String), - proxyPort: expect.any(Number), - rootPublicKeyPem: expect.any(String), - rootCertPem: expect.any(String), - rootCertChainPem: expect.any(String), - }); - }); - test('status on remote LIVE agent', async () => { - const passwordPath = path.join(dataDir, 'password'); - await fs.promises.writeFile(passwordPath, global.binAgentPassword); - const status = new Status({ - statusPath: path.join(global.binAgentDir, config.defaults.statusBase), - fs, - logger, - }); - const statusInfo = (await status.readStatus())!; - const { exitCode, stdout } = await testBinUtils.pkStdio([ - 'agent', - 'status', - '--password-file', - passwordPath, - '--node-id', - statusInfo.data.nodeId, - '--client-host', - statusInfo.data.clientHost, - '--client-port', - statusInfo.data.clientPort.toString(), - '--format', - 'json', - '--verbose', - ]); - expect(exitCode).toBe(0); - expect(JSON.parse(stdout)).toMatchObject({ - status: 'LIVE', - pid: expect.any(Number), - nodeId: statusInfo.data.nodeId, - clientHost: statusInfo.data.clientHost, - clientPort: statusInfo.data.clientPort, - ingressHost: statusInfo.data.ingressHost, - ingressPort: statusInfo.data.ingressPort, - egressHost: expect.any(String), - egressPort: expect.any(Number), - agentHost: expect.any(String), - agentPort: expect.any(Number), - proxyHost: expect.any(String), - proxyPort: expect.any(Number), - rootPublicKeyPem: expect.any(String), - rootCertPem: expect.any(String), - rootCertChainPem: expect.any(String), - }); - }); - test('status on missing agent', async () => { - const { exitCode, stderr } = await testBinUtils.pkStdio( - ['agent', 'status', '--verbose'], - { - PK_NODE_PATH: path.join(dataDir, 'polykey'), - }, - ); - testBinUtils.expectProcessError( - exitCode, - stderr, - new binErrors.ErrorCLIStatusMissing(), - ); - }); test( 'status on STARTING, STOPPING, DEAD agent', async () => { @@ -188,4 +89,105 @@ describe('status', () => { }, global.defaultTimeout * 2, ); + test('status on missing agent', async () => { + const { exitCode, stderr } = await testBinUtils.pkStdio( + ['agent', 'status', '--verbose'], + { + PK_NODE_PATH: path.join(dataDir, 'polykey'), + }, + ); + testBinUtils.expectProcessError( + exitCode, + stderr, + new binErrors.ErrorCLIStatusMissing(), + ); + }); + describe('status with global agent', () => { + let pkAgentClose; + beforeAll(async () => { + pkAgentClose = await testBinUtils.pkAgent(); + }, global.maxTimeout); + afterAll(async () => { + await pkAgentClose(); + }); + test('status on LIVE agent', async () => { + const status = new Status({ + statusPath: path.join(global.binAgentDir, config.defaults.statusBase), + fs, + logger, + }); + const statusInfo = (await status.readStatus())!; + const { exitCode, stdout } = await testBinUtils.pkStdio( + ['agent', 'status', '--format', 'json', '--verbose'], + { + PK_NODE_PATH: global.binAgentDir, + PK_PASSWORD: global.binAgentPassword, + }, + global.binAgentDir, + ); + expect(exitCode).toBe(0); + expect(JSON.parse(stdout)).toMatchObject({ + status: 'LIVE', + pid: expect.any(Number), + nodeId: statusInfo.data.nodeId, + clientHost: statusInfo.data.clientHost, + clientPort: statusInfo.data.clientPort, + ingressHost: statusInfo.data.ingressHost, + ingressPort: statusInfo.data.ingressPort, + egressHost: expect.any(String), + egressPort: expect.any(Number), + agentHost: expect.any(String), + agentPort: expect.any(Number), + proxyHost: expect.any(String), + proxyPort: expect.any(Number), + rootPublicKeyPem: expect.any(String), + rootCertPem: expect.any(String), + rootCertChainPem: expect.any(String), + }); + }); + test('status on remote LIVE agent', async () => { + const passwordPath = path.join(dataDir, 'password'); + await fs.promises.writeFile(passwordPath, global.binAgentPassword); + const status = new Status({ + statusPath: path.join(global.binAgentDir, config.defaults.statusBase), + fs, + logger, + }); + const statusInfo = (await status.readStatus())!; + const { exitCode, stdout } = await testBinUtils.pkStdio([ + 'agent', + 'status', + '--password-file', + passwordPath, + '--node-id', + statusInfo.data.nodeId, + '--client-host', + statusInfo.data.clientHost, + '--client-port', + statusInfo.data.clientPort.toString(), + '--format', + 'json', + '--verbose', + ]); + expect(exitCode).toBe(0); + expect(JSON.parse(stdout)).toMatchObject({ + status: 'LIVE', + pid: expect.any(Number), + nodeId: statusInfo.data.nodeId, + clientHost: statusInfo.data.clientHost, + clientPort: statusInfo.data.clientPort, + ingressHost: statusInfo.data.ingressHost, + ingressPort: statusInfo.data.ingressPort, + egressHost: expect.any(String), + egressPort: expect.any(Number), + agentHost: expect.any(String), + agentPort: expect.any(Number), + proxyHost: expect.any(String), + proxyPort: expect.any(Number), + rootPublicKeyPem: expect.any(String), + rootCertPem: expect.any(String), + rootCertChainPem: expect.any(String), + }); + }); + }); }); diff --git a/tests/bin/agent/unlock.test.ts b/tests/bin/agent/unlock.test.ts index ab0514138..1272642c8 100644 --- a/tests/bin/agent/unlock.test.ts +++ b/tests/bin/agent/unlock.test.ts @@ -1,10 +1,13 @@ import os from 'os'; import path from 'path'; import fs from 'fs'; +import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; +import { Session } from '@/sessions'; +import config from '@/config'; import * as testBinUtils from '../utils'; describe('unlock', () => { - let dataDir: string; + const logger = new Logger('lock test', LogLevel.WARN, [new StreamHandler()]); let pkAgentClose; beforeAll(async () => { pkAgentClose = await testBinUtils.pkAgent(); @@ -12,19 +15,11 @@ describe('unlock', () => { afterAll(async () => { await pkAgentClose(); }); + let dataDir: string; beforeEach(async () => { dataDir = await fs.promises.mkdtemp( path.join(os.tmpdir(), 'polykey-test-'), ); - // Invalidate all active sessions - await testBinUtils.pkStdio( - ['agent', 'lock'], - { - PK_NODE_PATH: global.binAgentDir, - PK_PASSWORD: global.binAgentPassword, - }, - global.binAgentDir, - ); }); afterEach(async () => { await fs.promises.rm(dataDir, { @@ -32,12 +27,17 @@ describe('unlock', () => { recursive: true, }); }); - test('should store session token in session file', async () => { - // Assert no existing session file - await expect( - fs.promises.readdir(path.join(global.binAgentDir)), - ).resolves.not.toContain('token'); - // Run command to set token + test('unlock acquires session token', async () => { + // Fresh session, to delete the token + const session = await Session.createSession({ + sessionTokenPath: path.join( + global.binAgentDir, + config.defaults.tokenBase, + ), + fs, + logger, + fresh: true + }); let exitCode, stdout; ({ exitCode, stdout } = await testBinUtils.pkStdio( ['agent', 'unlock'], @@ -48,9 +48,9 @@ describe('unlock', () => { global.binAgentDir, )); expect(exitCode).toBe(0); - // Run a command without password to check token is valid + // Run command without password ({ exitCode, stdout } = await testBinUtils.pkStdio( - ['agent', 'status', '--format', 'json', '--verbose'], + ['agent', 'status', '--format', 'json'], { PK_NODE_PATH: global.binAgentDir, }, @@ -58,35 +58,17 @@ describe('unlock', () => { )); expect(exitCode).toBe(0); expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); - }); - test('should fail to unlock if agent stopped', async () => { - // Stop agent - await testBinUtils.pkStdio( - ['agent', 'stop'], - { - PK_NODE_PATH: global.binAgentDir, - PK_PASSWORD: global.binAgentPassword, - }, - global.binAgentDir, - ); - // Run unlock command - const { exitCode } = await testBinUtils.pkStdio( - ['agent', 'unlock'], - { - PK_NODE_PATH: global.binAgentDir, - PK_PASSWORD: global.binAgentPassword, - }, - global.binAgentDir, - ); - expect(exitCode).toBe(64); - // Undo side-effects - await testBinUtils.pkStdio( - ['agent', 'start'], + // Run command with PK_TOKEN + ({ exitCode, stdout } = await testBinUtils.pkStdio( + ['agent', 'status', '--format', 'json'], { PK_NODE_PATH: global.binAgentDir, - PK_PASSWORD: global.binAgentPassword, + PK_TOKEN: await session.readToken() }, global.binAgentDir, - ); + )); + expect(exitCode).toBe(0); + expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); + await session.stop(); }); }); diff --git a/tests/bin/utils.ts b/tests/bin/utils.ts index a18ccc3d2..d18be222b 100644 --- a/tests/bin/utils.ts +++ b/tests/bin/utils.ts @@ -312,6 +312,10 @@ async function pkExpect({ * Uses fd-lock to serialise access to the pkAgent * This means all test modules using this will be serialised * Any beforeAll must use global.maxTimeout + * Tips for usage: + * * Do not restart this global agent + * * Ensure client-side side-effects are removed at the end of each test + * * Ensure server-side side-effects are removed at the end of each test */ async function pkAgent( args: Array = [], @@ -401,6 +405,7 @@ async function pkAgent( global.binAgentDir, ); // `pk agent stop` is asynchronous, need to wait for it to be DEAD + // This also means STDERR from the stopping agent may appear on the test logs await status.waitFor('DEAD'); }; } From 61604c3669bea2edf641cc411ae291867a561c6a Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 13 Dec 2021 12:56:58 +1100 Subject: [PATCH 18/29] nonces comment on sessions tests --- tests/bin/sessions.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/bin/sessions.test.ts b/tests/bin/sessions.test.ts index 98e2a3433..181826cce 100644 --- a/tests/bin/sessions.test.ts +++ b/tests/bin/sessions.test.ts @@ -69,6 +69,7 @@ describe('CLI Sessions', () => { const token1 = await session.readToken(); // New command should refresh token // Need to wait for 1100ms to ensure refreshed token will be different from previous one + // Our tokens are not nonces and are expected to be able to be reused await sleep(1100); const { exitCode, stdout } = await testBinUtils.pkStdio( ['agent', 'status', '--format', 'json', '--verbose'], @@ -103,6 +104,7 @@ describe('CLI Sessions', () => { const token1 = await session.readToken(); // Run second command // Need to wait for 1100ms to ensure refreshed token will be different from previous one + // Our tokens are not nonces and are expected to be able to be reused await sleep(1100); ({ exitCode, stdout } = await testBinUtils.pkStdio( ['agent', 'status', '--format', 'json', '--verbose'], From 42454b9885e5fb1c69c1cd028dcceedf817854b6 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 13 Dec 2021 13:29:07 +1100 Subject: [PATCH 19/29] test fixes from status command implementation --- tests/client/GRPCClientClient.test.ts | 66 ++++++++---- tests/client/PolykeyClient.test.ts | 148 ++++++++++++++------------ 2 files changed, 122 insertions(+), 92 deletions(-) diff --git a/tests/client/GRPCClientClient.test.ts b/tests/client/GRPCClientClient.test.ts index 76c7b3c06..63a553ca1 100644 --- a/tests/client/GRPCClientClient.test.ts +++ b/tests/client/GRPCClientClient.test.ts @@ -5,12 +5,13 @@ import os from 'os'; import path from 'path'; import fs from 'fs'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; - import { GRPCClientClient } from '@/client'; import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; import { PolykeyAgent } from '@'; +import { Status } from '@/status'; import * as binProcessors from '@/bin/utils/processors'; import { Session } from '@/sessions'; +import config from '@/config'; import { errors as clientErrors } from '@/client'; import * as testUtils from './utils'; @@ -29,14 +30,12 @@ describe('GRPCClientClient', () => { let client: GRPCClientClient; let server: grpc.Server; let port: number; - let polykeyAgent: PolykeyAgent; let dataDir: string; let nodePath: string; - let nodeId: NodeId; - - beforeEach(async () => { + let session: Session; + beforeAll(async () => { dataDir = await fs.promises.mkdtemp( path.join(os.tmpdir(), 'polykey-test-'), ); @@ -46,7 +45,6 @@ describe('GRPCClientClient', () => { nodePath, logger: logger, }); - nodeId = polykeyAgent.nodeManager.getNodeId(); [server, port] = await testUtils.openTestClientServer({ polykeyAgent, @@ -57,44 +55,70 @@ describe('GRPCClientClient', () => { await session.start({ sessionToken, }); - client = await GRPCClientClient.createGRPCClientClient({ - nodeId: nodeId, - host: '127.0.0.1' as Host, - port: port as Port, - tlsConfig: { keyPrivatePem: undefined, certChainPem: undefined }, - logger: logger, - timeout: 10000, - session: session, - }); - }, global.polykeyStartupTimeout * 3); - afterEach(async () => { + }, global.polykeyStartupTimeout); + afterAll(async () => { await client.destroy(); await testUtils.closeTestClientServer(server); - await polykeyAgent.stop(); await polykeyAgent.destroy(); - await fs.promises.rm(dataDir, { force: true, recursive: true, }); }); - test('cannot be called when destroyed', async () => { + client = await GRPCClientClient.createGRPCClientClient({ + nodeId: nodeId, + host: '127.0.0.1' as Host, + port: port as Port, + tlsConfig: { keyPrivatePem: undefined, certChainPem: undefined }, + logger: logger, + timeout: 10000, + session: session, + }); await client.destroy(); await expect(async () => { await client.agentStatus(new utilsPB.EmptyMessage()); }).rejects.toThrow(clientErrors.ErrorClientClientDestroyed); }); test('can get status', async () => { + client = await GRPCClientClient.createGRPCClientClient({ + nodeId: nodeId, + host: '127.0.0.1' as Host, + port: port as Port, + tlsConfig: { keyPrivatePem: undefined, certChainPem: undefined }, + logger: logger, + timeout: 10000, + session: session, + }); await fs.promises.writeFile(path.join(dataDir, 'password'), password); const meta = await binProcessors.processAuthentication( path.join(dataDir, 'password'), fs, ); + const status = new Status({ + statusPath: path.join(nodePath, config.defaults.statusBase), + fs, + logger, + }); + const statusInfo = (await status.readStatus())!; const emptyMessage = new utilsPB.EmptyMessage(); const response = await client.agentStatus(emptyMessage, meta); - expect(response.getAddress()).toBeTruthy(); + expect(typeof response.getPid()).toBe('number'); + expect(response.getNodeId()).toBe(statusInfo.data.nodeId); + expect(response.getClientHost()).toBe(statusInfo.data.clientHost); + expect(response.getClientPort()).toBe(statusInfo.data.clientPort); + expect(response.getIngressHost()).toBe(statusInfo.data.ingressHost); + expect(response.getIngressPort()).toBe(statusInfo.data.ingressPort); + expect(typeof response.getEgressHost()).toBe('string'); + expect(typeof response.getEgressPort()).toBe('number'); + expect(typeof response.getAgentHost()).toBe('string'); + expect(typeof response.getAgentPort()).toBe('number'); + expect(typeof response.getProxyHost()).toBe('string'); + expect(typeof response.getProxyPort()).toBe('number'); + expect(typeof response.getRootPublicKeyPem()).toBe('string'); + expect(typeof response.getRootCertPem()).toBe('string'); + expect(typeof response.getRootCertChainPem()).toBe('string'); await client.destroy(); }); }); diff --git a/tests/client/PolykeyClient.test.ts b/tests/client/PolykeyClient.test.ts index 1381bbe36..3c427e062 100644 --- a/tests/client/PolykeyClient.test.ts +++ b/tests/client/PolykeyClient.test.ts @@ -1,15 +1,16 @@ import type * as grpc from '@grpc/grpc-js'; import type { GRPCClientClient } from '@/client'; +import type { SessionToken } from '@/sessions/types'; import os from 'os'; import path from 'path'; import fs from 'fs'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; import * as binProcessors from '@/bin/utils/processors'; - import { PolykeyClient } from '@'; +import { Status } from '@/status'; import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; import { PolykeyAgent } from '@'; - +import config from '@/config'; import * as testUtils from './utils'; // Mocks. @@ -30,34 +31,39 @@ describe('PolykeyClient', () => { let _port: number; let passwordFile: string; let meta: grpc.Metadata; - let dataDir: string; let nodePath: string; + let nodePath2: string; let clientPath: string; - + let clientPath2: string; let polykeyAgent: PolykeyAgent; - - beforeEach(async () => { + let polykeyAgent2: PolykeyAgent; + let sessionToken: SessionToken; + beforeAll(async () => { dataDir = await fs.promises.mkdtemp( path.join(os.tmpdir(), 'polykey-test-'), ); - nodePath = path.join(dataDir, 'node'); - clientPath = path.join(dataDir, 'client'); + nodePath = path.join(dataDir, 'keynode1'); + clientPath = path.join(dataDir, 'client1'); + nodePath2 = path.join(dataDir, 'keynode2'); + clientPath2 = path.join(dataDir, 'client2'); passwordFile = path.join(dataDir, 'password'); await fs.promises.writeFile(passwordFile, password); meta = await binProcessors.processAuthentication(passwordFile, fs); - polykeyAgent = await PolykeyAgent.createPolykeyAgent({ password, nodePath, logger: logger, }); - + polykeyAgent2 = await PolykeyAgent.createPolykeyAgent({ + password, + nodePath: nodePath2, + logger: logger.getChild(PolykeyAgent.name), + }); [server, _port] = await testUtils.openTestClientServer({ polykeyAgent, secure: false, }); - pkClient = await PolykeyClient.createPolykeyClient({ nodeId: polykeyAgent.keyManager.getNodeId(), host: polykeyAgent.grpcServerClient.host, @@ -67,84 +73,84 @@ describe('PolykeyClient', () => { logger: logger, }); client = pkClient.grpcClient; - - const sessionToken = await polykeyAgent.sessionManager.createToken(); + sessionToken = await polykeyAgent.sessionManager.createToken(); await pkClient.session.start({ sessionToken }); }); - afterEach(async () => { + afterAll(async () => { await client.destroy(); await pkClient.stop(); await testUtils.closeTestClientServer(server); - + await polykeyAgent2.stop(); + await polykeyAgent2.destroy(); await polykeyAgent.stop(); await polykeyAgent.destroy(); - await fs.promises.rm(dataDir, { force: true, recursive: true, }); }); test('can get status', async () => { + const status = new Status({ + statusPath: path.join(nodePath, config.defaults.statusBase), + fs, + logger, + }); + const statusInfo = (await status.readStatus())!; const emptyMessage = new utilsPB.EmptyMessage(); const response = await client.agentStatus(emptyMessage, meta); - expect(response.getNodeId()).toBeTruthy(); - expect(response.getAddress()).toBeTruthy(); - expect(response.getCert()).toBeTruthy(); + expect(typeof response.getPid()).toBe('number'); + expect(response.getNodeId()).toBe(statusInfo.data.nodeId); + expect(response.getClientHost()).toBe(statusInfo.data.clientHost); + expect(response.getClientPort()).toBe(statusInfo.data.clientPort); + expect(response.getIngressHost()).toBe(statusInfo.data.ingressHost); + expect(response.getIngressPort()).toBe(statusInfo.data.ingressPort); + expect(typeof response.getEgressHost()).toBe('string'); + expect(typeof response.getEgressPort()).toBe('number'); + expect(typeof response.getAgentHost()).toBe('string'); + expect(typeof response.getAgentPort()).toBe('number'); + expect(typeof response.getProxyHost()).toBe('string'); + expect(typeof response.getProxyPort()).toBe('number'); + expect(typeof response.getRootPublicKeyPem()).toBe('string'); + expect(typeof response.getRootCertPem()).toBe('string'); + expect(typeof response.getRootCertChainPem()).toBe('string'); }); - describe('TLS tests', () => { - const password = 'password'; - const logger = new Logger('PolykeyAgent TLS', LogLevel.WARN, [ - new StreamHandler(), - ]); - let dataDir: string; - let nodePath2: string; - let clientPath2: string; - let polykeyAgent2: PolykeyAgent; - let sessionToken; - - beforeAll(async () => { - // Setting up paths and dirs. - dataDir = await fs.promises.mkdtemp( - path.join(os.tmpdir(), 'polykey-test-'), - ); - nodePath2 = path.join(dataDir, 'keynode'); - clientPath2 = path.join(dataDir, 'client2'); - - // Starting an agent. - polykeyAgent2 = await PolykeyAgent.createPolykeyAgent({ - password, - nodePath: nodePath2, - logger: logger.getChild(PolykeyAgent.name), - }); - - sessionToken = await polykeyAgent2.sessionManager.createToken(); - }, global.defaultTimeout * 3); - afterAll(async () => { - await polykeyAgent2.stop(); - await polykeyAgent2.destroy(); + test('can get status over TLS', async () => { + // Starting client. + const pkClient = await PolykeyClient.createPolykeyClient({ + nodeId: polykeyAgent2.keyManager.getNodeId(), + host: polykeyAgent2.grpcServerClient.host, + port: polykeyAgent2.grpcServerClient.port, + nodePath: clientPath2, + fs: fs, + logger: logger.getChild(PolykeyClient.name), }); - test('can get status over TLS', async () => { - // Starting client. - const pkClient = await PolykeyClient.createPolykeyClient({ - nodeId: polykeyAgent2.keyManager.getNodeId(), - host: polykeyAgent2.grpcServerClient.host, - port: polykeyAgent2.grpcServerClient.port, - nodePath: clientPath2, - fs: fs, - logger: logger.getChild(PolykeyClient.name), - }); - await pkClient.session.start({ sessionToken }); - const meta = await binProcessors.processAuthentication(passwordFile, fs); + await pkClient.session.start({ sessionToken }); + const meta = await binProcessors.processAuthentication(passwordFile, fs); - const emptyMessage = new utilsPB.EmptyMessage(); - const response = await pkClient.grpcClient.agentStatus( - emptyMessage, - meta, - ); - expect(response.getNodeId()).toBeTruthy(); - expect(response.getAddress()).toBeTruthy(); - expect(response.getCert()).toBeTruthy(); - expect(pkClient.grpcClient.secured).toBeTruthy(); + const status = new Status({ + statusPath: path.join(nodePath2, config.defaults.statusBase), + fs, + logger, }); + const statusInfo = (await status.readStatus())!; + + const emptyMessage = new utilsPB.EmptyMessage(); + const response = await pkClient.grpcClient.agentStatus(emptyMessage, meta); + expect(typeof response.getPid()).toBe('number'); + expect(response.getNodeId()).toBe(statusInfo.data.nodeId); + expect(response.getClientHost()).toBe(statusInfo.data.clientHost); + expect(response.getClientPort()).toBe(statusInfo.data.clientPort); + expect(response.getIngressHost()).toBe(statusInfo.data.ingressHost); + expect(response.getIngressPort()).toBe(statusInfo.data.ingressPort); + expect(typeof response.getEgressHost()).toBe('string'); + expect(typeof response.getEgressPort()).toBe('number'); + expect(typeof response.getAgentHost()).toBe('string'); + expect(typeof response.getAgentPort()).toBe('number'); + expect(typeof response.getProxyHost()).toBe('string'); + expect(typeof response.getProxyPort()).toBe('number'); + expect(typeof response.getRootPublicKeyPem()).toBe('string'); + expect(typeof response.getRootCertPem()).toBe('string'); + expect(typeof response.getRootCertChainPem()).toBe('string'); + expect(pkClient.grpcClient.secured).toBeTruthy(); }); }); From 17bba2a446f77f3fc57ff229062ee6554d916a1d Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Mon, 13 Dec 2021 13:13:36 +1100 Subject: [PATCH 20/29] Agent and sessions tests working --- tests/bin/agent/lockall.test.ts | 2 + tests/bin/sessions.test.ts | 118 ++++++++++---------------------- 2 files changed, 38 insertions(+), 82 deletions(-) diff --git a/tests/bin/agent/lockall.test.ts b/tests/bin/agent/lockall.test.ts index f8f1dfcc0..ea2ce7f66 100644 --- a/tests/bin/agent/lockall.test.ts +++ b/tests/bin/agent/lockall.test.ts @@ -64,6 +64,7 @@ describe('lockall', () => { logger, }); expect(await session.readToken()).toBeUndefined(); + await session.stop(); }); test('lockall ensures reauthentication is required', async () => { const password = global.binAgentPassword; @@ -116,6 +117,7 @@ describe('lockall', () => { logger, }); const token = await session.readToken(); + await session.stop(); await testBinUtils.pkStdio( ['agent', 'lockall'], { diff --git a/tests/bin/sessions.test.ts b/tests/bin/sessions.test.ts index 181826cce..6cb95c393 100644 --- a/tests/bin/sessions.test.ts +++ b/tests/bin/sessions.test.ts @@ -1,3 +1,8 @@ +/** + * There is no command call sessions + * This is just for testing the CLI Authentication Retry Loop + * @module + */ import os from 'os'; import path from 'path'; import fs from 'fs'; @@ -20,31 +25,18 @@ describe('CLI Sessions', () => { const logger = new Logger('sessions test', LogLevel.WARN, [ new StreamHandler(), ]); - let dataDir: string; let pkAgentClose; - const sessionTokenPath = path.join( - global.binAgentDir, - config.defaults.tokenBase, - ); beforeAll(async () => { pkAgentClose = await testBinUtils.pkAgent(); }, global.maxTimeout); afterAll(async () => { await pkAgentClose(); }); + let dataDir: string; beforeEach(async () => { dataDir = await fs.promises.mkdtemp( path.join(os.tmpdir(), 'polykey-test-'), ); - // Invalidate all active sessions - await testBinUtils.pkStdio( - ['agent', 'lock'], - { - PK_NODE_PATH: global.binAgentDir, - PK_PASSWORD: global.binAgentPassword, - }, - global.binAgentDir, - ); }); afterEach(async () => { await fs.promises.rm(dataDir, { @@ -52,47 +44,18 @@ describe('CLI Sessions', () => { recursive: true, }); }); - test('processes should refresh the session token', async () => { - const session = await Session.createSession({ - sessionTokenPath, - fs, - logger, - }); - await testBinUtils.pkStdio( - ['agent', 'unlock'], - { - PK_NODE_PATH: global.binAgentDir, - PK_PASSWORD: global.binAgentPassword, - }, - global.binAgentDir, - ); - const token1 = await session.readToken(); - // New command should refresh token - // Need to wait for 1100ms to ensure refreshed token will be different from previous one - // Our tokens are not nonces and are expected to be able to be reused - await sleep(1100); - const { exitCode, stdout } = await testBinUtils.pkStdio( - ['agent', 'status', '--format', 'json', '--verbose'], - { - PK_NODE_PATH: global.binAgentDir, - }, - global.binAgentDir, - ); - expect(exitCode).toBe(0); - expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); - const token2 = await session.readToken(); - expect(token1).not.toBe(token2); - }); - test('serial processes should both refresh the session token', async () => { + test('serial commands refresh the session token', async () => { const session = await Session.createSession({ - sessionTokenPath, + sessionTokenPath: path.join( + global.binAgentDir, + config.defaults.tokenBase, + ), fs, logger, }); - // Run first command - let exitCode, stdout; - ({ exitCode, stdout } = await testBinUtils.pkStdio( - ['agent', 'status', '--format', 'json', '--verbose'], + let exitCode; + ({ exitCode } = await testBinUtils.pkStdio( + ['agent', 'status'], { PK_NODE_PATH: global.binAgentDir, PK_PASSWORD: global.binAgentPassword, @@ -100,14 +63,13 @@ describe('CLI Sessions', () => { global.binAgentDir, )); expect(exitCode).toBe(0); - expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); const token1 = await session.readToken(); - // Run second command - // Need to wait for 1100ms to ensure refreshed token will be different from previous one - // Our tokens are not nonces and are expected to be able to be reused + // Tokens are not nonces + // Wait at least 1 second + // To ensure that the next token has a new expiry await sleep(1100); - ({ exitCode, stdout } = await testBinUtils.pkStdio( - ['agent', 'status', '--format', 'json', '--verbose'], + ({ exitCode } = await testBinUtils.pkStdio( + ['agent', 'status'], { PK_NODE_PATH: global.binAgentDir, PK_PASSWORD: global.binAgentPassword, @@ -115,12 +77,11 @@ describe('CLI Sessions', () => { global.binAgentDir, )); expect(exitCode).toBe(0); - expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); const token2 = await session.readToken(); - // Assert different expect(token1).not.toBe(token2); + await session.stop(); }); - test('unattended calls with invalid auth should fail', async () => { + test('unattended commands with invalid authentication should fail', async () => { let exitCode, stderr; // Password and Token set ({ exitCode, stderr } = await testBinUtils.pkStdio( @@ -168,46 +129,39 @@ describe('CLI Sessions', () => { new clientErrors.ErrorClientAuthDenied(), ); }); - test('password can be used to authenticate attended calls', async () => { + test('prompt for password to authenticate attended commands', async () => { const password = global.binAgentPassword; + await testBinUtils.pkStdio( + ['agent', 'lock'], + { + PK_NODE_PATH: global.binAgentDir, + }, + global.binAgentDir, + ); mockedPrompts.mockClear(); mockedPrompts.mockImplementation(async (_opts: any) => { return { password }; }); - const { exitCode, stdout } = await testBinUtils.pkStdio( - ['agent', 'status', '--format', 'json', '--verbose'], + const { exitCode } = await testBinUtils.pkStdio( + ['agent', 'status'], { PK_NODE_PATH: global.binAgentDir, }, global.binAgentDir, ); expect(exitCode).toBe(0); - expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); // Prompted for password 1 time expect(mockedPrompts.mock.calls.length).toBe(1); mockedPrompts.mockClear(); }); - test('re-prompt for password if unable to authenticate call', async () => { - const validPassword = global.binAgentPassword; - const invalidPassword = 'invalid'; - mockedPrompts.mockClear(); - mockedPrompts - .mockResolvedValueOnce({ password: invalidPassword }) - .mockResolvedValue({ password: validPassword }); - const { exitCode, stdout } = await testBinUtils.pkStdio( - ['agent', 'status', '--format', 'json', '--verbose'], + test('re-prompts for password if unable to authenticate command', async () => { + await testBinUtils.pkStdio( + ['agent', 'lock'], { PK_NODE_PATH: global.binAgentDir, }, global.binAgentDir, ); - expect(exitCode).toBe(0); - expect(JSON.parse(stdout)).toMatchObject({ status: 'LIVE' }); - // Prompted for password 2 times - expect(mockedPrompts.mock.calls.length).toBe(2); - mockedPrompts.mockClear(); - }); - test('will not prompt for password reauthentication on generic error', async () => { const validPassword = global.binAgentPassword; const invalidPassword = 'invalid'; mockedPrompts.mockClear(); @@ -215,13 +169,13 @@ describe('CLI Sessions', () => { .mockResolvedValueOnce({ password: invalidPassword }) .mockResolvedValue({ password: validPassword }); const { exitCode } = await testBinUtils.pkStdio( - ['identities', 'search', 'InvalidProvider'], + ['agent', 'status'], { PK_NODE_PATH: global.binAgentDir, }, global.binAgentDir, ); - expect(exitCode).not.toBe(0); + expect(exitCode).toBe(0); // Prompted for password 2 times expect(mockedPrompts.mock.calls.length).toBe(2); mockedPrompts.mockClear(); From e0de24ee4ebaa3af0c8f67d9988f6b159f9c0f8a Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 13 Dec 2021 13:34:30 +1100 Subject: [PATCH 21/29] more meaningful naming --- tests/client/rpcSessions.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/client/rpcSessions.test.ts b/tests/client/rpcSessions.test.ts index 15d58284c..581e93725 100644 --- a/tests/client/rpcSessions.test.ts +++ b/tests/client/rpcSessions.test.ts @@ -86,24 +86,24 @@ describe('Sessions client service', () => { callCredentials = testUtils.createCallCredentials(sessionToken); }); test('can request a session', async () => { - const requestJWT = grpcUtils.promisifyUnaryCall( + const unlock = grpcUtils.promisifyUnaryCall( client, client.sessionsUnlock, ); - const pCall = requestJWT(new utilsPB.EmptyMessage(), callCredentials); + const pCall = unlock(new utilsPB.EmptyMessage(), callCredentials); const meta = await pCall.meta; const token = clientUtils.decodeAuthToSession(meta); const result = await polykeyAgent.sessionManager.verifyToken(token!); expect(result).toBeTruthy(); }); test('can lock all sessions', async () => { - const requestJWT = grpcUtils.promisifyUnaryCall( + const lockall = grpcUtils.promisifyUnaryCall( client, client.sessionsLockAll, ); - await requestJWT(new utilsPB.EmptyMessage(), callCredentials); + await lockall(new utilsPB.EmptyMessage(), callCredentials); const prevToken = clientUtils.decodeAuthToSession(callCredentials); const result = await polykeyAgent.sessionManager.verifyToken(prevToken!); expect(result).toBeFalsy(); From 4ff1e88439bf1e411945a9ae371ed3496afd2615 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 13 Dec 2021 14:07:03 +1100 Subject: [PATCH 22/29] replacing meta?: Metadata with auth --- src/bin/identities/CommandAllow.ts | 6 ++---- src/bin/identities/CommandAuthenticate.ts | 6 ++---- src/bin/identities/CommandClaim.ts | 4 +--- src/bin/identities/CommandDisallow.ts | 6 ++---- src/bin/identities/CommandDiscover.ts | 6 ++---- src/bin/identities/CommandGet.ts | 6 ++---- src/bin/identities/CommandList.ts | 8 +++----- src/bin/identities/CommandPermissions.ts | 6 ++---- src/bin/identities/CommandSearch.ts | 4 +--- src/bin/identities/CommandTrust.ts | 6 ++---- src/bin/identities/CommandUntrust.ts | 6 ++---- src/bin/keys/CommandCert.ts | 4 +--- src/bin/keys/CommandCertchain.ts | 6 ++---- src/bin/keys/CommandDecrypt.ts | 4 +--- src/bin/keys/CommandEncrypt.ts | 4 +--- src/bin/keys/CommandRoot.ts | 4 +--- src/bin/keys/CommandSign.ts | 4 +--- src/bin/keys/CommandVerify.ts | 4 +--- src/bin/nodes/CommandAdd.ts | 4 +--- src/bin/nodes/CommandClaim.ts | 4 +--- src/bin/nodes/CommandFind.ts | 3 +-- src/bin/nodes/CommandPing.ts | 4 +--- src/bin/notifications/CommandClear.ts | 4 +--- src/bin/notifications/CommandRead.ts | 3 +-- src/bin/notifications/CommandSend.ts | 4 +--- src/bin/secrets/CommandCreate.ts | 4 +--- src/bin/secrets/CommandDelete.ts | 4 +--- src/bin/secrets/CommandDir.ts | 4 +--- src/bin/secrets/CommandEdit.ts | 4 +--- src/bin/secrets/CommandGet.ts | 4 +--- src/bin/secrets/CommandList.ts | 6 ++---- src/bin/secrets/CommandMkdir.ts | 4 +--- src/bin/secrets/CommandRename.ts | 4 +--- src/bin/secrets/CommandUpdate.ts | 4 +--- 34 files changed, 46 insertions(+), 112 deletions(-) diff --git a/src/bin/identities/CommandAllow.ts b/src/bin/identities/CommandAllow.ts index ae1ba6b8a..d1136e965 100644 --- a/src/bin/identities/CommandAllow.ts +++ b/src/bin/identities/CommandAllow.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -70,7 +68,7 @@ class CommandAllow extends CommandPolykey { name = `${gestaltId.nodeId}`; // Trusting await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.gestaltsActionsSetByNode(setActionMessage, auth), meta, ); @@ -85,7 +83,7 @@ class CommandAllow extends CommandPolykey { gestaltId.identityId, )}`; await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.gestaltsActionsSetByIdentity(setActionMessage, auth), meta, ); diff --git a/src/bin/identities/CommandAuthenticate.ts b/src/bin/identities/CommandAuthenticate.ts index 5902c76dc..1c09b673b 100644 --- a/src/bin/identities/CommandAuthenticate.ts +++ b/src/bin/identities/CommandAuthenticate.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -56,10 +54,10 @@ class CommandAuthenticate extends CommandPolykey { providerMessage.setMessage(identityId); // Sending message. const successMessage = await binUtils.retryAuthentication( - async (meta: Metadata) => { + async (auth) => { const stream = grpcClient.identitiesAuthenticate( providerMessage, - meta, + auth, ); const codeMessage = (await stream.next()).value; process.stdout.write( diff --git a/src/bin/identities/CommandClaim.ts b/src/bin/identities/CommandClaim.ts index d3c4aec4b..ca53000c2 100644 --- a/src/bin/identities/CommandClaim.ts +++ b/src/bin/identities/CommandClaim.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -58,7 +56,7 @@ class CommandClaim extends CommandPolykey { // Sending message. await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.identitiesClaim(providerMessage, auth), meta, ); diff --git a/src/bin/identities/CommandDisallow.ts b/src/bin/identities/CommandDisallow.ts index 40b79379f..8cb86e008 100644 --- a/src/bin/identities/CommandDisallow.ts +++ b/src/bin/identities/CommandDisallow.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binOptions from '../utils/options'; @@ -70,7 +68,7 @@ class CommandDisallow extends CommandPolykey { name = `${gestaltId.nodeId}`; // Trusting await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.gestaltsActionsUnsetByNode(setActionMessage, auth), meta, ); @@ -86,7 +84,7 @@ class CommandDisallow extends CommandPolykey { )}`; // Trusting. await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.gestaltsActionsUnsetByIdentity(setActionMessage, auth), meta, ); diff --git a/src/bin/identities/CommandDiscover.ts b/src/bin/identities/CommandDiscover.ts index 49b7ed7e9..d4b78e6cc 100644 --- a/src/bin/identities/CommandDiscover.ts +++ b/src/bin/identities/CommandDiscover.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binOptions from '../utils/options'; @@ -64,7 +62,7 @@ class CommandDiscover extends CommandPolykey { nodeMessage.setNodeId(gestaltId.nodeId); name = `${gestaltId.nodeId}`; await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.gestaltsDiscoveryByNode(nodeMessage, auth), meta, ); @@ -78,7 +76,7 @@ class CommandDiscover extends CommandPolykey { gestaltId.identityId, )}`; await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.gestaltsDiscoveryByIdentity(providerMessage, auth), meta, ); diff --git a/src/bin/identities/CommandGet.ts b/src/bin/identities/CommandGet.ts index 958c3ddfd..6c784f5d3 100644 --- a/src/bin/identities/CommandGet.ts +++ b/src/bin/identities/CommandGet.ts @@ -1,6 +1,4 @@ -import type { Metadata } from '@grpc/grpc-js'; import type gestaltsPB from '../../proto/js/polykey/v1/gestalts/gestalts_pb'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binOptions from '../utils/options'; @@ -64,7 +62,7 @@ class CommandGet extends CommandPolykey { const nodeMessage = new nodesPB.Node(); nodeMessage.setNodeId(gestaltId.nodeId); res = await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.gestaltsGestaltGetByNode(nodeMessage, auth), meta, ); @@ -74,7 +72,7 @@ class CommandGet extends CommandPolykey { providerMessage.setProviderId(gestaltId.providerId); providerMessage.setMessage(gestaltId.identityId); res = await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.gestaltsGestaltGetByIdentity(providerMessage, auth), meta, ); diff --git a/src/bin/identities/CommandList.ts b/src/bin/identities/CommandList.ts index 13a93aa69..0e5f7ef51 100644 --- a/src/bin/identities/CommandList.ts +++ b/src/bin/identities/CommandList.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binOptions from '../utils/options'; @@ -50,9 +48,9 @@ class CommandList extends CommandPolykey { const emptyMessage = new utilsPB.EmptyMessage(); let output: any; const gestalts = await binUtils.retryAuthentication( - async (meta: Metadata) => { + async (auth) => { const gestalts: Array = []; - const stream = grpcClient.gestaltsGestaltList(emptyMessage, meta); + const stream = grpcClient.gestaltsGestaltList(emptyMessage, auth); for await (const val of stream) { const gestalt = JSON.parse(val.getName()); const newGestalt: any = { @@ -75,7 +73,7 @@ class CommandList extends CommandPolykey { const nodeMessage = new nodesPB.Node(); nodeMessage.setNodeId(newGestalt.nodes[0].id); const actionsMessage = await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.gestaltsActionsGetByNode(nodeMessage, auth), meta, ); diff --git a/src/bin/identities/CommandPermissions.ts b/src/bin/identities/CommandPermissions.ts index 5985ee698..6f2af46be 100644 --- a/src/bin/identities/CommandPermissions.ts +++ b/src/bin/identities/CommandPermissions.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binOptions from '../utils/options'; @@ -60,7 +58,7 @@ class CommandPermissions extends CommandPolykey { const nodeMessage = new nodesPB.Node(); nodeMessage.setNodeId(gestaltId.nodeId); const res = await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.gestaltsActionsGetByNode(nodeMessage, auth), meta, ); @@ -71,7 +69,7 @@ class CommandPermissions extends CommandPolykey { providerMessage.setProviderId(gestaltId.providerId); providerMessage.setMessage(gestaltId.identityId); const res = await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.gestaltsActionsGetByIdentity(providerMessage, auth), meta, ); diff --git a/src/bin/identities/CommandSearch.ts b/src/bin/identities/CommandSearch.ts index 5b12c7cfc..9b5b24bc8 100644 --- a/src/bin/identities/CommandSearch.ts +++ b/src/bin/identities/CommandSearch.ts @@ -1,6 +1,4 @@ -import type { Metadata } from '@grpc/grpc-js'; import type { ProviderId, IdentityId } from '../../identities/types'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binOptions from '../utils/options'; @@ -57,7 +55,7 @@ class CommandSearch extends CommandPolykey { const providerMessage = new identitiesPB.Provider(); providerMessage.setProviderId(providerId); const res = await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.identitiesInfoGet(providerMessage, auth), meta, ); diff --git a/src/bin/identities/CommandTrust.ts b/src/bin/identities/CommandTrust.ts index b19142c8b..6e4bc64f6 100644 --- a/src/bin/identities/CommandTrust.ts +++ b/src/bin/identities/CommandTrust.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binOptions from '../utils/options'; @@ -69,7 +67,7 @@ class CommandTrust extends CommandPolykey { setActionMessage.setNode(nodeMessage); name = `${gestaltId.nodeId}`; await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.gestaltsActionsSetByNode(setActionMessage, auth), meta, ); @@ -84,7 +82,7 @@ class CommandTrust extends CommandPolykey { gestaltId.identityId, )}`; await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.gestaltsActionsSetByIdentity(setActionMessage, auth), meta, ); diff --git a/src/bin/identities/CommandUntrust.ts b/src/bin/identities/CommandUntrust.ts index 79b4c03aa..50788a2a6 100644 --- a/src/bin/identities/CommandUntrust.ts +++ b/src/bin/identities/CommandUntrust.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binOptions from '../utils/options'; @@ -69,7 +67,7 @@ class CommandUntrust extends CommandPolykey { setActionMessage.setNode(nodeMessage); name = `${gestaltId.nodeId}`; await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.gestaltsActionsUnsetByNode(setActionMessage, auth), meta, ); @@ -84,7 +82,7 @@ class CommandUntrust extends CommandPolykey { gestaltId.identityId, )}`; await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.gestaltsActionsUnsetByIdentity(setActionMessage, auth), meta, ); diff --git a/src/bin/keys/CommandCert.ts b/src/bin/keys/CommandCert.ts index a10bc47e0..c89f06f0e 100644 --- a/src/bin/keys/CommandCert.ts +++ b/src/bin/keys/CommandCert.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -48,7 +46,7 @@ class CommandCert extends CommandPolykey { const grpcClient = pkClient.grpcClient; const emptyMessage = new utilsPB.EmptyMessage(); const response = await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.keysCertsGet(emptyMessage, auth), + (auth) => grpcClient.keysCertsGet(emptyMessage, auth), meta, ); diff --git a/src/bin/keys/CommandCertchain.ts b/src/bin/keys/CommandCertchain.ts index 4aedc0fde..9f61c49e4 100644 --- a/src/bin/keys/CommandCertchain.ts +++ b/src/bin/keys/CommandCertchain.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -48,9 +46,9 @@ class CommandsCertchain extends CommandPolykey { const grpcClient = pkClient.grpcClient; const emptyMessage = new utilsPB.EmptyMessage(); const data = await binUtils.retryAuthentication( - async (meta: Metadata) => { + async (auth) => { const data: Array = []; - const stream = grpcClient.keysCertsChainGet(emptyMessage, meta); + const stream = grpcClient.keysCertsChainGet(emptyMessage, auth); for await (const cert of stream) { data.push(`Certificate:\t\t${cert.getCert()}`); } diff --git a/src/bin/keys/CommandDecrypt.ts b/src/bin/keys/CommandDecrypt.ts index 7410e9486..800b5bc23 100644 --- a/src/bin/keys/CommandDecrypt.ts +++ b/src/bin/keys/CommandDecrypt.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import * as binErrors from '../errors'; import CommandPolykey from '../CommandPolykey'; @@ -68,7 +66,7 @@ class CommandDecrypt extends CommandPolykey { cryptoMessage.setData(cipherText); const response = await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.keysDecrypt(cryptoMessage, auth), + (auth) => grpcClient.keysDecrypt(cryptoMessage, auth), meta, ); diff --git a/src/bin/keys/CommandEncrypt.ts b/src/bin/keys/CommandEncrypt.ts index 02ad669bf..1645b30f3 100644 --- a/src/bin/keys/CommandEncrypt.ts +++ b/src/bin/keys/CommandEncrypt.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import * as binErrors from '../errors'; import CommandPolykey from '../CommandPolykey'; @@ -69,7 +67,7 @@ class CommandEncypt extends CommandPolykey { cryptoMessage.setData(plainText); const response = await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.keysEncrypt(cryptoMessage, auth), + (auth) => grpcClient.keysEncrypt(cryptoMessage, auth), meta, ); diff --git a/src/bin/keys/CommandRoot.ts b/src/bin/keys/CommandRoot.ts index 9af8b359c..e405dce1f 100644 --- a/src/bin/keys/CommandRoot.ts +++ b/src/bin/keys/CommandRoot.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -49,7 +47,7 @@ class CommandRoot extends CommandPolykey { const emptyMessage = new utilsPB.EmptyMessage(); const keyPair = await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.keysKeyPairRoot(emptyMessage, auth), + (auth) => grpcClient.keysKeyPairRoot(emptyMessage, auth), meta, ); diff --git a/src/bin/keys/CommandSign.ts b/src/bin/keys/CommandSign.ts index fd5e4ab68..24d4e3a3c 100644 --- a/src/bin/keys/CommandSign.ts +++ b/src/bin/keys/CommandSign.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import * as binErrors from '../errors'; import CommandPolykey from '../CommandPolykey'; @@ -68,7 +66,7 @@ class CommandSign extends CommandPolykey { cryptoMessage.setData(data); const response = await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.keysSign(cryptoMessage, auth), + (auth) => grpcClient.keysSign(cryptoMessage, auth), meta, ); diff --git a/src/bin/keys/CommandVerify.ts b/src/bin/keys/CommandVerify.ts index 4569a274f..15b1b560c 100644 --- a/src/bin/keys/CommandVerify.ts +++ b/src/bin/keys/CommandVerify.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import * as binErrors from '../errors'; import CommandPolykey from '../CommandPolykey'; @@ -78,7 +76,7 @@ class CommandVerify extends CommandPolykey { cryptoMessage.setSignature(signature); const response = await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.keysVerify(cryptoMessage, auth), + (auth) => grpcClient.keysVerify(cryptoMessage, auth), meta, ); diff --git a/src/bin/nodes/CommandAdd.ts b/src/bin/nodes/CommandAdd.ts index b079783d3..440652d09 100644 --- a/src/bin/nodes/CommandAdd.ts +++ b/src/bin/nodes/CommandAdd.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils/utils'; @@ -55,7 +53,7 @@ class CommandAdd extends CommandPolykey { ); await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.nodesAdd(nodeAddressMessage, auth), + (auth) => grpcClient.nodesAdd(nodeAddressMessage, auth), meta, ); diff --git a/src/bin/nodes/CommandClaim.ts b/src/bin/nodes/CommandClaim.ts index fd0e783ef..6ed2b1a42 100644 --- a/src/bin/nodes/CommandClaim.ts +++ b/src/bin/nodes/CommandClaim.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -59,7 +57,7 @@ class CommandClaim extends CommandPolykey { } const response = await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.nodesClaim(nodeClaimMessage, auth), + (auth) => grpcClient.nodesClaim(nodeClaimMessage, auth), meta, ); const claimed = response.getSuccess(); diff --git a/src/bin/nodes/CommandFind.ts b/src/bin/nodes/CommandFind.ts index 68f0e22fe..db371074a 100644 --- a/src/bin/nodes/CommandFind.ts +++ b/src/bin/nodes/CommandFind.ts @@ -1,5 +1,4 @@ import type { Host, Port } from '../../network/types'; -import type { Metadata } from '@grpc/grpc-js'; import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; @@ -61,7 +60,7 @@ class CommandFind extends CommandPolykey { }; try { const response = await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.nodesFind(nodeMessage, auth), + (auth) => grpcClient.nodesFind(nodeMessage, auth), meta, ); diff --git a/src/bin/nodes/CommandPing.ts b/src/bin/nodes/CommandPing.ts index 8d32f339f..6dfca9259 100644 --- a/src/bin/nodes/CommandPing.ts +++ b/src/bin/nodes/CommandPing.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -54,7 +52,7 @@ class CommandPing extends CommandPolykey { let error; try { statusMessage = await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.nodesPing(nodeMessage, auth), + (auth) => grpcClient.nodesPing(nodeMessage, auth), meta, ); } catch (err) { diff --git a/src/bin/notifications/CommandClear.ts b/src/bin/notifications/CommandClear.ts index 563a5ccb1..1e2da6534 100644 --- a/src/bin/notifications/CommandClear.ts +++ b/src/bin/notifications/CommandClear.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -49,7 +47,7 @@ class CommandClear extends CommandPolykey { const emptyMessage = new utilsPB.EmptyMessage(); await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.notificationsClear(emptyMessage, auth), meta, ); diff --git a/src/bin/notifications/CommandRead.ts b/src/bin/notifications/CommandRead.ts index b3d174f60..005eb24a1 100644 --- a/src/bin/notifications/CommandRead.ts +++ b/src/bin/notifications/CommandRead.ts @@ -1,5 +1,4 @@ import type { Notification } from '../../notifications/types'; -import type { Metadata } from '@grpc/grpc-js'; import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; @@ -74,7 +73,7 @@ class CommandRead extends CommandPolykey { notificationsReadMessage.setOrder(options.order); const response = await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.notificationsRead(notificationsReadMessage, auth), meta, ); diff --git a/src/bin/notifications/CommandSend.ts b/src/bin/notifications/CommandSend.ts index 0375c0100..d8a1b601e 100644 --- a/src/bin/notifications/CommandSend.ts +++ b/src/bin/notifications/CommandSend.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -56,7 +54,7 @@ class CommandSend extends CommandPolykey { notificationsSendMessage.setData(generalMessage); await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.notificationsSend(notificationsSendMessage, auth), meta, ); diff --git a/src/bin/secrets/CommandCreate.ts b/src/bin/secrets/CommandCreate.ts index 1a6a08d3c..7ff082ede 100644 --- a/src/bin/secrets/CommandCreate.ts +++ b/src/bin/secrets/CommandCreate.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import * as binErrors from '../errors'; import CommandPolykey from '../CommandPolykey'; @@ -82,7 +80,7 @@ class CommandCreate extends CommandPolykey { secretMessage.setSecretContent(content); await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.vaultsSecretsNew(secretMessage, auth), + (auth) => grpcClient.vaultsSecretsNew(secretMessage, auth), meta, ); diff --git a/src/bin/secrets/CommandDelete.ts b/src/bin/secrets/CommandDelete.ts index b987fe8aa..0453c0ab1 100644 --- a/src/bin/secrets/CommandDelete.ts +++ b/src/bin/secrets/CommandDelete.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -64,7 +62,7 @@ class CommandDelete extends CommandPolykey { secretMessage.setSecretName(secretPath[1]); await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.vaultsSecretsDelete(secretMessage, auth), meta, ); diff --git a/src/bin/secrets/CommandDir.ts b/src/bin/secrets/CommandDir.ts index 1c5b93868..a4fcb616d 100644 --- a/src/bin/secrets/CommandDir.ts +++ b/src/bin/secrets/CommandDir.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -62,7 +60,7 @@ class CommandDir extends CommandPolykey { secretDirectoryMessage.setSecretDirectory(directoryPath); await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.vaultsSecretsNewDir(secretDirectoryMessage, auth), meta, ); diff --git a/src/bin/secrets/CommandEdit.ts b/src/bin/secrets/CommandEdit.ts index 2d1bdda26..8d1b08472 100644 --- a/src/bin/secrets/CommandEdit.ts +++ b/src/bin/secrets/CommandEdit.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import * as binErrors from '../errors'; import CommandPolykey from '../CommandPolykey'; @@ -67,7 +65,7 @@ class CommandEdit extends CommandPolykey { secretMessage.setSecretName(secretPath[1]); const response = await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.vaultsSecretsGet(secretMessage, auth), + (auth) => grpcClient.vaultsSecretsGet(secretMessage, auth), meta, ); diff --git a/src/bin/secrets/CommandGet.ts b/src/bin/secrets/CommandGet.ts index 21e412643..3672deb04 100644 --- a/src/bin/secrets/CommandGet.ts +++ b/src/bin/secrets/CommandGet.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -68,7 +66,7 @@ class CommandGet extends CommandPolykey { secretMessage.setSecretName(secretPath[1]); const response = await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.vaultsSecretsGet(secretMessage, auth), + (auth) => grpcClient.vaultsSecretsGet(secretMessage, auth), meta, ); diff --git a/src/bin/secrets/CommandList.ts b/src/bin/secrets/CommandList.ts index f43448e6d..923bb6bce 100644 --- a/src/bin/secrets/CommandList.ts +++ b/src/bin/secrets/CommandList.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -53,9 +51,9 @@ class CommandList extends CommandPolykey { vaultMessage.setNameOrId(vaultName); const data = await binUtils.retryAuthentication( - async (meta: Metadata) => { + async (auth) => { const data: Array = []; - const stream = grpcClient.vaultsSecretsList(vaultMessage, meta); + const stream = grpcClient.vaultsSecretsList(vaultMessage, auth); for await (const secret of stream) { data.push(`${secret.getSecretName()}`); } diff --git a/src/bin/secrets/CommandMkdir.ts b/src/bin/secrets/CommandMkdir.ts index 9df108740..0d01ad805 100644 --- a/src/bin/secrets/CommandMkdir.ts +++ b/src/bin/secrets/CommandMkdir.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -62,7 +60,7 @@ class CommandMkdir extends CommandPolykey { vaultMkdirMessage.setRecursive(options.recursive); await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.vaultsSecretsMkdir(vaultMkdirMessage, auth), meta, ); diff --git a/src/bin/secrets/CommandRename.ts b/src/bin/secrets/CommandRename.ts index 2a0a33713..d8534f00d 100644 --- a/src/bin/secrets/CommandRename.ts +++ b/src/bin/secrets/CommandRename.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -67,7 +65,7 @@ class CommandRename extends CommandPolykey { secretRenameMessage.setNewName(newSecretName); await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.vaultsSecretsRename(secretRenameMessage, auth), meta, ); diff --git a/src/bin/secrets/CommandUpdate.ts b/src/bin/secrets/CommandUpdate.ts index ef1df6806..bde010c3e 100644 --- a/src/bin/secrets/CommandUpdate.ts +++ b/src/bin/secrets/CommandUpdate.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import * as binErrors from '../errors'; import CommandPolykey from '../CommandPolykey'; @@ -81,7 +79,7 @@ class CommandUpdate extends CommandPolykey { secretMessage.setSecretContent(content); await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.vaultsSecretsEdit(secretMessage, auth), meta, ); From 3dfa2cd7178cd1fd78f619969fe5e58f6cfd4699 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 13 Dec 2021 14:22:12 +1100 Subject: [PATCH 23/29] missed metas in vaults commands --- src/bin/vaults/CommandClone.ts | 4 +--- src/bin/vaults/CommandCreate.ts | 4 +--- src/bin/vaults/CommandDelete.ts | 4 +--- src/bin/vaults/CommandPull.ts | 4 +--- src/bin/vaults/CommandRename.ts | 4 +--- src/bin/vaults/CommandShare.ts | 4 +--- src/bin/vaults/CommandUnshare.ts | 4 +--- src/bin/vaults/CommandVersion.ts | 4 +--- 8 files changed, 8 insertions(+), 24 deletions(-) diff --git a/src/bin/vaults/CommandClone.ts b/src/bin/vaults/CommandClone.ts index e5867dcf9..38fda0148 100644 --- a/src/bin/vaults/CommandClone.ts +++ b/src/bin/vaults/CommandClone.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -59,7 +57,7 @@ class CommandClone extends CommandPolykey { vaultMessage.setNameOrId(vaultNameOrId); await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.vaultsClone(vaultCloneMessage, auth), + (auth) => grpcClient.vaultsClone(vaultCloneMessage, auth), meta, ); diff --git a/src/bin/vaults/CommandCreate.ts b/src/bin/vaults/CommandCreate.ts index 3cd40cf0f..904696db3 100644 --- a/src/bin/vaults/CommandCreate.ts +++ b/src/bin/vaults/CommandCreate.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -53,7 +51,7 @@ class CommandCreate extends CommandPolykey { vaultMessage.setNameOrId(vaultName); const response = await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.vaultsCreate(vaultMessage, auth), + (auth) => grpcClient.vaultsCreate(vaultMessage, auth), meta, ); diff --git a/src/bin/vaults/CommandDelete.ts b/src/bin/vaults/CommandDelete.ts index 50134c1fa..704ddf8b7 100644 --- a/src/bin/vaults/CommandDelete.ts +++ b/src/bin/vaults/CommandDelete.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -52,7 +50,7 @@ class CommandDelete extends CommandPolykey { const vaultMessage = new vaultsPB.Vault(); vaultMessage.setNameOrId(vaultName); await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.vaultsDelete(vaultMessage, auth), + (auth) => grpcClient.vaultsDelete(vaultMessage, auth), meta, ); diff --git a/src/bin/vaults/CommandPull.ts b/src/bin/vaults/CommandPull.ts index 6c195817e..c99b5c8fb 100644 --- a/src/bin/vaults/CommandPull.ts +++ b/src/bin/vaults/CommandPull.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -59,7 +57,7 @@ class CommandPull extends CommandPolykey { vaultMessage.setNameOrId(vaultName); await binUtils.retryAuthentication( - (auth?: Metadata) => grpcClient.vaultsPull(vaultPullMessage, auth), + (auth) => grpcClient.vaultsPull(vaultPullMessage, auth), meta, ); diff --git a/src/bin/vaults/CommandRename.ts b/src/bin/vaults/CommandRename.ts index 97ed9fcdc..958fd3681 100644 --- a/src/bin/vaults/CommandRename.ts +++ b/src/bin/vaults/CommandRename.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -56,7 +54,7 @@ class CommandRename extends CommandPolykey { vaultRenameMessage.setNewName(newVaultName); await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.vaultsRename(vaultRenameMessage, auth), meta, ); diff --git a/src/bin/vaults/CommandShare.ts b/src/bin/vaults/CommandShare.ts index 0c88b11b7..1e4deebb9 100644 --- a/src/bin/vaults/CommandShare.ts +++ b/src/bin/vaults/CommandShare.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -59,7 +57,7 @@ class CommandShare extends CommandPolykey { nodeMessage.setNodeId(nodeId); await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.vaultsPermissionsSet(setVaultPermsMessage, auth), meta, ); diff --git a/src/bin/vaults/CommandUnshare.ts b/src/bin/vaults/CommandUnshare.ts index 671fc094a..55145f172 100644 --- a/src/bin/vaults/CommandUnshare.ts +++ b/src/bin/vaults/CommandUnshare.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -59,7 +57,7 @@ class CommandUnshare extends CommandPolykey { nodeMessage.setNodeId(nodeId); await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.vaultsPermissionsUnset(unsetVaultPermsMessage, auth), meta, ); diff --git a/src/bin/vaults/CommandVersion.ts b/src/bin/vaults/CommandVersion.ts index 051acecfd..2232d762e 100644 --- a/src/bin/vaults/CommandVersion.ts +++ b/src/bin/vaults/CommandVersion.ts @@ -1,5 +1,3 @@ -import type { Metadata } from '@grpc/grpc-js'; - import type PolykeyClient from '../../PolykeyClient'; import CommandPolykey from '../CommandPolykey'; import * as binUtils from '../utils'; @@ -56,7 +54,7 @@ class CommandVersion extends CommandPolykey { vaultsVersionMessage.setVersionId(versionId); await binUtils.retryAuthentication( - (auth?: Metadata) => + (auth) => grpcClient.vaultsVersion(vaultsVersionMessage, auth), meta, ); From 63d6294a51f7846cc8ff8d263028fe59bfcc5fc5 Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 13 Dec 2021 15:06:20 +1100 Subject: [PATCH 24/29] moving preprocessing outside of try blocks --- src/bin/identities/CommandAllow.ts | 21 ++++++--------- src/bin/identities/CommandAuthenticate.ts | 22 +++++----------- src/bin/identities/CommandClaim.ts | 23 +++++------------ src/bin/identities/CommandDisallow.ts | 21 ++++++--------- src/bin/identities/CommandDiscover.ts | 22 ++++++---------- src/bin/identities/CommandGet.ts | 23 ++++++----------- src/bin/identities/CommandList.ts | 21 ++++++--------- src/bin/identities/CommandPermissions.ts | 21 ++++++--------- src/bin/identities/CommandSearch.ts | 20 +++++---------- src/bin/identities/CommandTrust.ts | 22 ++++++---------- src/bin/identities/CommandUntrust.ts | 22 ++++++---------- src/bin/keys/CommandCert.ts | 20 +++++---------- src/bin/keys/CommandCertchain.ts | 20 +++++---------- src/bin/keys/CommandDecrypt.ts | 21 +++++---------- src/bin/keys/CommandEncrypt.ts | 22 +++++----------- src/bin/keys/CommandRoot.ts | 21 +++++---------- src/bin/keys/CommandSign.ts | 21 +++++---------- src/bin/keys/CommandVerify.ts | 22 +++++----------- src/bin/nodes/CommandAdd.ts | 20 +++++---------- src/bin/nodes/CommandClaim.ts | 20 +++++---------- src/bin/nodes/CommandFind.ts | 21 +++++---------- src/bin/nodes/CommandPing.ts | 23 +++++------------ src/bin/notifications/CommandClear.ts | 21 +++++---------- src/bin/notifications/CommandRead.ts | 23 +++++------------ src/bin/notifications/CommandSend.ts | 20 +++++---------- src/bin/secrets/CommandCreate.ts | 22 +++++----------- src/bin/secrets/CommandDelete.ts | 20 +++++---------- src/bin/secrets/CommandDir.ts | 20 +++++---------- src/bin/secrets/CommandEdit.ts | 31 ++++++----------------- src/bin/secrets/CommandGet.ts | 20 +++++---------- src/bin/secrets/CommandList.ts | 19 +++++--------- src/bin/secrets/CommandMkdir.ts | 20 +++++---------- src/bin/secrets/CommandRename.ts | 20 +++++---------- src/bin/secrets/CommandUpdate.ts | 21 +++++---------- src/bin/vaults/CommandClone.ts | 20 +++++---------- src/bin/vaults/CommandCreate.ts | 20 +++++---------- src/bin/vaults/CommandDelete.ts | 20 +++++---------- src/bin/vaults/CommandList.ts | 18 +++++-------- src/bin/vaults/CommandLog.ts | 19 +++++--------- src/bin/vaults/CommandPull.ts | 20 +++++---------- src/bin/vaults/CommandRename.ts | 20 +++++---------- src/bin/vaults/CommandShare.ts | 20 +++++---------- src/bin/vaults/CommandUnshare.ts | 20 +++++---------- src/bin/vaults/CommandVersion.ts | 23 +++++------------ 44 files changed, 317 insertions(+), 609 deletions(-) diff --git a/src/bin/identities/CommandAllow.ts b/src/bin/identities/CommandAllow.ts index d1136e965..49edc74cb 100644 --- a/src/bin/identities/CommandAllow.ts +++ b/src/bin/identities/CommandAllow.ts @@ -28,7 +28,6 @@ class CommandAllow extends CommandPolykey { '../../proto/js/polykey/v1/permissions/permissions_pb' ); const nodesPB = await import('../../proto/js/polykey/v1/nodes/nodes_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -37,8 +36,11 @@ class CommandAllow extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -50,13 +52,6 @@ class CommandAllow extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - - const grpcClient = pkClient.grpcClient; const setActionMessage = new permissionsPB.ActionSet(); setActionMessage.setAction(permissions); let name: string; @@ -69,7 +64,7 @@ class CommandAllow extends CommandPolykey { // Trusting await binUtils.retryAuthentication( (auth) => - grpcClient.gestaltsActionsSetByNode(setActionMessage, auth), + pkClient.grpcClient.gestaltsActionsSetByNode(setActionMessage, auth), meta, ); } else { @@ -84,7 +79,7 @@ class CommandAllow extends CommandPolykey { )}`; await binUtils.retryAuthentication( (auth) => - grpcClient.gestaltsActionsSetByIdentity(setActionMessage, auth), + pkClient.grpcClient.gestaltsActionsSetByIdentity(setActionMessage, auth), meta, ); } @@ -95,7 +90,7 @@ class CommandAllow extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/identities/CommandAuthenticate.ts b/src/bin/identities/CommandAuthenticate.ts index 1c09b673b..dd19ace19 100644 --- a/src/bin/identities/CommandAuthenticate.ts +++ b/src/bin/identities/CommandAuthenticate.ts @@ -19,7 +19,6 @@ class CommandAuthenticate extends CommandPolykey { const identitiesPB = await import( '../../proto/js/polykey/v1/identities/identities_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -28,8 +27,11 @@ class CommandAuthenticate extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -41,21 +43,12 @@ class CommandAuthenticate extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - - const grpcClient = pkClient.grpcClient; - // Constructing message. const providerMessage = new identitiesPB.Provider(); providerMessage.setProviderId(providerId); providerMessage.setMessage(identityId); - // Sending message. const successMessage = await binUtils.retryAuthentication( async (auth) => { - const stream = grpcClient.identitiesAuthenticate( + const stream = pkClient.grpcClient.identitiesAuthenticate( providerMessage, auth, ); @@ -70,7 +63,6 @@ class CommandAuthenticate extends CommandPolykey { }, meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -80,7 +72,7 @@ class CommandAuthenticate extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/identities/CommandClaim.ts b/src/bin/identities/CommandClaim.ts index ca53000c2..85c97d0c0 100644 --- a/src/bin/identities/CommandClaim.ts +++ b/src/bin/identities/CommandClaim.ts @@ -19,7 +19,6 @@ class CommandClaim extends CommandPolykey { const identitiesPB = await import( '../../proto/js/polykey/v1/identities/identities_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -28,8 +27,11 @@ class CommandClaim extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -41,27 +43,16 @@ class CommandClaim extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - - const grpcClient = pkClient.grpcClient; - - // Constructing message. const providerMessage = new identitiesPB.Provider(); providerMessage.setProviderId(providerId); providerMessage.setMessage(identityId); - - // Sending message. await binUtils.retryAuthentication( (auth) => - grpcClient.identitiesClaim(providerMessage, auth), + pkClient.grpcClient.identitiesClaim(providerMessage, auth), meta, ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/identities/CommandDisallow.ts b/src/bin/identities/CommandDisallow.ts index 8cb86e008..3356ec19c 100644 --- a/src/bin/identities/CommandDisallow.ts +++ b/src/bin/identities/CommandDisallow.ts @@ -28,7 +28,6 @@ class CommandDisallow extends CommandPolykey { '../../proto/js/polykey/v1/permissions/permissions_pb' ); const nodesPB = await import('../../proto/js/polykey/v1/nodes/nodes_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -37,8 +36,11 @@ class CommandDisallow extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -50,16 +52,9 @@ class CommandDisallow extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; let name: string; const setActionMessage = new permissionsPB.ActionSet(); setActionMessage.setAction(permissions); - if (gestaltId.nodeId) { // Setting by Node. const nodeMessage = new nodesPB.Node(); @@ -69,7 +64,7 @@ class CommandDisallow extends CommandPolykey { // Trusting await binUtils.retryAuthentication( (auth) => - grpcClient.gestaltsActionsUnsetByNode(setActionMessage, auth), + pkClient.grpcClient.gestaltsActionsUnsetByNode(setActionMessage, auth), meta, ); } else { @@ -85,7 +80,7 @@ class CommandDisallow extends CommandPolykey { // Trusting. await binUtils.retryAuthentication( (auth) => - grpcClient.gestaltsActionsUnsetByIdentity(setActionMessage, auth), + pkClient.grpcClient.gestaltsActionsUnsetByIdentity(setActionMessage, auth), meta, ); } @@ -98,7 +93,7 @@ class CommandDisallow extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/identities/CommandDiscover.ts b/src/bin/identities/CommandDiscover.ts index d4b78e6cc..29f2abe69 100644 --- a/src/bin/identities/CommandDiscover.ts +++ b/src/bin/identities/CommandDiscover.ts @@ -26,7 +26,6 @@ class CommandDiscover extends CommandPolykey { '../../proto/js/polykey/v1/identities/identities_pb' ); const nodesPB = await import('../../proto/js/polykey/v1/nodes/nodes_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -35,8 +34,11 @@ class CommandDiscover extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -48,14 +50,7 @@ class CommandDiscover extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; let name: string; - if (gestaltId.nodeId) { // Discovery by Node. const nodeMessage = new nodesPB.Node(); @@ -63,7 +58,7 @@ class CommandDiscover extends CommandPolykey { name = `${gestaltId.nodeId}`; await binUtils.retryAuthentication( (auth) => - grpcClient.gestaltsDiscoveryByNode(nodeMessage, auth), + pkClient.grpcClient.gestaltsDiscoveryByNode(nodeMessage, auth), meta, ); } else { @@ -77,11 +72,10 @@ class CommandDiscover extends CommandPolykey { )}`; await binUtils.retryAuthentication( (auth) => - grpcClient.gestaltsDiscoveryByIdentity(providerMessage, auth), + pkClient.grpcClient.gestaltsDiscoveryByIdentity(providerMessage, auth), meta, ); } - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -89,7 +83,7 @@ class CommandDiscover extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/identities/CommandGet.ts b/src/bin/identities/CommandGet.ts index 6c784f5d3..a7ec500cd 100644 --- a/src/bin/identities/CommandGet.ts +++ b/src/bin/identities/CommandGet.ts @@ -27,7 +27,6 @@ class CommandGet extends CommandPolykey { '../../proto/js/polykey/v1/identities/identities_pb' ); const nodesPB = await import('../../proto/js/polykey/v1/nodes/nodes_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -36,8 +35,11 @@ class CommandGet extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -49,21 +51,14 @@ class CommandGet extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; let res: gestaltsPB.Graph; - if (gestaltId.nodeId) { // Getting from node. const nodeMessage = new nodesPB.Node(); nodeMessage.setNodeId(gestaltId.nodeId); res = await binUtils.retryAuthentication( (auth) => - grpcClient.gestaltsGestaltGetByNode(nodeMessage, auth), + pkClient.grpcClient.gestaltsGestaltGetByNode(nodeMessage, auth), meta, ); } else { @@ -73,13 +68,12 @@ class CommandGet extends CommandPolykey { providerMessage.setMessage(gestaltId.identityId); res = await binUtils.retryAuthentication( (auth) => - grpcClient.gestaltsGestaltGetByIdentity(providerMessage, auth), + pkClient.grpcClient.gestaltsGestaltGetByIdentity(providerMessage, auth), meta, ); } const gestalt = JSON.parse(res.getGestaltGraph()); let output: any = gestalt; - if (options.format !== 'json') { // Creating a list. output = []; @@ -99,7 +93,6 @@ class CommandGet extends CommandPolykey { ); } } - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -107,7 +100,7 @@ class CommandGet extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/identities/CommandList.ts b/src/bin/identities/CommandList.ts index 0e5f7ef51..bc6c2b85f 100644 --- a/src/bin/identities/CommandList.ts +++ b/src/bin/identities/CommandList.ts @@ -17,7 +17,6 @@ class CommandList extends CommandPolykey { const { default: PolykeyClient } = await import('../../PolykeyClient'); const utilsPB = await import('../../proto/js/polykey/v1/utils/utils_pb'); const nodesPB = await import('../../proto/js/polykey/v1/nodes/nodes_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -26,8 +25,11 @@ class CommandList extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -39,18 +41,12 @@ class CommandList extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const emptyMessage = new utilsPB.EmptyMessage(); let output: any; const gestalts = await binUtils.retryAuthentication( async (auth) => { const gestalts: Array = []; - const stream = grpcClient.gestaltsGestaltList(emptyMessage, auth); + const stream = pkClient.grpcClient.gestaltsGestaltList(emptyMessage, auth); for await (const val of stream) { const gestalt = JSON.parse(val.getName()); const newGestalt: any = { @@ -74,7 +70,7 @@ class CommandList extends CommandPolykey { nodeMessage.setNodeId(newGestalt.nodes[0].id); const actionsMessage = await binUtils.retryAuthentication( (auth) => - grpcClient.gestaltsActionsGetByNode(nodeMessage, auth), + pkClient.grpcClient.gestaltsActionsGetByNode(nodeMessage, auth), meta, ); const actionList = actionsMessage.getActionList(); @@ -86,7 +82,6 @@ class CommandList extends CommandPolykey { }, meta, ); - output = gestalts; if (options.format !== 'json') { // Convert to a human readable list. @@ -121,7 +116,7 @@ class CommandList extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/identities/CommandPermissions.ts b/src/bin/identities/CommandPermissions.ts index 6f2af46be..9dc9617b0 100644 --- a/src/bin/identities/CommandPermissions.ts +++ b/src/bin/identities/CommandPermissions.ts @@ -24,7 +24,6 @@ class CommandPermissions extends CommandPolykey { '../../proto/js/polykey/v1/identities/identities_pb' ); const nodesPB = await import('../../proto/js/polykey/v1/nodes/nodes_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -33,8 +32,11 @@ class CommandPermissions extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -46,12 +48,6 @@ class CommandPermissions extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; let actions; if (gestaltId.nodeId) { // Getting by Node. @@ -59,7 +55,7 @@ class CommandPermissions extends CommandPolykey { nodeMessage.setNodeId(gestaltId.nodeId); const res = await binUtils.retryAuthentication( (auth) => - grpcClient.gestaltsActionsGetByNode(nodeMessage, auth), + pkClient.grpcClient.gestaltsActionsGetByNode(nodeMessage, auth), meta, ); actions = res.getActionList(); @@ -70,12 +66,11 @@ class CommandPermissions extends CommandPolykey { providerMessage.setMessage(gestaltId.identityId); const res = await binUtils.retryAuthentication( (auth) => - grpcClient.gestaltsActionsGetByIdentity(providerMessage, auth), + pkClient.grpcClient.gestaltsActionsGetByIdentity(providerMessage, auth), meta, ); actions = res.getActionList(); } - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -83,7 +78,7 @@ class CommandPermissions extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/identities/CommandSearch.ts b/src/bin/identities/CommandSearch.ts index 9b5b24bc8..c6bc660d1 100644 --- a/src/bin/identities/CommandSearch.ts +++ b/src/bin/identities/CommandSearch.ts @@ -23,7 +23,6 @@ class CommandSearch extends CommandPolykey { const identitiesPB = await import( '../../proto/js/polykey/v1/identities/identities_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -32,8 +31,11 @@ class CommandSearch extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -45,21 +47,13 @@ class CommandSearch extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - - const grpcClient = pkClient.grpcClient; const providerMessage = new identitiesPB.Provider(); providerMessage.setProviderId(providerId); const res = await binUtils.retryAuthentication( (auth) => - grpcClient.identitiesInfoGet(providerMessage, auth), + pkClient.grpcClient.identitiesInfoGet(providerMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -72,7 +66,7 @@ class CommandSearch extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/identities/CommandTrust.ts b/src/bin/identities/CommandTrust.ts index 6e4bc64f6..a3d086d24 100644 --- a/src/bin/identities/CommandTrust.ts +++ b/src/bin/identities/CommandTrust.ts @@ -27,7 +27,6 @@ class CommandTrust extends CommandPolykey { '../../proto/js/polykey/v1/permissions/permissions_pb' ); const nodesPB = await import('../../proto/js/polykey/v1/nodes/nodes_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -36,8 +35,11 @@ class CommandTrust extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -49,17 +51,10 @@ class CommandTrust extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const action = 'notify'; const setActionMessage = new permissionsPB.ActionSet(); setActionMessage.setAction(action); let name: string; - if (gestaltId.nodeId) { // Setting by Node. const nodeMessage = new nodesPB.Node(); @@ -68,7 +63,7 @@ class CommandTrust extends CommandPolykey { name = `${gestaltId.nodeId}`; await binUtils.retryAuthentication( (auth) => - grpcClient.gestaltsActionsSetByNode(setActionMessage, auth), + pkClient.grpcClient.gestaltsActionsSetByNode(setActionMessage, auth), meta, ); } else { @@ -83,11 +78,10 @@ class CommandTrust extends CommandPolykey { )}`; await binUtils.retryAuthentication( (auth) => - grpcClient.gestaltsActionsSetByIdentity(setActionMessage, auth), + pkClient.grpcClient.gestaltsActionsSetByIdentity(setActionMessage, auth), meta, ); } - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -95,7 +89,7 @@ class CommandTrust extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/identities/CommandUntrust.ts b/src/bin/identities/CommandUntrust.ts index 50788a2a6..cf10ffba0 100644 --- a/src/bin/identities/CommandUntrust.ts +++ b/src/bin/identities/CommandUntrust.ts @@ -27,7 +27,6 @@ class CommandUntrust extends CommandPolykey { '../../proto/js/polykey/v1/permissions/permissions_pb' ); const nodesPB = await import('../../proto/js/polykey/v1/nodes/nodes_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -36,8 +35,11 @@ class CommandUntrust extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -49,17 +51,10 @@ class CommandUntrust extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const action = 'notify'; const setActionMessage = new permissionsPB.ActionSet(); setActionMessage.setAction(action); let name: string; - if (gestaltId.nodeId) { // Setting by Node. const nodeMessage = new nodesPB.Node(); @@ -68,7 +63,7 @@ class CommandUntrust extends CommandPolykey { name = `${gestaltId.nodeId}`; await binUtils.retryAuthentication( (auth) => - grpcClient.gestaltsActionsUnsetByNode(setActionMessage, auth), + pkClient.grpcClient.gestaltsActionsUnsetByNode(setActionMessage, auth), meta, ); } else { @@ -83,11 +78,10 @@ class CommandUntrust extends CommandPolykey { )}`; await binUtils.retryAuthentication( (auth) => - grpcClient.gestaltsActionsUnsetByIdentity(setActionMessage, auth), + pkClient.grpcClient.gestaltsActionsUnsetByIdentity(setActionMessage, auth), meta, ); } - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -95,7 +89,7 @@ class CommandUntrust extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/keys/CommandCert.ts b/src/bin/keys/CommandCert.ts index c89f06f0e..f16937a48 100644 --- a/src/bin/keys/CommandCert.ts +++ b/src/bin/keys/CommandCert.ts @@ -15,7 +15,6 @@ class CommandCert extends CommandPolykey { this.action(async (options) => { const { default: PolykeyClient } = await import('../../PolykeyClient'); const utilsPB = await import('../../proto/js/polykey/v1/utils/utils_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -24,8 +23,11 @@ class CommandCert extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -37,19 +39,11 @@ class CommandCert extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - - const grpcClient = pkClient.grpcClient; const emptyMessage = new utilsPB.EmptyMessage(); const response = await binUtils.retryAuthentication( - (auth) => grpcClient.keysCertsGet(emptyMessage, auth), + (auth) => pkClient.grpcClient.keysCertsGet(emptyMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -57,7 +51,7 @@ class CommandCert extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/keys/CommandCertchain.ts b/src/bin/keys/CommandCertchain.ts index 9f61c49e4..53a42e5da 100644 --- a/src/bin/keys/CommandCertchain.ts +++ b/src/bin/keys/CommandCertchain.ts @@ -15,7 +15,6 @@ class CommandsCertchain extends CommandPolykey { this.action(async (options) => { const { default: PolykeyClient } = await import('../../PolykeyClient'); const utilsPB = await import('../../proto/js/polykey/v1/utils/utils_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -24,8 +23,11 @@ class CommandsCertchain extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -37,18 +39,11 @@ class CommandsCertchain extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - - const grpcClient = pkClient.grpcClient; const emptyMessage = new utilsPB.EmptyMessage(); const data = await binUtils.retryAuthentication( async (auth) => { const data: Array = []; - const stream = grpcClient.keysCertsChainGet(emptyMessage, auth); + const stream = pkClient.grpcClient.keysCertsChainGet(emptyMessage, auth); for await (const cert of stream) { data.push(`Certificate:\t\t${cert.getCert()}`); } @@ -56,7 +51,6 @@ class CommandsCertchain extends CommandPolykey { }, meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -64,7 +58,7 @@ class CommandsCertchain extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/keys/CommandDecrypt.ts b/src/bin/keys/CommandDecrypt.ts index 800b5bc23..dec93bd68 100644 --- a/src/bin/keys/CommandDecrypt.ts +++ b/src/bin/keys/CommandDecrypt.ts @@ -20,7 +20,6 @@ class CommandDecrypt extends CommandPolykey { this.action(async (filePath, options) => { const { default: PolykeyClient } = await import('../../PolykeyClient'); const keysPB = await import('../../proto/js/polykey/v1/keys/keys_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -29,8 +28,11 @@ class CommandDecrypt extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -42,13 +44,6 @@ class CommandDecrypt extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - - const grpcClient = pkClient.grpcClient; const cryptoMessage = new keysPB.Crypto(); let cipherText: string; try { @@ -63,13 +58,11 @@ class CommandDecrypt extends CommandPolykey { path: e.path, }); } - cryptoMessage.setData(cipherText); const response = await binUtils.retryAuthentication( - (auth) => grpcClient.keysDecrypt(cryptoMessage, auth), + (auth) => pkClient.grpcClient.keysDecrypt(cryptoMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -77,7 +70,7 @@ class CommandDecrypt extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/keys/CommandEncrypt.ts b/src/bin/keys/CommandEncrypt.ts index 1645b30f3..7488a0193 100644 --- a/src/bin/keys/CommandEncrypt.ts +++ b/src/bin/keys/CommandEncrypt.ts @@ -20,7 +20,6 @@ class CommandEncypt extends CommandPolykey { this.action(async (filePath, options) => { const { default: PolykeyClient } = await import('../../PolykeyClient'); const keysPB = await import('../../proto/js/polykey/v1/keys/keys_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -29,8 +28,11 @@ class CommandEncypt extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -42,15 +44,7 @@ class CommandEncypt extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - - const grpcClient = pkClient.grpcClient; const cryptoMessage = new keysPB.Crypto(); - let plainText: string; try { plainText = await this.fs.promises.readFile(filePath, { @@ -64,13 +58,11 @@ class CommandEncypt extends CommandPolykey { path: e.path, }); } - cryptoMessage.setData(plainText); const response = await binUtils.retryAuthentication( - (auth) => grpcClient.keysEncrypt(cryptoMessage, auth), + (auth) => pkClient.grpcClient.keysEncrypt(cryptoMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -78,7 +70,7 @@ class CommandEncypt extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/keys/CommandRoot.ts b/src/bin/keys/CommandRoot.ts index e405dce1f..8303871e8 100644 --- a/src/bin/keys/CommandRoot.ts +++ b/src/bin/keys/CommandRoot.ts @@ -16,7 +16,6 @@ class CommandRoot extends CommandPolykey { this.action(async (options) => { const { default: PolykeyClient } = await import('../../PolykeyClient'); const utilsPB = await import('../../proto/js/polykey/v1/utils/utils_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -25,8 +24,11 @@ class CommandRoot extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -38,26 +40,17 @@ class CommandRoot extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const emptyMessage = new utilsPB.EmptyMessage(); - const keyPair = await binUtils.retryAuthentication( - (auth) => grpcClient.keysKeyPairRoot(emptyMessage, auth), + (auth) => pkClient.grpcClient.keysKeyPairRoot(emptyMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', data: [`public key:\t\t${keyPair.getPublic()}...`], }), ); - if (options.privateKey) { process.stdout.write( binUtils.outputFormatter({ @@ -67,7 +60,7 @@ class CommandRoot extends CommandPolykey { ); } } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/keys/CommandSign.ts b/src/bin/keys/CommandSign.ts index 24d4e3a3c..bf195e9dc 100644 --- a/src/bin/keys/CommandSign.ts +++ b/src/bin/keys/CommandSign.ts @@ -20,7 +20,6 @@ class CommandSign extends CommandPolykey { this.action(async (filePath, options) => { const { default: PolykeyClient } = await import('../../PolykeyClient'); const keysPB = await import('../../proto/js/polykey/v1/keys/keys_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -29,8 +28,11 @@ class CommandSign extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -42,14 +44,7 @@ class CommandSign extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const cryptoMessage = new keysPB.Crypto(); - let data: string; try { data = await this.fs.promises.readFile(filePath, { @@ -64,12 +59,10 @@ class CommandSign extends CommandPolykey { }); } cryptoMessage.setData(data); - const response = await binUtils.retryAuthentication( - (auth) => grpcClient.keysSign(cryptoMessage, auth), + (auth) => pkClient.grpcClient.keysSign(cryptoMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -77,7 +70,7 @@ class CommandSign extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/keys/CommandVerify.ts b/src/bin/keys/CommandVerify.ts index 15b1b560c..88e3da00c 100644 --- a/src/bin/keys/CommandVerify.ts +++ b/src/bin/keys/CommandVerify.ts @@ -24,7 +24,6 @@ class CommandVerify extends CommandPolykey { this.action(async (filePath, signaturePath, options) => { const { default: PolykeyClient } = await import('../../PolykeyClient'); const keysPB = await import('../../proto/js/polykey/v1/keys/keys_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -33,8 +32,11 @@ class CommandVerify extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -46,14 +48,7 @@ class CommandVerify extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const cryptoMessage = new keysPB.Crypto(); - let data: string; let signature: string; try { @@ -71,15 +66,12 @@ class CommandVerify extends CommandPolykey { path: e.path, }); } - cryptoMessage.setData(data); cryptoMessage.setSignature(signature); - const response = await binUtils.retryAuthentication( - (auth) => grpcClient.keysVerify(cryptoMessage, auth), + (auth) => pkClient.grpcClient.keysVerify(cryptoMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -87,7 +79,7 @@ class CommandVerify extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/nodes/CommandAdd.ts b/src/bin/nodes/CommandAdd.ts index 440652d09..c62adb5b7 100644 --- a/src/bin/nodes/CommandAdd.ts +++ b/src/bin/nodes/CommandAdd.ts @@ -18,7 +18,6 @@ class CommandAdd extends CommandPolykey { this.action(async (nodeId, host, port, options) => { const { default: PolykeyClient } = await import('../../PolykeyClient'); const nodesPB = await import('../../proto/js/polykey/v1/nodes/nodes_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -27,8 +26,11 @@ class CommandAdd extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -40,23 +42,15 @@ class CommandAdd extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const nodeAddressMessage = new nodesPB.NodeAddress(); nodeAddressMessage.setNodeId(nodeId); nodeAddressMessage.setAddress( new nodesPB.Address().setHost(host).setPort(port), ); - await binUtils.retryAuthentication( - (auth) => grpcClient.nodesAdd(nodeAddressMessage, auth), + (auth) => pkClient.grpcClient.nodesAdd(nodeAddressMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -64,7 +58,7 @@ class CommandAdd extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/nodes/CommandClaim.ts b/src/bin/nodes/CommandClaim.ts index 6ed2b1a42..ca7408aee 100644 --- a/src/bin/nodes/CommandClaim.ts +++ b/src/bin/nodes/CommandClaim.ts @@ -20,7 +20,6 @@ class CommandClaim extends CommandPolykey { this.action(async (nodeId, options) => { const { default: PolykeyClient } = await import('../../PolykeyClient'); const nodesPB = await import('../../proto/js/polykey/v1/nodes/nodes_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -29,8 +28,11 @@ class CommandClaim extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -42,12 +44,6 @@ class CommandClaim extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const nodeClaimMessage = new nodesPB.Claim(); nodeClaimMessage.setNodeId(nodeId); if (options.forceInvite) { @@ -55,13 +51,11 @@ class CommandClaim extends CommandPolykey { } else { nodeClaimMessage.setForceInvite(false); } - const response = await binUtils.retryAuthentication( - (auth) => grpcClient.nodesClaim(nodeClaimMessage, auth), + (auth) => pkClient.grpcClient.nodesClaim(nodeClaimMessage, auth), meta, ); const claimed = response.getSuccess(); - if (claimed) { process.stdout.write( binUtils.outputFormatter({ @@ -82,7 +76,7 @@ class CommandClaim extends CommandPolykey { ); } } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/nodes/CommandFind.ts b/src/bin/nodes/CommandFind.ts index db371074a..61d7c3cd5 100644 --- a/src/bin/nodes/CommandFind.ts +++ b/src/bin/nodes/CommandFind.ts @@ -21,7 +21,6 @@ class CommandFind extends CommandPolykey { const networkUtils = await import('../../network/utils'); const CLIErrors = await import('../errors'); const nodesErrors = await import('../../nodes/errors'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -30,8 +29,11 @@ class CommandFind extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -43,12 +45,6 @@ class CommandFind extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const nodeMessage = new nodesPB.Node(); nodeMessage.setNodeId(nodeId); const result = { @@ -60,10 +56,9 @@ class CommandFind extends CommandPolykey { }; try { const response = await binUtils.retryAuthentication( - (auth) => grpcClient.nodesFind(nodeMessage, auth), + (auth) => pkClient.grpcClient.nodesFind(nodeMessage, auth), meta, ); - result.success = true; result.id = response.getNodeId(); result.host = response.getAddress()!.getHost(); @@ -82,10 +77,8 @@ class CommandFind extends CommandPolykey { result.port = 0; result.message = `Failed to find node ${result.id}`; } - let output: any = result; if (options.format === 'human') output = [result.message]; - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -96,7 +89,7 @@ class CommandFind extends CommandPolykey { if (!result.success) throw new CLIErrors.ErrorNodeFindFailed(result.message); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/nodes/CommandPing.ts b/src/bin/nodes/CommandPing.ts index 6dfca9259..387abaca4 100644 --- a/src/bin/nodes/CommandPing.ts +++ b/src/bin/nodes/CommandPing.ts @@ -18,7 +18,6 @@ class CommandPing extends CommandPolykey { const nodesPB = await import('../../proto/js/polykey/v1/nodes/nodes_pb'); const CLIErrors = await import('../errors'); const nodesErrors = await import('../../nodes/errors'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -27,8 +26,11 @@ class CommandPing extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -40,19 +42,13 @@ class CommandPing extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const nodeMessage = new nodesPB.Node(); nodeMessage.setNodeId(nodeId); let statusMessage; let error; try { statusMessage = await binUtils.retryAuthentication( - (auth) => grpcClient.nodesPing(nodeMessage, auth), + (auth) => pkClient.grpcClient.nodesPing(nodeMessage, auth), meta, ); } catch (err) { @@ -64,28 +60,23 @@ class CommandPing extends CommandPolykey { throw err; } } - const status = { success: false, message: '' }; status.success = statusMessage ? statusMessage.getSuccess() : false; if (!status.success && !error) error = new CLIErrors.ErrorNodePingFailed('No response received'); - if (status.success) status.message = 'Node is Active.'; else status.message = error.message; - const output: any = options.format === 'json' ? status : [status.message]; - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', data: output, }), ); - if (error != null) throw error; } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/notifications/CommandClear.ts b/src/bin/notifications/CommandClear.ts index 1e2da6534..9ef013727 100644 --- a/src/bin/notifications/CommandClear.ts +++ b/src/bin/notifications/CommandClear.ts @@ -15,7 +15,6 @@ class CommandClear extends CommandPolykey { this.action(async (options) => { const { default: PolykeyClient } = await import('../../PolykeyClient'); const utilsPB = await import('../../proto/js/polykey/v1/utils/utils_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -24,8 +23,11 @@ class CommandClear extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -37,21 +39,12 @@ class CommandClear extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - - const grpcClient = pkClient.grpcClient; const emptyMessage = new utilsPB.EmptyMessage(); - await binUtils.retryAuthentication( (auth) => - grpcClient.notificationsClear(emptyMessage, auth), + pkClient.grpcClient.notificationsClear(emptyMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -59,7 +52,7 @@ class CommandClear extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/notifications/CommandRead.ts b/src/bin/notifications/CommandRead.ts index 005eb24a1..140e6781b 100644 --- a/src/bin/notifications/CommandRead.ts +++ b/src/bin/notifications/CommandRead.ts @@ -34,7 +34,6 @@ class CommandRead extends CommandPolykey { '../../proto/js/polykey/v1/notifications/notifications_pb' ); const notificationsUtils = await import('../../notifications/utils'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -43,8 +42,11 @@ class CommandRead extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -56,14 +58,7 @@ class CommandRead extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const notificationsReadMessage = new notificationsPB.Read(); - if (options.unread) { notificationsReadMessage.setUnread(true); } else { @@ -71,13 +66,11 @@ class CommandRead extends CommandPolykey { } notificationsReadMessage.setNumber(options.number); notificationsReadMessage.setOrder(options.order); - const response = await binUtils.retryAuthentication( (auth) => - grpcClient.notificationsRead(notificationsReadMessage, auth), + pkClient.grpcClient.notificationsRead(notificationsReadMessage, auth), meta, ); - const notificationMessages = response.getNotificationList(); const notifications: Array = []; for (const message of notificationMessages) { @@ -110,7 +103,6 @@ class CommandRead extends CommandPolykey { break; } } - const notification = { data: data, senderId: message.getSenderId(), @@ -120,7 +112,6 @@ class CommandRead extends CommandPolykey { notificationsUtils.validateNotification(notification), ); } - if (notifications.length === 0) { process.stdout.write( binUtils.outputFormatter({ @@ -166,7 +157,7 @@ class CommandRead extends CommandPolykey { ); } } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/notifications/CommandSend.ts b/src/bin/notifications/CommandSend.ts index d8a1b601e..3a9579ba4 100644 --- a/src/bin/notifications/CommandSend.ts +++ b/src/bin/notifications/CommandSend.ts @@ -19,7 +19,6 @@ class CommandSend extends CommandPolykey { const notificationsPB = await import( '../../proto/js/polykey/v1/notifications/notifications_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -28,8 +27,11 @@ class CommandSend extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -41,24 +43,16 @@ class CommandSend extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const notificationsSendMessage = new notificationsPB.Send(); const generalMessage = new notificationsPB.General(); generalMessage.setMessage(message); notificationsSendMessage.setReceiverId(node); notificationsSendMessage.setData(generalMessage); - await binUtils.retryAuthentication( (auth) => - grpcClient.notificationsSend(notificationsSendMessage, auth), + pkClient.grpcClient.notificationsSend(notificationsSendMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -70,7 +64,7 @@ class CommandSend extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/secrets/CommandCreate.ts b/src/bin/secrets/CommandCreate.ts index 7ff082ede..987632d1e 100644 --- a/src/bin/secrets/CommandCreate.ts +++ b/src/bin/secrets/CommandCreate.ts @@ -31,7 +31,6 @@ class CommandCreate extends CommandPolykey { const secretsPB = await import( '../../proto/js/polykey/v1/secrets/secrets_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -40,8 +39,11 @@ class CommandCreate extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -53,19 +55,11 @@ class CommandCreate extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - - const grpcClient = pkClient.grpcClient; const secretMessage = new secretsPB.Secret(); const vaultMessage = new vaultsPB.Vault(); secretMessage.setVault(vaultMessage); vaultMessage.setNameOrId(secretPath[0]); secretMessage.setSecretName(secretPath[1]); - let content: Buffer; try { content = await this.fs.promises.readFile(directoryPath); @@ -78,12 +72,10 @@ class CommandCreate extends CommandPolykey { }); } secretMessage.setSecretContent(content); - await binUtils.retryAuthentication( - (auth) => grpcClient.vaultsSecretsNew(secretMessage, auth), + (auth) => pkClient.grpcClient.vaultsSecretsNew(secretMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -93,7 +85,7 @@ class CommandCreate extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/secrets/CommandDelete.ts b/src/bin/secrets/CommandDelete.ts index 0453c0ab1..c169529e6 100644 --- a/src/bin/secrets/CommandDelete.ts +++ b/src/bin/secrets/CommandDelete.ts @@ -27,7 +27,6 @@ class CommandDelete extends CommandPolykey { const secretsPB = await import( '../../proto/js/polykey/v1/secrets/secrets_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -36,8 +35,11 @@ class CommandDelete extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -49,24 +51,16 @@ class CommandDelete extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const vaultMessage = new vaultsPB.Vault(); const secretMessage = new secretsPB.Secret(); vaultMessage.setNameOrId(secretPath[0]); secretMessage.setVault(vaultMessage); secretMessage.setSecretName(secretPath[1]); - await binUtils.retryAuthentication( (auth) => - grpcClient.vaultsSecretsDelete(secretMessage, auth), + pkClient.grpcClient.vaultsSecretsDelete(secretMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -76,7 +70,7 @@ class CommandDelete extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/secrets/CommandDir.ts b/src/bin/secrets/CommandDir.ts index a4fcb616d..3bdffbbcd 100644 --- a/src/bin/secrets/CommandDir.ts +++ b/src/bin/secrets/CommandDir.ts @@ -25,7 +25,6 @@ class CommandDir extends CommandPolykey { const secretsPB = await import( '../../proto/js/polykey/v1/secrets/secrets_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -34,8 +33,11 @@ class CommandDir extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -47,24 +49,16 @@ class CommandDir extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const secretDirectoryMessage = new secretsPB.Directory(); const vaultMessage = new vaultsPB.Vault(); vaultMessage.setNameOrId(vaultName); secretDirectoryMessage.setVault(vaultMessage); secretDirectoryMessage.setSecretDirectory(directoryPath); - await binUtils.retryAuthentication( (auth) => - grpcClient.vaultsSecretsNewDir(secretDirectoryMessage, auth), + pkClient.grpcClient.vaultsSecretsNewDir(secretDirectoryMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -74,7 +68,7 @@ class CommandDir extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/secrets/CommandEdit.ts b/src/bin/secrets/CommandEdit.ts index 8d1b08472..9abca91d1 100644 --- a/src/bin/secrets/CommandEdit.ts +++ b/src/bin/secrets/CommandEdit.ts @@ -29,7 +29,6 @@ class CommandEdit extends CommandPolykey { const secretsPB = await import( '../../proto/js/polykey/v1/secrets/secrets_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -38,8 +37,11 @@ class CommandEdit extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -51,35 +53,22 @@ class CommandEdit extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - - const grpcClient = pkClient.grpcClient; const secretMessage = new secretsPB.Secret(); const vaultMessage = new vaultsPB.Vault(); vaultMessage.setNameOrId(secretPath[0]); secretMessage.setVault(vaultMessage); secretMessage.setSecretName(secretPath[1]); - const response = await binUtils.retryAuthentication( - (auth) => grpcClient.vaultsSecretsGet(secretMessage, auth), + (auth) => pkClient.grpcClient.vaultsSecretsGet(secretMessage, auth), meta, ); - const secretContent = response.getSecretName(); - // Linux const tmpDir = `${os.tmpdir}/pksecret`; await this.fs.promises.mkdir(tmpDir); const tmpFile = `${tmpDir}/pkSecretFile`; - await this.fs.promises.writeFile(tmpFile, secretContent); - execSync(`$EDITOR \"${tmpFile}\"`, { stdio: 'inherit' }); - let content: Buffer; try { content = await this.fs.promises.readFile(tmpFile); @@ -91,16 +80,12 @@ class CommandEdit extends CommandPolykey { path: e.path, }); } - secretMessage.setVault(vaultMessage); secretMessage.setSecretContent(content); - await grpcClient.vaultsSecretsEdit(secretMessage); - + await pkClient.grpcClient.vaultsSecretsEdit(secretMessage); await this.fs.promises.rmdir(tmpDir, { recursive: true }); - // Windows // TODO: complete windows impl - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -110,7 +95,7 @@ class CommandEdit extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/secrets/CommandGet.ts b/src/bin/secrets/CommandGet.ts index 3672deb04..764a0fb91 100644 --- a/src/bin/secrets/CommandGet.ts +++ b/src/bin/secrets/CommandGet.ts @@ -30,7 +30,6 @@ class CommandGet extends CommandPolykey { const secretsPB = await import( '../../proto/js/polykey/v1/secrets/secrets_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -39,8 +38,11 @@ class CommandGet extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -52,24 +54,16 @@ class CommandGet extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const isEnv: boolean = options.env ?? false; const secretMessage = new secretsPB.Secret(); const vaultMessage = new vaultsPB.Vault(); vaultMessage.setNameOrId(secretPath[0]); secretMessage.setVault(vaultMessage); secretMessage.setSecretName(secretPath[1]); - const response = await binUtils.retryAuthentication( - (auth) => grpcClient.vaultsSecretsGet(secretMessage, auth), + (auth) => pkClient.grpcClient.vaultsSecretsGet(secretMessage, auth), meta, ); - if (isEnv) { process.stdout.write( binUtils.outputFormatter({ @@ -93,7 +87,7 @@ class CommandGet extends CommandPolykey { ); } } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/secrets/CommandList.ts b/src/bin/secrets/CommandList.ts index 923bb6bce..7054ff0db 100644 --- a/src/bin/secrets/CommandList.ts +++ b/src/bin/secrets/CommandList.ts @@ -19,7 +19,6 @@ class CommandList extends CommandPolykey { const vaultsPB = await import( '../../proto/js/polykey/v1/vaults/vaults_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -28,8 +27,11 @@ class CommandList extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -41,19 +43,12 @@ class CommandList extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const vaultMessage = new vaultsPB.Vault(); vaultMessage.setNameOrId(vaultName); - const data = await binUtils.retryAuthentication( async (auth) => { const data: Array = []; - const stream = grpcClient.vaultsSecretsList(vaultMessage, auth); + const stream = pkClient.grpcClient.vaultsSecretsList(vaultMessage, auth); for await (const secret of stream) { data.push(`${secret.getSecretName()}`); } @@ -68,7 +63,7 @@ class CommandList extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/secrets/CommandMkdir.ts b/src/bin/secrets/CommandMkdir.ts index 0d01ad805..a6f1427a1 100644 --- a/src/bin/secrets/CommandMkdir.ts +++ b/src/bin/secrets/CommandMkdir.ts @@ -24,7 +24,6 @@ class CommandMkdir extends CommandPolykey { const vaultsPB = await import( '../../proto/js/polykey/v1/vaults/vaults_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -33,8 +32,11 @@ class CommandMkdir extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -46,25 +48,17 @@ class CommandMkdir extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const vaultMkdirMessage = new vaultsPB.Mkdir(); const vaultMessage = new vaultsPB.Vault(); vaultMessage.setNameOrId(secretPath[0]); vaultMkdirMessage.setVault(vaultMessage); vaultMkdirMessage.setDirName(secretPath[1]); vaultMkdirMessage.setRecursive(options.recursive); - await binUtils.retryAuthentication( (auth) => - grpcClient.vaultsSecretsMkdir(vaultMkdirMessage, auth), + pkClient.grpcClient.vaultsSecretsMkdir(vaultMkdirMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -74,7 +68,7 @@ class CommandMkdir extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/secrets/CommandRename.ts b/src/bin/secrets/CommandRename.ts index d8534f00d..abb3627e8 100644 --- a/src/bin/secrets/CommandRename.ts +++ b/src/bin/secrets/CommandRename.ts @@ -27,7 +27,6 @@ class CommandRename extends CommandPolykey { const secretsPB = await import( '../../proto/js/polykey/v1/secrets/secrets_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -36,8 +35,11 @@ class CommandRename extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -49,12 +51,6 @@ class CommandRename extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const vaultMessage = new vaultsPB.Vault(); const secretMessage = new secretsPB.Secret(); const secretRenameMessage = new secretsPB.Rename(); @@ -63,13 +59,11 @@ class CommandRename extends CommandPolykey { vaultMessage.setNameOrId(secretPath[0]); secretMessage.setSecretName(secretPath[1]); secretRenameMessage.setNewName(newSecretName); - await binUtils.retryAuthentication( (auth) => - grpcClient.vaultsSecretsRename(secretRenameMessage, auth), + pkClient.grpcClient.vaultsSecretsRename(secretRenameMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -79,7 +73,7 @@ class CommandRename extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/secrets/CommandUpdate.ts b/src/bin/secrets/CommandUpdate.ts index bde010c3e..ed552e726 100644 --- a/src/bin/secrets/CommandUpdate.ts +++ b/src/bin/secrets/CommandUpdate.ts @@ -31,7 +31,6 @@ class CommandUpdate extends CommandPolykey { const secretsPB = await import( '../../proto/js/polykey/v1/secrets/secrets_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -40,8 +39,11 @@ class CommandUpdate extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -53,18 +55,11 @@ class CommandUpdate extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const vaultMessage = new vaultsPB.Vault(); const secretMessage = new secretsPB.Secret(); secretMessage.setVault(vaultMessage); vaultMessage.setNameOrId(secretPath[0]); secretMessage.setSecretName(secretPath[1]); - let content: Buffer; try { content = await this.fs.promises.readFile(directoryPath); @@ -77,13 +72,11 @@ class CommandUpdate extends CommandPolykey { }); } secretMessage.setSecretContent(content); - await binUtils.retryAuthentication( (auth) => - grpcClient.vaultsSecretsEdit(secretMessage, auth), + pkClient.grpcClient.vaultsSecretsEdit(secretMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -93,7 +86,7 @@ class CommandUpdate extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/vaults/CommandClone.ts b/src/bin/vaults/CommandClone.ts index 38fda0148..3bd089a6a 100644 --- a/src/bin/vaults/CommandClone.ts +++ b/src/bin/vaults/CommandClone.ts @@ -20,7 +20,6 @@ class CommandClone extends CommandPolykey { '../../proto/js/polykey/v1/vaults/vaults_pb' ); const nodesPB = await import('../../proto/js/polykey/v1/nodes/nodes_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -29,8 +28,11 @@ class CommandClone extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -42,12 +44,6 @@ class CommandClone extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const vaultMessage = new vaultsPB.Vault(); const nodeMessage = new nodesPB.Node(); const vaultCloneMessage = new vaultsPB.Clone(); @@ -55,12 +51,10 @@ class CommandClone extends CommandPolykey { vaultCloneMessage.setNode(nodeMessage); nodeMessage.setNodeId(nodeId); vaultMessage.setNameOrId(vaultNameOrId); - await binUtils.retryAuthentication( - (auth) => grpcClient.vaultsClone(vaultCloneMessage, auth), + (auth) => pkClient.grpcClient.vaultsClone(vaultCloneMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -70,7 +64,7 @@ class CommandClone extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/vaults/CommandCreate.ts b/src/bin/vaults/CommandCreate.ts index 904696db3..511d69ed0 100644 --- a/src/bin/vaults/CommandCreate.ts +++ b/src/bin/vaults/CommandCreate.ts @@ -19,7 +19,6 @@ class CommandCreate extends CommandPolykey { const vaultsPB = await import( '../../proto/js/polykey/v1/vaults/vaults_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -28,8 +27,11 @@ class CommandCreate extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -41,20 +43,12 @@ class CommandCreate extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const vaultMessage = new vaultsPB.Vault(); vaultMessage.setNameOrId(vaultName); - const response = await binUtils.retryAuthentication( - (auth) => grpcClient.vaultsCreate(vaultMessage, auth), + (auth) => pkClient.grpcClient.vaultsCreate(vaultMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -62,7 +56,7 @@ class CommandCreate extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/vaults/CommandDelete.ts b/src/bin/vaults/CommandDelete.ts index 704ddf8b7..55e579417 100644 --- a/src/bin/vaults/CommandDelete.ts +++ b/src/bin/vaults/CommandDelete.ts @@ -18,7 +18,6 @@ class CommandDelete extends CommandPolykey { const vaultsPB = await import( '../../proto/js/polykey/v1/vaults/vaults_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -27,8 +26,11 @@ class CommandDelete extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -40,20 +42,12 @@ class CommandDelete extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - - const grpcClient = pkClient.grpcClient; const vaultMessage = new vaultsPB.Vault(); vaultMessage.setNameOrId(vaultName); await binUtils.retryAuthentication( - (auth) => grpcClient.vaultsDelete(vaultMessage, auth), + (auth) => pkClient.grpcClient.vaultsDelete(vaultMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -61,7 +55,7 @@ class CommandDelete extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/vaults/CommandList.ts b/src/bin/vaults/CommandList.ts index f947f5839..3a5b3f1f9 100644 --- a/src/bin/vaults/CommandList.ts +++ b/src/bin/vaults/CommandList.ts @@ -17,7 +17,6 @@ class CommandList extends CommandPolykey { this.action(async (options) => { const { default: PolykeyClient } = await import('../../PolykeyClient'); const utilsPB = await import('../../proto/js/polykey/v1/utils/utils_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -26,8 +25,11 @@ class CommandList extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -39,17 +41,11 @@ class CommandList extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const emptyMessage = new utilsPB.EmptyMessage(); const data = await binUtils.retryAuthentication( async (meta: Metadata) => { const data: Array = []; - const stream = grpcClient.vaultsList(emptyMessage, meta); + const stream = pkClient.grpcClient.vaultsList(emptyMessage, meta); for await (const vault of stream) { data.push(`${vault.getVaultName()}:\t\t${vault.getVaultId()}`); } @@ -64,7 +60,7 @@ class CommandList extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/vaults/CommandLog.ts b/src/bin/vaults/CommandLog.ts index 6d0829f88..12d7e696d 100644 --- a/src/bin/vaults/CommandLog.ts +++ b/src/bin/vaults/CommandLog.ts @@ -25,7 +25,6 @@ class CommandLog extends CommandPolykey { const vaultsPB = await import( '../../proto/js/polykey/v1/vaults/vaults_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -34,8 +33,11 @@ class CommandLog extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -47,23 +49,16 @@ class CommandLog extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const vaultMessage = new vaultsPB.Vault(); vaultMessage.setNameOrId(vault); const vaultsLogMessage = new vaultsPB.Log(); vaultsLogMessage.setVault(vaultMessage); vaultsLogMessage.setLogDepth(options.depth); vaultsLogMessage.setCommitId(options.commitId ?? ''); - const data = await binUtils.retryAuthentication( async (meta: Metadata) => { const data: Array = []; - const stream = grpcClient.vaultsLog(vaultsLogMessage, meta); + const stream = pkClient.grpcClient.vaultsLog(vaultsLogMessage, meta); for await (const commit of stream) { const timeStamp = commit.getTimeStamp(); const date = new Date(timeStamp); @@ -83,7 +78,7 @@ class CommandLog extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/vaults/CommandPull.ts b/src/bin/vaults/CommandPull.ts index c99b5c8fb..9bb0dce62 100644 --- a/src/bin/vaults/CommandPull.ts +++ b/src/bin/vaults/CommandPull.ts @@ -20,7 +20,6 @@ class CommandPull extends CommandPolykey { '../../proto/js/polykey/v1/vaults/vaults_pb' ); const nodesPB = await import('../../proto/js/polykey/v1/nodes/nodes_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -29,8 +28,11 @@ class CommandPull extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -42,12 +44,6 @@ class CommandPull extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const vaultMessage = new vaultsPB.Vault(); const nodeMessage = new nodesPB.Node(); const vaultPullMessage = new vaultsPB.Pull(); @@ -55,12 +51,10 @@ class CommandPull extends CommandPolykey { vaultPullMessage.setNode(nodeMessage); nodeMessage.setNodeId(nodeId); vaultMessage.setNameOrId(vaultName); - await binUtils.retryAuthentication( - (auth) => grpcClient.vaultsPull(vaultPullMessage, auth), + (auth) => pkClient.grpcClient.vaultsPull(vaultPullMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -70,7 +64,7 @@ class CommandPull extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/vaults/CommandRename.ts b/src/bin/vaults/CommandRename.ts index 958fd3681..4caaf908e 100644 --- a/src/bin/vaults/CommandRename.ts +++ b/src/bin/vaults/CommandRename.ts @@ -19,7 +19,6 @@ class CommandRename extends CommandPolykey { const vaultsPB = await import( '../../proto/js/polykey/v1/vaults/vaults_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -28,8 +27,11 @@ class CommandRename extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -41,24 +43,16 @@ class CommandRename extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const vaultMessage = new vaultsPB.Vault(); const vaultRenameMessage = new vaultsPB.Rename(); vaultRenameMessage.setVault(vaultMessage); vaultMessage.setNameOrId(vaultName); vaultRenameMessage.setNewName(newVaultName); - await binUtils.retryAuthentication( (auth) => - grpcClient.vaultsRename(vaultRenameMessage, auth), + pkClient.grpcClient.vaultsRename(vaultRenameMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -68,7 +62,7 @@ class CommandRename extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/vaults/CommandShare.ts b/src/bin/vaults/CommandShare.ts index 1e4deebb9..a5bc89330 100644 --- a/src/bin/vaults/CommandShare.ts +++ b/src/bin/vaults/CommandShare.ts @@ -20,7 +20,6 @@ class CommandShare extends CommandPolykey { '../../proto/js/polykey/v1/vaults/vaults_pb' ); const nodesPB = await import('../../proto/js/polykey/v1/nodes/nodes_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -29,8 +28,11 @@ class CommandShare extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -42,12 +44,6 @@ class CommandShare extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const vaultMessage = new vaultsPB.Vault(); const nodeMessage = new nodesPB.Node(); const setVaultPermsMessage = new vaultsPB.PermSet(); @@ -55,13 +51,11 @@ class CommandShare extends CommandPolykey { setVaultPermsMessage.setNode(nodeMessage); vaultMessage.setNameOrId(vaultName); nodeMessage.setNodeId(nodeId); - await binUtils.retryAuthentication( (auth) => - grpcClient.vaultsPermissionsSet(setVaultPermsMessage, auth), + pkClient.grpcClient.vaultsPermissionsSet(setVaultPermsMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -75,7 +69,7 @@ class CommandShare extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/vaults/CommandUnshare.ts b/src/bin/vaults/CommandUnshare.ts index 55145f172..64430c861 100644 --- a/src/bin/vaults/CommandUnshare.ts +++ b/src/bin/vaults/CommandUnshare.ts @@ -20,7 +20,6 @@ class CommandUnshare extends CommandPolykey { '../../proto/js/polykey/v1/vaults/vaults_pb' ); const nodesPB = await import('../../proto/js/polykey/v1/nodes/nodes_pb'); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -29,8 +28,11 @@ class CommandUnshare extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -42,12 +44,6 @@ class CommandUnshare extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const unsetVaultPermsMessage = new vaultsPB.PermUnset(); const vaultMessage = new vaultsPB.Vault(); const nodeMessage = new nodesPB.Node(); @@ -55,13 +51,11 @@ class CommandUnshare extends CommandPolykey { unsetVaultPermsMessage.setNode(nodeMessage); vaultMessage.setNameOrId(vaultName); nodeMessage.setNodeId(nodeId); - await binUtils.retryAuthentication( (auth) => - grpcClient.vaultsPermissionsUnset(unsetVaultPermsMessage, auth), + pkClient.grpcClient.vaultsPermissionsUnset(unsetVaultPermsMessage, auth), meta, ); - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -75,7 +69,7 @@ class CommandUnshare extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } diff --git a/src/bin/vaults/CommandVersion.ts b/src/bin/vaults/CommandVersion.ts index 2232d762e..1d461e0a9 100644 --- a/src/bin/vaults/CommandVersion.ts +++ b/src/bin/vaults/CommandVersion.ts @@ -19,7 +19,6 @@ class CommandVersion extends CommandPolykey { const vaultsPB = await import( '../../proto/js/polykey/v1/vaults/vaults_pb' ); - const clientOptions = await binProcessors.processClientOptions( options.nodePath, options.nodeId, @@ -28,8 +27,11 @@ class CommandVersion extends CommandPolykey { this.fs, this.logger.getChild(binProcessors.processClientOptions.name), ); - - let pkClient: PolykeyClient | undefined; + const meta = await binProcessors.processAuthentication( + options.passwordFile, + this.fs, + ); + let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { if (pkClient != null) await pkClient.stop(); }); @@ -41,30 +43,20 @@ class CommandVersion extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - - const meta = await binProcessors.processAuthentication( - options.passwordFile, - this.fs, - ); - const grpcClient = pkClient.grpcClient; const vaultMessage = new vaultsPB.Vault(); const vaultsVersionMessage = new vaultsPB.Version(); vaultMessage.setNameOrId(vault); vaultsVersionMessage.setVault(vaultMessage); vaultsVersionMessage.setVersionId(versionId); - await binUtils.retryAuthentication( (auth) => - grpcClient.vaultsVersion(vaultsVersionMessage, auth), + pkClient.grpcClient.vaultsVersion(vaultsVersionMessage, auth), meta, ); - let successMessage = [`Vault ${vault} is now at version ${versionId}.`]; - if (versionId.toLowerCase() === 'last') { successMessage = [`Vault ${vault} is now at the latest version.`]; } - /** * Previous status message: * --- @@ -72,7 +64,6 @@ class CommandVersion extends CommandPolykey { * will discard all changes applied to the vault in later versions. You will * not be able to return to these later versions if changes are made. */ - process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', @@ -80,7 +71,7 @@ class CommandVersion extends CommandPolykey { }), ); } finally { - if (pkClient != null) await pkClient.stop(); + if (pkClient! != null) await pkClient.stop(); } }); } From 35618f2b20dafe80cc9c1d3749ee6912b4e5276b Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Mon, 13 Dec 2021 14:43:30 +1100 Subject: [PATCH 25/29] Moved `PolykeyClient.test.ts` out of `tests/client` to `tests` --- tests/{client => }/PolykeyClient.test.ts | 7 +++---- tests/client/GRPCClientClient.test.ts | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) rename tests/{client => }/PolykeyClient.test.ts (97%) diff --git a/tests/client/PolykeyClient.test.ts b/tests/PolykeyClient.test.ts similarity index 97% rename from tests/client/PolykeyClient.test.ts rename to tests/PolykeyClient.test.ts index 3c427e062..554ff592b 100644 --- a/tests/client/PolykeyClient.test.ts +++ b/tests/PolykeyClient.test.ts @@ -11,9 +11,8 @@ import { Status } from '@/status'; import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; import { PolykeyAgent } from '@'; import config from '@/config'; -import * as testUtils from './utils'; +import * as testClientUtils from './client/utils'; -// Mocks. jest.mock('@/keys/utils', () => ({ ...jest.requireActual('@/keys/utils'), generateDeterministicKeyPair: @@ -60,7 +59,7 @@ describe('PolykeyClient', () => { nodePath: nodePath2, logger: logger.getChild(PolykeyAgent.name), }); - [server, _port] = await testUtils.openTestClientServer({ + [server, _port] = await testClientUtils.openTestClientServer({ polykeyAgent, secure: false, }); @@ -79,7 +78,7 @@ describe('PolykeyClient', () => { afterAll(async () => { await client.destroy(); await pkClient.stop(); - await testUtils.closeTestClientServer(server); + await testClientUtils.closeTestClientServer(server); await polykeyAgent2.stop(); await polykeyAgent2.destroy(); await polykeyAgent.stop(); diff --git a/tests/client/GRPCClientClient.test.ts b/tests/client/GRPCClientClient.test.ts index 63a553ca1..f32216641 100644 --- a/tests/client/GRPCClientClient.test.ts +++ b/tests/client/GRPCClientClient.test.ts @@ -15,7 +15,6 @@ import config from '@/config'; import { errors as clientErrors } from '@/client'; import * as testUtils from './utils'; -// Mocks. jest.mock('@/keys/utils', () => ({ ...jest.requireActual('@/keys/utils'), generateDeterministicKeyPair: From b21d3bd9a1c2065ccf6d997e97fa6ff474bc2ffe Mon Sep 17 00:00:00 2001 From: Emma Casolin Date: Mon, 13 Dec 2021 15:33:04 +1100 Subject: [PATCH 26/29] removing unnecessary writes to stdout --- src/bin/identities/CommandAllow.ts | 12 ------------ src/bin/identities/CommandDisallow.ts | 14 -------------- src/bin/identities/CommandDiscover.ts | 12 ------------ src/bin/identities/CommandTrust.ts | 12 ------------ src/bin/identities/CommandUntrust.ts | 12 ------------ src/bin/nodes/CommandAdd.ts | 6 ------ src/bin/notifications/CommandClear.ts | 6 ------ src/bin/notifications/CommandSend.ts | 10 ---------- src/bin/secrets/CommandCreate.ts | 8 -------- src/bin/secrets/CommandDelete.ts | 8 -------- src/bin/secrets/CommandDir.ts | 8 -------- src/bin/secrets/CommandEdit.ts | 8 -------- src/bin/secrets/CommandMkdir.ts | 8 -------- src/bin/secrets/CommandRename.ts | 8 -------- src/bin/secrets/CommandUpdate.ts | 8 -------- src/bin/vaults/CommandClone.ts | 8 -------- src/bin/vaults/CommandDelete.ts | 6 ------ src/bin/vaults/CommandPull.ts | 8 -------- src/bin/vaults/CommandRename.ts | 8 -------- src/bin/vaults/CommandShare.ts | 12 ------------ src/bin/vaults/CommandUnshare.ts | 12 ------------ src/bin/vaults/CommandVersion.ts | 10 ---------- tests/bin/nodes.test.ts | 14 -------------- tests/bin/notifications.test.ts | 15 --------------- tests/bin/vaults.test.ts | 4 ---- 25 files changed, 237 deletions(-) diff --git a/src/bin/identities/CommandAllow.ts b/src/bin/identities/CommandAllow.ts index 49edc74cb..9d8a18b11 100644 --- a/src/bin/identities/CommandAllow.ts +++ b/src/bin/identities/CommandAllow.ts @@ -54,13 +54,11 @@ class CommandAllow extends CommandPolykey { }); const setActionMessage = new permissionsPB.ActionSet(); setActionMessage.setAction(permissions); - let name: string; if (gestaltId.nodeId) { // Setting by Node const nodeMessage = new nodesPB.Node(); nodeMessage.setNodeId(gestaltId.nodeId); setActionMessage.setNode(nodeMessage); - name = `${gestaltId.nodeId}`; // Trusting await binUtils.retryAuthentication( (auth) => @@ -73,22 +71,12 @@ class CommandAllow extends CommandPolykey { providerMessage.setProviderId(gestaltId.providerId); providerMessage.setMessage(gestaltId.identityId); setActionMessage.setIdentity(providerMessage); - name = `${parsers.formatIdentityString( - gestaltId.providerId, - gestaltId.identityId, - )}`; await binUtils.retryAuthentication( (auth) => pkClient.grpcClient.gestaltsActionsSetByIdentity(setActionMessage, auth), meta, ); } - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [`Allowing: ${name} ${permissions}`], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/identities/CommandDisallow.ts b/src/bin/identities/CommandDisallow.ts index 3356ec19c..c585c2c58 100644 --- a/src/bin/identities/CommandDisallow.ts +++ b/src/bin/identities/CommandDisallow.ts @@ -52,7 +52,6 @@ class CommandDisallow extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - let name: string; const setActionMessage = new permissionsPB.ActionSet(); setActionMessage.setAction(permissions); if (gestaltId.nodeId) { @@ -60,7 +59,6 @@ class CommandDisallow extends CommandPolykey { const nodeMessage = new nodesPB.Node(); nodeMessage.setNodeId(gestaltId.nodeId); setActionMessage.setNode(nodeMessage); - name = `${gestaltId.nodeId}`; // Trusting await binUtils.retryAuthentication( (auth) => @@ -73,10 +71,6 @@ class CommandDisallow extends CommandPolykey { providerMessage.setProviderId(gestaltId.providerId); providerMessage.setMessage(gestaltId.identityId); setActionMessage.setIdentity(providerMessage); - name = `${parsers.formatIdentityString( - gestaltId.providerId, - gestaltId.identityId, - )}`; // Trusting. await binUtils.retryAuthentication( (auth) => @@ -84,14 +78,6 @@ class CommandDisallow extends CommandPolykey { meta, ); } - - const action = options.action; - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [`Allowing: ${name} ${action}`], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/identities/CommandDiscover.ts b/src/bin/identities/CommandDiscover.ts index 29f2abe69..6b34562d3 100644 --- a/src/bin/identities/CommandDiscover.ts +++ b/src/bin/identities/CommandDiscover.ts @@ -50,12 +50,10 @@ class CommandDiscover extends CommandPolykey { port: clientOptions.clientPort, logger: this.logger.getChild(PolykeyClient.name), }); - let name: string; if (gestaltId.nodeId) { // Discovery by Node. const nodeMessage = new nodesPB.Node(); nodeMessage.setNodeId(gestaltId.nodeId); - name = `${gestaltId.nodeId}`; await binUtils.retryAuthentication( (auth) => pkClient.grpcClient.gestaltsDiscoveryByNode(nodeMessage, auth), @@ -66,22 +64,12 @@ class CommandDiscover extends CommandPolykey { const providerMessage = new identitiesPB.Provider(); providerMessage.setProviderId(gestaltId.providerId); providerMessage.setMessage(gestaltId.identityId); - name = `${parsers.formatIdentityString( - gestaltId.providerId, - gestaltId.identityId, - )}`; await binUtils.retryAuthentication( (auth) => pkClient.grpcClient.gestaltsDiscoveryByIdentity(providerMessage, auth), meta, ); } - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [`Starting discovery at: ${name}...`], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/identities/CommandTrust.ts b/src/bin/identities/CommandTrust.ts index a3d086d24..c0b19995e 100644 --- a/src/bin/identities/CommandTrust.ts +++ b/src/bin/identities/CommandTrust.ts @@ -54,13 +54,11 @@ class CommandTrust extends CommandPolykey { const action = 'notify'; const setActionMessage = new permissionsPB.ActionSet(); setActionMessage.setAction(action); - let name: string; if (gestaltId.nodeId) { // Setting by Node. const nodeMessage = new nodesPB.Node(); nodeMessage.setNodeId(gestaltId.nodeId); setActionMessage.setNode(nodeMessage); - name = `${gestaltId.nodeId}`; await binUtils.retryAuthentication( (auth) => pkClient.grpcClient.gestaltsActionsSetByNode(setActionMessage, auth), @@ -72,22 +70,12 @@ class CommandTrust extends CommandPolykey { providerMessage.setProviderId(gestaltId.providerId!); providerMessage.setMessage(gestaltId.identityId!); setActionMessage.setIdentity(providerMessage); - name = `${parsers.formatIdentityString( - gestaltId.providerId, - gestaltId.identityId, - )}`; await binUtils.retryAuthentication( (auth) => pkClient.grpcClient.gestaltsActionsSetByIdentity(setActionMessage, auth), meta, ); } - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [`Trusting: ${name}`], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/identities/CommandUntrust.ts b/src/bin/identities/CommandUntrust.ts index cf10ffba0..3463c9ce4 100644 --- a/src/bin/identities/CommandUntrust.ts +++ b/src/bin/identities/CommandUntrust.ts @@ -54,13 +54,11 @@ class CommandUntrust extends CommandPolykey { const action = 'notify'; const setActionMessage = new permissionsPB.ActionSet(); setActionMessage.setAction(action); - let name: string; if (gestaltId.nodeId) { // Setting by Node. const nodeMessage = new nodesPB.Node(); nodeMessage.setNodeId(gestaltId.nodeId); setActionMessage.setNode(nodeMessage); - name = `${gestaltId.nodeId}`; await binUtils.retryAuthentication( (auth) => pkClient.grpcClient.gestaltsActionsUnsetByNode(setActionMessage, auth), @@ -72,22 +70,12 @@ class CommandUntrust extends CommandPolykey { providerMessage.setProviderId(gestaltId.providerId!); providerMessage.setMessage(gestaltId.identityId!); setActionMessage.setIdentity(providerMessage); - name = `${parsers.formatIdentityString( - gestaltId.providerId, - gestaltId.identityId, - )}`; await binUtils.retryAuthentication( (auth) => pkClient.grpcClient.gestaltsActionsUnsetByIdentity(setActionMessage, auth), meta, ); } - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [`untrusting: ${name}`], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/nodes/CommandAdd.ts b/src/bin/nodes/CommandAdd.ts index c62adb5b7..6cbdc0115 100644 --- a/src/bin/nodes/CommandAdd.ts +++ b/src/bin/nodes/CommandAdd.ts @@ -51,12 +51,6 @@ class CommandAdd extends CommandPolykey { (auth) => pkClient.grpcClient.nodesAdd(nodeAddressMessage, auth), meta, ); - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: ['Added node'], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/notifications/CommandClear.ts b/src/bin/notifications/CommandClear.ts index 9ef013727..ad9bdfe81 100644 --- a/src/bin/notifications/CommandClear.ts +++ b/src/bin/notifications/CommandClear.ts @@ -45,12 +45,6 @@ class CommandClear extends CommandPolykey { pkClient.grpcClient.notificationsClear(emptyMessage, auth), meta, ); - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [`Successsfully cleared all notifications`], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/notifications/CommandSend.ts b/src/bin/notifications/CommandSend.ts index 3a9579ba4..798b40a44 100644 --- a/src/bin/notifications/CommandSend.ts +++ b/src/bin/notifications/CommandSend.ts @@ -53,16 +53,6 @@ class CommandSend extends CommandPolykey { pkClient.grpcClient.notificationsSend(notificationsSendMessage, auth), meta, ); - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [ - `Successsfully sent notification: "${notificationsSendMessage - .getData() - ?.getMessage()}" to Keynode with ID: ${notificationsSendMessage.getReceiverId()}`, - ], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/secrets/CommandCreate.ts b/src/bin/secrets/CommandCreate.ts index 987632d1e..b0d9a7d0d 100644 --- a/src/bin/secrets/CommandCreate.ts +++ b/src/bin/secrets/CommandCreate.ts @@ -76,14 +76,6 @@ class CommandCreate extends CommandPolykey { (auth) => pkClient.grpcClient.vaultsSecretsNew(secretMessage, auth), meta, ); - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [ - `Secret: ${secretMessage.getSecretName()} successfully created in vault: ${vaultMessage.getNameOrId()}`, - ], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/secrets/CommandDelete.ts b/src/bin/secrets/CommandDelete.ts index c169529e6..300879931 100644 --- a/src/bin/secrets/CommandDelete.ts +++ b/src/bin/secrets/CommandDelete.ts @@ -61,14 +61,6 @@ class CommandDelete extends CommandPolykey { pkClient.grpcClient.vaultsSecretsDelete(secretMessage, auth), meta, ); - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [ - `Secret: ${secretMessage.getSecretName()} in vault: ${vaultMessage.getNameOrId()} successfully deleted`, - ], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/secrets/CommandDir.ts b/src/bin/secrets/CommandDir.ts index 3bdffbbcd..fceff9809 100644 --- a/src/bin/secrets/CommandDir.ts +++ b/src/bin/secrets/CommandDir.ts @@ -59,14 +59,6 @@ class CommandDir extends CommandPolykey { pkClient.grpcClient.vaultsSecretsNewDir(secretDirectoryMessage, auth), meta, ); - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [ - `Secret directory added to vault: ${secretDirectoryMessage.getSecretDirectory()}`, - ], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/secrets/CommandEdit.ts b/src/bin/secrets/CommandEdit.ts index 9abca91d1..f3d005810 100644 --- a/src/bin/secrets/CommandEdit.ts +++ b/src/bin/secrets/CommandEdit.ts @@ -86,14 +86,6 @@ class CommandEdit extends CommandPolykey { await this.fs.promises.rmdir(tmpDir, { recursive: true }); // Windows // TODO: complete windows impl - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [ - `Edited secret: ${vaultMessage.getNameOrId()} in vault: ${vaultMessage.getNameOrId()}`, - ], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/secrets/CommandMkdir.ts b/src/bin/secrets/CommandMkdir.ts index a6f1427a1..bba9e0db9 100644 --- a/src/bin/secrets/CommandMkdir.ts +++ b/src/bin/secrets/CommandMkdir.ts @@ -59,14 +59,6 @@ class CommandMkdir extends CommandPolykey { pkClient.grpcClient.vaultsSecretsMkdir(vaultMkdirMessage, auth), meta, ); - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [ - `Directory: ${vaultMkdirMessage.getDirName()} created inside vault: ${vaultMessage.getNameOrId()}`, - ], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/secrets/CommandRename.ts b/src/bin/secrets/CommandRename.ts index abb3627e8..9717b1c84 100644 --- a/src/bin/secrets/CommandRename.ts +++ b/src/bin/secrets/CommandRename.ts @@ -64,14 +64,6 @@ class CommandRename extends CommandPolykey { pkClient.grpcClient.vaultsSecretsRename(secretRenameMessage, auth), meta, ); - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [ - `Renamed secret: ${secretMessage.getSecretName()} in vault: ${vaultMessage.getNameOrId()} to ${secretRenameMessage.getNewName()}`, - ], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/secrets/CommandUpdate.ts b/src/bin/secrets/CommandUpdate.ts index ed552e726..1276f93a4 100644 --- a/src/bin/secrets/CommandUpdate.ts +++ b/src/bin/secrets/CommandUpdate.ts @@ -77,14 +77,6 @@ class CommandUpdate extends CommandPolykey { pkClient.grpcClient.vaultsSecretsEdit(secretMessage, auth), meta, ); - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [ - `Updated secret: ${secretMessage.getSecretName()} in vault: ${vaultMessage.getNameOrId()}`, - ], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/vaults/CommandClone.ts b/src/bin/vaults/CommandClone.ts index 3bd089a6a..a0af7d2ad 100644 --- a/src/bin/vaults/CommandClone.ts +++ b/src/bin/vaults/CommandClone.ts @@ -55,14 +55,6 @@ class CommandClone extends CommandPolykey { (auth) => pkClient.grpcClient.vaultsClone(vaultCloneMessage, auth), meta, ); - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [ - `Clone Vault: ${vaultMessage.getNameOrId()} from Node: ${nodeMessage.getNodeId()} successful`, - ], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/vaults/CommandDelete.ts b/src/bin/vaults/CommandDelete.ts index 55e579417..e5bd72b32 100644 --- a/src/bin/vaults/CommandDelete.ts +++ b/src/bin/vaults/CommandDelete.ts @@ -48,12 +48,6 @@ class CommandDelete extends CommandPolykey { (auth) => pkClient.grpcClient.vaultsDelete(vaultMessage, auth), meta, ); - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [`Vault: ${vaultMessage.getNameOrId()} deleted successfully`], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/vaults/CommandPull.ts b/src/bin/vaults/CommandPull.ts index 9bb0dce62..dc549deca 100644 --- a/src/bin/vaults/CommandPull.ts +++ b/src/bin/vaults/CommandPull.ts @@ -55,14 +55,6 @@ class CommandPull extends CommandPolykey { (auth) => pkClient.grpcClient.vaultsPull(vaultPullMessage, auth), meta, ); - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [ - `Pull Vault: ${vaultMessage.getNameOrId()} from Node: ${nodeMessage.getNodeId()} successful`, - ], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/vaults/CommandRename.ts b/src/bin/vaults/CommandRename.ts index 4caaf908e..dbf550803 100644 --- a/src/bin/vaults/CommandRename.ts +++ b/src/bin/vaults/CommandRename.ts @@ -53,14 +53,6 @@ class CommandRename extends CommandPolykey { pkClient.grpcClient.vaultsRename(vaultRenameMessage, auth), meta, ); - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [ - `Renamed vault: ${vaultMessage.getNameOrId()} to ${vaultRenameMessage.getNewName()}`, - ], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/vaults/CommandShare.ts b/src/bin/vaults/CommandShare.ts index a5bc89330..2377f3f91 100644 --- a/src/bin/vaults/CommandShare.ts +++ b/src/bin/vaults/CommandShare.ts @@ -56,18 +56,6 @@ class CommandShare extends CommandPolykey { pkClient.grpcClient.vaultsPermissionsSet(setVaultPermsMessage, auth), meta, ); - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [ - `Shared Vault: ${setVaultPermsMessage - .getVault() - ?.getNameOrId()} to: ${setVaultPermsMessage - .getNode() - ?.getNodeId()}`, - ], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/vaults/CommandUnshare.ts b/src/bin/vaults/CommandUnshare.ts index 64430c861..ca3920a92 100644 --- a/src/bin/vaults/CommandUnshare.ts +++ b/src/bin/vaults/CommandUnshare.ts @@ -56,18 +56,6 @@ class CommandUnshare extends CommandPolykey { pkClient.grpcClient.vaultsPermissionsUnset(unsetVaultPermsMessage, auth), meta, ); - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: [ - `Unshared Vault: ${unsetVaultPermsMessage - .getVault() - ?.getNameOrId()} to: ${unsetVaultPermsMessage - .getNode() - ?.getNodeId()}`, - ], - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/src/bin/vaults/CommandVersion.ts b/src/bin/vaults/CommandVersion.ts index 1d461e0a9..e2262d4fa 100644 --- a/src/bin/vaults/CommandVersion.ts +++ b/src/bin/vaults/CommandVersion.ts @@ -53,10 +53,6 @@ class CommandVersion extends CommandPolykey { pkClient.grpcClient.vaultsVersion(vaultsVersionMessage, auth), meta, ); - let successMessage = [`Vault ${vault} is now at version ${versionId}.`]; - if (versionId.toLowerCase() === 'last') { - successMessage = [`Vault ${vault} is now at the latest version.`]; - } /** * Previous status message: * --- @@ -64,12 +60,6 @@ class CommandVersion extends CommandPolykey { * will discard all changes applied to the vault in later versions. You will * not be able to return to these later versions if changes are made. */ - process.stdout.write( - binUtils.outputFormatter({ - type: options.format === 'json' ? 'json' : 'list', - data: successMessage, - }), - ); } finally { if (pkClient! != null) await pkClient.stop(); } diff --git a/tests/bin/nodes.test.ts b/tests/bin/nodes.test.ts index 3e969f458..f5fb736df 100644 --- a/tests/bin/nodes.test.ts +++ b/tests/bin/nodes.test.ts @@ -15,19 +15,6 @@ jest.mock('@/keys/utils', () => ({ jest.requireActual('@/keys/utils').generateKeyPair, })); -/** - * This test file has been optimised to use only one instance of PolykeyAgent where posible. - * Setting up the PolykeyAgent has been done in a beforeAll block. - * Keep this in mind when adding or editing tests. - * Any side effects need to be undone when the test has completed. - * Preferably within a `afterEach()` since any cleanup will be skipped inside a failing test. - * - * - left over state can cause a test to fail in certain cases. - * - left over state can cause similar tests to succeed when they should fail. - * - starting or stopping the agent within tests should be done on a new instance of the polykey agent. - * - when in doubt test each modified or added test on it's own as well as the whole file. - * - Looking into adding a way to safely clear each domain's DB information with out breaking modules. - */ describe('CLI Nodes', () => { const password = 'password'; const logger = new Logger('pkStdio Test', LogLevel.WARN, [ @@ -362,7 +349,6 @@ describe('CLI Nodes', () => { ]); const result = await testUtils.pkStdio(commands, {}, dataDir); expect(result.exitCode).toBe(0); - expect(result.stdout).toContain('Added node'); // Checking if node was added. const res = await polykeyAgent.nodeManager.getNode(validNodeId); diff --git a/tests/bin/notifications.test.ts b/tests/bin/notifications.test.ts index 357f92e00..3ccd1070f 100644 --- a/tests/bin/notifications.test.ts +++ b/tests/bin/notifications.test.ts @@ -17,19 +17,6 @@ jest.mock('@/keys/utils', () => ({ jest.requireActual('@/keys/utils').generateKeyPair, })); -/** - * This test file has been optimised to use only one instance of PolykeyAgent where posible. - * Setting up the PolykeyAgent has been done in a beforeAll block. - * Keep this in mind when adding or editing tests. - * Any side effects need to be undone when the test has completed. - * Preferably within a `afterEach()` since any cleanup will be skipped inside a failing test. - * - * - left over state can cause a test to fail in certain cases. - * - left over state can cause similar tests to succeed when they should fail. - * - starting or stopping the agent within tests should be done on a new instance of the polykey agent. - * - when in doubt test each modified or added test on it's own as well as the whole file. - * - Looking into adding a way to safely clear each domain's DB information with out breaking modules. - */ describe('CLI Notifications', () => { const password = 'password'; const logger = new Logger('pkStdio Test', LogLevel.WARN, [ @@ -123,7 +110,6 @@ describe('CLI Notifications', () => { const commands = genCommandsSender(['send', receiverNodeId, 'msg']); const result = await testUtils.pkStdio(commands, {}, senderDataDir); expect(result.exitCode).toBe(0); // Succeeds - expect(result.stdout).toContain('msg'); const notifications = await receiverPolykeyAgent.notificationsManager.readNotifications(); expect(notifications[0].data).toEqual({ @@ -139,7 +125,6 @@ describe('CLI Notifications', () => { const commands = genCommandsSender(['send', receiverNodeId, 'msg']); const result = await testUtils.pkStdio(commands, {}, senderDataDir); expect(result.exitCode).toBe(0); // Succeeds - expect(result.stdout).toContain('msg'); const notifications = await receiverPolykeyAgent.notificationsManager.readNotifications(); expect(notifications).toEqual([]); // Notification should be sent but not received diff --git a/tests/bin/vaults.test.ts b/tests/bin/vaults.test.ts index eed8ca1ca..1d8873a80 100644 --- a/tests/bin/vaults.test.ts +++ b/tests/bin/vaults.test.ts @@ -528,8 +528,6 @@ describe('CLI vaults', () => { const result = await utils.pkStdio([...command], {}, dataDir); expect(result.exitCode).toBe(0); - expect(result.stdout).toContain(vaultName); - expect(result.stdout).toContain(ver1Oid); const fileContents = await vault.access(async (efs) => { return (await efs.readFile(secret1.name)).toString(); @@ -562,8 +560,6 @@ describe('CLI vaults', () => { const result2 = await utils.pkStdio([...command2], {}, dataDir); expect(result2.exitCode).toBe(0); - expect(result2.stdout).toContain(vaultName); - expect(result2.stdout).toContain('latest'); }); test('should handle invalid version IDs', async () => { await polykeyAgent.vaultManager.createVault(vaultName); From 481a10f0271d40560b16cd93b960f6fce5d1bc2c Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Mon, 13 Dec 2021 15:39:57 +1100 Subject: [PATCH 27/29] Setup global root keypair for `tests/PolykeyClient.test.ts` --- tests/PolykeyClient.test.ts | 164 +++++++++++------------------------- tests/globalSetup.ts | 32 ++++++- tests/globalTeardown.ts | 13 ++- tests/setup.ts | 8 ++ tests/utils.ts | 20 ++++- 5 files changed, 113 insertions(+), 124 deletions(-) diff --git a/tests/PolykeyClient.test.ts b/tests/PolykeyClient.test.ts index 554ff592b..06c2d71fb 100644 --- a/tests/PolykeyClient.test.ts +++ b/tests/PolykeyClient.test.ts @@ -1,155 +1,85 @@ -import type * as grpc from '@grpc/grpc-js'; -import type { GRPCClientClient } from '@/client'; import type { SessionToken } from '@/sessions/types'; import os from 'os'; import path from 'path'; import fs from 'fs'; import Logger, { LogLevel, StreamHandler } from '@matrixai/logger'; -import * as binProcessors from '@/bin/utils/processors'; -import { PolykeyClient } from '@'; -import { Status } from '@/status'; -import * as utilsPB from '@/proto/js/polykey/v1/utils/utils_pb'; -import { PolykeyAgent } from '@'; +import { PolykeyClient, PolykeyAgent } from '@'; +import { Session } from '@/sessions'; +import * as keysUtils from '@/keys/utils'; import config from '@/config'; -import * as testClientUtils from './client/utils'; +import * as testUtils from './utils'; -jest.mock('@/keys/utils', () => ({ - ...jest.requireActual('@/keys/utils'), - generateDeterministicKeyPair: - jest.requireActual('@/keys/utils').generateKeyPair, -})); +jest.spyOn(keysUtils, 'generateKeyPair') + .mockImplementation(testUtils.getGlobalKeyPair); +jest.spyOn(keysUtils, 'generateDeterministicKeyPair') + .mockImplementation(testUtils.getGlobalKeyPair); describe('PolykeyClient', () => { const password = 'password'; - const logger = new Logger('GRPCClientClientTest', LogLevel.WARN, [ + const logger = new Logger('PolykeyClient Test', LogLevel.WARN, [ new StreamHandler(), ]); - let client: GRPCClientClient; - let pkClient: PolykeyClient; - let server: grpc.Server; - let _port: number; - let passwordFile: string; - let meta: grpc.Metadata; let dataDir: string; let nodePath: string; - let nodePath2: string; - let clientPath: string; - let clientPath2: string; - let polykeyAgent: PolykeyAgent; - let polykeyAgent2: PolykeyAgent; - let sessionToken: SessionToken; + let pkAgent: PolykeyAgent; beforeAll(async () => { dataDir = await fs.promises.mkdtemp( path.join(os.tmpdir(), 'polykey-test-'), ); - nodePath = path.join(dataDir, 'keynode1'); - clientPath = path.join(dataDir, 'client1'); - nodePath2 = path.join(dataDir, 'keynode2'); - clientPath2 = path.join(dataDir, 'client2'); - passwordFile = path.join(dataDir, 'password'); - await fs.promises.writeFile(passwordFile, password); - meta = await binProcessors.processAuthentication(passwordFile, fs); - polykeyAgent = await PolykeyAgent.createPolykeyAgent({ + nodePath = path.join(dataDir, 'polykey'); + pkAgent = await PolykeyAgent.createPolykeyAgent({ password, nodePath, - logger: logger, - }); - polykeyAgent2 = await PolykeyAgent.createPolykeyAgent({ - password, - nodePath: nodePath2, - logger: logger.getChild(PolykeyAgent.name), - }); - [server, _port] = await testClientUtils.openTestClientServer({ - polykeyAgent, - secure: false, - }); - pkClient = await PolykeyClient.createPolykeyClient({ - nodeId: polykeyAgent.keyManager.getNodeId(), - host: polykeyAgent.grpcServerClient.host, - port: polykeyAgent.grpcServerClient.port, - nodePath: clientPath, - fs: fs, - logger: logger, + logger, }); - client = pkClient.grpcClient; - sessionToken = await polykeyAgent.sessionManager.createToken(); - await pkClient.session.start({ sessionToken }); }); afterAll(async () => { - await client.destroy(); - await pkClient.stop(); - await testClientUtils.closeTestClientServer(server); - await polykeyAgent2.stop(); - await polykeyAgent2.destroy(); - await polykeyAgent.stop(); - await polykeyAgent.destroy(); + await pkAgent.stop(); await fs.promises.rm(dataDir, { force: true, recursive: true, }); }); - test('can get status', async () => { - const status = new Status({ - statusPath: path.join(nodePath, config.defaults.statusBase), + test('create PolykeyClient and connect to PolykeyAgent', async () => { + const pkClient = await PolykeyClient.createPolykeyClient({ + nodeId: pkAgent.keyManager.getNodeId(), + host: pkAgent.grpcServerClient.host, + port: pkAgent.grpcServerClient.port, + nodePath, fs, logger, }); - const statusInfo = (await status.readStatus())!; - const emptyMessage = new utilsPB.EmptyMessage(); - const response = await client.agentStatus(emptyMessage, meta); - expect(typeof response.getPid()).toBe('number'); - expect(response.getNodeId()).toBe(statusInfo.data.nodeId); - expect(response.getClientHost()).toBe(statusInfo.data.clientHost); - expect(response.getClientPort()).toBe(statusInfo.data.clientPort); - expect(response.getIngressHost()).toBe(statusInfo.data.ingressHost); - expect(response.getIngressPort()).toBe(statusInfo.data.ingressPort); - expect(typeof response.getEgressHost()).toBe('string'); - expect(typeof response.getEgressPort()).toBe('number'); - expect(typeof response.getAgentHost()).toBe('string'); - expect(typeof response.getAgentPort()).toBe('number'); - expect(typeof response.getProxyHost()).toBe('string'); - expect(typeof response.getProxyPort()).toBe('number'); - expect(typeof response.getRootPublicKeyPem()).toBe('string'); - expect(typeof response.getRootCertPem()).toBe('string'); - expect(typeof response.getRootCertChainPem()).toBe('string'); + expect(pkClient.grpcClient.nodeId).toBe(pkAgent.keyManager.getNodeId()); + expect(pkClient.grpcClient.host).toBe(pkAgent.grpcServerClient.host); + expect(pkClient.grpcClient.port).toBe(pkAgent.grpcServerClient.port); + expect(pkClient.grpcClient.secured).toBe(true); + await pkClient.stop(); }); - test('can get status over TLS', async () => { - // Starting client. - const pkClient = await PolykeyClient.createPolykeyClient({ - nodeId: polykeyAgent2.keyManager.getNodeId(), - host: polykeyAgent2.grpcServerClient.host, - port: polykeyAgent2.grpcServerClient.port, - nodePath: clientPath2, - fs: fs, - logger: logger.getChild(PolykeyClient.name), + test('preserving and destroying session state', async () => { + const session = await Session.createSession({ + sessionTokenPath: path.join( + nodePath, + config.defaults.tokenBase, + ), + fs, + logger, }); - await pkClient.session.start({ sessionToken }); - const meta = await binProcessors.processAuthentication(passwordFile, fs); - - const status = new Status({ - statusPath: path.join(nodePath2, config.defaults.statusBase), + await session.writeToken('dummy' as SessionToken); + // Using fresh: true means that any token would be destroyed + const pkClient = await PolykeyClient.createPolykeyClient({ + nodeId: pkAgent.keyManager.getNodeId(), + host: pkAgent.grpcServerClient.host, + port: pkAgent.grpcServerClient.port, + nodePath, fs, logger, + fresh: true }); - const statusInfo = (await status.readStatus())!; - - const emptyMessage = new utilsPB.EmptyMessage(); - const response = await pkClient.grpcClient.agentStatus(emptyMessage, meta); - expect(typeof response.getPid()).toBe('number'); - expect(response.getNodeId()).toBe(statusInfo.data.nodeId); - expect(response.getClientHost()).toBe(statusInfo.data.clientHost); - expect(response.getClientPort()).toBe(statusInfo.data.clientPort); - expect(response.getIngressHost()).toBe(statusInfo.data.ingressHost); - expect(response.getIngressPort()).toBe(statusInfo.data.ingressPort); - expect(typeof response.getEgressHost()).toBe('string'); - expect(typeof response.getEgressPort()).toBe('number'); - expect(typeof response.getAgentHost()).toBe('string'); - expect(typeof response.getAgentPort()).toBe('number'); - expect(typeof response.getProxyHost()).toBe('string'); - expect(typeof response.getProxyPort()).toBe('number'); - expect(typeof response.getRootPublicKeyPem()).toBe('string'); - expect(typeof response.getRootCertPem()).toBe('string'); - expect(typeof response.getRootCertChainPem()).toBe('string'); - expect(pkClient.grpcClient.secured).toBeTruthy(); + expect(await session.readToken()).toBeUndefined(); + await session.writeToken('abc' as SessionToken); + await pkClient.stop(); + expect(await session.readToken()).toBeDefined(); + await pkClient.destroy(); + expect(await session.readToken()).toBeUndefined(); }); }); diff --git a/tests/globalSetup.ts b/tests/globalSetup.ts index c97a0baf5..08614db5f 100644 --- a/tests/globalSetup.ts +++ b/tests/globalSetup.ts @@ -1,13 +1,41 @@ +/** + * Global setup for all jest tests + * Side-effects are performed here + * No variable context is passed to the test modules + * Jest does not support `@/` imports here + * @module + */ import os from 'os'; import fs from 'fs'; import path from 'path'; +import * as keysUtils from '../src/keys/utils'; async function setup() { // eslint-disable-next-line no-console console.log('\nGLOBAL SETUP'); - // Globals defined in setup.ts is not available here + // Globals defined in setup.ts must be copied here + const keyPairDir = path.join(os.tmpdir(), 'polykey-test-keypair'); const binAgentDir = path.join(os.tmpdir(), 'polykey-test-bin'); - // The global agent directory must be fresh + // Setup global root key pair + // eslint-disable-next-line no-console + console.log(`Creating global.keyPairDir: ${keyPairDir}`); + await fs.promises.rm(keyPairDir, { force: true, recursive: true }); + await fs.promises.mkdir(keyPairDir); + const rootKeyPair = await keysUtils.generateKeyPair(1024); + const rootKeyPairPem = keysUtils.keyPairToPem(rootKeyPair); + await Promise.all([ + fs.promises.writeFile( + path.join(keyPairDir, 'root.pub'), + rootKeyPairPem.publicKey, + 'utf-8' + ), + fs.promises.writeFile( + path.join(keyPairDir, 'root.key'), + rootKeyPairPem.privateKey, + 'utf-8' + ) + ]); + // Setup global agent directory // eslint-disable-next-line no-console console.log(`Creating global.binAgentDir: ${binAgentDir}`); await fs.promises.rm(binAgentDir, { force: true, recursive: true }); diff --git a/tests/globalTeardown.ts b/tests/globalTeardown.ts index 0f2df08a5..0959608ad 100644 --- a/tests/globalTeardown.ts +++ b/tests/globalTeardown.ts @@ -1,3 +1,10 @@ +/** + * Global teardown for all jest tests + * Side-effects are performed here + * No variable context is inherited from test modules + * Jest does not support `@/` imports here + * @module + */ import os from 'os'; import fs from 'fs'; import path from 'path'; @@ -5,8 +12,12 @@ import path from 'path'; async function teardown() { // eslint-disable-next-line no-console console.log('GLOBAL TEARDOWN'); - // Globals defined in setup.ts is not available here + // Globals defined in setup.ts must be copied here + const keyPairDir = path.join(os.tmpdir(), 'polykey-test-keypair'); const binAgentDir = path.join(os.tmpdir(), 'polykey-test-bin'); + // eslint-disable-next-line no-console + console.log(`Destroying global.keyPairDir: ${keyPairDir}`); + await fs.promises.rm(keyPairDir, { force: true, recursive: true }); // The global agent directory must be fresh // eslint-disable-next-line no-console console.log(`Destroying global.binAgentDir: ${binAgentDir}`); diff --git a/tests/setup.ts b/tests/setup.ts index d79c793fb..5cac9b6aa 100644 --- a/tests/setup.ts +++ b/tests/setup.ts @@ -6,6 +6,7 @@ declare global { interface Global { projectDir: string; testDir: string; + keyPairDir: string; binAgentDir: string; binAgentPassword: string; defaultTimeout: number; @@ -26,6 +27,13 @@ global.projectDir = path.join(__dirname, '../'); */ global.testDir = __dirname; +/** + * Absolute directory to shared keypair directory + * Generating the root key pair takes time + * This global key pair can be used by mocks + */ +global.keyPairDir = path.join(os.tmpdir(), 'polykey-test-keypair'); + /** * Absolute directory to a shared data directory used by bin tests * This has to be a static path diff --git a/tests/utils.ts b/tests/utils.ts index debd93584..2d98504e7 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -3,8 +3,19 @@ import type { NodeAddress } from '@/nodes/types'; import os from 'os'; import path from 'path'; import fs from 'fs'; -import { utils as keyUtils } from '@/keys'; -import { PolykeyAgent } from '../src'; +import { PolykeyAgent } from '@'; +import * as keysUtils from '@/keys/utils'; + +async function getGlobalKeyPair () { + const [publicKeyPem, privateKeyPem ] = await Promise.all([ + fs.promises.readFile(path.join(global.keyPairDir, 'root.pub'), 'utf-8'), + fs.promises.readFile(path.join(global.keyPairDir, 'root.key'), 'utf-8') + ]); + return keysUtils.keyPairFromPem({ + publicKey: publicKeyPem, + privateKey: privateKeyPem + }); +} /** * Helper function to create a remote keynode to contact. @@ -65,13 +76,14 @@ function makeCrypto(dbKey: Buffer) { return { key: dbKey, ops: { - encrypt: keyUtils.encryptWithKey, - decrypt: keyUtils.decryptWithKey, + encrypt: keysUtils.encryptWithKey, + decrypt: keysUtils.decryptWithKey, }, }; } export { + getGlobalKeyPair, setupRemoteKeynode, cleanupRemoteKeynode, addRemoteDetails, From fd2236a6cfac1c614ca1a60b12addaac1c6c412a Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Mon, 13 Dec 2021 15:41:51 +1100 Subject: [PATCH 28/29] Linted --- src/bin/agent/CommandStart.ts | 4 +- src/bin/identities/CommandAllow.ts | 10 +++- src/bin/identities/CommandClaim.ts | 3 +- src/bin/identities/CommandDisallow.ts | 10 +++- src/bin/identities/CommandDiscover.ts | 5 +- src/bin/identities/CommandGet.ts | 5 +- src/bin/identities/CommandList.ts | 76 ++++++++++++------------ src/bin/identities/CommandPermissions.ts | 5 +- src/bin/identities/CommandTrust.ts | 10 +++- src/bin/identities/CommandUntrust.ts | 10 +++- src/bin/keys/CommandCertchain.ts | 22 +++---- src/bin/keys/CommandPassword.ts | 5 +- src/bin/keys/CommandRenew.ts | 2 +- src/bin/keys/CommandReset.ts | 2 +- src/bin/notifications/CommandClear.ts | 3 +- src/bin/notifications/CommandRead.ts | 5 +- src/bin/notifications/CommandSend.ts | 5 +- src/bin/secrets/CommandDir.ts | 5 +- src/bin/secrets/CommandList.ts | 22 +++---- src/bin/secrets/CommandUpdate.ts | 3 +- src/bin/utils/options.ts | 2 +- src/bin/utils/processors.ts | 10 ++-- src/bin/vaults/CommandLog.ts | 5 +- src/bin/vaults/CommandRename.ts | 3 +- src/bin/vaults/CommandShare.ts | 5 +- src/bin/vaults/CommandUnshare.ts | 5 +- tests/PolykeyClient.test.ts | 13 ++-- tests/bin/agent/lock.test.ts | 2 +- tests/bin/agent/lockall.test.ts | 2 +- tests/bin/agent/stop.test.ts | 8 +-- tests/bin/agent/unlock.test.ts | 4 +- tests/globalSetup.ts | 6 +- tests/utils.ts | 8 +-- 33 files changed, 166 insertions(+), 119 deletions(-) diff --git a/src/bin/agent/CommandStart.ts b/src/bin/agent/CommandStart.ts index ea3c1a802..cf4f54e07 100644 --- a/src/bin/agent/CommandStart.ts +++ b/src/bin/agent/CommandStart.ts @@ -46,9 +46,7 @@ class CommandStart extends CommandPolykey { options.passwordFile, this.fs, ); - } else if ( - await dirEmpty(this.fs, options.nodePath) - ) { + } else if (await dirEmpty(this.fs, options.nodePath)) { // If the node path is empty, get a new password password = await binProcessors.processNewPassword( options.passwordFile, diff --git a/src/bin/identities/CommandAllow.ts b/src/bin/identities/CommandAllow.ts index 9d8a18b11..04d0190de 100644 --- a/src/bin/identities/CommandAllow.ts +++ b/src/bin/identities/CommandAllow.ts @@ -62,7 +62,10 @@ class CommandAllow extends CommandPolykey { // Trusting await binUtils.retryAuthentication( (auth) => - pkClient.grpcClient.gestaltsActionsSetByNode(setActionMessage, auth), + pkClient.grpcClient.gestaltsActionsSetByNode( + setActionMessage, + auth, + ), meta, ); } else { @@ -73,7 +76,10 @@ class CommandAllow extends CommandPolykey { setActionMessage.setIdentity(providerMessage); await binUtils.retryAuthentication( (auth) => - pkClient.grpcClient.gestaltsActionsSetByIdentity(setActionMessage, auth), + pkClient.grpcClient.gestaltsActionsSetByIdentity( + setActionMessage, + auth, + ), meta, ); } diff --git a/src/bin/identities/CommandClaim.ts b/src/bin/identities/CommandClaim.ts index 85c97d0c0..ba5ae6241 100644 --- a/src/bin/identities/CommandClaim.ts +++ b/src/bin/identities/CommandClaim.ts @@ -47,8 +47,7 @@ class CommandClaim extends CommandPolykey { providerMessage.setProviderId(providerId); providerMessage.setMessage(identityId); await binUtils.retryAuthentication( - (auth) => - pkClient.grpcClient.identitiesClaim(providerMessage, auth), + (auth) => pkClient.grpcClient.identitiesClaim(providerMessage, auth), meta, ); } finally { diff --git a/src/bin/identities/CommandDisallow.ts b/src/bin/identities/CommandDisallow.ts index c585c2c58..3f143b97d 100644 --- a/src/bin/identities/CommandDisallow.ts +++ b/src/bin/identities/CommandDisallow.ts @@ -62,7 +62,10 @@ class CommandDisallow extends CommandPolykey { // Trusting await binUtils.retryAuthentication( (auth) => - pkClient.grpcClient.gestaltsActionsUnsetByNode(setActionMessage, auth), + pkClient.grpcClient.gestaltsActionsUnsetByNode( + setActionMessage, + auth, + ), meta, ); } else { @@ -74,7 +77,10 @@ class CommandDisallow extends CommandPolykey { // Trusting. await binUtils.retryAuthentication( (auth) => - pkClient.grpcClient.gestaltsActionsUnsetByIdentity(setActionMessage, auth), + pkClient.grpcClient.gestaltsActionsUnsetByIdentity( + setActionMessage, + auth, + ), meta, ); } diff --git a/src/bin/identities/CommandDiscover.ts b/src/bin/identities/CommandDiscover.ts index 6b34562d3..748ba142e 100644 --- a/src/bin/identities/CommandDiscover.ts +++ b/src/bin/identities/CommandDiscover.ts @@ -66,7 +66,10 @@ class CommandDiscover extends CommandPolykey { providerMessage.setMessage(gestaltId.identityId); await binUtils.retryAuthentication( (auth) => - pkClient.grpcClient.gestaltsDiscoveryByIdentity(providerMessage, auth), + pkClient.grpcClient.gestaltsDiscoveryByIdentity( + providerMessage, + auth, + ), meta, ); } diff --git a/src/bin/identities/CommandGet.ts b/src/bin/identities/CommandGet.ts index a7ec500cd..ef0cfcc1d 100644 --- a/src/bin/identities/CommandGet.ts +++ b/src/bin/identities/CommandGet.ts @@ -68,7 +68,10 @@ class CommandGet extends CommandPolykey { providerMessage.setMessage(gestaltId.identityId); res = await binUtils.retryAuthentication( (auth) => - pkClient.grpcClient.gestaltsGestaltGetByIdentity(providerMessage, auth), + pkClient.grpcClient.gestaltsGestaltGetByIdentity( + providerMessage, + auth, + ), meta, ); } diff --git a/src/bin/identities/CommandList.ts b/src/bin/identities/CommandList.ts index bc6c2b85f..ff0a353f0 100644 --- a/src/bin/identities/CommandList.ts +++ b/src/bin/identities/CommandList.ts @@ -43,45 +43,45 @@ class CommandList extends CommandPolykey { }); const emptyMessage = new utilsPB.EmptyMessage(); let output: any; - const gestalts = await binUtils.retryAuthentication( - async (auth) => { - const gestalts: Array = []; - const stream = pkClient.grpcClient.gestaltsGestaltList(emptyMessage, auth); - for await (const val of stream) { - const gestalt = JSON.parse(val.getName()); - const newGestalt: any = { - permissions: [], - nodes: [], - identities: [], - }; - for (const node of Object.keys(gestalt.nodes)) { - const nodeInfo = gestalt.nodes[node]; - newGestalt.nodes.push({ id: nodeInfo.id }); - } - for (const identity of Object.keys(gestalt.identities)) { - const identityInfo = gestalt.identities[identity]; - newGestalt.identities.push({ - providerId: identityInfo.providerId, - identityId: identityInfo.identityId, - }); - } - // Getting the permissions for the gestalt. - const nodeMessage = new nodesPB.Node(); - nodeMessage.setNodeId(newGestalt.nodes[0].id); - const actionsMessage = await binUtils.retryAuthentication( - (auth) => - pkClient.grpcClient.gestaltsActionsGetByNode(nodeMessage, auth), - meta, - ); - const actionList = actionsMessage.getActionList(); - if (actionList.length === 0) newGestalt.permissions = null; - else newGestalt.permissions = actionList; - gestalts.push(newGestalt); + const gestalts = await binUtils.retryAuthentication(async (auth) => { + const gestalts: Array = []; + const stream = pkClient.grpcClient.gestaltsGestaltList( + emptyMessage, + auth, + ); + for await (const val of stream) { + const gestalt = JSON.parse(val.getName()); + const newGestalt: any = { + permissions: [], + nodes: [], + identities: [], + }; + for (const node of Object.keys(gestalt.nodes)) { + const nodeInfo = gestalt.nodes[node]; + newGestalt.nodes.push({ id: nodeInfo.id }); } - return gestalts; - }, - meta, - ); + for (const identity of Object.keys(gestalt.identities)) { + const identityInfo = gestalt.identities[identity]; + newGestalt.identities.push({ + providerId: identityInfo.providerId, + identityId: identityInfo.identityId, + }); + } + // Getting the permissions for the gestalt. + const nodeMessage = new nodesPB.Node(); + nodeMessage.setNodeId(newGestalt.nodes[0].id); + const actionsMessage = await binUtils.retryAuthentication( + (auth) => + pkClient.grpcClient.gestaltsActionsGetByNode(nodeMessage, auth), + meta, + ); + const actionList = actionsMessage.getActionList(); + if (actionList.length === 0) newGestalt.permissions = null; + else newGestalt.permissions = actionList; + gestalts.push(newGestalt); + } + return gestalts; + }, meta); output = gestalts; if (options.format !== 'json') { // Convert to a human readable list. diff --git a/src/bin/identities/CommandPermissions.ts b/src/bin/identities/CommandPermissions.ts index 9dc9617b0..b4509efb6 100644 --- a/src/bin/identities/CommandPermissions.ts +++ b/src/bin/identities/CommandPermissions.ts @@ -66,7 +66,10 @@ class CommandPermissions extends CommandPolykey { providerMessage.setMessage(gestaltId.identityId); const res = await binUtils.retryAuthentication( (auth) => - pkClient.grpcClient.gestaltsActionsGetByIdentity(providerMessage, auth), + pkClient.grpcClient.gestaltsActionsGetByIdentity( + providerMessage, + auth, + ), meta, ); actions = res.getActionList(); diff --git a/src/bin/identities/CommandTrust.ts b/src/bin/identities/CommandTrust.ts index c0b19995e..8e4f8d57f 100644 --- a/src/bin/identities/CommandTrust.ts +++ b/src/bin/identities/CommandTrust.ts @@ -61,7 +61,10 @@ class CommandTrust extends CommandPolykey { setActionMessage.setNode(nodeMessage); await binUtils.retryAuthentication( (auth) => - pkClient.grpcClient.gestaltsActionsSetByNode(setActionMessage, auth), + pkClient.grpcClient.gestaltsActionsSetByNode( + setActionMessage, + auth, + ), meta, ); } else { @@ -72,7 +75,10 @@ class CommandTrust extends CommandPolykey { setActionMessage.setIdentity(providerMessage); await binUtils.retryAuthentication( (auth) => - pkClient.grpcClient.gestaltsActionsSetByIdentity(setActionMessage, auth), + pkClient.grpcClient.gestaltsActionsSetByIdentity( + setActionMessage, + auth, + ), meta, ); } diff --git a/src/bin/identities/CommandUntrust.ts b/src/bin/identities/CommandUntrust.ts index 3463c9ce4..22e331203 100644 --- a/src/bin/identities/CommandUntrust.ts +++ b/src/bin/identities/CommandUntrust.ts @@ -61,7 +61,10 @@ class CommandUntrust extends CommandPolykey { setActionMessage.setNode(nodeMessage); await binUtils.retryAuthentication( (auth) => - pkClient.grpcClient.gestaltsActionsUnsetByNode(setActionMessage, auth), + pkClient.grpcClient.gestaltsActionsUnsetByNode( + setActionMessage, + auth, + ), meta, ); } else { @@ -72,7 +75,10 @@ class CommandUntrust extends CommandPolykey { setActionMessage.setIdentity(providerMessage); await binUtils.retryAuthentication( (auth) => - pkClient.grpcClient.gestaltsActionsUnsetByIdentity(setActionMessage, auth), + pkClient.grpcClient.gestaltsActionsUnsetByIdentity( + setActionMessage, + auth, + ), meta, ); } diff --git a/src/bin/keys/CommandCertchain.ts b/src/bin/keys/CommandCertchain.ts index 53a42e5da..a3065a842 100644 --- a/src/bin/keys/CommandCertchain.ts +++ b/src/bin/keys/CommandCertchain.ts @@ -40,17 +40,17 @@ class CommandsCertchain extends CommandPolykey { logger: this.logger.getChild(PolykeyClient.name), }); const emptyMessage = new utilsPB.EmptyMessage(); - const data = await binUtils.retryAuthentication( - async (auth) => { - const data: Array = []; - const stream = pkClient.grpcClient.keysCertsChainGet(emptyMessage, auth); - for await (const cert of stream) { - data.push(`Certificate:\t\t${cert.getCert()}`); - } - return data; - }, - meta, - ); + const data = await binUtils.retryAuthentication(async (auth) => { + const data: Array = []; + const stream = pkClient.grpcClient.keysCertsChainGet( + emptyMessage, + auth, + ); + for await (const cert of stream) { + data.push(`Certificate:\t\t${cert.getCert()}`); + } + return data; + }, meta); process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', diff --git a/src/bin/keys/CommandPassword.ts b/src/bin/keys/CommandPassword.ts index aa452abc6..b56da6572 100644 --- a/src/bin/keys/CommandPassword.ts +++ b/src/bin/keys/CommandPassword.ts @@ -33,7 +33,7 @@ class CommandPassword extends CommandPolykey { const passwordNew = await binProcessors.processNewPassword( options.passwordNewFile, this.fs, - true + true, ); let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { @@ -50,7 +50,8 @@ class CommandPassword extends CommandPolykey { const passwordMessage = new sessionsPB.Password(); passwordMessage.setPassword(passwordNew); await binUtils.retryAuthentication( - (auth) => pkClient.grpcClient.keysPasswordChange(passwordMessage, auth), + (auth) => + pkClient.grpcClient.keysPasswordChange(passwordMessage, auth), meta, ); } finally { diff --git a/src/bin/keys/CommandRenew.ts b/src/bin/keys/CommandRenew.ts index 362c0c472..d7d1d2918 100644 --- a/src/bin/keys/CommandRenew.ts +++ b/src/bin/keys/CommandRenew.ts @@ -31,7 +31,7 @@ class CommandRenew extends CommandPolykey { const passwordNew = await binProcessors.processNewPassword( options.passwordNewFile, this.fs, - true + true, ); let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { diff --git a/src/bin/keys/CommandReset.ts b/src/bin/keys/CommandReset.ts index 83eeb7d4d..3e47974a1 100644 --- a/src/bin/keys/CommandReset.ts +++ b/src/bin/keys/CommandReset.ts @@ -31,7 +31,7 @@ class CommandReset extends CommandPolykey { const passwordNew = await binProcessors.processNewPassword( options.passwordNewFile, this.fs, - true + true, ); let pkClient: PolykeyClient; this.exitHandlers.handlers.push(async () => { diff --git a/src/bin/notifications/CommandClear.ts b/src/bin/notifications/CommandClear.ts index ad9bdfe81..a149f88cb 100644 --- a/src/bin/notifications/CommandClear.ts +++ b/src/bin/notifications/CommandClear.ts @@ -41,8 +41,7 @@ class CommandClear extends CommandPolykey { }); const emptyMessage = new utilsPB.EmptyMessage(); await binUtils.retryAuthentication( - (auth) => - pkClient.grpcClient.notificationsClear(emptyMessage, auth), + (auth) => pkClient.grpcClient.notificationsClear(emptyMessage, auth), meta, ); } finally { diff --git a/src/bin/notifications/CommandRead.ts b/src/bin/notifications/CommandRead.ts index 140e6781b..2735a5154 100644 --- a/src/bin/notifications/CommandRead.ts +++ b/src/bin/notifications/CommandRead.ts @@ -68,7 +68,10 @@ class CommandRead extends CommandPolykey { notificationsReadMessage.setOrder(options.order); const response = await binUtils.retryAuthentication( (auth) => - pkClient.grpcClient.notificationsRead(notificationsReadMessage, auth), + pkClient.grpcClient.notificationsRead( + notificationsReadMessage, + auth, + ), meta, ); const notificationMessages = response.getNotificationList(); diff --git a/src/bin/notifications/CommandSend.ts b/src/bin/notifications/CommandSend.ts index 798b40a44..40bc72104 100644 --- a/src/bin/notifications/CommandSend.ts +++ b/src/bin/notifications/CommandSend.ts @@ -50,7 +50,10 @@ class CommandSend extends CommandPolykey { notificationsSendMessage.setData(generalMessage); await binUtils.retryAuthentication( (auth) => - pkClient.grpcClient.notificationsSend(notificationsSendMessage, auth), + pkClient.grpcClient.notificationsSend( + notificationsSendMessage, + auth, + ), meta, ); } finally { diff --git a/src/bin/secrets/CommandDir.ts b/src/bin/secrets/CommandDir.ts index fceff9809..813ab7aab 100644 --- a/src/bin/secrets/CommandDir.ts +++ b/src/bin/secrets/CommandDir.ts @@ -56,7 +56,10 @@ class CommandDir extends CommandPolykey { secretDirectoryMessage.setSecretDirectory(directoryPath); await binUtils.retryAuthentication( (auth) => - pkClient.grpcClient.vaultsSecretsNewDir(secretDirectoryMessage, auth), + pkClient.grpcClient.vaultsSecretsNewDir( + secretDirectoryMessage, + auth, + ), meta, ); } finally { diff --git a/src/bin/secrets/CommandList.ts b/src/bin/secrets/CommandList.ts index 7054ff0db..c792a617c 100644 --- a/src/bin/secrets/CommandList.ts +++ b/src/bin/secrets/CommandList.ts @@ -45,17 +45,17 @@ class CommandList extends CommandPolykey { }); const vaultMessage = new vaultsPB.Vault(); vaultMessage.setNameOrId(vaultName); - const data = await binUtils.retryAuthentication( - async (auth) => { - const data: Array = []; - const stream = pkClient.grpcClient.vaultsSecretsList(vaultMessage, auth); - for await (const secret of stream) { - data.push(`${secret.getSecretName()}`); - } - return data; - }, - meta, - ); + const data = await binUtils.retryAuthentication(async (auth) => { + const data: Array = []; + const stream = pkClient.grpcClient.vaultsSecretsList( + vaultMessage, + auth, + ); + for await (const secret of stream) { + data.push(`${secret.getSecretName()}`); + } + return data; + }, meta); process.stdout.write( binUtils.outputFormatter({ type: options.format === 'json' ? 'json' : 'list', diff --git a/src/bin/secrets/CommandUpdate.ts b/src/bin/secrets/CommandUpdate.ts index 1276f93a4..941006aed 100644 --- a/src/bin/secrets/CommandUpdate.ts +++ b/src/bin/secrets/CommandUpdate.ts @@ -73,8 +73,7 @@ class CommandUpdate extends CommandPolykey { } secretMessage.setSecretContent(content); await binUtils.retryAuthentication( - (auth) => - pkClient.grpcClient.vaultsSecretsEdit(secretMessage, auth), + (auth) => pkClient.grpcClient.vaultsSecretsEdit(secretMessage, auth), meta, ); } finally { diff --git a/src/bin/utils/options.ts b/src/bin/utils/options.ts index 68e508e78..2dc3fed43 100644 --- a/src/bin/utils/options.ts +++ b/src/bin/utils/options.ts @@ -90,7 +90,7 @@ const passwordFile = new commander.Option( const passwordNewFile = new commander.Option( '-pnf, --password-new-file ', - 'Path to new Password' + 'Path to new Password', ); const recoveryCodeFile = new commander.Option( diff --git a/src/bin/utils/processors.ts b/src/bin/utils/processors.ts index 24f0c23e9..9d3353539 100644 --- a/src/bin/utils/processors.ts +++ b/src/bin/utils/processors.ts @@ -50,7 +50,7 @@ async function promptNewPassword(): Promise { if (password == null) { break; } - const { passwordConfirm }= await prompts({ + const { passwordConfirm } = await prompts({ name: 'passwordConfirm', type: 'password', message: 'Confirm new password', @@ -120,12 +120,14 @@ async function processPassword( async function processNewPassword( passwordNewFile?: string, fs: FileSystem = require('fs'), - existing: boolean = false + existing: boolean = false, ): Promise { let passwordNew: string | undefined; if (passwordNewFile != null) { try { - passwordNew = (await fs.promises.readFile(passwordNewFile, 'utf-8')).trim(); + passwordNew = ( + await fs.promises.readFile(passwordNewFile, 'utf-8') + ).trim(); } catch (e) { throw new binErrors.ErrorCLIPasswordFileRead(e.message, { errno: e.errno, @@ -134,7 +136,7 @@ async function processNewPassword( path: e.path, }); } - } else if (!existing && (typeof process.env['PK_PASSWORD'] === 'string')) { + } else if (!existing && typeof process.env['PK_PASSWORD'] === 'string') { passwordNew = process.env['PK_PASSWORD']; } else { passwordNew = await promptNewPassword(); diff --git a/src/bin/vaults/CommandLog.ts b/src/bin/vaults/CommandLog.ts index 12d7e696d..12e1f6a3f 100644 --- a/src/bin/vaults/CommandLog.ts +++ b/src/bin/vaults/CommandLog.ts @@ -58,7 +58,10 @@ class CommandLog extends CommandPolykey { const data = await binUtils.retryAuthentication( async (meta: Metadata) => { const data: Array = []; - const stream = pkClient.grpcClient.vaultsLog(vaultsLogMessage, meta); + const stream = pkClient.grpcClient.vaultsLog( + vaultsLogMessage, + meta, + ); for await (const commit of stream) { const timeStamp = commit.getTimeStamp(); const date = new Date(timeStamp); diff --git a/src/bin/vaults/CommandRename.ts b/src/bin/vaults/CommandRename.ts index dbf550803..9df0f2d75 100644 --- a/src/bin/vaults/CommandRename.ts +++ b/src/bin/vaults/CommandRename.ts @@ -49,8 +49,7 @@ class CommandRename extends CommandPolykey { vaultMessage.setNameOrId(vaultName); vaultRenameMessage.setNewName(newVaultName); await binUtils.retryAuthentication( - (auth) => - pkClient.grpcClient.vaultsRename(vaultRenameMessage, auth), + (auth) => pkClient.grpcClient.vaultsRename(vaultRenameMessage, auth), meta, ); } finally { diff --git a/src/bin/vaults/CommandShare.ts b/src/bin/vaults/CommandShare.ts index 2377f3f91..12a53a202 100644 --- a/src/bin/vaults/CommandShare.ts +++ b/src/bin/vaults/CommandShare.ts @@ -53,7 +53,10 @@ class CommandShare extends CommandPolykey { nodeMessage.setNodeId(nodeId); await binUtils.retryAuthentication( (auth) => - pkClient.grpcClient.vaultsPermissionsSet(setVaultPermsMessage, auth), + pkClient.grpcClient.vaultsPermissionsSet( + setVaultPermsMessage, + auth, + ), meta, ); } finally { diff --git a/src/bin/vaults/CommandUnshare.ts b/src/bin/vaults/CommandUnshare.ts index ca3920a92..8a4cabbd4 100644 --- a/src/bin/vaults/CommandUnshare.ts +++ b/src/bin/vaults/CommandUnshare.ts @@ -53,7 +53,10 @@ class CommandUnshare extends CommandPolykey { nodeMessage.setNodeId(nodeId); await binUtils.retryAuthentication( (auth) => - pkClient.grpcClient.vaultsPermissionsUnset(unsetVaultPermsMessage, auth), + pkClient.grpcClient.vaultsPermissionsUnset( + unsetVaultPermsMessage, + auth, + ), meta, ); } finally { diff --git a/tests/PolykeyClient.test.ts b/tests/PolykeyClient.test.ts index 06c2d71fb..8f97b80aa 100644 --- a/tests/PolykeyClient.test.ts +++ b/tests/PolykeyClient.test.ts @@ -9,9 +9,11 @@ import * as keysUtils from '@/keys/utils'; import config from '@/config'; import * as testUtils from './utils'; -jest.spyOn(keysUtils, 'generateKeyPair') +jest + .spyOn(keysUtils, 'generateKeyPair') .mockImplementation(testUtils.getGlobalKeyPair); -jest.spyOn(keysUtils, 'generateDeterministicKeyPair') +jest + .spyOn(keysUtils, 'generateDeterministicKeyPair') .mockImplementation(testUtils.getGlobalKeyPair); describe('PolykeyClient', () => { @@ -57,10 +59,7 @@ describe('PolykeyClient', () => { }); test('preserving and destroying session state', async () => { const session = await Session.createSession({ - sessionTokenPath: path.join( - nodePath, - config.defaults.tokenBase, - ), + sessionTokenPath: path.join(nodePath, config.defaults.tokenBase), fs, logger, }); @@ -73,7 +72,7 @@ describe('PolykeyClient', () => { nodePath, fs, logger, - fresh: true + fresh: true, }); expect(await session.readToken()).toBeUndefined(); await session.writeToken('abc' as SessionToken); diff --git a/tests/bin/agent/lock.test.ts b/tests/bin/agent/lock.test.ts index f19a16a73..74475b138 100644 --- a/tests/bin/agent/lock.test.ts +++ b/tests/bin/agent/lock.test.ts @@ -91,7 +91,7 @@ describe('lock', () => { { PK_NODE_PATH: global.binAgentDir, }, - global.binAgentDir + global.binAgentDir, ); // Prompted for password 1 time expect(mockedPrompts.mock.calls.length).toBe(1); diff --git a/tests/bin/agent/lockall.test.ts b/tests/bin/agent/lockall.test.ts index ea2ce7f66..e6a5a3814 100644 --- a/tests/bin/agent/lockall.test.ts +++ b/tests/bin/agent/lockall.test.ts @@ -79,7 +79,7 @@ describe('lockall', () => { await testBinUtils.pkStdio( ['agent', 'lockall'], { - PK_NODE_PATH: global.binAgentDir + PK_NODE_PATH: global.binAgentDir, }, global.binAgentDir, ); diff --git a/tests/bin/agent/stop.test.ts b/tests/bin/agent/stop.test.ts index bc797dac2..889b64590 100644 --- a/tests/bin/agent/stop.test.ts +++ b/tests/bin/agent/stop.test.ts @@ -6,8 +6,8 @@ import { Status } from '@/status'; import config from '@/config'; import * as binErrors from '@/bin/errors'; import * as clientErrors from '@/client/errors'; -import * as testBinUtils from '../utils'; import { sleep } from '@/utils'; +import * as testBinUtils from '../utils'; describe('stop', () => { const logger = new Logger('stop test', LogLevel.WARN, [new StreamHandler()]); @@ -210,7 +210,7 @@ describe('stop', () => { testBinUtils.expectProcessError( exitCode, stderr, - new clientErrors.ErrorClientAuthDenied() + new clientErrors.ErrorClientAuthDenied(), ); // Should still be LIVE await sleep(500); @@ -227,6 +227,6 @@ describe('stop', () => { ); await status.waitFor('DEAD'); }, - global.defaultTimeout * 2 - ); + global.defaultTimeout * 2, + ); }); diff --git a/tests/bin/agent/unlock.test.ts b/tests/bin/agent/unlock.test.ts index 1272642c8..3cabdcd3e 100644 --- a/tests/bin/agent/unlock.test.ts +++ b/tests/bin/agent/unlock.test.ts @@ -36,7 +36,7 @@ describe('unlock', () => { ), fs, logger, - fresh: true + fresh: true, }); let exitCode, stdout; ({ exitCode, stdout } = await testBinUtils.pkStdio( @@ -63,7 +63,7 @@ describe('unlock', () => { ['agent', 'status', '--format', 'json'], { PK_NODE_PATH: global.binAgentDir, - PK_TOKEN: await session.readToken() + PK_TOKEN: await session.readToken(), }, global.binAgentDir, )); diff --git a/tests/globalSetup.ts b/tests/globalSetup.ts index 08614db5f..8a976ac68 100644 --- a/tests/globalSetup.ts +++ b/tests/globalSetup.ts @@ -27,13 +27,13 @@ async function setup() { fs.promises.writeFile( path.join(keyPairDir, 'root.pub'), rootKeyPairPem.publicKey, - 'utf-8' + 'utf-8', ), fs.promises.writeFile( path.join(keyPairDir, 'root.key'), rootKeyPairPem.privateKey, - 'utf-8' - ) + 'utf-8', + ), ]); // Setup global agent directory // eslint-disable-next-line no-console diff --git a/tests/utils.ts b/tests/utils.ts index 2d98504e7..a3bd2027f 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -6,14 +6,14 @@ import fs from 'fs'; import { PolykeyAgent } from '@'; import * as keysUtils from '@/keys/utils'; -async function getGlobalKeyPair () { - const [publicKeyPem, privateKeyPem ] = await Promise.all([ +async function getGlobalKeyPair() { + const [publicKeyPem, privateKeyPem] = await Promise.all([ fs.promises.readFile(path.join(global.keyPairDir, 'root.pub'), 'utf-8'), - fs.promises.readFile(path.join(global.keyPairDir, 'root.key'), 'utf-8') + fs.promises.readFile(path.join(global.keyPairDir, 'root.key'), 'utf-8'), ]); return keysUtils.keyPairFromPem({ publicKey: publicKeyPem, - privateKey: privateKeyPem + privateKey: privateKeyPem, }); } From ea8493fc4fbf2bbfc79d2becc7b545651a4de4f0 Mon Sep 17 00:00:00 2001 From: Roger Qiu Date: Mon, 13 Dec 2021 16:03:27 +1100 Subject: [PATCH 29/29] Added timeouts to bootstrapping --- tests/bin/bootstrap.test.ts | 234 +++++++++++++++++++----------------- 1 file changed, 121 insertions(+), 113 deletions(-) diff --git a/tests/bin/bootstrap.test.ts b/tests/bin/bootstrap.test.ts index beae34f75..9b557f794 100644 --- a/tests/bin/bootstrap.test.ts +++ b/tests/bin/bootstrap.test.ts @@ -51,130 +51,138 @@ describe('bootstrap', () => { recoveryCode.split(' ').length === 24, ).toBe(true); }, - global.defaultTimeout, + global.defaultTimeout * 2, ); - test('bootstrapping occupied node state', async () => { - const password = 'password'; - await fs.promises.mkdir(path.join(dataDir, 'polykey')); - await fs.promises.writeFile(path.join(dataDir, 'polykey', 'test'), ''); - let exitCode, stdout, stderr; - ({ exitCode, stdout, stderr } = await testBinUtils.pkStdio( - [ - 'bootstrap', - '--node-path', - path.join(dataDir, 'polykey'), - '--root-key-pair-bits', - '1024', - '--verbose', - ], - { - PK_PASSWORD: password, - }, - dataDir, - )); - const errorBootstrapExistingState = - new bootstrapErrors.ErrorBootstrapExistingState(); - expect(exitCode).toBe(errorBootstrapExistingState.exitCode); - const stdErrLine = stderr.trim().split('\n').pop(); - const eOutput = binUtils - .outputFormatter({ - type: 'error', - name: errorBootstrapExistingState.name, - description: errorBootstrapExistingState.description, - message: errorBootstrapExistingState.message, - }) - .trim(); - expect(stdErrLine).toBe(eOutput); - ({ exitCode, stdout, stderr } = await testBinUtils.pkStdio( - [ - 'bootstrap', - '--node-path', - path.join(dataDir, 'polykey'), - '--root-key-pair-bits', - '1024', - '--fresh', - '--verbose', - ], - { - PK_PASSWORD: password, - }, - dataDir, - )); - expect(exitCode).toBe(0); - const recoveryCode = stdout.trim(); - expect( - recoveryCode.split(' ').length === 12 || - recoveryCode.split(' ').length === 24, - ).toBe(true); - }); - test('concurrent bootstrapping are coalesced', async () => { - const password = 'password'; - const [bootstrapProcess1, bootstrapProcess2] = await Promise.all([ - testBinUtils.pkSpawn( - ['bootstrap', '--root-key-pair-bits', '1024', '--verbose'], + test( + 'bootstrapping occupied node state', + async () => { + const password = 'password'; + await fs.promises.mkdir(path.join(dataDir, 'polykey')); + await fs.promises.writeFile(path.join(dataDir, 'polykey', 'test'), ''); + let exitCode, stdout, stderr; + ({ exitCode, stdout, stderr } = await testBinUtils.pkStdio( + [ + 'bootstrap', + '--node-path', + path.join(dataDir, 'polykey'), + '--root-key-pair-bits', + '1024', + '--verbose', + ], { - PK_NODE_PATH: path.join(dataDir, 'polykey'), PK_PASSWORD: password, }, dataDir, - logger.getChild('bootstrapProcess1'), - ), - testBinUtils.pkSpawn( - ['bootstrap', '--root-key-pair-bits', '1024', '--verbose'], + )); + const errorBootstrapExistingState = + new bootstrapErrors.ErrorBootstrapExistingState(); + expect(exitCode).toBe(errorBootstrapExistingState.exitCode); + const stdErrLine = stderr.trim().split('\n').pop(); + const eOutput = binUtils + .outputFormatter({ + type: 'error', + name: errorBootstrapExistingState.name, + description: errorBootstrapExistingState.description, + message: errorBootstrapExistingState.message, + }) + .trim(); + expect(stdErrLine).toBe(eOutput); + ({ exitCode, stdout, stderr } = await testBinUtils.pkStdio( + [ + 'bootstrap', + '--node-path', + path.join(dataDir, 'polykey'), + '--root-key-pair-bits', + '1024', + '--fresh', + '--verbose', + ], { - PK_NODE_PATH: path.join(dataDir, 'polykey'), PK_PASSWORD: password, }, dataDir, - logger.getChild('bootstrapProcess2'), - ), - ]); - // These will be the last line of STDERR - // The readline library will automatically trim off newlines - let stdErrLine1; - let stdErrLine2; - const rlErr1 = readline.createInterface(bootstrapProcess1.stderr!); - const rlErr2 = readline.createInterface(bootstrapProcess2.stderr!); - rlErr1.on('line', (l) => { - stdErrLine1 = l; - }); - rlErr2.on('line', (l) => { - stdErrLine2 = l; - }); - const [index, exitCode, signal] = await new Promise< - [number, number | null, NodeJS.Signals | null] - >((resolve) => { - bootstrapProcess1.once('exit', (code, signal) => { - resolve([0, code, signal]); + )); + expect(exitCode).toBe(0); + const recoveryCode = stdout.trim(); + expect( + recoveryCode.split(' ').length === 12 || + recoveryCode.split(' ').length === 24, + ).toBe(true); + }, + global.defaultTimeout * 2, + ); + test( + 'concurrent bootstrapping are coalesced', + async () => { + const password = 'password'; + const [bootstrapProcess1, bootstrapProcess2] = await Promise.all([ + testBinUtils.pkSpawn( + ['bootstrap', '--root-key-pair-bits', '1024', '--verbose'], + { + PK_NODE_PATH: path.join(dataDir, 'polykey'), + PK_PASSWORD: password, + }, + dataDir, + logger.getChild('bootstrapProcess1'), + ), + testBinUtils.pkSpawn( + ['bootstrap', '--root-key-pair-bits', '1024', '--verbose'], + { + PK_NODE_PATH: path.join(dataDir, 'polykey'), + PK_PASSWORD: password, + }, + dataDir, + logger.getChild('bootstrapProcess2'), + ), + ]); + // These will be the last line of STDERR + // The readline library will automatically trim off newlines + let stdErrLine1; + let stdErrLine2; + const rlErr1 = readline.createInterface(bootstrapProcess1.stderr!); + const rlErr2 = readline.createInterface(bootstrapProcess2.stderr!); + rlErr1.on('line', (l) => { + stdErrLine1 = l; }); - bootstrapProcess2.once('exit', (code, signal) => { - resolve([1, code, signal]); + rlErr2.on('line', (l) => { + stdErrLine2 = l; }); - }); - const errorStatusLocked = new statusErrors.ErrorStatusLocked(); - expect(exitCode).toBe(errorStatusLocked.exitCode); - expect(signal).toBe(null); - const eOutput = binUtils - .outputFormatter({ - type: 'error', - name: errorStatusLocked.name, - description: errorStatusLocked.description, - message: errorStatusLocked.message, - }) - .trim(); - // It's either the first or second process - if (index === 0) { - expect(stdErrLine1).toBeDefined(); - expect(stdErrLine1).toBe(eOutput); - const [exitCode] = await testBinUtils.processExit(bootstrapProcess2); - expect(exitCode).toBe(0); - } else if (index === 1) { - expect(stdErrLine2).toBeDefined(); - expect(stdErrLine2).toBe(eOutput); - const [exitCode] = await testBinUtils.processExit(bootstrapProcess1); - expect(exitCode).toBe(0); - } - }); + const [index, exitCode, signal] = await new Promise< + [number, number | null, NodeJS.Signals | null] + >((resolve) => { + bootstrapProcess1.once('exit', (code, signal) => { + resolve([0, code, signal]); + }); + bootstrapProcess2.once('exit', (code, signal) => { + resolve([1, code, signal]); + }); + }); + const errorStatusLocked = new statusErrors.ErrorStatusLocked(); + expect(exitCode).toBe(errorStatusLocked.exitCode); + expect(signal).toBe(null); + const eOutput = binUtils + .outputFormatter({ + type: 'error', + name: errorStatusLocked.name, + description: errorStatusLocked.description, + message: errorStatusLocked.message, + }) + .trim(); + // It's either the first or second process + if (index === 0) { + expect(stdErrLine1).toBeDefined(); + expect(stdErrLine1).toBe(eOutput); + const [exitCode] = await testBinUtils.processExit(bootstrapProcess2); + expect(exitCode).toBe(0); + } else if (index === 1) { + expect(stdErrLine2).toBeDefined(); + expect(stdErrLine2).toBe(eOutput); + const [exitCode] = await testBinUtils.processExit(bootstrapProcess1); + expect(exitCode).toBe(0); + } + }, + global.defaultTimeout * 2, + ); test( 'bootstrap when interrupted, requires fresh on next bootstrap', async () => {