mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-16 17:30:06 +00:00
Complete first iteration of CRUD secrets operations by name
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { Request, Response } from 'express';
|
||||
import { Types } from 'mongoose';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import { Bot, BotKey } from '../../models';
|
||||
import { createBot } from '../../helpers/bot';
|
||||
@@ -29,7 +30,7 @@ export const getBotByWorkspaceId = async (req: Request, res: Response) => {
|
||||
// -> create a new bot and return it
|
||||
bot = await createBot({
|
||||
name: 'Infisical Bot',
|
||||
workspaceId
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
@@ -2,7 +2,7 @@ import to from 'await-to-js';
|
||||
import { Types } from 'mongoose';
|
||||
import { Request, Response } from 'express';
|
||||
import { ISecret, Secret } from '../../models';
|
||||
import { IAction } from '../../ee/models';
|
||||
import { IAction, SecretVersion } from '../../ee/models';
|
||||
import {
|
||||
SECRET_PERSONAL,
|
||||
SECRET_SHARED,
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
* @param res
|
||||
*/
|
||||
export const batchSecrets = async (req: Request, res: Response) => {
|
||||
|
||||
const channel = getChannelFromUserAgent(req.headers['user-agent']);
|
||||
const postHogClient = TelemetryService.getPostHogClient();
|
||||
|
||||
@@ -146,7 +147,7 @@ export const batchSecrets = async (req: Request, res: Response) => {
|
||||
|
||||
await Secret.bulkWrite(updateOperations);
|
||||
|
||||
const secretVersions = updateSecrets.map((u) => ({
|
||||
const secretVersions = updateSecrets.map((u) => new SecretVersion({
|
||||
secret: new Types.ObjectId(u._id),
|
||||
version: listedSecretsObj[u._id.toString()].version,
|
||||
workspace: new Types.ObjectId(workspaceId),
|
||||
@@ -253,7 +254,7 @@ export const batchSecrets = async (req: Request, res: Response) => {
|
||||
|
||||
// (EE) take a secret snapshot
|
||||
await EESecretService.takeSecretSnapshot({
|
||||
workspaceId
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
});
|
||||
|
||||
const resObj: { [key: string]: ISecret[] | string[] } = {}
|
||||
@@ -422,13 +423,8 @@ export const createSecrets = async (req: Request, res: Response) => {
|
||||
secretKeyTag,
|
||||
secretValueCiphertext,
|
||||
secretValueIV,
|
||||
secretValueTag,
|
||||
secretCommentCiphertext,
|
||||
secretCommentIV,
|
||||
secretCommentTag,
|
||||
tags
|
||||
}) => ({
|
||||
_id: new Types.ObjectId(),
|
||||
secretValueTag
|
||||
}) => new SecretVersion({
|
||||
secret: _id,
|
||||
version,
|
||||
workspace,
|
||||
@@ -441,11 +437,7 @@ export const createSecrets = async (req: Request, res: Response) => {
|
||||
secretKeyTag,
|
||||
secretValueCiphertext,
|
||||
secretValueIV,
|
||||
secretValueTag,
|
||||
secretCommentCiphertext,
|
||||
secretCommentIV,
|
||||
secretCommentTag,
|
||||
tags
|
||||
secretValueTag
|
||||
}))
|
||||
});
|
||||
|
||||
@@ -471,7 +463,7 @@ export const createSecrets = async (req: Request, res: Response) => {
|
||||
|
||||
// (EE) take a secret snapshot
|
||||
await EESecretService.takeSecretSnapshot({
|
||||
workspaceId
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
});
|
||||
|
||||
const postHogClient = TelemetryService.getPostHogClient();
|
||||
@@ -872,7 +864,7 @@ export const updateSecrets = async (req: Request, res: Response) => {
|
||||
|
||||
// (EE) take a secret snapshot
|
||||
await EESecretService.takeSecretSnapshot({
|
||||
workspaceId: key
|
||||
workspaceId: new Types.ObjectId(key)
|
||||
})
|
||||
|
||||
const postHogClient = TelemetryService.getPostHogClient();
|
||||
@@ -955,10 +947,6 @@ export const deleteSecrets = async (req: Request, res: Response) => {
|
||||
}
|
||||
*/
|
||||
|
||||
return res.status(200).send({
|
||||
message: 'delete secrets!!'
|
||||
});
|
||||
|
||||
const channel = getChannelFromUserAgent(req.headers['user-agent'])
|
||||
const toDelete = req.secrets.map((s: any) => s._id);
|
||||
|
||||
@@ -1012,8 +1000,8 @@ export const deleteSecrets = async (req: Request, res: Response) => {
|
||||
|
||||
// (EE) take a secret snapshot
|
||||
await EESecretService.takeSecretSnapshot({
|
||||
workspaceId: key
|
||||
})
|
||||
workspaceId: new Types.ObjectId(key)
|
||||
});
|
||||
|
||||
const postHogClient = TelemetryService.getPostHogClient();
|
||||
if (postHogClient) {
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
import { Request, Response } from 'express';
|
||||
import { Types } from 'mongoose';
|
||||
import {
|
||||
Secret
|
||||
} from '../../models';
|
||||
import crypto from 'crypto';
|
||||
import { SecretService } from '../../services';
|
||||
|
||||
|
||||
// TODO: modularize argon2id
|
||||
import * as argon2 from 'argon2';
|
||||
import { SecretService, TelemetryService } from '../../services';
|
||||
import { getAuthDataPayloadIdObj } from '../../utils/auth';
|
||||
import { BadRequestError } from '../../utils/errors';
|
||||
|
||||
/**
|
||||
* Get secrets for workspace with id [workspaceId] and environment
|
||||
@@ -17,41 +11,92 @@ import * as argon2 from 'argon2';
|
||||
* @param res
|
||||
*/
|
||||
export const getSecrets = async (req: Request, res: Response) => {
|
||||
return res.status(200).send({
|
||||
const workspaceId = req.query.workspaceId as string;
|
||||
const environment = req.query.environment as string;
|
||||
|
||||
const secrets = await SecretService.getSecrets({
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
environment,
|
||||
authData: req.authData
|
||||
});
|
||||
|
||||
const postHogClient = TelemetryService.getPostHogClient();
|
||||
if (postHogClient) {
|
||||
postHogClient.capture({
|
||||
event: 'secrets pulled',
|
||||
distinctId: TelemetryService.getDistinctId({
|
||||
user: req.user,
|
||||
serviceAccount: req.serviceAccount,
|
||||
serviceTokenData: req.serviceTokenData
|
||||
}),
|
||||
properties: {
|
||||
numberOfSecrets: secrets.length,
|
||||
environment,
|
||||
workspaceId,
|
||||
channel: req.authData.authChannel,
|
||||
userAgent: req.headers?.['user-agent']
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return res.status(200).send({
|
||||
secrets
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return secret with name [secretName] for workspace with id [workspaceId]
|
||||
* and environment [environment]
|
||||
* Get secret with name [secretName]
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
export const getSecretByName = async (req: Request, res: Response) => {
|
||||
const { secretName } = req.params;
|
||||
const workspaceId = req.query.workspaceId as string;
|
||||
const environment = req.query.workspaceId as string;
|
||||
const environment = req.query.environment as string;
|
||||
const type = req.query.type as 'shared' | 'personal' | undefined;
|
||||
|
||||
const secret = await SecretService.getSecret({
|
||||
secretName,
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
environment,
|
||||
type,
|
||||
authData: req.authData
|
||||
});
|
||||
|
||||
const postHogClient = TelemetryService.getPostHogClient();
|
||||
if (postHogClient) {
|
||||
postHogClient.capture({
|
||||
event: 'secrets pull',
|
||||
distinctId: TelemetryService.getDistinctId({
|
||||
user: req.user,
|
||||
serviceAccount: req.serviceAccount,
|
||||
serviceTokenData: req.serviceTokenData
|
||||
}),
|
||||
properties: {
|
||||
numberOfSecrets: 1,
|
||||
environment,
|
||||
workspaceId,
|
||||
channel: req.authData.authChannel,
|
||||
userAgent: req.headers?.['user-agent']
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return res.status(200).send({
|
||||
|
||||
secret
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Create secret for workspace with id [workspaceId] and
|
||||
* environment [environment]
|
||||
* Create secret with name [secretName]
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
export const createSecret = async (req: Request, res: Response) => {
|
||||
// TODO: the middleware should've prevalidated that the
|
||||
// workspace with id [workspaceId] has disabled E2EE
|
||||
const { secretName } = req.params;
|
||||
const {
|
||||
workspaceId,
|
||||
environment,
|
||||
value,
|
||||
type,
|
||||
secretKeyCiphertext,
|
||||
secretKeyIV,
|
||||
@@ -61,66 +106,140 @@ export const createSecret = async (req: Request, res: Response) => {
|
||||
secretValueTag
|
||||
} = req.body;
|
||||
|
||||
const secretBlindIndex = await SecretService.createSecretBlindIndex({
|
||||
const secret = await SecretService.createSecret({
|
||||
secretName,
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
workspaceId: new Types.ObjectId(workspaceId),
|
||||
environment,
|
||||
type,
|
||||
authData: req.authData,
|
||||
secretKeyCiphertext,
|
||||
secretKeyIV,
|
||||
secretKeyTag,
|
||||
secretValueCiphertext,
|
||||
secretValueIV,
|
||||
secretValueTag
|
||||
});
|
||||
|
||||
// // use workspace salt
|
||||
// const randomBytes = crypto.randomBytes(16);
|
||||
|
||||
// // generate blind index
|
||||
// // TODO 1: abstract away into create blind index function
|
||||
// // TODO 2: create a get blind index function
|
||||
// const secretBlindIndex = (await argon2.hash(secretName, {
|
||||
// type: argon2.argon2id,
|
||||
// salt: randomBytes,
|
||||
// saltLength: 16, // default 16 bytes
|
||||
// memoryCost: 65536, // default pool of 64 MiB per thread.
|
||||
// hashLength: 32,
|
||||
// parallelism: 1,
|
||||
// raw: true
|
||||
// })).toString('base64');
|
||||
|
||||
// const secret = await new Secret({
|
||||
// workspace: new Types.ObjectId(workspaceId),
|
||||
// environment,
|
||||
// type,
|
||||
// secretBlindIndex,
|
||||
// secretKeyCiphertext,
|
||||
// secretKeyIV,
|
||||
// secretKeyTag,
|
||||
// secretValueCiphertext,
|
||||
// secretValueIV,
|
||||
// secretValueTag
|
||||
// }).save();
|
||||
|
||||
const postHogClient = TelemetryService.getPostHogClient();
|
||||
if (postHogClient) {
|
||||
postHogClient.capture({
|
||||
event: 'secrets added',
|
||||
distinctId: TelemetryService.getDistinctId({
|
||||
user: req.user,
|
||||
serviceAccount: req.serviceAccount,
|
||||
serviceTokenData: req.serviceTokenData
|
||||
}),
|
||||
properties: {
|
||||
numberOfSecrets: 1,
|
||||
environment,
|
||||
workspaceId,
|
||||
channel: req.authData.authChannel,
|
||||
userAgent: req.headers?.['user-agent']
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const secretWithoutBlindIndex = secret.toObject();
|
||||
delete secretWithoutBlindIndex.secretBlindIndex;
|
||||
|
||||
return res.status(200).send({
|
||||
|
||||
secret: secretWithoutBlindIndex
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update secret with name [secretName] in workspace with id [workspaceId]
|
||||
* Update secret with name [secretName]
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
export const updateSecretByName = async (req: Request, res: Response) => {
|
||||
const { secretName } = req.params;
|
||||
const {
|
||||
workspaceId,
|
||||
environment,
|
||||
type,
|
||||
secretValueCiphertext,
|
||||
secretValueIV,
|
||||
secretValueTag
|
||||
} = req.body;
|
||||
|
||||
const secret = await SecretService.updateSecret({
|
||||
secretName,
|
||||
workspaceId,
|
||||
environment,
|
||||
type,
|
||||
authData: req.authData,
|
||||
secretValueCiphertext,
|
||||
secretValueIV,
|
||||
secretValueTag
|
||||
});
|
||||
|
||||
|
||||
const postHogClient = TelemetryService.getPostHogClient();
|
||||
if (postHogClient) {
|
||||
postHogClient.capture({
|
||||
event: 'secrets modified',
|
||||
distinctId: TelemetryService.getDistinctId({
|
||||
user: req.user,
|
||||
serviceAccount: req.serviceAccount,
|
||||
serviceTokenData: req.serviceTokenData
|
||||
}),
|
||||
properties: {
|
||||
numberOfSecrets: 1,
|
||||
environment,
|
||||
workspaceId,
|
||||
channel: req.authData.authChannel,
|
||||
userAgent: req.headers?.['user-agent']
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return res.status(200).send({
|
||||
|
||||
secret
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete secret with name [secretName] in workspace with id [workspaceId]
|
||||
* Delete secret with name [secretName]
|
||||
* @param req
|
||||
* @param res
|
||||
*/
|
||||
export const deleteSecretByName = async (req: Request, res: Response) => {
|
||||
const { secretName } = req.params;
|
||||
const {
|
||||
workspaceId,
|
||||
environment,
|
||||
type
|
||||
} = req.body;
|
||||
|
||||
const { secret, secrets } = await SecretService.deleteSecret({
|
||||
secretName,
|
||||
workspaceId,
|
||||
environment,
|
||||
type,
|
||||
authData: req.authData
|
||||
});
|
||||
|
||||
const postHogClient = TelemetryService.getPostHogClient();
|
||||
if (postHogClient) {
|
||||
postHogClient.capture({
|
||||
event: 'secrets deleted',
|
||||
distinctId: TelemetryService.getDistinctId({
|
||||
user: req.user,
|
||||
serviceAccount: req.serviceAccount,
|
||||
serviceTokenData: req.serviceTokenData
|
||||
}),
|
||||
properties: {
|
||||
numberOfSecrets: secrets.length,
|
||||
environment,
|
||||
workspaceId,
|
||||
channel: req.authData.authChannel,
|
||||
userAgent: req.headers?.['user-agent']
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return res.status(200).send({
|
||||
|
||||
secret
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user