0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00
logto/packages/schemas/alterations/1.0.0-1678425761-m2m-app-for-tenants.ts
2024-03-16 19:04:55 +08:00

179 lines
5.2 KiB
TypeScript

import { generateStandardId } from '@logto/shared/universal';
import { sql } from '@silverhand/slonik';
import type { AlterationScript } from '../lib/types/alteration.js';
const adminTenantId = 'admin';
const adminRoleName = 'admin:admin';
const alteration: AlterationScript = {
up: async (pool) => {
const scopeIds = {
sms: generateStandardId(),
email: generateStandardId(),
};
const { id: resourceId } = await pool.one<{ id: string }>(sql`
select id from resources
where tenant_id = ${adminTenantId}
and indicator = 'https://cloud.logto.io/api'
`);
// Insert scopes
await pool.query(sql`
insert into scopes (tenant_id, id, name, description, resource_id)
values (
${adminTenantId},
${scopeIds.sms},
'send:sms',
'Allow sending SMS. This scope is only available to M2M application.',
${resourceId}
), (
${adminTenantId},
${scopeIds.email},
'send:email',
'Allow sending emails. This scope is only available to M2M application.',
${resourceId}
);
`);
// Insert role
const roleId = generateStandardId();
await pool.query(sql`
insert into roles (tenant_id, id, name, description)
values (
${adminTenantId},
${roleId},
'tenantApplication',
'The role for M2M applications that represent a user tenant and send requests to Logto Cloud.'
);
`);
await pool.query(sql`
insert into roles_scopes (tenant_id, id, role_id, scope_id)
values (
${adminTenantId},
${generateStandardId()},
${roleId},
${scopeIds.sms}
), (
${adminTenantId},
${generateStandardId()},
${roleId},
${scopeIds.email}
);
`);
// Insert new scopes to admin role
const { id: adminRoleId } = await pool.one<{ id: string }>(sql`
select id from roles
where name = ${adminRoleName}
and tenant_id = ${adminTenantId}
`);
await pool.query(sql`
insert into roles_scopes (tenant_id, id, role_id, scope_id)
values (
${adminTenantId},
${generateStandardId()},
${adminRoleId},
${scopeIds.sms}
), (
${adminTenantId},
${generateStandardId()},
${adminRoleId},
${scopeIds.email}
);
`);
// Insert m2m applications for each tenant (except admin tenant)
const { rows } = await pool.query<{ id: string }>(sql`
select id from tenants
`);
await Promise.all(
rows.map(async (row) => {
const tenantId = row.id;
if (tenantId === adminTenantId) {
return;
}
const applicationId = generateStandardId();
const description = `Machine to machine application for tenant ${tenantId}`;
const oidcClientMetadata = { redirectUris: [], postLogoutRedirectUris: [] };
const customClientMetadata = { tenantId };
await pool.query(sql`
insert into applications (tenant_id, id, name, description, secret, type, oidc_client_metadata, custom_client_metadata)
values (
'admin',
${applicationId},
'Cloud Service',
${description},
${generateStandardId()},
'MachineToMachine',
${JSON.stringify(oidcClientMetadata)},
${JSON.stringify(customClientMetadata)}
);
`);
await pool.query(sql`
insert into applications_roles (tenant_id, id, role_id, application_id)
values (
'admin',
${generateStandardId()},
${roleId},
${applicationId}
);
`);
})
);
},
down: async (pool) => {
const role = await pool.one<{ id: string }>(sql`
select id from roles
where tenant_id = ${adminTenantId}
and name='tenantApplication'
`);
const { rows: applications } = await pool.query<{ id: string }>(sql`
select application_id as id from applications_roles
where tenant_id = ${adminTenantId}
and role_id = ${role.id}
`);
await pool.query(sql`
delete from applications_roles
where tenant_id = ${adminTenantId}
and role_id = ${role.id};
`);
await pool.query(sql`
delete from roles_scopes
where tenant_id = ${adminTenantId}
and role_id = ${role.id};
`);
await pool.query(sql`
delete from roles
where tenant_id = ${adminTenantId}
and id = ${role.id};
`);
if (applications.length > 0) {
await pool.query(sql`
delete from applications
where tenant_id = ${adminTenantId}
and id in (${sql.join(
applications.map(({ id }) => id),
sql`, `
)});
`);
}
await pool.query(sql`
delete from scopes
using resources
where resources.id = scopes.resource_id
and scopes.tenant_id = ${adminTenantId}
and resources.indicator = 'https://cloud.logto.io/api'
and (scopes.name='send:sms' or scopes.name='send:email');
`);
},
};
export default alteration;