Skip to content

Commit

Permalink
feat: updating behavior of secrets get
Browse files Browse the repository at this point in the history
  • Loading branch information
aryanjassal committed Sep 13, 2024
1 parent 8490111 commit 69e9b36
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 27 deletions.
4 changes: 2 additions & 2 deletions src/client/callers/vaultsSecretsGet.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { HandlerTypes } from '@matrixai/rpc';
import type VaultsSecretsGet from '../handlers/VaultsSecretsGet';
import { UnaryCaller } from '@matrixai/rpc';
import { ServerCaller } from '@matrixai/rpc';

type CallerTypes = HandlerTypes<VaultsSecretsGet>;

const vaultsSecretsGet = new UnaryCaller<
const vaultsSecretsGet = new ServerCaller<
CallerTypes['input'],
CallerTypes['output']
>();
Expand Down
38 changes: 23 additions & 15 deletions src/client/handlers/VaultsSecretsGet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,32 @@ import type {
ClientRPCRequestParams,
ClientRPCResponseResult,
ContentMessage,
SecretIdentifierMessage,
SecretCatMessage,
} from '../types';
import type VaultManager from '../../vaults/VaultManager';
import { UnaryHandler } from '@matrixai/rpc';
import { ServerHandler } from '@matrixai/rpc';
import * as vaultsUtils from '../../vaults/utils';
import * as vaultsErrors from '../../vaults/errors';
import * as vaultOps from '../../vaults/VaultOps';

class VaultsSecretsGet extends UnaryHandler<
class VaultsSecretsGet extends ServerHandler<
{
vaultManager: VaultManager;
db: DB;
},
ClientRPCRequestParams<SecretIdentifierMessage>,
ClientRPCRequestParams<SecretCatMessage>,
ClientRPCResponseResult<ContentMessage>
> {
public handle = async (
input: ClientRPCRequestParams<SecretIdentifierMessage>,
): Promise<ClientRPCResponseResult<ContentMessage>> => {
public async *handle(
input: ClientRPCRequestParams<SecretCatMessage>,
): AsyncGenerator<ClientRPCResponseResult<ContentMessage>, void, void> {
const { vaultManager, db } = this.container;
return await db.withTransactionF(async (tran) => {

yield* db.withTransactionG(async function* (tran): AsyncGenerator<
ContentMessage,
void,
void
> {
const vaultIdFromName = await vaultManager.getVaultId(
input.nameOrId,
tran,
Expand All @@ -33,18 +38,21 @@ class VaultsSecretsGet extends UnaryHandler<
if (vaultId == null) {
throw new vaultsErrors.ErrorVaultsVaultUndefined();
}
const secretContent = await vaultManager.withVaults(
yield* vaultManager.withVaultsG(
[vaultId],
async (vault) => {
return await vaultOps.getSecret(vault, input.secretName);
async function* (vault): AsyncGenerator<ContentMessage, void, void> {
for (const secretName of input.secretNames) {
yield {
secretContent: (
await vaultOps.getSecret(vault, secretName)
).toString('binary'),
};
}
},
tran,
);
return {
secretContent: secretContent.toString('binary'),
};
});
};
}
}

export default VaultsSecretsGet;
5 changes: 5 additions & 0 deletions src/client/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,10 @@ type SecretPathMessage = {

type SecretIdentifierMessage = VaultIdentifierMessage & SecretPathMessage;

type SecretCatMessage = VaultIdentifierMessage & {
secretNames: Array<string>;
};

// Contains binary content as a binary string 'toString('binary')'
type ContentMessage = {
secretContent: string;
Expand Down Expand Up @@ -417,6 +421,7 @@ export type {
SecretPathMessage,
SecretIdentifierMessage,
ContentMessage,
SecretCatMessage,
SecretContentMessage,
SecretMkdirMessage,
SecretDirMessage,
Expand Down
52 changes: 42 additions & 10 deletions tests/client/handlers/vaults.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1449,26 +1449,58 @@ describe('vaultsSecretsNew and vaultsSecretsDelete, vaultsSecretsGet', () => {
});
expect(createResponse.success).toBeTruthy();
// Get secret
const getResponse1 = await rpcClient.methods.vaultsSecretsGet({
const getResponse = await rpcClient.methods.vaultsSecretsGet({
nameOrId: vaultIdEncoded,
secretName: secret,
secretNames: [secret],
});
const secretContent = getResponse1.secretContent;
expect(secretContent).toStrictEqual(secret);
const secretContent: Array<string> = [];
for await (const data of getResponse) {
secretContent.push(data.secretContent);
}
const concatenatedContent = secretContent.join('');
expect(concatenatedContent).toStrictEqual(secret);
// Delete secret
const deleteResponse = await rpcClient.methods.vaultsSecretsDelete({
nameOrId: vaultIdEncoded,
secretName: secret,
});
expect(deleteResponse.success).toBeTruthy();
// Check secret was deleted
await testsUtils.expectRemoteError(
rpcClient.methods.vaultsSecretsGet({
const deleteGetResponse = await rpcClient.methods.vaultsSecretsGet({
nameOrId: vaultIdEncoded,
secretNames: [secret],
});
await expect(async () => {
try {
for await (const _ of deleteGetResponse);
} catch (e) {
throw e.cause;
}
}).rejects.toThrow(vaultsErrors.ErrorSecretsSecretUndefined);
});
test('concatenates multiple secrets together', async () => {
// Create secret
const secretNames = ['test-secret1', 'test-secret2', 'test-secret3'];
const vaultId = await vaultManager.createVault('test-vault');
const vaultIdEncoded = vaultsUtils.encodeVaultId(vaultId);
for (const secretName of secretNames) {
const createResponse = await rpcClient.methods.vaultsSecretsNew({
nameOrId: vaultIdEncoded,
secretName: secret,
}),
vaultsErrors.ErrorSecretsSecretUndefined,
);
secretName: secretName,
secretContent: Buffer.from(secretName).toString('binary'),
});
expect(createResponse.success).toBeTruthy();
}
// Get secret
const getResponse = await rpcClient.methods.vaultsSecretsGet({
nameOrId: vaultIdEncoded,
secretNames: secretNames,
});
const secretContent: Array<string> = [];
for await (const data of getResponse) {
secretContent.push(data.secretContent);
}
expect(secretContent.join('')).toStrictEqual(secretNames.join(''));
});
});
describe('vaultsSecretsNewDir and vaultsSecretsList', () => {
Expand Down

0 comments on commit 69e9b36

Please sign in to comment.