feat(infisical-pg): made identity ua client sec backward compat

This commit is contained in:
Akhil Mohan
2024-01-27 12:40:37 +05:30
parent 9849312317
commit 4d184003a8
7 changed files with 72 additions and 53 deletions
@@ -20,7 +20,7 @@ export async function up(knex: Knex): Promise<void> {
} }
if (!(await knex.schema.hasTable(TableName.IdentityUaClientSecret))) { if (!(await knex.schema.hasTable(TableName.IdentityUaClientSecret))) {
await knex.schema.createTable(TableName.IdentityUaClientSecret, (t) => { await knex.schema.createTable(TableName.IdentityUaClientSecret, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid()); t.string("id", 36).primary().defaultTo(knex.fn.uuid());
t.string("description").notNullable(); t.string("description").notNullable();
t.string("clientSecretPrefix").notNullable(); t.string("clientSecretPrefix").notNullable();
t.string("clientSecretHash").notNullable(); t.string("clientSecretHash").notNullable();
@@ -14,7 +14,7 @@ export async function up(knex: Knex): Promise<void> {
t.datetime("accessTokenLastUsedAt"); t.datetime("accessTokenLastUsedAt");
t.datetime("accessTokenLastRenewedAt"); t.datetime("accessTokenLastRenewedAt");
t.boolean("isAccessTokenRevoked").defaultTo(false).notNullable(); t.boolean("isAccessTokenRevoked").defaultTo(false).notNullable();
t.uuid("identityUAClientSecretId"); t.string("identityUAClientSecretId");
t.foreign("identityUAClientSecretId") t.foreign("identityUAClientSecretId")
.references("id") .references("id")
.inTable(TableName.IdentityUaClientSecret) .inTable(TableName.IdentityUaClientSecret)
@@ -16,7 +16,7 @@ export const IdentityAccessTokensSchema = z.object({
accessTokenLastUsedAt: z.date().nullable().optional(), accessTokenLastUsedAt: z.date().nullable().optional(),
accessTokenLastRenewedAt: z.date().nullable().optional(), accessTokenLastRenewedAt: z.date().nullable().optional(),
isAccessTokenRevoked: z.boolean().default(false), isAccessTokenRevoked: z.boolean().default(false),
identityUAClientSecretId: z.string().uuid().nullable().optional(), identityUAClientSecretId: z.string().nullable().optional(),
identityId: z.string().uuid(), identityId: z.string().uuid(),
createdAt: z.date(), createdAt: z.date(),
updatedAt: z.date(), updatedAt: z.date(),
@@ -8,7 +8,7 @@ import { z } from "zod";
import { TImmutableDBKeys } from "./models"; import { TImmutableDBKeys } from "./models";
export const IdentityUaClientSecretsSchema = z.object({ export const IdentityUaClientSecretsSchema = z.object({
id: z.string().uuid(), id: z.string(),
description: z.string(), description: z.string(),
clientSecretPrefix: z.string(), clientSecretPrefix: z.string(),
clientSecretHash: z.string(), clientSecretHash: z.string(),
+42 -30
View File
@@ -180,7 +180,9 @@ export const migrateCollection = async <
console.log("Total batches", Math.ceil(totalMongoCount / 1000)); console.log("Total batches", Math.ceil(totalMongoCount / 1000));
let batch = 1; let batch = 1;
for await (const doc of mongooseCollection.find(filter || {}).cursor({ batchSize: 100 })) { for await (const doc of mongooseCollection
.find(filter || {})
.cursor({ batchSize: 100 })) {
mongooseDoc.push(doc); mongooseDoc.push(doc);
const preProcessedData = await preProcessing( const preProcessedData = await preProcessing(
doc.toObject({ virtuals: true }), doc.toObject({ virtuals: true }),
@@ -234,7 +236,10 @@ export const migrateCollection = async <
pgDoc.splice(0, pgDoc.length); pgDoc.splice(0, pgDoc.length);
} }
migrationCheckPointsKv.put(`${postgresTableName}-${mongooseCollection.modelName}`, "done"); migrationCheckPointsKv.put(
`${postgresTableName}-${mongooseCollection.modelName}`,
"done",
);
console.log( console.log(
"Finished migration of ", "Finished migration of ",
@@ -585,7 +590,7 @@ const main = async () => {
const getEnvId = async (workspace: string, environment: string) => { const getEnvId = async (workspace: string, environment: string) => {
const envKv = envPKv.sublevel(workspace); const envKv = envPKv.sublevel(workspace);
return envKv.get(environment) return envKv.get(environment);
}; };
const getFolderKv = (workspace: string, environment: string) => { const getFolderKv = (workspace: string, environment: string) => {
const envKv = envPKv.sublevel(workspace); const envKv = envPKv.sublevel(workspace);
@@ -643,8 +648,8 @@ const main = async () => {
: null; : null;
if (!orgId) return; if (!orgId) return;
let results = []; let results = [];
for (const env of doc.environments) { for (const env of doc.environments) {
const id = uuidV4(); const id = uuidV4();
// case: we forgot to clean up folders that belong to deleted env slugs // case: we forgot to clean up folders that belong to deleted env slugs
@@ -656,28 +661,27 @@ const main = async () => {
if (!isEnvFound) continue; if (!isEnvFound) continue;
const envId = await getEnvId( const envId = await getEnvId(
doc._id.toString(), doc._id.toString(),
truncateAndSlugify(env.slug), truncateAndSlugify(env.slug),
); );
const folderKv = getFolderKv( const folderKv = getFolderKv(
doc._id.toString(), doc._id.toString(),
truncateAndSlugify(env.slug), truncateAndSlugify(env.slug),
); );
await folderKv.put("root", id); await folderKv.put("root", id);
results.push({ results.push({
id, id,
name: "root", name: "root",
envId, envId,
version: 1, version: 1,
createdAt: new Date(), createdAt: new Date(),
updatedAt: new Date(), updatedAt: new Date(),
}); });
} }
return results;
return results;
}, },
}); });
@@ -826,7 +830,12 @@ const main = async () => {
const { name, version } = folder; const { name, version } = folder;
const id = uuidV4(); const id = uuidV4();
await folderKv.put(folder.id, id); await folderKv.put(folder.id, id);
const parentId = folder?.parentId ? await folderKv.get(folder?.parentId).catch((e) => {console.log("parent folder not found==>", folder); throw e;}) : null; const parentId = folder?.parentId
? await folderKv.get(folder?.parentId).catch((e) => {
console.log("parent folder not found==>", folder);
throw e;
})
: null;
pgFolder.push({ pgFolder.push({
name, name,
@@ -1084,17 +1093,19 @@ const main = async () => {
// Case: if folder id doesn't exist and the root of the folder also doesn;t exist, THEN put the secret at the ROOT // Case: if folder id doesn't exist and the root of the folder also doesn;t exist, THEN put the secret at the ROOT
// case: after deleting a folder, we don't clean up the secrets that link to that folder // case: after deleting a folder, we don't clean up the secrets that link to that folder
const folderId = await folderKv.get(doc.folder || "root").catch(() => null); const folderId = await folderKv
.get(doc.folder || "root")
.catch(() => null);
// case: when environments are renamed, there used to be a TIMEE when the related folder's slugs weren't updated with it... :( // case: when environments are renamed, there used to be a TIMEE when the related folder's slugs weren't updated with it... :(
if (!folderId) return if (!folderId) return;
// issue with personal // issue with personal
const userId = doc.user const userId = doc.user
? await userKv.get(doc.user.toString()).catch(() => null) ? await userKv.get(doc.user.toString()).catch(() => null)
: null; : null;
if ( doc.type === "personal" && !userId) return; if (doc.type === "personal" && !userId) return;
const id = uuidV4(); const id = uuidV4();
await secKv.put(doc._id.toString(), id); await secKv.put(doc._id.toString(), id);
@@ -1291,8 +1302,10 @@ const main = async () => {
if (!projectKvRes) return; if (!projectKvRes) return;
// if we try to process two bots for the same workspace, then skip // if we try to process two bots for the same workspace, then skip
if (await projectBotKv.get(doc.workspace.toString()).catch(() => null)){ if (
return await projectBotKv.get(doc.workspace.toString()).catch(() => null)
) {
return;
} }
await projectBotKv.put(doc.workspace.toString(), id); await projectBotKv.put(doc.workspace.toString(), id);
@@ -1306,9 +1319,9 @@ const main = async () => {
.lean(); .lean();
// case: when no bots are found for this project, skip // case: when no bots are found for this project, skip
if (!bot) return if (!bot) return;
const botKey = await BotKey.findOne({bot: bot?._id}) const botKey = await BotKey.findOne({ bot: bot?._id });
const senderId = botKey?.sender const senderId = botKey?.sender
? await userKv.get(botKey.sender.toString()).catch(() => null) ? await userKv.get(botKey.sender.toString()).catch(() => null)
@@ -1554,13 +1567,12 @@ const main = async () => {
postgresTableName: TableName.IdentityUaClientSecret, postgresTableName: TableName.IdentityUaClientSecret,
returnKeys: ["id"], returnKeys: ["id"],
preProcessing: async (doc) => { preProcessing: async (doc) => {
const id = uuidV4();
const identityUAId = await identityUaKv.get( const identityUAId = await identityUaKv.get(
doc.identityUniversalAuth.toString(), doc.identityUniversalAuth.toString(),
); );
await identityUaClientSecKv.put(doc._id.toString(), id); await identityUaClientSecKv.put(doc._id.toString(), doc._id.toString());
return { return {
id, id: doc._id.toString(),
identityUAId, identityUAId,
description: doc.description, description: doc.description,
clientSecretTTL: doc.clientSecretTTL, clientSecretTTL: doc.clientSecretTTL,
@@ -2348,7 +2360,7 @@ const main = async () => {
// }, // },
// }); // });
console.log("MIGRATION SCRIPT COMPLETED SUCCESSFULLY") console.log("MIGRATION SCRIPT COMPLETED SUCCESSFULLY");
process.exit(1); process.exit(1);
} catch (error) { } catch (error) {
console.error(error); console.error(error);
@@ -16,7 +16,7 @@ export const IdentityAccessTokensSchema = z.object({
accessTokenLastUsedAt: z.date().nullable().optional(), accessTokenLastUsedAt: z.date().nullable().optional(),
accessTokenLastRenewedAt: z.date().nullable().optional(), accessTokenLastRenewedAt: z.date().nullable().optional(),
isAccessTokenRevoked: z.boolean().default(false), isAccessTokenRevoked: z.boolean().default(false),
identityUAClientSecretId: z.string().uuid().nullable().optional(), identityUAClientSecretId: z.string().nullable().optional(),
identityId: z.string().uuid(), identityId: z.string().uuid(),
createdAt: z.date(), createdAt: z.date(),
updatedAt: z.date(), updatedAt: z.date(),
@@ -8,7 +8,7 @@ import { z } from "zod";
import { TImmutableDBKeys } from "./models"; import { TImmutableDBKeys } from "./models";
export const IdentityUaClientSecretsSchema = z.object({ export const IdentityUaClientSecretsSchema = z.object({
id: z.string().uuid(), id: z.string(),
description: z.string(), description: z.string(),
clientSecretPrefix: z.string(), clientSecretPrefix: z.string(),
clientSecretHash: z.string(), clientSecretHash: z.string(),
@@ -22,6 +22,13 @@ export const IdentityUaClientSecretsSchema = z.object({
identityUAId: z.string().uuid(), identityUAId: z.string().uuid(),
}); });
export type TIdentityUaClientSecrets = z.infer<typeof IdentityUaClientSecretsSchema>; export type TIdentityUaClientSecrets = z.infer<
export type TIdentityUaClientSecretsInsert = Omit<TIdentityUaClientSecrets, TImmutableDBKeys>; typeof IdentityUaClientSecretsSchema
export type TIdentityUaClientSecretsUpdate = Partial<Omit<TIdentityUaClientSecrets, TImmutableDBKeys>>; >;
export type TIdentityUaClientSecretsInsert = Omit<
TIdentityUaClientSecrets,
TImmutableDBKeys
>;
export type TIdentityUaClientSecretsUpdate = Partial<
Omit<TIdentityUaClientSecrets, TImmutableDBKeys>
>;