mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Fix commonjs import/export for patchRouterParam and make secret versioning/snapshots compatible with prev unversioned secrets
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import { patchRouterParam } from './utils/patchAsyncRoutes';
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const { patchRouterParam } = require('./utils/patchAsyncRoutes');
|
||||
|
||||
import express from 'express';
|
||||
import helmet from 'helmet';
|
||||
import cors from 'cors';
|
||||
@@ -6,7 +8,7 @@ import cookieParser from 'cookie-parser';
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
dotenv.config();
|
||||
import { PORT, NODE_ENV, SITE_URL, LICENSE_KEY } from './config';
|
||||
import { PORT, NODE_ENV, SITE_URL } from './config';
|
||||
import { apiLimiter } from './helpers/rateLimiter';
|
||||
|
||||
import {
|
||||
@@ -38,8 +40,8 @@ import { getLogger } from './utils/logger';
|
||||
import { RouteNotFoundError } from './utils/errors';
|
||||
import { requestErrorHandler } from './middleware/requestErrorHandler';
|
||||
|
||||
//* Patch Async route params to handle Promise Rejections
|
||||
patchRouterParam()
|
||||
// patch async route params to handle Promise Rejections
|
||||
patchRouterParam();
|
||||
|
||||
export const app = express();
|
||||
|
||||
|
||||
@@ -19,10 +19,8 @@ class EESecretService {
|
||||
* @param {String} obj.workspaceId
|
||||
*/
|
||||
static async takeSecretSnapshot({
|
||||
licenseKey,
|
||||
workspaceId
|
||||
}: {
|
||||
licenseKey: string;
|
||||
workspaceId: string;
|
||||
}) {
|
||||
if (!EELicenseService.isLicenseValid) return;
|
||||
|
||||
@@ -56,6 +56,7 @@ const pushSecrets = async ({
|
||||
environment: string;
|
||||
secrets: PushSecret[];
|
||||
}): Promise<void> => {
|
||||
// TODO: clean up function and fix up types
|
||||
try {
|
||||
// construct useful data structures
|
||||
const oldSecrets = await pullSecrets({
|
||||
@@ -63,10 +64,11 @@ const pushSecrets = async ({
|
||||
workspaceId,
|
||||
environment
|
||||
});
|
||||
|
||||
const oldSecretsObj: any = oldSecrets.reduce((accumulator, s: any) =>
|
||||
({ ...accumulator, [`${s.type}-${s.secretKeyHash}`]: s })
|
||||
, {});
|
||||
const newSecretsObj = secrets.reduce((accumulator, s) =>
|
||||
const newSecretsObj: any = secrets.reduce((accumulator, s) =>
|
||||
({ ...accumulator, [`${s.type}-${s.hashKey}`]: s })
|
||||
, {});
|
||||
|
||||
@@ -79,8 +81,6 @@ const pushSecrets = async ({
|
||||
if (toDelete.length > 0) {
|
||||
await Secret.deleteMany({
|
||||
_id: { $in: toDelete }
|
||||
}, {
|
||||
rawResult: true
|
||||
});
|
||||
|
||||
await SecretVersion.updateMany({
|
||||
@@ -89,31 +89,48 @@ const pushSecrets = async ({
|
||||
isDeleted: true
|
||||
});
|
||||
}
|
||||
|
||||
// handle modifying secrets where type or value changed
|
||||
const toUpdate = secrets
|
||||
|
||||
const toUpdate = oldSecrets
|
||||
.filter((s) => {
|
||||
if (`${s.type}-${s.hashKey}` in oldSecretsObj) {
|
||||
if (s.hashValue !== oldSecretsObj[`${s.type}-${s.hashKey}`].secretValueHash) {
|
||||
if (`${s.type}-${s.secretKeyHash}` in newSecretsObj) {
|
||||
if (s.secretValueHash !== newSecretsObj[`${s.type}-${s.secretKeyHash}`].hashValue) {
|
||||
// case: filter secrets where value changed
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!s.version) {
|
||||
// case: filter (legacy) secrets that were not versioned
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
const operations = toUpdate
|
||||
.map((s) => {
|
||||
const {
|
||||
ciphertextValue,
|
||||
ivValue,
|
||||
tagValue,
|
||||
hashValue
|
||||
} = newSecretsObj[`${s.type}-${s.secretKeyHash}`];
|
||||
|
||||
const update: Update = {
|
||||
secretValueCiphertext: s.ciphertextValue,
|
||||
secretValueIV: s.ivValue,
|
||||
secretValueTag: s.tagValue,
|
||||
secretValueHash: s.hashValue,
|
||||
$inc: {
|
||||
secretValueCiphertext: ciphertextValue,
|
||||
secretValueIV: ivValue,
|
||||
secretValueTag: tagValue,
|
||||
secretValueHash: hashValue
|
||||
}
|
||||
|
||||
if (!s.version) {
|
||||
// case: (legacy) secret was not versioned
|
||||
update.version = 1;
|
||||
} else {
|
||||
update['$inc'] = {
|
||||
version: 1
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (s.type === SECRET_PERSONAL) {
|
||||
// attach user associated with the personal secret
|
||||
@@ -123,7 +140,7 @@ const pushSecrets = async ({
|
||||
return {
|
||||
updateOne: {
|
||||
filter: {
|
||||
_id: oldSecretsObj[`${s.type}-${s.hashKey}`]._id
|
||||
_id: oldSecretsObj[`${s.type}-${s.secretKeyHash}`]._id
|
||||
},
|
||||
update
|
||||
}
|
||||
@@ -134,28 +151,26 @@ const pushSecrets = async ({
|
||||
// (EE) add secret versions for updated secrets
|
||||
await EESecretService.addSecretVersions({
|
||||
secretVersions: toUpdate.map(({
|
||||
_id,
|
||||
version,
|
||||
type,
|
||||
ciphertextKey,
|
||||
ivKey,
|
||||
tagKey,
|
||||
hashKey,
|
||||
ciphertextValue,
|
||||
ivValue,
|
||||
tagValue,
|
||||
hashValue
|
||||
}) => ({
|
||||
secret: oldSecretsObj[`${type}-${hashKey}`]._id,
|
||||
version: oldSecretsObj[`${type}-${hashKey}`].version + 1,
|
||||
isDeleted: false,
|
||||
secretKeyCiphertext: ciphertextKey,
|
||||
secretKeyIV: ivKey,
|
||||
secretKeyTag: tagKey,
|
||||
secretKeyHash: hashKey,
|
||||
secretValueCiphertext: ciphertextValue,
|
||||
secretValueIV: ivValue,
|
||||
secretValueTag: tagValue,
|
||||
secretValueHash: hashValue
|
||||
}))
|
||||
secretKeyHash,
|
||||
}) => {
|
||||
const newSecret = newSecretsObj[`${type}-${secretKeyHash}`];
|
||||
return ({
|
||||
secret: _id,
|
||||
version: version ? version + 1 : 1,
|
||||
isDeleted: false,
|
||||
secretKeyCiphertext: newSecret.ciphertextKey,
|
||||
secretKeyIV: newSecret.ivKey,
|
||||
secretKeyTag: newSecret.tagKey,
|
||||
secretKeyHash: newSecret.hashKey,
|
||||
secretValueCiphertext: newSecret.ciphertextValue,
|
||||
secretValueIV: newSecret.ivValue,
|
||||
secretValueTag: newSecret.tagValue,
|
||||
secretValueHash: newSecret.hashValue
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
// handle adding new secrets
|
||||
@@ -166,6 +181,7 @@ const pushSecrets = async ({
|
||||
const newSecrets = await Secret.insertMany(
|
||||
toAdd.map((s, idx) => {
|
||||
const obj: any = {
|
||||
version: 1,
|
||||
workspace: workspaceId,
|
||||
type: toAdd[idx].type,
|
||||
environment,
|
||||
@@ -217,7 +233,6 @@ const pushSecrets = async ({
|
||||
|
||||
// (EE) take a secret snapshot
|
||||
await EESecretService.takeSecretSnapshot({
|
||||
licenseKey: LICENSE_KEY,
|
||||
workspaceId
|
||||
})
|
||||
} catch (err) {
|
||||
|
||||
@@ -29,8 +29,7 @@ const secretSchema = new Schema<ISecret>(
|
||||
{
|
||||
version: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
required: true
|
||||
required: true
|
||||
},
|
||||
workspace: {
|
||||
type: Schema.Types.ObjectId,
|
||||
|
||||
@@ -45,7 +45,7 @@ function wrap(fn) {
|
||||
return copyFnProps(fn, newFn);
|
||||
}
|
||||
|
||||
export function patchRouterParam() {
|
||||
function patchRouterParam() {
|
||||
const originalParam = Router.prototype.constructor.param;
|
||||
Router.prototype.constructor.param = function param(name, fn) {
|
||||
fn = wrap(fn);
|
||||
@@ -62,4 +62,8 @@ Object.defineProperty(Layer.prototype, 'handle', {
|
||||
fn = wrap(fn);
|
||||
this.__handle = fn;
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
patchRouterParam
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user