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