mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat(onboarding): added migration script for super admin
This commit is contained in:
@@ -3,99 +3,156 @@ import { GITLAB_URL } from "../variables";
|
||||
import InfisicalClient from "infisical-node";
|
||||
|
||||
export const client = new InfisicalClient({
|
||||
token: process.env.INFISICAL_TOKEN!,
|
||||
token: process.env.INFISICAL_TOKEN!
|
||||
});
|
||||
|
||||
export const getPort = async () => (await client.getSecret("PORT")).secretValue || 4000;
|
||||
export const getEncryptionKey = async () => {
|
||||
const secretValue = (await client.getSecret("ENCRYPTION_KEY")).secretValue;
|
||||
return secretValue === "" ? undefined : secretValue;
|
||||
}
|
||||
};
|
||||
export const getRootEncryptionKey = async () => {
|
||||
const secretValue = (await client.getSecret("ROOT_ENCRYPTION_KEY")).secretValue;
|
||||
return secretValue === "" ? undefined : secretValue;
|
||||
}
|
||||
export const getInviteOnlySignup = async () => (await client.getSecret("INVITE_ONLY_SIGNUP")).secretValue === "true"
|
||||
export const getSaltRounds = async () => parseInt((await client.getSecret("SALT_ROUNDS")).secretValue) || 10;
|
||||
export const getAuthSecret = async () => (await client.getSecret("JWT_AUTH_SECRET")).secretValue ?? (await client.getSecret("AUTH_SECRET")).secretValue;
|
||||
export const getJwtAuthLifetime = async () => (await client.getSecret("JWT_AUTH_LIFETIME")).secretValue || "10d";
|
||||
export const getJwtMfaLifetime = async () => (await client.getSecret("JWT_MFA_LIFETIME")).secretValue || "5m";
|
||||
export const getJwtRefreshLifetime = async () => (await client.getSecret("JWT_REFRESH_LIFETIME")).secretValue || "90d";
|
||||
export const getJwtServiceSecret = async () => (await client.getSecret("JWT_SERVICE_SECRET")).secretValue; // TODO: deprecate (related to ST V1)
|
||||
export const getJwtSignupLifetime = async () => (await client.getSecret("JWT_SIGNUP_LIFETIME")).secretValue || "15m";
|
||||
export const getJwtProviderAuthLifetime = async () => (await client.getSecret("JWT_PROVIDER_AUTH_LIFETIME")).secretValue || "15m";
|
||||
};
|
||||
export const getInviteOnlySignup = async () =>
|
||||
(await client.getSecret("INVITE_ONLY_SIGNUP")).secretValue === "true";
|
||||
export const getSaltRounds = async () =>
|
||||
parseInt((await client.getSecret("SALT_ROUNDS")).secretValue) || 10;
|
||||
export const getAuthSecret = async () =>
|
||||
(await client.getSecret("JWT_AUTH_SECRET")).secretValue ??
|
||||
(await client.getSecret("AUTH_SECRET")).secretValue;
|
||||
export const getJwtAuthLifetime = async () =>
|
||||
(await client.getSecret("JWT_AUTH_LIFETIME")).secretValue || "10d";
|
||||
export const getJwtMfaLifetime = async () =>
|
||||
(await client.getSecret("JWT_MFA_LIFETIME")).secretValue || "5m";
|
||||
export const getJwtRefreshLifetime = async () =>
|
||||
(await client.getSecret("JWT_REFRESH_LIFETIME")).secretValue || "90d";
|
||||
export const getJwtServiceSecret = async () =>
|
||||
(await client.getSecret("JWT_SERVICE_SECRET")).secretValue; // TODO: deprecate (related to ST V1)
|
||||
export const getJwtSignupLifetime = async () =>
|
||||
(await client.getSecret("JWT_SIGNUP_LIFETIME")).secretValue || "15m";
|
||||
export const getJwtProviderAuthLifetime = async () =>
|
||||
(await client.getSecret("JWT_PROVIDER_AUTH_LIFETIME")).secretValue || "15m";
|
||||
export const getMongoURL = async () => (await client.getSecret("MONGO_URL")).secretValue;
|
||||
export const getNodeEnv = async () => (await client.getSecret("NODE_ENV")).secretValue || "production";
|
||||
export const getVerboseErrorOutput = async () => (await client.getSecret("VERBOSE_ERROR_OUTPUT")).secretValue === "true" && true;
|
||||
export const getNodeEnv = async () =>
|
||||
(await client.getSecret("NODE_ENV")).secretValue || "production";
|
||||
export const getVerboseErrorOutput = async () =>
|
||||
(await client.getSecret("VERBOSE_ERROR_OUTPUT")).secretValue === "true" && true;
|
||||
export const getLokiHost = async () => (await client.getSecret("LOKI_HOST")).secretValue;
|
||||
export const getClientIdAzure = async () => (await client.getSecret("CLIENT_ID_AZURE")).secretValue;
|
||||
export const getClientIdHeroku = async () => (await client.getSecret("CLIENT_ID_HEROKU")).secretValue;
|
||||
export const getClientIdVercel = async () => (await client.getSecret("CLIENT_ID_VERCEL")).secretValue;
|
||||
export const getClientIdNetlify = async () => (await client.getSecret("CLIENT_ID_NETLIFY")).secretValue;
|
||||
export const getClientIdGitHub = async () => (await client.getSecret("CLIENT_ID_GITHUB")).secretValue;
|
||||
export const getClientIdGitLab = async () => (await client.getSecret("CLIENT_ID_GITLAB")).secretValue;
|
||||
export const getClientIdBitBucket = async () => (await client.getSecret("CLIENT_ID_BITBUCKET")).secretValue;
|
||||
export const getClientIdGCPSecretManager = async () => (await client.getSecret("CLIENT_ID_GCP_SECRET_MANAGER")).secretValue;
|
||||
export const getClientSecretAzure = async () => (await client.getSecret("CLIENT_SECRET_AZURE")).secretValue;
|
||||
export const getClientSecretHeroku = async () => (await client.getSecret("CLIENT_SECRET_HEROKU")).secretValue;
|
||||
export const getClientSecretVercel = async () => (await client.getSecret("CLIENT_SECRET_VERCEL")).secretValue;
|
||||
export const getClientSecretNetlify = async () => (await client.getSecret("CLIENT_SECRET_NETLIFY")).secretValue;
|
||||
export const getClientSecretGitHub = async () => (await client.getSecret("CLIENT_SECRET_GITHUB")).secretValue;
|
||||
export const getClientSecretGitLab = async () => (await client.getSecret("CLIENT_SECRET_GITLAB")).secretValue;
|
||||
export const getClientSecretBitBucket = async () => (await client.getSecret("CLIENT_SECRET_BITBUCKET")).secretValue;
|
||||
export const getClientSecretGCPSecretManager = async () => (await client.getSecret("CLIENT_SECRET_GCP_SECRET_MANAGER")).secretValue;
|
||||
export const getClientSlugVercel = async () => (await client.getSecret("CLIENT_SLUG_VERCEL")).secretValue;
|
||||
export const getClientIdHeroku = async () =>
|
||||
(await client.getSecret("CLIENT_ID_HEROKU")).secretValue;
|
||||
export const getClientIdVercel = async () =>
|
||||
(await client.getSecret("CLIENT_ID_VERCEL")).secretValue;
|
||||
export const getClientIdNetlify = async () =>
|
||||
(await client.getSecret("CLIENT_ID_NETLIFY")).secretValue;
|
||||
export const getClientIdGitHub = async () =>
|
||||
(await client.getSecret("CLIENT_ID_GITHUB")).secretValue;
|
||||
export const getClientIdGitLab = async () =>
|
||||
(await client.getSecret("CLIENT_ID_GITLAB")).secretValue;
|
||||
export const getClientIdBitBucket = async () =>
|
||||
(await client.getSecret("CLIENT_ID_BITBUCKET")).secretValue;
|
||||
export const getClientIdGCPSecretManager = async () =>
|
||||
(await client.getSecret("CLIENT_ID_GCP_SECRET_MANAGER")).secretValue;
|
||||
export const getClientSecretAzure = async () =>
|
||||
(await client.getSecret("CLIENT_SECRET_AZURE")).secretValue;
|
||||
export const getClientSecretHeroku = async () =>
|
||||
(await client.getSecret("CLIENT_SECRET_HEROKU")).secretValue;
|
||||
export const getClientSecretVercel = async () =>
|
||||
(await client.getSecret("CLIENT_SECRET_VERCEL")).secretValue;
|
||||
export const getClientSecretNetlify = async () =>
|
||||
(await client.getSecret("CLIENT_SECRET_NETLIFY")).secretValue;
|
||||
export const getClientSecretGitHub = async () =>
|
||||
(await client.getSecret("CLIENT_SECRET_GITHUB")).secretValue;
|
||||
export const getClientSecretGitLab = async () =>
|
||||
(await client.getSecret("CLIENT_SECRET_GITLAB")).secretValue;
|
||||
export const getClientSecretBitBucket = async () =>
|
||||
(await client.getSecret("CLIENT_SECRET_BITBUCKET")).secretValue;
|
||||
export const getClientSecretGCPSecretManager = async () =>
|
||||
(await client.getSecret("CLIENT_SECRET_GCP_SECRET_MANAGER")).secretValue;
|
||||
export const getClientSlugVercel = async () =>
|
||||
(await client.getSecret("CLIENT_SLUG_VERCEL")).secretValue;
|
||||
|
||||
export const getClientIdGoogleLogin = async () => (await client.getSecret("CLIENT_ID_GOOGLE_LOGIN")).secretValue;
|
||||
export const getClientSecretGoogleLogin = async () => (await client.getSecret("CLIENT_SECRET_GOOGLE_LOGIN")).secretValue;
|
||||
export const getClientIdGitHubLogin = async () => (await client.getSecret("CLIENT_ID_GITHUB_LOGIN")).secretValue;
|
||||
export const getClientSecretGitHubLogin = async () => (await client.getSecret("CLIENT_SECRET_GITHUB_LOGIN")).secretValue;
|
||||
export const getClientIdGitLabLogin = async () => (await client.getSecret("CLIENT_ID_GITLAB_LOGIN")).secretValue;
|
||||
export const getClientSecretGitLabLogin = async () => (await client.getSecret("CLIENT_SECRET_GITLAB_LOGIN")).secretValue;
|
||||
export const getUrlGitLabLogin = async () => (await client.getSecret("URL_GITLAB_LOGIN")).secretValue || GITLAB_URL;
|
||||
export const getClientIdGoogleLogin = async () =>
|
||||
(await client.getSecret("CLIENT_ID_GOOGLE_LOGIN")).secretValue;
|
||||
export const getClientSecretGoogleLogin = async () =>
|
||||
(await client.getSecret("CLIENT_SECRET_GOOGLE_LOGIN")).secretValue;
|
||||
export const getClientIdGitHubLogin = async () =>
|
||||
(await client.getSecret("CLIENT_ID_GITHUB_LOGIN")).secretValue;
|
||||
export const getClientSecretGitHubLogin = async () =>
|
||||
(await client.getSecret("CLIENT_SECRET_GITHUB_LOGIN")).secretValue;
|
||||
export const getClientIdGitLabLogin = async () =>
|
||||
(await client.getSecret("CLIENT_ID_GITLAB_LOGIN")).secretValue;
|
||||
export const getClientSecretGitLabLogin = async () =>
|
||||
(await client.getSecret("CLIENT_SECRET_GITLAB_LOGIN")).secretValue;
|
||||
export const getUrlGitLabLogin = async () =>
|
||||
(await client.getSecret("URL_GITLAB_LOGIN")).secretValue || GITLAB_URL;
|
||||
|
||||
export const getPostHogHost = async () => (await client.getSecret("POSTHOG_HOST")).secretValue || "https://app.posthog.com";
|
||||
export const getPostHogProjectApiKey = async () => (await client.getSecret("POSTHOG_PROJECT_API_KEY")).secretValue || "phc_nSin8j5q2zdhpFDI1ETmFNUIuTG4DwKVyIigrY10XiE";
|
||||
export const getPostHogHost = async () =>
|
||||
(await client.getSecret("POSTHOG_HOST")).secretValue || "https://app.posthog.com";
|
||||
export const getPostHogProjectApiKey = async () =>
|
||||
(await client.getSecret("POSTHOG_PROJECT_API_KEY")).secretValue ||
|
||||
"phc_nSin8j5q2zdhpFDI1ETmFNUIuTG4DwKVyIigrY10XiE";
|
||||
export const getSentryDSN = async () => (await client.getSecret("SENTRY_DSN")).secretValue;
|
||||
export const getSiteURL = async () => (await client.getSecret("SITE_URL")).secretValue;
|
||||
export const getSmtpHost = async () => (await client.getSecret("SMTP_HOST")).secretValue;
|
||||
export const getSmtpSecure = async () => (await client.getSecret("SMTP_SECURE")).secretValue === "true" || false;
|
||||
export const getSmtpPort = async () => parseInt((await client.getSecret("SMTP_PORT")).secretValue) || 587;
|
||||
export const getSmtpSecure = async () =>
|
||||
(await client.getSecret("SMTP_SECURE")).secretValue === "true" || false;
|
||||
export const getSmtpPort = async () =>
|
||||
parseInt((await client.getSecret("SMTP_PORT")).secretValue) || 587;
|
||||
export const getSmtpUsername = async () => (await client.getSecret("SMTP_USERNAME")).secretValue;
|
||||
export const getSmtpPassword = async () => (await client.getSecret("SMTP_PASSWORD")).secretValue;
|
||||
export const getSmtpFromAddress = async () => (await client.getSecret("SMTP_FROM_ADDRESS")).secretValue;
|
||||
export const getSmtpFromName = async () => (await client.getSecret("SMTP_FROM_NAME")).secretValue || "Infisical";
|
||||
export const getSmtpFromAddress = async () =>
|
||||
(await client.getSecret("SMTP_FROM_ADDRESS")).secretValue;
|
||||
export const getSmtpFromName = async () =>
|
||||
(await client.getSecret("SMTP_FROM_NAME")).secretValue || "Infisical";
|
||||
|
||||
export const getSecretScanningWebhookProxy = async () => (await client.getSecret("SECRET_SCANNING_WEBHOOK_PROXY")).secretValue;
|
||||
export const getSecretScanningWebhookSecret = async () => (await client.getSecret("SECRET_SCANNING_WEBHOOK_SECRET")).secretValue;
|
||||
export const getSecretScanningGitAppId = async () => (await client.getSecret("SECRET_SCANNING_GIT_APP_ID")).secretValue;
|
||||
export const getSecretScanningPrivateKey = async () => (await client.getSecret("SECRET_SCANNING_PRIVATE_KEY")).secretValue;
|
||||
export const getSecretScanningWebhookProxy = async () =>
|
||||
(await client.getSecret("SECRET_SCANNING_WEBHOOK_PROXY")).secretValue;
|
||||
export const getSecretScanningWebhookSecret = async () =>
|
||||
(await client.getSecret("SECRET_SCANNING_WEBHOOK_SECRET")).secretValue;
|
||||
export const getSecretScanningGitAppId = async () =>
|
||||
(await client.getSecret("SECRET_SCANNING_GIT_APP_ID")).secretValue;
|
||||
export const getSecretScanningPrivateKey = async () =>
|
||||
(await client.getSecret("SECRET_SCANNING_PRIVATE_KEY")).secretValue;
|
||||
|
||||
export const getRedisUrl = async () => (await client.getSecret("REDIS_URL")).secretValue;
|
||||
export const getIsInfisicalCloud = async () =>
|
||||
(await client.getSecret("INFISICAL_CLOUD")).secretValue === "true";
|
||||
|
||||
export const getLicenseKey = async () => {
|
||||
const secretValue = (await client.getSecret("LICENSE_KEY")).secretValue;
|
||||
return secretValue === "" ? undefined : secretValue;
|
||||
}
|
||||
};
|
||||
export const getLicenseServerKey = async () => {
|
||||
const secretValue = (await client.getSecret("LICENSE_SERVER_KEY")).secretValue;
|
||||
return secretValue === "" ? undefined : secretValue;
|
||||
}
|
||||
export const getLicenseServerUrl = async () => (await client.getSecret("LICENSE_SERVER_URL")).secretValue || "https://portal.infisical.com";
|
||||
};
|
||||
export const getLicenseServerUrl = async () =>
|
||||
(await client.getSecret("LICENSE_SERVER_URL")).secretValue || "https://portal.infisical.com";
|
||||
|
||||
export const getTelemetryEnabled = async () => (await client.getSecret("TELEMETRY_ENABLED")).secretValue !== "false" && true;
|
||||
export const getTelemetryEnabled = async () =>
|
||||
(await client.getSecret("TELEMETRY_ENABLED")).secretValue !== "false" && true;
|
||||
export const getLoopsApiKey = async () => (await client.getSecret("LOOPS_API_KEY")).secretValue;
|
||||
export const getSmtpConfigured = async () => (await client.getSecret("SMTP_HOST")).secretValue == "" || (await client.getSecret("SMTP_HOST")).secretValue == undefined ? false : true
|
||||
export const getSmtpConfigured = async () =>
|
||||
(await client.getSecret("SMTP_HOST")).secretValue == "" ||
|
||||
(await client.getSecret("SMTP_HOST")).secretValue == undefined
|
||||
? false
|
||||
: true;
|
||||
export const getHttpsEnabled = async () => {
|
||||
if ((await getNodeEnv()) != "production") {
|
||||
// no https for anything other than prod
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((await client.getSecret("HTTPS_ENABLED")).secretValue == undefined || (await client.getSecret("HTTPS_ENABLED")).secretValue == "") {
|
||||
if (
|
||||
(await client.getSecret("HTTPS_ENABLED")).secretValue == undefined ||
|
||||
(await client.getSecret("HTTPS_ENABLED")).secretValue == ""
|
||||
) {
|
||||
// default when no value present
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
|
||||
return (await client.getSecret("HTTPS_ENABLED")).secretValue === "true" && true
|
||||
}
|
||||
return (await client.getSecret("HTTPS_ENABLED")).secretValue === "true" && true;
|
||||
};
|
||||
|
||||
@@ -82,6 +82,7 @@ import { healthCheck } from "./routes/status";
|
||||
import { RouteNotFoundError } from "./utils/errors";
|
||||
import { requestErrorHandler } from "./middleware/requestErrorHandler";
|
||||
import {
|
||||
getMongoURL,
|
||||
getNodeEnv,
|
||||
getPort,
|
||||
getSecretScanningGitAppId,
|
||||
@@ -102,8 +103,10 @@ let handler: null | any = null;
|
||||
const main = async () => {
|
||||
const port = await getPort();
|
||||
|
||||
await setup();
|
||||
// initializing the database connection
|
||||
await DatabaseService.initDatabase(await getMongoURL());
|
||||
const serverCfg = await serverConfigInit();
|
||||
await setup();
|
||||
|
||||
await EELicenseService.initGlobalFeatureSet();
|
||||
|
||||
|
||||
@@ -2,12 +2,12 @@ import crypto from "crypto";
|
||||
import { Types } from "mongoose";
|
||||
import { encryptSymmetric128BitHexKeyUTF8 } from "../crypto";
|
||||
import { EESecretService } from "../../ee/services";
|
||||
import { redisClient } from "../../services/RedisService"
|
||||
import {
|
||||
IPType,
|
||||
ISecretVersion,
|
||||
Role,
|
||||
SecretSnapshot,
|
||||
import { redisClient } from "../../services/RedisService";
|
||||
import {
|
||||
IPType,
|
||||
ISecretVersion,
|
||||
Role,
|
||||
SecretSnapshot,
|
||||
SecretVersion,
|
||||
TrustedIP
|
||||
} from "../../ee/models";
|
||||
@@ -30,7 +30,7 @@ import {
|
||||
Workspace
|
||||
} from "../../models";
|
||||
import { generateKeyPair } from "../../utils/crypto";
|
||||
import { client, getEncryptionKey, getRootEncryptionKey } from "../../config";
|
||||
import { client, getEncryptionKey, getIsInfisicalCloud, getRootEncryptionKey } from "../../config";
|
||||
import {
|
||||
ADMIN,
|
||||
ALGORITHM_AES_256_GCM,
|
||||
@@ -47,6 +47,7 @@ import {
|
||||
memberProjectPermissions
|
||||
} from "../../ee/services/ProjectRoleService";
|
||||
import { logger } from "../logging";
|
||||
import { getServerConfig, updateServerConfig } from "../../config/serverConfig";
|
||||
|
||||
/**
|
||||
* Backfill secrets to ensure that they're all versioned and have
|
||||
@@ -693,7 +694,7 @@ export const backfillUserAuthMethods = async () => {
|
||||
|
||||
export const backfillPermission = async () => {
|
||||
const lockKey = "backfill_permission_lock";
|
||||
const timeout = 900000; // 15 min lock timeout in milliseconds
|
||||
const timeout = 900000; // 15 min lock timeout in milliseconds
|
||||
const lock = await redisClient?.set(lockKey, 1, "PX", timeout, "NX");
|
||||
|
||||
if (lock) {
|
||||
@@ -705,13 +706,16 @@ export const backfillPermission = async () => {
|
||||
$exists: true,
|
||||
$ne: []
|
||||
},
|
||||
role: MEMBER,
|
||||
role: MEMBER
|
||||
})
|
||||
.populate<{ workspace: IWorkspace }>("workspace")
|
||||
.lean();
|
||||
|
||||
// group memberships that need the same permission set
|
||||
const roleMap = new Map<string, { membershipIds: string[], permissions: any[], organizationId: string, workspaceId: string }>();
|
||||
const roleMap = new Map<
|
||||
string,
|
||||
{ membershipIds: string[]; permissions: any[]; organizationId: string; workspaceId: string }
|
||||
>();
|
||||
|
||||
for (const membership of memberships) {
|
||||
// get permissions of members except secret permission
|
||||
@@ -729,11 +733,11 @@ export const backfillPermission = async () => {
|
||||
});
|
||||
|
||||
// environments that are not listed in deniedPermissions should be set to allowed for both read & and write
|
||||
membership.workspace.environments.forEach(env => {
|
||||
membership.workspace.environments.forEach((env) => {
|
||||
if (!secretAccessRule?.[env.slug]) {
|
||||
secretAccessRule[env.slug] = { read: true, write: true };
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
const secretPermissions: any = [];
|
||||
Object.entries(secretAccessRule).forEach(([envSlug, { read, write }]) => {
|
||||
@@ -769,21 +773,27 @@ export const backfillPermission = async () => {
|
||||
const value = roleMap.get(key);
|
||||
if (value) {
|
||||
value.membershipIds.push(membership._id.toString());
|
||||
value.organizationId = membership.workspace.organization.toString()
|
||||
value.workspaceId = membership.workspace._id.toString()
|
||||
value.organizationId = membership.workspace.organization.toString();
|
||||
value.workspaceId = membership.workspace._id.toString();
|
||||
} else {
|
||||
roleMap.set(key, { membershipIds: [membership._id.toString()], permissions: [...customPermissions, ...secretPermissions], organizationId: membership.workspace.organization.toString(), workspaceId: membership.workspace._id.toString() });
|
||||
roleMap.set(key, {
|
||||
membershipIds: [membership._id.toString()],
|
||||
permissions: [...customPermissions, ...secretPermissions],
|
||||
organizationId: membership.workspace.organization.toString(),
|
||||
workspaceId: membership.workspace._id.toString()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (const [key, value] of roleMap.entries()) {
|
||||
const { membershipIds, permissions, workspaceId, organizationId } = value
|
||||
const membership_identity = crypto.randomBytes(3).toString("hex")
|
||||
const { membershipIds, permissions, workspaceId, organizationId } = value;
|
||||
const membership_identity = crypto.randomBytes(3).toString("hex");
|
||||
const role = new Role({
|
||||
name: `Limited [${membership_identity.toUpperCase()}]`,
|
||||
organization: organizationId,
|
||||
workspace: workspaceId,
|
||||
description: "This role was auto generated by Infisical in effort to migrate your project members to our new permission system",
|
||||
description:
|
||||
"This role was auto generated by Infisical in effort to migrate your project members to our new permission system",
|
||||
isOrgRole: false,
|
||||
slug: `custom-role-${membership_identity}`,
|
||||
permissions: permissions
|
||||
@@ -792,7 +802,8 @@ export const backfillPermission = async () => {
|
||||
await role.save();
|
||||
|
||||
for (const id of membershipIds) {
|
||||
await Membership.findByIdAndUpdate(id, { // document db doesn't support update many so we must loop
|
||||
await Membership.findByIdAndUpdate(id, {
|
||||
// document db doesn't support update many so we must loop
|
||||
$set: {
|
||||
role: CUSTOM,
|
||||
customRole: role
|
||||
@@ -815,11 +826,9 @@ export const backfillPermission = async () => {
|
||||
);
|
||||
|
||||
logger.info("Backfill: Finished converting owner role to member");
|
||||
|
||||
} catch (error) {
|
||||
logger.error(error, "An error occurred when running script [backfillPermission]");
|
||||
}
|
||||
|
||||
} else {
|
||||
logger.info("Could not acquire lock for script [backfillPermission], skipping");
|
||||
}
|
||||
@@ -838,4 +847,34 @@ export const migrateRoleFromOwnerToAdmin = async () => {
|
||||
);
|
||||
|
||||
logger.info("Backfill: Finished converting owner role to member");
|
||||
}
|
||||
};
|
||||
|
||||
export const migrationAssignSuperadmin = async () => {
|
||||
const users = await User.find({}).sort({ createdAt: 1 }).limit(2);
|
||||
const serverCfg = getServerConfig();
|
||||
if (serverCfg.initialized) return;
|
||||
|
||||
if (await getIsInfisicalCloud()) {
|
||||
await updateServerConfig({ initialized: true });
|
||||
logger.info("Backfill: Infisical Cloud(initialized)");
|
||||
return;
|
||||
}
|
||||
|
||||
const isNewInstance = !users.length;
|
||||
if (!isNewInstance) {
|
||||
let superAdminUserId = "";
|
||||
const firstAccount = users?.[0];
|
||||
if (firstAccount.email === "test@localhost.local" && users.length === 2) {
|
||||
superAdminUserId = users?.[1]?._id.toString();
|
||||
} else {
|
||||
superAdminUserId = firstAccount._id.toString();
|
||||
}
|
||||
|
||||
if (superAdminUserId) {
|
||||
const user = await User.findByIdAndUpdate(superAdminUserId, { superAdmin: true });
|
||||
await updateServerConfig({ initialized: true });
|
||||
logger.info(`Migrated ${user?.email} to superuser`);
|
||||
}
|
||||
logger.info("Backfill: Migrated first infisical user to super admin");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import * as Sentry from "@sentry/node";
|
||||
import { DatabaseService, TelemetryService } from "../../services";
|
||||
import { TelemetryService } from "../../services";
|
||||
import { setTransporter } from "../../helpers/nodemailer";
|
||||
import { EELicenseService } from "../../ee/services";
|
||||
import { initSmtp } from "../../services/smtp";
|
||||
import { createTestUserForDevelopment } from "../addDevelopmentUser";
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
import { validateEncryptionKeysConfig } from "./validateConfig";
|
||||
import {
|
||||
@@ -18,14 +17,15 @@ import {
|
||||
backfillServiceTokenMultiScope,
|
||||
backfillTrustedIps,
|
||||
backfillUserAuthMethods,
|
||||
migrateRoleFromOwnerToAdmin
|
||||
migrateRoleFromOwnerToAdmin,
|
||||
migrationAssignSuperadmin
|
||||
} from "./backfillData";
|
||||
import {
|
||||
reencryptBotOrgKeys,
|
||||
reencryptBotPrivateKeys,
|
||||
reencryptSecretBlindIndexDataSalts
|
||||
} from "./reencryptData";
|
||||
import { getMongoURL, getNodeEnv, getRedisUrl, getSentryDSN } from "../../config";
|
||||
import { getNodeEnv, getRedisUrl, getSentryDSN } from "../../config";
|
||||
import {
|
||||
initializeGitHubStrategy,
|
||||
initializeGitLabStrategy,
|
||||
@@ -73,8 +73,6 @@ export const setup = async () => {
|
||||
// await reencryptBotPrivateKeys();
|
||||
// await reencryptSecretBlindIndexDataSalts();
|
||||
|
||||
// initializing the database connection
|
||||
await DatabaseService.initDatabase(await getMongoURL());
|
||||
await bootstrap({ transporter });
|
||||
|
||||
/**
|
||||
@@ -96,6 +94,7 @@ export const setup = async () => {
|
||||
await backfillUserAuthMethods();
|
||||
// await backfillPermission();
|
||||
await migrateRoleFromOwnerToAdmin();
|
||||
await migrationAssignSuperadmin();
|
||||
|
||||
// re-encrypt any data previously encrypted under server hex 128-bit ENCRYPTION_KEY
|
||||
// to base64 256-bit ROOT_ENCRYPTION_KEY
|
||||
@@ -111,5 +110,7 @@ export const setup = async () => {
|
||||
environment: await getNodeEnv()
|
||||
});
|
||||
|
||||
await createTestUserForDevelopment();
|
||||
// akhilmhdh: removed dev account as we have now admin account onboarding flow
|
||||
// That will be user's first account going forward
|
||||
// await createTestUserForDevelopment();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user