diff --git a/packages/cli/src/commands/database/ogcio/common-rbac.ts b/packages/cli/src/commands/database/ogcio/common-rbac.ts index 9155b1f3bd85..7aa82df891b1 100644 --- a/packages/cli/src/commands/database/ogcio/common-rbac.ts +++ b/packages/cli/src/commands/database/ogcio/common-rbac.ts @@ -276,6 +276,9 @@ export const createScopes = async < fillScopesMethod: (scopesToSeed: T[]) => O; }): Promise => { const scopesToCreate = params.fillScopesMethod(params.scopesToSeed); + if (params.scopesToSeed.length === 0) { + return scopesToCreate; + } const queries: Array< Promise & { id: string }> > = []; diff --git a/packages/cli/src/commands/database/ogcio/index.ts b/packages/cli/src/commands/database/ogcio/index.ts index 7f080d8bc51e..c337257aaa34 100644 --- a/packages/cli/src/commands/database/ogcio/index.ts +++ b/packages/cli/src/commands/database/ogcio/index.ts @@ -1,6 +1,9 @@ import { readFileSync } from 'node:fs'; +/* eslint-disable eslint-comments/disable-enable-pair */ +/* eslint-disable unicorn/import-style */ import { resolve } from 'node:path'; +import { getEnv } from '@silverhand/essentials'; import type { CommandModule } from 'yargs'; import { createPoolAndDatabaseIfNeeded } from '../../../database.js'; @@ -11,9 +14,25 @@ import { seedOgcio } from './ogcio.js'; const DEFAULT_SEEDER_FILE = './src/commands/database/ogcio/ogcio-seeder.json'; -const loadSeederData = (path: string): OgcioTenantSeeder => +const interpolateString = (content: string): string => { + const regExp = /<\w+>/g; + + return content.replaceAll(regExp, function (match) { + const variableName = match.slice(1, -1); + if (!getEnv(variableName)) { + return match; + } + return getEnv(variableName); + }); +}; + +const loadSeederData = (path: string): OgcioTenantSeeder => { + const content = readFileSync(new URL(path, import.meta.url), 'utf8'); + const interpolatedContent = interpolateString(content); + // eslint-disable-next-line @typescript-eslint/no-unsafe-return - JSON.parse(readFileSync(new URL(path, import.meta.url), 'utf8')); + return JSON.parse(interpolatedContent); +}; const getSeederData = async (seederFilepath: unknown): Promise => { if (typeof seederFilepath !== 'string' || seederFilepath.length === 0) { diff --git a/packages/cli/src/commands/database/ogcio/ogcio-seeder-deployment.json b/packages/cli/src/commands/database/ogcio/ogcio-seeder-deployment.json deleted file mode 100644 index 6c12200883ec..000000000000 --- a/packages/cli/src/commands/database/ogcio/ogcio-seeder-deployment.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "default": { - "connectors": [{ - "id": "mygovid", - "sync_profile": false, - "connector_id": "mygovid", - "config": { - "scope": "openid profile email ${MYGOVID_CLIENT_ID}", - "clientId": "${MYGOVID_CLIENT_ID}", - "clientSecret": "${MYGOVID_CLIENT_SECRET}", - "tokenEndpoint": "${MYGOVID_TOKEN_ENDPOINT}", - "authorizationEndpoint": "${MYGOVID_AUTHORIZATION_ENDPOINT}", - "tokenEndpointAuthMethod": "client_secret_post", - "idTokenVerificationConfig": { - "jwksUri": "${MYGOVID_JWS_URI}" - }, - "clientSecretJwtSigningAlgorithm": "HS256" - }, - "metadata": { - "logo": "https://mygovidstatic.blob.core.windows.net/assets/images/favicon_196x196.png", - "name": { - "en": "MyGovId" - }, - "target": "MyGovId (MyGovId connector)" - } - - - - - }] - } -} diff --git a/packages/cli/src/commands/database/ogcio/ogcio-seeder-dev.json b/packages/cli/src/commands/database/ogcio/ogcio-seeder-dev.json new file mode 100644 index 000000000000..a56a5d3c7f34 --- /dev/null +++ b/packages/cli/src/commands/database/ogcio/ogcio-seeder-dev.json @@ -0,0 +1,114 @@ +{ + "default": { + "organizations": [ + { + "name": "OGCIO", + "description": "OGCIO Organization", + "id": "ogcio" + } + ], + "applications": [ + { + "name": "Payments Building Block", + "description": "Payments App of Life Events", + "type": "Traditional", + "redirect_uri": "", + "logout_redirect_uri": "", + "secret": "", + "id": "r5f56tpkytpqyyshiutd2" + }, + { + "name": "Messaging Building Block", + "description": "Messaging App of Life Events", + "type": "Traditional", + "redirect_uri": "", + "logout_redirect_uri": "", + "secret": "", + "id": "1lvmteh2ao3xrswyq7j3e" + } + ], + "resources": [ + { + "id": "payments-api", + "name": "Payments Building Block API", + "indicator": "" + }, + { + "id": "messaging-api", + "name": "Messaging Building Block API", + "indicator": "" + } + ], + "connectors": [ + { + "id": "mygovid", + "sync_profile": false, + "connector_id": "mygovid", + "config": { + "scope": "openid profile email", + "clientId": "", + "clientSecret": "", + "tokenEndpoint": "", + "authorizationEndpoint": "", + "tokenEndpointAuthMethod": "client_secret_post", + "idTokenVerificationConfig": { + "jwksUri": "" + }, + "clientSecretJwtSigningAlgorithm": "HS256" + }, + "metadata": { + "logo": "https://mygovidstatic.blob.core.windows.net/assets/images/favicon_196x196.png", + "name": { + "en": "MyGovId" + }, + "target": "MyGovId (MyGovId connector)" + } + } + ], + "sign_in_experiences": [ + { + "id": "default", + "color": { + "primaryColor": "#007DA6", + "darkPrimaryColor": "#007DA6", + "isDarkModeEnabled": false + }, + "branding": { + "logoUrl": "https://mygovidstatic.blob.core.windows.net/assets/images/helpchat-logo.png", + "darkLogoUrl": "https://mygovidstatic.blob.core.windows.net/assets/images/helpchat-logo.png" + }, + "language_info": { + "autoDetect": true, + "fallbackLanguage": "en" + }, + "sign_in": { + "methods": [] + }, + "sign_up": { + "verify": false, + "password": false, + "identifiers": [] + }, + "social_sign_in_connector_targets": [ + "MyGovId (MyGovId connector)" + ], + "sign_in_mode": "SignInAndRegister" + } + ], + "webhooks": [ + { + "id": "login_webhook", + "name": "User log in", + "events": [ + "PostRegister", + "PostSignIn" + ], + "config": { + "url": "" + }, + "signing_key": "", + "enabled": true + } + ] + } +} diff --git a/packages/cli/src/commands/database/ogcio/ogcio-seeder.json b/packages/cli/src/commands/database/ogcio/ogcio-seeder.json index 50cb93bd12cf..a33424ae1f59 100644 --- a/packages/cli/src/commands/database/ogcio/ogcio-seeder.json +++ b/packages/cli/src/commands/database/ogcio/ogcio-seeder.json @@ -111,8 +111,8 @@ { "id": "default", "color": { - "primaryColor": "#FFFFFF", - "darkPrimaryColor": "#FFFFFF", + "primaryColor": "#007DA6", + "darkPrimaryColor": "#007DA6", "isDarkModeEnabled": false }, "branding": { diff --git a/packages/cli/src/commands/database/ogcio/ogcio.ts b/packages/cli/src/commands/database/ogcio/ogcio.ts index c9d50c301f1d..5a68923df3da 100644 --- a/packages/cli/src/commands/database/ogcio/ogcio.ts +++ b/packages/cli/src/commands/database/ogcio/ogcio.ts @@ -19,47 +19,66 @@ const createDataForTenant = async ( tenantId: string, tenantData: OgcioSeeder ) => { - const organizations = await createOrganizations({ - transaction, - tenantId, - organizations: tenantData.organizations, - }); + if (tenantData.organizations.length > 0) { + const organizations = await createOrganizations({ + transaction, + tenantId, + organizations: tenantData.organizations, + }); + } + const organizationsRbac = await seedOrganizationRbacData({ transaction, tenantId, toSeed: tenantData, }); - const applications = await seedApplications({ - transaction, - tenantId, - applications: tenantData.applications, - }); - const resources = await seedResources({ - transaction, - tenantId, - inputResources: tenantData.resources, - }); - const resourcesRbac = await seedResourceRbacData({ - tenantId, - transaction, - toSeed: tenantData, - seededResources: resources, - }); - const connectors = await seedConnectors({ - transaction, - tenantId, - connectors: tenantData.connectors, - }); - const signInExperiences = await seedSignInExperiences({ - transaction, - tenantId, - experiences: tenantData.sign_in_experiences, - }); - const webhooks = await seedWebhooks({ - transaction, - tenantId, - hooks: tenantData.webhooks - }); + + if (tenantData.applications.length > 0) { + const applications = await seedApplications({ + transaction, + tenantId, + applications: tenantData.applications, + }); + } + + if (tenantData.resources.length > 0) { + const resources = await seedResources({ + transaction, + tenantId, + inputResources: tenantData.resources, + }); + + const resourcesRbac = await seedResourceRbacData({ + tenantId, + transaction, + toSeed: tenantData, + seededResources: resources, + }); + } + + if (tenantData.connectors.length > 0) { + const connectors = await seedConnectors({ + transaction, + tenantId, + connectors: tenantData.connectors, + }); + } + + if (tenantData.sign_in_experiences.length > 0) { + const signInExperiences = await seedSignInExperiences({ + transaction, + tenantId, + experiences: tenantData.sign_in_experiences, + }); + } + + if (tenantData.webhooks.length > 0) { + const webhooks = await seedWebhooks({ + transaction, + tenantId, + hooks: tenantData.webhooks, + }); + } }; const transactionMethod = async (transaction: DatabaseTransactionConnection) => { diff --git a/packages/cli/src/commands/database/ogcio/organizations-rbac.ts b/packages/cli/src/commands/database/ogcio/organizations-rbac.ts index d295ca5e88bb..729fd36992ab 100644 --- a/packages/cli/src/commands/database/ogcio/organizations-rbac.ts +++ b/packages/cli/src/commands/database/ogcio/organizations-rbac.ts @@ -94,20 +94,33 @@ export const seedOrganizationRbacData = async (params: { roles: Record; relations: SeedingRelation[]; }> => { - const createdScopes = await createScopes({ - transaction: params.transaction, - tenantId: params.tenantId, - scopesToSeed: params.toSeed.organization_permissions, - fillScopesMethod: fillScopes, - }); - const createdRoles = await createRoles({ - transaction: params.transaction, - tenantId: params.tenantId, - scopesLists: createdScopes, - rolesToSeed: params.toSeed.organization_roles, - fillRolesMethod: fillRoles, - }); - const relations = await createRelations(params.transaction, params.tenantId, createdRoles); + if (params.toSeed.organization_permissions.length > 0) { + const createdScopes = await createScopes({ + transaction: params.transaction, + tenantId: params.tenantId, + scopesToSeed: params.toSeed.organization_permissions, + fillScopesMethod: fillScopes, + }); + const createdRoles = await createRoles({ + transaction: params.transaction, + tenantId: params.tenantId, + scopesLists: createdScopes, + rolesToSeed: params.toSeed.organization_roles, + fillRolesMethod: fillRoles, + }); + const relations = await createRelations(params.transaction, params.tenantId, createdRoles); - return { scopes: createdScopes, roles: createdRoles, relations }; + return { scopes: createdScopes, roles: createdRoles, relations }; + } + + return { + scopes: { + scopesList: [], + scopesByEntity: {}, + scopesByAction: {}, + scopesByFullName: {}, + }, + roles: {}, + relations: [], + }; }; diff --git a/packages/cli/src/commands/database/ogcio/resources-rbac.ts b/packages/cli/src/commands/database/ogcio/resources-rbac.ts index d58d883aa02d..6ff4bf1bccf6 100644 --- a/packages/cli/src/commands/database/ogcio/resources-rbac.ts +++ b/packages/cli/src/commands/database/ogcio/resources-rbac.ts @@ -97,30 +97,38 @@ const replaceWithResourceIdFromDatabase = ( resource_permissions: ResourcePermissionSeeder[]; resource_roles: ResourceRoleSeeder[]; } => { - for (const permission of toSeed.resource_permissions) { - const toSetResourceIds = []; - for (const resourceId of permission.for_resource_ids) { - if (!seededResources[resourceId]) { - throw new Error(`Resource scopes. Referring to a not existent resource id: ${resourceId}!`); - } - toSetResourceIds.push(seededResources[resourceId]!.id!); - } - permission.for_resource_ids = toSetResourceIds; - } - for (const roles of toSeed.resource_roles) { - const toSetResourceIds = []; - for (const permissionGroup of roles.permissions) { - for (const resourceId of permissionGroup.for_resource_ids) { + if (toSeed.resource_permissions.length > 0) { + for (const permission of toSeed.resource_permissions) { + const toSetResourceIds = []; + for (const resourceId of permission.for_resource_ids) { if (!seededResources[resourceId]) { throw new Error( - `Resource roles. Referring to a not existent resource id: ${resourceId}!` + `Resource scopes. Referring to a not existent resource id: ${resourceId}!` ); } toSetResourceIds.push(seededResources[resourceId]!.id!); } - permissionGroup.for_resource_ids = toSetResourceIds; + permission.for_resource_ids = toSetResourceIds; + } + } + + if (toSeed.resource_roles.length > 0) { + for (const roles of toSeed.resource_roles) { + const toSetResourceIds = []; + for (const permissionGroup of roles.permissions) { + for (const resourceId of permissionGroup.for_resource_ids) { + if (!seededResources[resourceId]) { + throw new Error( + `Resource roles. Referring to a not existent resource id: ${resourceId}!` + ); + } + toSetResourceIds.push(seededResources[resourceId]!.id!); + } + permissionGroup.for_resource_ids = toSetResourceIds; + } } } + return toSeed; }; @@ -138,26 +146,30 @@ export const seedResourceRbacData = async (params: { relations: SeedingRelation[]; }> => { params.toSeed = replaceWithResourceIdFromDatabase(params.seededResources, params.toSeed); - const createdScopes = await createScopes({ - transaction: params.transaction, - tenantId: params.tenantId, - scopesToSeed: params.toSeed.resource_permissions, - fillScopesMethod: fillScopes, - }); - const createdRoles = await createRoles({ - transaction: params.transaction, - tenantId: params.tenantId, - scopesLists: createdScopes, - rolesToSeed: params.toSeed.resource_roles, - fillRolesMethod: fillRoles, - }); - const createdRelations = await createRelations({ - transaction: params.transaction, - tenantId: params.tenantId, - roles: createdRoles, - }); + if (params.toSeed.resource_permissions.length > 0) { + const createdScopes = await createScopes({ + transaction: params.transaction, + tenantId: params.tenantId, + scopesToSeed: params.toSeed.resource_permissions, + fillScopesMethod: fillScopes, + }); + const createdRoles = await createRoles({ + transaction: params.transaction, + tenantId: params.tenantId, + scopesLists: createdScopes, + rolesToSeed: params.toSeed.resource_roles, + fillRolesMethod: fillRoles, + }); + const createdRelations = await createRelations({ + transaction: params.transaction, + tenantId: params.tenantId, + roles: createdRoles, + }); + + return { scopes: createdScopes, roles: createdRoles, relations: createdRelations }; + } - return { scopes: createdScopes, roles: createdRoles, relations: createdRelations }; + return { scopes: {}, roles: {}, relations: [] }; }; const getEmptyList = (): ScopesLists => ({