upgrade major version of mongoose from v6 to v7

This commit is contained in:
Maidul Islam
2023-08-01 13:24:38 -04:00
parent 941a8699b5
commit 9df51424a2
8 changed files with 605 additions and 437 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -30,7 +30,8 @@
"jsrp": "^0.2.4", "jsrp": "^0.2.4",
"libsodium-wrappers": "^0.7.10", "libsodium-wrappers": "^0.7.10",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"mongoose": "^6.10.5", "mongodb": "^5.7.0",
"mongoose": "^7.4.1",
"nanoid": "^3.3.6", "nanoid": "^3.3.6",
"node-cache": "^5.1.2", "node-cache": "^5.1.2",
"nodemailer": "^6.8.0", "nodemailer": "^6.8.0",

View File

@@ -72,7 +72,8 @@ export const deleteWebhook = async (req: Request, res: Response) => {
workspaceId: webhook.workspace, workspaceId: webhook.workspace,
acceptedRoles: [ADMIN, MEMBER] acceptedRoles: [ADMIN, MEMBER]
}); });
await webhook.remove();
await webhook.deleteOne();
return res.status(200).send({ return res.status(200).send({
message: "successfully removed webhook" message: "successfully removed webhook"

View File

@@ -309,16 +309,16 @@ export const updateSecret = async (req: Request, res: Response) => {
{ _id: secretModificationsRequested._id, workspace: workspaceId }, { _id: secretModificationsRequested._id, workspace: workspaceId },
{ $inc: { version: 1 }, $set: sanitizedSecret } { $inc: { version: 1 }, $set: sanitizedSecret }
) )
.catch((error) => { .catch((error) => {
if (error instanceof ValidationError) { if (error instanceof ValidationError) {
throw RouteValidationError({ throw RouteValidationError({
message: "Unable to apply modifications, please try again", message: "Unable to apply modifications, please try again",
stack: error.stack stack: error.stack
}); });
} }
throw error; throw error;
}); });
if (postHogClient) { if (postHogClient) {
postHogClient.capture({ postHogClient.capture({
@@ -370,12 +370,12 @@ export const getSecrets = async (req: Request, res: Response) => {
$or: [{ user: userId }, { user: { $exists: false } }], $or: [{ user: userId }, { user: { $exists: false } }],
type: { $in: [SECRET_SHARED, SECRET_PERSONAL] } type: { $in: [SECRET_SHARED, SECRET_PERSONAL] }
}) })
.catch((err) => { .catch((err) => {
throw RouteValidationError({ throw RouteValidationError({
message: "Failed to get secrets, please try again", message: "Failed to get secrets, please try again",
stack: err.stack stack: err.stack
}); });
}) })
if (postHogClient) { if (postHogClient) {
postHogClient.capture({ postHogClient.capture({

View File

@@ -2,7 +2,7 @@ import { Request, Response } from "express";
import { Types } from "mongoose"; import { Types } from "mongoose";
import crypto from "crypto"; import crypto from "crypto";
import bcrypt from "bcrypt"; import bcrypt from "bcrypt";
import { import {
ServiceAccount, ServiceAccount,
ServiceAccountKey, ServiceAccountKey,
ServiceAccountOrganizationPermission, ServiceAccountOrganizationPermission,
@@ -21,11 +21,11 @@ import { getSaltRounds } from "../../config";
*/ */
export const getCurrentServiceAccount = async (req: Request, res: Response) => { export const getCurrentServiceAccount = async (req: Request, res: Response) => {
const serviceAccount = await ServiceAccount.findById(req.serviceAccount._id); const serviceAccount = await ServiceAccount.findById(req.serviceAccount._id);
if (!serviceAccount) { if (!serviceAccount) {
throw ServiceAccountNotFoundError({ message: "Failed to find service account" }); throw ServiceAccountNotFoundError({ message: "Failed to find service account" });
} }
return res.status(200).send({ return res.status(200).send({
serviceAccount, serviceAccount,
}); });
@@ -38,13 +38,13 @@ export const getCurrentServiceAccount = async (req: Request, res: Response) => {
*/ */
export const getServiceAccountById = async (req: Request, res: Response) => { export const getServiceAccountById = async (req: Request, res: Response) => {
const { serviceAccountId } = req.params; const { serviceAccountId } = req.params;
const serviceAccount = await ServiceAccount.findById(serviceAccountId); const serviceAccount = await ServiceAccount.findById(serviceAccountId);
if (!serviceAccount) { if (!serviceAccount) {
throw ServiceAccountNotFoundError({ message: "Failed to find service account" }); throw ServiceAccountNotFoundError({ message: "Failed to find service account" });
} }
return res.status(200).send({ return res.status(200).send({
serviceAccount, serviceAccount,
}); });
@@ -73,7 +73,7 @@ export const createServiceAccount = async (req: Request, res: Response) => {
const secret = crypto.randomBytes(16).toString("base64"); const secret = crypto.randomBytes(16).toString("base64");
const secretHash = await bcrypt.hash(secret, await getSaltRounds()); const secretHash = await bcrypt.hash(secret, await getSaltRounds());
// create service account // create service account
const serviceAccount = await new ServiceAccount({ const serviceAccount = await new ServiceAccount({
name, name,
@@ -83,17 +83,17 @@ export const createServiceAccount = async (req: Request, res: Response) => {
lastUsed: new Date(), lastUsed: new Date(),
expiresAt, expiresAt,
secretHash, secretHash,
}).save(); }).save()
const serviceAccountObj = serviceAccount.toObject(); const serviceAccountObj = serviceAccount.toObject();
delete serviceAccountObj.secretHash; delete serviceAccountObj.secretHash;
// provision default org-level permission for service account // provision default org-level permission for service account
await new ServiceAccountOrganizationPermission({ await new ServiceAccountOrganizationPermission({
serviceAccount: serviceAccount._id, serviceAccount: serviceAccount._id,
}).save(); }).save();
const secretId = Buffer.from(serviceAccount._id.toString(), "hex").toString("base64"); const secretId = Buffer.from(serviceAccount._id.toString(), "hex").toString("base64");
return res.status(200).send({ return res.status(200).send({
@@ -111,7 +111,7 @@ export const createServiceAccount = async (req: Request, res: Response) => {
export const changeServiceAccountName = async (req: Request, res: Response) => { export const changeServiceAccountName = async (req: Request, res: Response) => {
const { serviceAccountId } = req.params; const { serviceAccountId } = req.params;
const { name } = req.body; const { name } = req.body;
const serviceAccount = await ServiceAccount.findOneAndUpdate( const serviceAccount = await ServiceAccount.findOneAndUpdate(
{ {
_id: new Types.ObjectId(serviceAccountId), _id: new Types.ObjectId(serviceAccountId),
@@ -123,7 +123,7 @@ export const changeServiceAccountName = async (req: Request, res: Response) => {
new: true, new: true,
} }
); );
return res.status(200).send({ return res.status(200).send({
serviceAccount, serviceAccount,
}); });
@@ -142,7 +142,7 @@ export const addServiceAccountKey = async (req: Request, res: Response) => {
encryptedKey, encryptedKey,
nonce, nonce,
} = req.body; } = req.body;
const serviceAccountKey = await new ServiceAccountKey({ const serviceAccountKey = await new ServiceAccountKey({
encryptedKey, encryptedKey,
nonce, nonce,
@@ -163,7 +163,7 @@ export const getServiceAccountWorkspacePermissions = async (req: Request, res: R
const serviceAccountWorkspacePermissions = await ServiceAccountWorkspacePermission.find({ const serviceAccountWorkspacePermissions = await ServiceAccountWorkspacePermission.find({
serviceAccount: req.serviceAccount._id, serviceAccount: req.serviceAccount._id,
}).populate("workspace"); }).populate("workspace");
return res.status(200).send({ return res.status(200).send({
serviceAccountWorkspacePermissions, serviceAccountWorkspacePermissions,
}); });
@@ -184,19 +184,19 @@ export const addServiceAccountWorkspacePermission = async (req: Request, res: Re
encryptedKey, encryptedKey,
nonce, nonce,
} = req.body; } = req.body;
if (!req.membership.workspace.environments.some((e: { name: string; slug: string }) => e.slug === environment)) { if (!req.membership.workspace.environments.some((e: { name: string; slug: string }) => e.slug === environment)) {
return res.status(400).send({ return res.status(400).send({
message: "Failed to validate workspace environment", message: "Failed to validate workspace environment",
}); });
} }
const existingPermission = await ServiceAccountWorkspacePermission.findOne({ const existingPermission = await ServiceAccountWorkspacePermission.findOne({
serviceAccount: new Types.ObjectId(serviceAccountId), serviceAccount: new Types.ObjectId(serviceAccountId),
workspace: new Types.ObjectId(workspaceId), workspace: new Types.ObjectId(workspaceId),
environment, environment,
}); });
if (existingPermission) throw BadRequestError({ message: "Failed to add workspace permission to service account due to already-existing " }); if (existingPermission) throw BadRequestError({ message: "Failed to add workspace permission to service account due to already-existing " });
const serviceAccountWorkspacePermission = await new ServiceAccountWorkspacePermission({ const serviceAccountWorkspacePermission = await new ServiceAccountWorkspacePermission({
@@ -206,12 +206,12 @@ export const addServiceAccountWorkspacePermission = async (req: Request, res: Re
read, read,
write, write,
}).save(); }).save();
const existingServiceAccountKey = await ServiceAccountKey.findOne({ const existingServiceAccountKey = await ServiceAccountKey.findOne({
serviceAccount: new Types.ObjectId(serviceAccountId), serviceAccount: new Types.ObjectId(serviceAccountId),
workspace: new Types.ObjectId(workspaceId), workspace: new Types.ObjectId(workspaceId),
}); });
if (!existingServiceAccountKey) { if (!existingServiceAccountKey) {
await new ServiceAccountKey({ await new ServiceAccountKey({
encryptedKey, encryptedKey,
@@ -242,7 +242,7 @@ export const deleteServiceAccountWorkspacePermission = async (req: Request, res:
serviceAccount, serviceAccount,
workspace, workspace,
}); });
if (count === 0) { if (count === 0) {
await ServiceAccountKey.findOneAndDelete({ await ServiceAccountKey.findOneAndDelete({
serviceAccount, serviceAccount,
@@ -294,12 +294,12 @@ export const deleteServiceAccount = async (req: Request, res: Response) => {
*/ */
export const getServiceAccountKeys = async (req: Request, res: Response) => { export const getServiceAccountKeys = async (req: Request, res: Response) => {
const workspaceId = req.query.workspaceId as string; const workspaceId = req.query.workspaceId as string;
const serviceAccountKeys = await ServiceAccountKey.find({ const serviceAccountKeys = await ServiceAccountKey.find({
serviceAccount: req.serviceAccount._id, serviceAccount: req.serviceAccount._id,
...(workspaceId ? { workspace: new Types.ObjectId(workspaceId) } : {}), ...(workspaceId ? { workspace: new Types.ObjectId(workspaceId) } : {}),
}); });
return res.status(200).send({ return res.status(200).send({
serviceAccountKeys, serviceAccountKeys,
}); });

View File

@@ -122,11 +122,11 @@ export const getAuthUserPayload = async ({
}, { }, {
lastUsed: new Date(), lastUsed: new Date(),
}); });
if (!tokenVersion) throw UnauthorizedRequestError({ if (!tokenVersion) throw UnauthorizedRequestError({
message: "Failed to validate access token", message: "Failed to validate access token",
}); });
if (decodedToken.accessVersion !== tokenVersion.accessVersion) throw UnauthorizedRequestError({ if (decodedToken.accessVersion !== tokenVersion.accessVersion) throw UnauthorizedRequestError({
message: "Failed to validate access token", message: "Failed to validate access token",
}); });
@@ -151,7 +151,7 @@ export const getAuthSTDPayload = async ({
const [_, TOKEN_IDENTIFIER, TOKEN_SECRET] = <[string, string, string]>authTokenValue.split(".", 3); const [_, TOKEN_IDENTIFIER, TOKEN_SECRET] = <[string, string, string]>authTokenValue.split(".", 3);
let serviceTokenData = await ServiceTokenData let serviceTokenData = await ServiceTokenData
.findById(TOKEN_IDENTIFIER, "+secretHash +expiresAt"); .findById(TOKEN_IDENTIFIER, "+secretHash +expiresAt").lean();
if (!serviceTokenData) { if (!serviceTokenData) {
throw ServiceTokenDataNotFoundError({ message: "Failed to find service token data" }); throw ServiceTokenDataNotFoundError({ message: "Failed to find service token data" });
@@ -176,7 +176,7 @@ export const getAuthSTDPayload = async ({
}, { }, {
new: true, new: true,
}) })
.select("+encryptedKey +iv +tag"); .select("+encryptedKey +iv +tag").lean();
if (!serviceTokenData) throw ServiceTokenDataNotFoundError({ message: "Failed to find service token data" }); if (!serviceTokenData) throw ServiceTokenDataNotFoundError({ message: "Failed to find service token data" });
@@ -275,11 +275,11 @@ export const getAuthAPIKeyPayload = async ({
* @return {String} obj.token - issued JWT token * @return {String} obj.token - issued JWT token
* @return {String} obj.refreshToken - issued refresh token * @return {String} obj.refreshToken - issued refresh token
*/ */
export const issueAuthTokens = async ({ export const issueAuthTokens = async ({
userId, userId,
ip, ip,
userAgent, userAgent,
}: { }: {
userId: Types.ObjectId; userId: Types.ObjectId;
ip: string; ip: string;
userAgent: string; userAgent: string;
@@ -292,7 +292,7 @@ export const issueAuthTokens = async ({
ip, ip,
userAgent, userAgent,
}); });
if (!tokenVersion) { if (!tokenVersion) {
// case: no existing ip and user agent exists // case: no existing ip and user agent exists
// -> create new (session) token version for ip and user agent // -> create new (session) token version for ip and user agent
@@ -389,7 +389,7 @@ export const validateProviderAuthToken = async ({
const decodedToken = <jwt.ProviderAuthJwtPayload>( const decodedToken = <jwt.ProviderAuthJwtPayload>(
jwt.verify(providerAuthToken, await getJwtProviderAuthSecret()) jwt.verify(providerAuthToken, await getJwtProviderAuthSecret())
); );
if ( if (
decodedToken.authProvider !== user.authProvider || decodedToken.authProvider !== user.authProvider ||
decodedToken.email !== email decodedToken.email !== email

View File

@@ -109,9 +109,9 @@ export const v1PushSecrets = async ({
if (`${s.type}-${s.secretKeyHash}` in newSecretsObj) { if (`${s.type}-${s.secretKeyHash}` in newSecretsObj) {
if ( if (
s.secretValueHash !== s.secretValueHash !==
newSecretsObj[`${s.type}-${s.secretKeyHash}`].hashValue || newSecretsObj[`${s.type}-${s.secretKeyHash}`].hashValue ||
s.secretCommentHash !== s.secretCommentHash !==
newSecretsObj[`${s.type}-${s.secretKeyHash}`].hashComment newSecretsObj[`${s.type}-${s.secretKeyHash}`].hashComment
) { ) {
// case: filter secrets where value or comment changed // case: filter secrets where value or comment changed
return true; return true;
@@ -371,9 +371,9 @@ export const v2PushSecrets = async ({
if (`${s.type}-${s.secretKeyHash}` in newSecretsObj) { if (`${s.type}-${s.secretKeyHash}` in newSecretsObj) {
if ( if (
s.secretValueHash !== s.secretValueHash !==
newSecretsObj[`${s.type}-${s.secretKeyHash}`].secretValueHash || newSecretsObj[`${s.type}-${s.secretKeyHash}`].secretValueHash ||
s.secretCommentHash !== s.secretCommentHash !==
newSecretsObj[`${s.type}-${s.secretKeyHash}`].secretCommentHash newSecretsObj[`${s.type}-${s.secretKeyHash}`].secretCommentHash
) { ) {
// case: filter secrets where value or comment changed // case: filter secrets where value or comment changed
return true; return true;
@@ -484,7 +484,7 @@ export const v2PushSecrets = async ({
// (EE) add secret versions for new secrets // (EE) add secret versions for new secrets
EESecretService.addSecretVersions({ EESecretService.addSecretVersions({
secretVersions: newSecrets.map((secretDocument: ISecret) => { secretVersions: newSecrets.map((secretDocument) => {
return new SecretVersion({ return new SecretVersion({
...secretDocument, ...secretDocument,
secret: secretDocument._id, secret: secretDocument._id,

View File

@@ -3,9 +3,9 @@ import crypto from "crypto";
import { Types } from "mongoose"; import { Types } from "mongoose";
import { encryptSymmetric128BitHexKeyUTF8 } from "../crypto"; import { encryptSymmetric128BitHexKeyUTF8 } from "../crypto";
import { EESecretService } from "../../ee/services"; import { EESecretService } from "../../ee/services";
import { import {
IPType, IPType,
ISecretVersion, ISecretVersion,
SecretSnapshot, SecretSnapshot,
SecretVersion, SecretVersion,
TrustedIP TrustedIP
@@ -164,7 +164,7 @@ export const backfillBotOrgs = async () => {
const botsToInsert = await Promise.all( const botsToInsert = await Promise.all(
organizationIdsToAddBot.map(async (organizationToAddBot) => { organizationIdsToAddBot.map(async (organizationToAddBot) => {
const { publicKey, privateKey } = generateKeyPair(); const { publicKey, privateKey } = generateKeyPair();
const key = client.createSymmetricKey(); const key = client.createSymmetricKey();
if (rootEncryptionKey) { if (rootEncryptionKey) {
@@ -204,7 +204,7 @@ export const backfillBotOrgs = async () => {
plaintext: privateKey, plaintext: privateKey,
key: encryptionKey key: encryptionKey
}); });
const { const {
ciphertext: encryptedSymmetricKey, ciphertext: encryptedSymmetricKey,
iv: symmetricKeyIV, iv: symmetricKeyIV,
@@ -236,7 +236,7 @@ export const backfillBotOrgs = async () => {
}); });
}) })
); );
await BotOrg.insertMany(botsToInsert); await BotOrg.insertMany(botsToInsert);
}; };
@@ -490,7 +490,7 @@ export const backfillSecretFolders = async () => {
}); });
await SecretSnapshot.insertMany(newSnapshots); await SecretSnapshot.insertMany(newSnapshots);
await secSnapshot.delete(); await secSnapshot.deleteOne();
} }
secretSnapshots = await SecretSnapshot.find({ secretSnapshots = await SecretSnapshot.find({
@@ -567,7 +567,7 @@ export const backfillTrustedIps = async () => {
$nin: workspaceIdsWithTrustedIps $nin: workspaceIdsWithTrustedIps
} }
}); });
if (workspaceIdsToAddTrustedIp.length > 0) { if (workspaceIdsToAddTrustedIp.length > 0) {
const operations: { const operations: {
updateOne: { updateOne: {
@@ -586,7 +586,7 @@ export const backfillTrustedIps = async () => {
upsert: boolean; upsert: boolean;
} }
}[] = []; }[] = [];
workspaceIdsToAddTrustedIp.forEach((workspaceId) => { workspaceIdsToAddTrustedIp.forEach((workspaceId) => {
// default IPv4 trusted CIDR // default IPv4 trusted CIDR
operations.push({ operations.push({
@@ -606,7 +606,7 @@ export const backfillTrustedIps = async () => {
upsert: true upsert: true
} }
}); });
// default IPv6 trusted CIDR // default IPv6 trusted CIDR
operations.push({ operations.push({
updateOne: { updateOne: {