Add frontend migration support for existing project to be blind-indexed

This commit is contained in:
Tuan Dang
2023-04-18 12:43:06 +03:00
parent b62ea41e02
commit acb90ee0f7
18 changed files with 212 additions and 138 deletions
@@ -15,7 +15,7 @@ import { UnauthorizedRequestError, ValidationError } from '../../utils/errors';
import { EventService } from '../../services';
import { eventPushSecrets } from '../../events';
import { EESecretService, EELogService } from '../../ee/services';
import { TelemetryService } from '../../services';
import { TelemetryService, SecretService } from '../../services';
import { getChannelFromUserAgent } from '../../utils/posthog';
import { PERMISSION_WRITE_SECRETS } from '../../variables';
import { userHasNoAbility, userHasWorkspaceAccess, userHasWriteOnlyAbility } from '../../ee/helpers/checkMembershipPermissions';
@@ -51,29 +51,47 @@ export const batchSecrets = async (req: Request, res: Response) => {
const updateSecrets: BatchSecret[] = [];
const deleteSecrets: Types.ObjectId[] = [];
const actions: IAction[] = [];
// get secret blind index salt
const salt = await SecretService.getSecretBlindIndexSalt({
workspaceId: new Types.ObjectId(workspaceId)
});
requests.forEach((request) => {
for await (const request of requests) {
let secretBlindIndex = '';
switch (request.method) {
case 'POST':
secretBlindIndex = await SecretService.generateSecretBlindIndexWithSalt({
secretName: request.secret.secretName,
salt
});
createSecrets.push({
...request.secret,
version: 1,
user: request.secret.type === SECRET_PERSONAL ? req.user : undefined,
environment,
workspace: new Types.ObjectId(workspaceId)
workspace: new Types.ObjectId(workspaceId),
secretBlindIndex
});
break;
case 'PATCH':
secretBlindIndex = await SecretService.generateSecretBlindIndexWithSalt({
secretName: request.secret.secretName,
salt
});
updateSecrets.push({
...request.secret,
_id: new Types.ObjectId(request.secret._id)
_id: new Types.ObjectId(request.secret._id),
secretBlindIndex
});
break;
case 'DELETE':
deleteSecrets.push(new Types.ObjectId(request.secret._id));
break;
}
});
}
// handle create secrets
let createdSecrets: ISecret[] = [];
@@ -134,7 +152,10 @@ export const batchSecrets = async (req: Request, res: Response) => {
const updateOperations = updateSecrets.map((u) => ({
updateOne: {
filter: { _id: new Types.ObjectId(u._id) },
filter: {
_id: new Types.ObjectId(u._id),
workspace: new Types.ObjectId(workspaceId)
},
update: {
$inc: {
version: 1
@@ -154,6 +175,7 @@ export const batchSecrets = async (req: Request, res: Response) => {
type: listedSecretsObj[u._id.toString()].type,
environment,
isDeleted: false,
secretBlindIndex: u.secretBlindIndex,
secretKeyCiphertext: u.secretKeyCiphertext,
secretKeyIV: u.secretKeyIV,
secretKeyTag: u.secretKeyTag,
@@ -1,11 +1,7 @@
import { Request, Response } from 'express';
import { Types } from 'mongoose';
import { Secret, Workspace, SecretBlindIndexData } from '../../models';
import { Secret } from '../../models';
import { SecretService } from'../../services';
import { BadRequestError } from '../../utils/errors';
import { decryptSymmetric } from '../../utils/crypto';
import { getEncryptionKey } from '../../config';
import * as argon2 from 'argon2';
/**
* Return whether or not all secrets in workspace with id [workspaceId]
@@ -18,12 +14,13 @@ export const getWorkspaceBlindIndexStatus = async (req: Request, res: Response)
const { workspaceId } = req.params;
const secretsWithoutBlindIndex = await Secret.countDocuments({
workspace: new Types.ObjectId(workspaceId)
workspace: new Types.ObjectId(workspaceId),
secretBlindIndex: {
$exists: false
}
});
const isBlindIndexed = secretsWithoutBlindIndex === 0;
return res.status(200).send(isBlindIndexed);
return res.status(200).send(secretsWithoutBlindIndex === 0);
}
/**
@@ -47,7 +44,6 @@ export const getWorkspaceSecrets = async (req: Request, res: Response) => {
* @param res
*/
export const nameWorkspaceSecrets = async (req: Request, res: Response) => {
interface SecretToUpdate {
secretName: string;
_id: string;
@@ -89,6 +85,6 @@ export const nameWorkspaceSecrets = async (req: Request, res: Response) => {
await Secret.bulkWrite(operations);
return res.status(200).send({
operations
message: 'Successfully named workspace secrets'
});
}