Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: merge staging to master #812

Merged
merged 2 commits into from
Sep 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 { DuplexCaller } from '@matrixai/rpc';

type CallerTypes = HandlerTypes<VaultsSecretsGet>;

const vaultsSecretsGet = new UnaryCaller<
const vaultsSecretsGet = new DuplexCaller<
CallerTypes['input'],
CallerTypes['output']
>();
Expand Down
4 changes: 2 additions & 2 deletions src/client/callers/vaultsSecretsRemove.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { HandlerTypes } from '@matrixai/rpc';
import type VaultsSecretsRemove from '../handlers/VaultsSecretsRemove';
import { UnaryCaller } from '@matrixai/rpc';
import { ClientCaller } from '@matrixai/rpc';

type CallerTypes = HandlerTypes<VaultsSecretsRemove>;

const vaultsSecretsRemove = new UnaryCaller<
const vaultsSecretsRemove = new ClientCaller<
CallerTypes['input'],
CallerTypes['output']
>();
Expand Down
76 changes: 50 additions & 26 deletions src/client/handlers/VaultsSecretsGet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,71 @@ import type { DB } from '@matrixai/db';
import type {
ClientRPCRequestParams,
ClientRPCResponseResult,
ContentMessage,
ContentWithErrorMessage,
SecretIdentifierMessage,
} from '../types';
import type VaultManager from '../../vaults/VaultManager';
import { UnaryHandler } from '@matrixai/rpc';
import { DuplexHandler } 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 DuplexHandler<
{
vaultManager: VaultManager;
db: DB;
},
ClientRPCRequestParams<SecretIdentifierMessage>,
ClientRPCResponseResult<ContentMessage>
ClientRPCResponseResult<ContentWithErrorMessage>
> {
public handle = async (
input: ClientRPCRequestParams<SecretIdentifierMessage>,
): Promise<ClientRPCResponseResult<ContentMessage>> => {
public handle = async function* (
input: AsyncIterable<ClientRPCRequestParams<SecretIdentifierMessage>>,
_cancel,
_meta,
ctx,
): AsyncGenerator<ClientRPCResponseResult<ContentWithErrorMessage>> {
if (ctx.signal.aborted) throw ctx.signal.reason;
const { vaultManager, db } = this.container;
return await db.withTransactionF(async (tran) => {
const vaultIdFromName = await vaultManager.getVaultId(
input.nameOrId,
tran,
);
const vaultId =
vaultIdFromName ?? vaultsUtils.decodeVaultId(input.nameOrId);
if (vaultId == null) {
throw new vaultsErrors.ErrorVaultsVaultUndefined();
yield* db.withTransactionG(async function* (tran): AsyncGenerator<
ClientRPCResponseResult<ContentWithErrorMessage>
> {
if (ctx.signal.aborted) throw ctx.signal.reason;
// As we need to preserve the order of parameters, we need to loop over
// them individually, as grouping them would make them go out of order.
let metadata: any = undefined;
for await (const secretIdentiferMessage of input) {
if (ctx.signal.aborted) throw ctx.signal.reason;
if (metadata == null) metadata = secretIdentiferMessage.metadata ?? {};
const { nameOrId, secretName } = secretIdentiferMessage;
const vaultIdFromName = await vaultManager.getVaultId(nameOrId, tran);
const vaultId = vaultIdFromName ?? vaultsUtils.decodeVaultId(nameOrId);
if (vaultId == null) throw new vaultsErrors.ErrorVaultsVaultUndefined();
yield await vaultManager.withVaults(
[vaultId],
async (vault) => {
try {
const content = await vaultOps.getSecret(vault, secretName);
return { secretContent: content.toString('binary') };
} catch (e) {
if (metadata?.options?.continueOnError === true) {
if (e instanceof vaultsErrors.ErrorSecretsSecretUndefined) {
return {
secretContent: '',
error: `${e.name}: ${secretName}: No such secret or directory\n`,
};
} else if (e instanceof vaultsErrors.ErrorSecretsIsDirectory) {
return {
secretContent: '',
error: `${e.name}: ${secretName}: Is a directory\n`,
};
}
}
throw e;
}
},
tran,
);
}
const secretContent = await vaultManager.withVaults(
[vaultId],
async (vault) => {
return await vaultOps.getSecret(vault, input.secretName);
},
tran,
);
return {
secretContent: secretContent.toString('binary'),
};
});
};
}
Expand Down
26 changes: 18 additions & 8 deletions src/client/handlers/VaultsSecretsRemove.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,44 @@ import type {
ClientRPCRequestParams,
ClientRPCResponseResult,
SuccessMessage,
SecretRemoveMessage,
SecretIdentifierMessage,
} from '../types';
import type VaultManager from '../../vaults/VaultManager';
import { UnaryHandler } from '@matrixai/rpc';
import { ClientHandler } from '@matrixai/rpc';
import * as vaultsUtils from '../../vaults/utils';
import * as vaultsErrors from '../../vaults/errors';
import * as vaultOps from '../../vaults/VaultOps';

class VaultsSecretsRemove extends UnaryHandler<
class VaultsSecretsRemove extends ClientHandler<
{
vaultManager: VaultManager;
db: DB;
},
ClientRPCRequestParams<SecretRemoveMessage>,
ClientRPCRequestParams<SecretIdentifierMessage>,
ClientRPCResponseResult<SuccessMessage>
> {
public handle = async (
input: ClientRPCRequestParams<SecretRemoveMessage>,
input: AsyncIterable<ClientRPCRequestParams<SecretIdentifierMessage>>,
): Promise<ClientRPCResponseResult<SuccessMessage>> => {
const { vaultManager, db } = this.container;
// Create a record of secrets to be removed, grouped by vault names
const vaultGroups: Record<string, string[]> = {};
input.secretNames.forEach(([vaultName, secretName]) => {
const vaultGroups: Record<string, Array<string>> = {};
const secretNames: Array<[string, string]> = [];
let metadata: any = undefined;
for await (const secretRemoveMessage of input) {
if (metadata == null) metadata = secretRemoveMessage.metadata ?? {};
secretNames.push([
secretRemoveMessage.nameOrId,
secretRemoveMessage.secretName,
]);
}
secretNames.forEach(([vaultName, secretName]) => {
if (vaultGroups[vaultName] == null) {
vaultGroups[vaultName] = [];
}
vaultGroups[vaultName].push(secretName);
});

await db.withTransactionF(async (tran) => {
for (const [vaultName, secretNames] of Object.entries(vaultGroups)) {
const vaultIdFromName = await vaultManager.getVaultId(vaultName, tran);
Expand All @@ -40,7 +50,7 @@ class VaultsSecretsRemove extends UnaryHandler<
[vaultId],
async (vault) => {
await vaultOps.deleteSecret(vault, secretNames, {
recursive: input.options?.recursive,
recursive: metadata?.options?.recursive,
});
},
tran,
Expand Down
13 changes: 5 additions & 8 deletions src/client/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,18 +306,15 @@ type SecretPathMessage = {

type SecretIdentifierMessage = VaultIdentifierMessage & SecretPathMessage;

type SecretRemoveMessage = {
secretNames: Array<Array<string>>;
options?: {
recursive?: boolean;
};
};

// Contains binary content as a binary string 'toString('binary')'
type ContentMessage = {
secretContent: string;
};

type ContentWithErrorMessage = ContentMessage & {
error?: string;
};

type SecretContentMessage = SecretIdentifierMessage & ContentMessage;

type SecretMkdirMessage = VaultIdentifierMessage & {
Expand Down Expand Up @@ -423,8 +420,8 @@ export type {
VaultsLatestVersionMessage,
SecretPathMessage,
SecretIdentifierMessage,
SecretRemoveMessage,
ContentMessage,
ContentWithErrorMessage,
SecretContentMessage,
SecretMkdirMessage,
SecretDirMessage,
Expand Down
Loading