mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-16 17:30:06 +00:00
Enable all auth clients for secrets v3, remove serviceTokenData .populate in middleware, make secret versions and rollbacks compatible with blind indexing
This commit is contained in:
@@ -8,6 +8,8 @@ import { BadRequestError, InternalServerError, UnauthorizedRequestError, Validat
|
||||
import { AnyBulkWriteOperation } from 'mongodb';
|
||||
import { SECRET_PERSONAL, SECRET_SHARED } from "../../variables";
|
||||
import { TelemetryService } from '../../services';
|
||||
import { User } from "../../models";
|
||||
import { AccountNotFoundError } from '../../utils/errors';
|
||||
|
||||
/**
|
||||
* Create secret for workspace with id [workspaceId] and environment [environment]
|
||||
@@ -340,15 +342,18 @@ export const getSecrets = async (req: Request, res: Response) => {
|
||||
const { workspaceId } = req.params;
|
||||
|
||||
let userId: Types.ObjectId | undefined = undefined // used for getting personal secrets for user
|
||||
let userEmail: Types.ObjectId | undefined = undefined // used for posthog
|
||||
let userEmail: string | undefined = undefined // used for posthog
|
||||
if (req.user) {
|
||||
userId = req.user._id;
|
||||
userEmail = req.user.email;
|
||||
}
|
||||
|
||||
if (req.serviceTokenData) {
|
||||
userId = req.serviceTokenData.user._id
|
||||
userEmail = req.serviceTokenData.user.email;
|
||||
userId = req.serviceTokenData.user;
|
||||
|
||||
const user = await User.findById(req.serviceTokenData.user, 'email');
|
||||
if (!user) throw AccountNotFoundError();
|
||||
userEmail = user.email;
|
||||
}
|
||||
|
||||
const [err, secrets] = await to(Secret.find(
|
||||
|
||||
@@ -374,8 +374,14 @@ export const createSecrets = async (req: Request, res: Response) => {
|
||||
listOfSecretsToCreate = [req.body.secrets];
|
||||
}
|
||||
|
||||
// get secret blind index salt
|
||||
const salt = await SecretService.getSecretBlindIndexSalt({
|
||||
workspaceId: new Types.ObjectId(workspaceId)
|
||||
});
|
||||
|
||||
type secretsToCreateType = {
|
||||
type: string;
|
||||
secretName?: string;
|
||||
secretKeyCiphertext: string;
|
||||
secretKeyIV: string;
|
||||
secretKeyTag: string;
|
||||
@@ -388,25 +394,10 @@ export const createSecrets = async (req: Request, res: Response) => {
|
||||
tags: string[]
|
||||
}
|
||||
|
||||
const secretsToInsert: ISecret[] = listOfSecretsToCreate.map(({
|
||||
type,
|
||||
secretKeyCiphertext,
|
||||
secretKeyIV,
|
||||
secretKeyTag,
|
||||
secretValueCiphertext,
|
||||
secretValueIV,
|
||||
secretValueTag,
|
||||
secretCommentCiphertext,
|
||||
secretCommentIV,
|
||||
secretCommentTag,
|
||||
tags
|
||||
}: secretsToCreateType) => {
|
||||
return ({
|
||||
version: 1,
|
||||
workspace: new Types.ObjectId(workspaceId),
|
||||
const secretsToInsert: ISecret[] = await Promise.all(
|
||||
listOfSecretsToCreate.map(async ({
|
||||
type,
|
||||
user: (req.user && type === SECRET_PERSONAL) ? req.user : undefined,
|
||||
environment,
|
||||
secretName,
|
||||
secretKeyCiphertext,
|
||||
secretKeyIV,
|
||||
secretKeyTag,
|
||||
@@ -417,11 +408,38 @@ export const createSecrets = async (req: Request, res: Response) => {
|
||||
secretCommentIV,
|
||||
secretCommentTag,
|
||||
tags
|
||||
});
|
||||
});
|
||||
}: secretsToCreateType) => {
|
||||
let secretBlindIndex;
|
||||
if (secretName) {
|
||||
secretBlindIndex = await SecretService.generateSecretBlindIndexWithSalt({
|
||||
secretName,
|
||||
salt
|
||||
});
|
||||
}
|
||||
|
||||
return ({
|
||||
version: 1,
|
||||
workspace: new Types.ObjectId(workspaceId),
|
||||
type,
|
||||
...(secretBlindIndex ? { secretBlindIndex } : {}),
|
||||
user: (req.user && type === SECRET_PERSONAL) ? req.user : undefined,
|
||||
environment,
|
||||
secretKeyCiphertext,
|
||||
secretKeyIV,
|
||||
secretKeyTag,
|
||||
secretValueCiphertext,
|
||||
secretValueIV,
|
||||
secretValueTag,
|
||||
secretCommentCiphertext,
|
||||
secretCommentIV,
|
||||
secretCommentTag,
|
||||
tags
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
const newlyCreatedSecrets: ISecret[] = (await Secret.insertMany(secretsToInsert)).map((insertedSecret) => insertedSecret.toObject());
|
||||
|
||||
|
||||
setTimeout(async () => {
|
||||
// trigger event - push secrets
|
||||
await EventService.handleEvent({
|
||||
@@ -440,6 +458,7 @@ export const createSecrets = async (req: Request, res: Response) => {
|
||||
type,
|
||||
user,
|
||||
environment,
|
||||
secretBlindIndex,
|
||||
secretKeyCiphertext,
|
||||
secretKeyIV,
|
||||
secretKeyTag,
|
||||
@@ -453,6 +472,7 @@ export const createSecrets = async (req: Request, res: Response) => {
|
||||
type,
|
||||
user,
|
||||
environment,
|
||||
secretBlindIndex,
|
||||
isDeleted: false,
|
||||
secretKeyCiphertext,
|
||||
secretKeyIV,
|
||||
@@ -492,7 +512,7 @@ export const createSecrets = async (req: Request, res: Response) => {
|
||||
if (postHogClient) {
|
||||
postHogClient.capture({
|
||||
event: 'secrets added',
|
||||
distinctId: TelemetryService.getDistinctId({
|
||||
distinctId: await TelemetryService.getDistinctId({
|
||||
authData: req.authData
|
||||
}),
|
||||
properties: {
|
||||
@@ -607,7 +627,7 @@ export const getSecrets = async (req: Request, res: Response) => {
|
||||
|
||||
// case: client authorization is via service token
|
||||
if (req.serviceTokenData) {
|
||||
const userId = req.serviceTokenData.user._id
|
||||
const userId = req.serviceTokenData.user;
|
||||
|
||||
const secretQuery: any = {
|
||||
workspace: workspaceId,
|
||||
@@ -667,7 +687,7 @@ export const getSecrets = async (req: Request, res: Response) => {
|
||||
if (postHogClient) {
|
||||
postHogClient.capture({
|
||||
event: 'secrets pulled',
|
||||
distinctId: TelemetryService.getDistinctId({
|
||||
distinctId: await TelemetryService.getDistinctId({
|
||||
authData: req.authData
|
||||
}),
|
||||
properties: {
|
||||
@@ -889,7 +909,7 @@ export const updateSecrets = async (req: Request, res: Response) => {
|
||||
if (postHogClient) {
|
||||
postHogClient.capture({
|
||||
event: 'secrets modified',
|
||||
distinctId: TelemetryService.getDistinctId({
|
||||
distinctId: await TelemetryService.getDistinctId({
|
||||
authData: req.authData
|
||||
}),
|
||||
properties: {
|
||||
@@ -1023,7 +1043,7 @@ export const deleteSecrets = async (req: Request, res: Response) => {
|
||||
if (postHogClient) {
|
||||
postHogClient.capture({
|
||||
event: 'secrets deleted',
|
||||
distinctId: TelemetryService.getDistinctId({
|
||||
distinctId: await TelemetryService.getDistinctId({
|
||||
authData: req.authData
|
||||
}),
|
||||
properties: {
|
||||
|
||||
@@ -11,9 +11,11 @@ import { userHasWorkspaceAccess } from '../../ee/helpers/checkMembershipPermissi
|
||||
import {
|
||||
PERMISSION_READ_SECRETS,
|
||||
AUTH_MODE_JWT,
|
||||
AUTH_MODE_SERVICE_ACCOUNT
|
||||
AUTH_MODE_SERVICE_ACCOUNT,
|
||||
AUTH_MODE_SERVICE_TOKEN
|
||||
} from '../../variables';
|
||||
import { getSaltRounds } from '../../config';
|
||||
import { BadRequestError } from '../../utils/errors';
|
||||
|
||||
/**
|
||||
* Return service token data associated with service token on request
|
||||
@@ -48,7 +50,15 @@ export const getServiceTokenData = async (req: Request, res: Response) => {
|
||||
}
|
||||
*/
|
||||
|
||||
return res.status(200).json(req.serviceTokenData);
|
||||
if (!(req.authData.authPayload instanceof ServiceTokenData)) throw BadRequestError({
|
||||
message: 'Failed accepted client validation for service token data'
|
||||
});
|
||||
|
||||
const serviceTokenData = await ServiceTokenData
|
||||
.findById(req.authData.authPayload._id)
|
||||
.populate('user');
|
||||
|
||||
return res.status(200).json(serviceTokenData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -132,7 +132,7 @@ export const pullSecrets = async (req: Request, res: Response) => {
|
||||
if (req.user) {
|
||||
userId = req.user._id.toString();
|
||||
} else if (req.serviceTokenData) {
|
||||
userId = req.serviceTokenData.user._id
|
||||
userId = req.serviceTokenData.user.toString();
|
||||
}
|
||||
// validate environment
|
||||
const workspaceEnvs = req.membership.workspace.environments;
|
||||
|
||||
@@ -70,7 +70,10 @@ export const createSecret = async (req: Request, res: Response) => {
|
||||
secretKeyTag,
|
||||
secretValueCiphertext,
|
||||
secretValueIV,
|
||||
secretValueTag
|
||||
secretValueTag,
|
||||
secretCommentCiphertext,
|
||||
secretCommentIV,
|
||||
secretCommentTag
|
||||
} = req.body;
|
||||
|
||||
const secret = await SecretService.createSecret({
|
||||
@@ -84,7 +87,12 @@ export const createSecret = async (req: Request, res: Response) => {
|
||||
secretKeyTag,
|
||||
secretValueCiphertext,
|
||||
secretValueIV,
|
||||
secretValueTag
|
||||
secretValueTag,
|
||||
...((secretCommentCiphertext && secretCommentIV && secretCommentTag) ? {
|
||||
secretCommentCiphertext,
|
||||
secretCommentIV,
|
||||
secretCommentTag
|
||||
} : {})
|
||||
});
|
||||
|
||||
await EventService.handleEvent({
|
||||
|
||||
Reference in New Issue
Block a user