0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-01-06 20:40:08 -05:00

feat(cloud,schemas): add demo social connectors for tenant (#3444)

This commit is contained in:
wangsijie 2023-03-17 10:21:48 +08:00 committed by GitHub
parent 63be7d04a5
commit 5b8d8c8c14
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 118 additions and 5 deletions

View file

@ -0,0 +1,7 @@
---
"@logto/cloud": minor
"@logto/schemas": minor
"@logto/shared": minor
---
Add demo social connectors for new tenant

View file

@ -26,12 +26,15 @@ import { createApplicationsQueries } from '#src/queries/application.js';
import { createConnectorsQuery } from '#src/queries/connector.js';
import type { Queries } from '#src/queries/index.js';
import { createRolesQuery } from '#src/queries/roles.js';
import { createSystemsQuery } from '#src/queries/system.js';
import { createTenantsQueries } from '#src/queries/tenants.js';
import { createUsersQueries } from '#src/queries/users.js';
import { getDatabaseName } from '#src/queries/utils.js';
import { insertInto } from '#src/utils/query.js';
import { getTenantIdFromManagementApiIndicator } from '#src/utils/tenant.js';
const demoSocialConnectorId = 'logto-social-demo';
export const tenantInfoGuard: ZodType<TenantInfo> = z.object({
id: z.string(),
indicator: z.string(),
@ -71,6 +74,7 @@ export class TenantsLibrary {
const applications = createApplicationsQueries(transaction);
const roles = createRolesQuery(transaction);
const connectors = createConnectorsQuery(transaction);
const systems = createSystemsQuery(transaction);
/* === Start === */
await transaction.start();
@ -128,6 +132,32 @@ export class TenantsLibrary {
},
});
// Create demo social connectors
const presetSocialConnectors = await systems.getDemoSocialValue();
if (presetSocialConnectors) {
await Promise.all(
presetSocialConnectors.map(async (connector) => {
return connectors.insertConnector({
id: generateStandardId(),
tenantId,
connectorId: demoSocialConnectorId,
metadata: {
name: { en: connector.name },
target: connector.provider,
logo: connector.logo,
logoDark: connector.logoDark,
},
config: {
provider: connector.provider,
clientId: connector.clientId,
redirectUri: `${cloudUrlSet.endpoint.toString()}social-demo-callback`,
},
});
})
);
}
// Update Redirect URI for Admin Console
await tenants.appendAdminConsoleRedirectUris(
...['http://localhost:3003', 'https://cloud.logto.dev'].map(

View file

@ -22,7 +22,10 @@ export const createConnectorsQuery = (client: Queryable<PostgreSql>) => {
const insertConnector = async (
// TODO @sijie update with-typed "JsonObject" to support "unknown" value
connector: Pick<CreateConnector, 'id' | 'tenantId' | 'connectorId'> & { config: JsonObject }
connector: Pick<CreateConnector, 'id' | 'tenantId' | 'connectorId'> & {
config: JsonObject;
metadata?: JsonObject;
}
) => client.query(insertInto(connector, 'connectors'));
return { findAllConnectors, insertConnector };

View file

@ -6,6 +6,7 @@ import { parseDsn } from '#src/utils/postgres.js';
import { createApplicationsQueries } from './application.js';
import { createConnectorsQuery } from './connector.js';
import { createServiceLogsQueries } from './service-logs.js';
import { createSystemsQuery } from './system.js';
import { createTenantsQueries } from './tenants.js';
import { createUsersQueries } from './users.js';
@ -18,4 +19,5 @@ export class Queries {
public readonly applications = createApplicationsQueries(this.client);
public readonly connectors = createConnectorsQuery(this.client);
public readonly serviceLogs = createServiceLogsQueries(this.client);
public readonly systems = createSystemsQuery(this.client);
}

View file

@ -0,0 +1,29 @@
import type { System } from '@logto/schemas';
import { demoSocialDataGuard, DemoSocialKey } from '@logto/schemas';
import type { PostgreSql } from '@withtyped/postgres';
import { sql } from '@withtyped/postgres';
import type { Queryable } from '@withtyped/server';
export type SystemsQuery = ReturnType<typeof createSystemsQuery>;
export const createSystemsQuery = (client: Queryable<PostgreSql>) => {
const getDemoSocialValue = async () => {
const { rows } = await client.query<System>(sql`
select key, value
from systems
where key=${DemoSocialKey.DemoSocial}
`);
if (!rows[0]) {
return;
}
const result = demoSocialDataGuard.safeParse(rows[0].value);
if (result.success) {
return result.data;
}
};
return { getDemoSocialValue };
};

View file

@ -64,17 +64,54 @@ export const storageProviderGuard: Readonly<{
[StorageProviderKey.StorageProvider]: storageProviderDataGuard,
});
// Demo social connectors
export enum DemoSocialProvider {
Google = 'google',
GitHub = 'github',
Discord = 'discord',
}
export const demoSocialDataGuard = z
.object({
name: z.string(),
logo: z.string(),
logoDark: z.string(),
provider: z.nativeEnum(DemoSocialProvider),
clientId: z.string(),
})
.array();
export type DemoSocialData = z.infer<typeof demoSocialDataGuard>;
export enum DemoSocialKey {
DemoSocial = 'demoSocial',
}
export type DemoSocialType = {
[DemoSocialKey.DemoSocial]: DemoSocialData;
};
export const demoSocialGuard: Readonly<{
[key in DemoSocialKey]: ZodType<DemoSocialType[key]>;
}> = Object.freeze({
[DemoSocialKey.DemoSocial]: demoSocialDataGuard,
});
// Summary
export type SystemKey = AlterationStateKey | StorageProviderKey;
export type SystemType = AlterationStateType | StorageProviderType;
export type SystemGuard = typeof alterationStateGuard & typeof storageProviderGuard;
export type SystemKey = AlterationStateKey | StorageProviderKey | DemoSocialKey;
export type SystemType = AlterationStateType | StorageProviderType | DemoSocialType;
export type SystemGuard = typeof alterationStateGuard &
typeof storageProviderGuard &
typeof demoSocialGuard;
export const systemKeys: readonly SystemKey[] = Object.freeze([
...Object.values(AlterationStateKey),
...Object.values(StorageProviderKey),
...Object.values(DemoSocialKey),
]);
export const systemGuards: SystemGuard = Object.freeze({
...alterationStateGuard,
...storageProviderGuard,
...demoSocialGuard,
});

View file

@ -1,6 +1,11 @@
export enum DemoConnector {
Sms = 'logto-sms',
Email = 'logto-email',
Social = 'logto-social-demo',
}
export const demoConnectorIds: string[] = [DemoConnector.Sms, DemoConnector.Email];
export const demoConnectorIds: string[] = [
DemoConnector.Sms,
DemoConnector.Email,
DemoConnector.Social,
];