diff --git a/packages/cli/src/commands/database/ogcio/ogcio-seeder-local.json b/packages/cli/src/commands/database/ogcio/ogcio-seeder-local.json index ae7b44b3137..d2c9c0d9119 100644 --- a/packages/cli/src/commands/database/ogcio/ogcio-seeder-local.json +++ b/packages/cli/src/commands/database/ogcio/ogcio-seeder-local.json @@ -472,6 +472,17 @@ "signing_key": "webhooks_local_signing_key", "enabled": true } + ], + "users": [ + { + "id": "e2e-user-1", + "username": "e2e_test_user_1", + "primary_email": "e2e_test_1@user.com", + "primary_phone": "+21312666999", + "name": "E2E First User", + "application_id": "4695d8onfb9f3bv18phtq", + "resource_role_ids": ["bb-citizen"] + } ] } } diff --git a/packages/cli/src/commands/database/ogcio/ogcio-seeder-testing.json b/packages/cli/src/commands/database/ogcio/ogcio-seeder-testing.json index 9e75dac7156..ae3e6925020 100644 --- a/packages/cli/src/commands/database/ogcio/ogcio-seeder-testing.json +++ b/packages/cli/src/commands/database/ogcio/ogcio-seeder-testing.json @@ -440,5 +440,16 @@ "enabled": true } ] - } + }, + "users": [ + { + "id": "e2e-user-1", + "username": "e2e_test_user_1", + "primary_email": "e2e_test_1@user.com", + "primary_phone": "+21312666999", + "name": "E2E First User", + "application_id": "1lvmteh2ao3xrswyq7j3e", + "resource_role_ids": ["bb-citizen"] + } + ] } diff --git a/packages/cli/src/commands/database/ogcio/ogcio-seeder.ts b/packages/cli/src/commands/database/ogcio/ogcio-seeder.ts index 4c7184c7274..58160a25fe1 100644 --- a/packages/cli/src/commands/database/ogcio/ogcio-seeder.ts +++ b/packages/cli/src/commands/database/ogcio/ogcio-seeder.ts @@ -16,6 +16,7 @@ export type OgcioSeeder = { sign_in_experiences?: SignInExperienceSeeder[]; resource_permissions?: ResourcePermissionSeeder[]; resource_roles?: ResourceRoleSeeder[]; + users?: UserSeeder[]; }; export type OrganizationSeeder = { @@ -137,6 +138,16 @@ export type WebhookSeeder = { enabled: true; }; +export type UserSeeder = { + id: string; + username: string; + primary_email: string; + primary_phone?: string; + name: string; + application_id: string; + resource_role_ids: string[]; +}; + let inputSeeder: OgcioTenantSeeder | undefined; export const getTenantSeederData = (): OgcioTenantSeeder => { if (inputSeeder === undefined) { diff --git a/packages/cli/src/commands/database/ogcio/ogcio.ts b/packages/cli/src/commands/database/ogcio/ogcio.ts index ecf079b7fee..5e13b1b3624 100644 --- a/packages/cli/src/commands/database/ogcio/ogcio.ts +++ b/packages/cli/src/commands/database/ogcio/ogcio.ts @@ -12,6 +12,7 @@ import { createOrganizations } from './organizations.js'; import { seedResourceRbacData } from './resources-rbac.js'; import { seedResources } from './resources.js'; import { seedSignInExperiences } from './sign-in-experiences.js'; +import { seedUsers } from './users.js'; import { seedWebhooks } from './webhooks.js'; const createDataForTenant = async ( @@ -79,6 +80,14 @@ const createDataForTenant = async ( hooks: tenantData.webhooks, }); } + + if (tenantData.users?.length) { + const users = await seedUsers({ + transaction, + tenantId, + usersToSeed: tenantData.users, + }); + } }; const transactionMethod = async (transaction: DatabaseTransactionConnection) => { diff --git a/packages/cli/src/commands/database/ogcio/users.ts b/packages/cli/src/commands/database/ogcio/users.ts new file mode 100644 index 00000000000..b084dee9c62 --- /dev/null +++ b/packages/cli/src/commands/database/ogcio/users.ts @@ -0,0 +1,73 @@ +/* eslint-disable eslint-comments/disable-enable-pair */ +/* eslint-disable @silverhand/fp/no-mutating-methods */ + +import { Users, UsersRoles } from '@logto/schemas'; +import { sql, type DatabaseTransactionConnection } from '@silverhand/slonik'; + +import { type UserSeeder } from './ogcio-seeder.js'; +import { createOrUpdateItem } from './queries.js'; + +export const seedUsers = async (params: { + transaction: DatabaseTransactionConnection; + tenantId: string; + usersToSeed: UserSeeder[]; +}) => { + if (params.usersToSeed.length === 0) { + return {}; + } + + const queries: Array> = []; + + for (const user of params.usersToSeed) { + queries.push(createUser({ ...params, userToSeed: user })); + } + + await Promise.all(queries); + + return params.usersToSeed; +}; + +const createUser = async (params: { + transaction: DatabaseTransactionConnection; + tenantId: string; + userToSeed: UserSeeder; +}): Promise => { + await createOrUpdateItem({ + transaction: params.transaction, + tenantId: params.tenantId, + toLogFieldName: 'id', + whereClauses: [sql`tenant_id = ${params.tenantId}`, sql`id = ${params.userToSeed.id}`], + toInsert: { + id: params.userToSeed.id, + username: params.userToSeed.username, + primary_email: params.userToSeed.primary_email, + primary_phone: params.userToSeed.primary_phone ?? undefined, + name: params.userToSeed.name, + application_id: params.userToSeed.application_id, + }, + tableName: Users.table, + }); + + const assignRoleQueries = []; + for (const roleId of params.userToSeed.resource_role_ids) { + assignRoleQueries.push( + createOrUpdateItem({ + transaction: params.transaction, + tenantId: params.tenantId, + toLogFieldName: 'role_id', + whereClauses: [ + sql`tenant_id = ${params.tenantId}`, + sql`user_id = ${params.userToSeed.id}`, + sql`role_id = ${roleId}`, + ], + toInsert: { + user_id: params.userToSeed.id, + role_id: roleId, + }, + tableName: UsersRoles.table, + }) + ); + } + + await Promise.all(assignRoleQueries); +};