0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2025-03-10 22:22:45 -05:00

Merge pull request #5453 from logto-io/yemq-log-8281-update-logto-config-table-types

feat(schemas): update `logto_configs` table related types
This commit is contained in:
Darcy Ye 2024-03-07 14:09:24 +08:00 committed by GitHub
commit 038733e023
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 123 additions and 4 deletions

View file

@ -2,7 +2,7 @@ export * from './connector.js';
export * from './log/index.js';
export * from './oidc-config.js';
export * from './user.js';
export * from './logto-config.js';
export * from './logto-config/index.js';
export * from './interactions.js';
export * from './search.js';
export * from './resource.js';

View file

@ -1,6 +1,12 @@
import type { ZodType } from 'zod';
import { z } from 'zod';
import { jsonObjectGuard } from '../../foundations/index.js';
import { accessTokenPayloadGuard, clientCredentialsPayloadGuard } from './oidc-provider.js';
export * from './oidc-provider.js';
/**
* Logto OIDC signing key types, used mainly in REST API routes.
*/
@ -45,6 +51,45 @@ export const logtoOidcConfigGuard: Readonly<{
[LogtoOidcConfigKey.CookieKeys]: oidcConfigKeyGuard.array(),
});
export enum LogtoJwtTokenKey {
AccessToken = 'jwt.accessToken',
ClientCredentials = 'jwt.clientCredentials',
}
const jwtCustomizerGuard = z
.object({
script: z.string(),
envVars: z.record(z.string()),
contextSample: jsonObjectGuard,
})
.partial();
export const jwtCustomizerAccessTokenGuard = jwtCustomizerGuard.extend({
// Use partial token guard since users customization may not rely on all fields.
tokenSample: accessTokenPayloadGuard.partial().optional(),
});
export type JwtCustomizerAccessToken = z.infer<typeof jwtCustomizerAccessTokenGuard>;
export const jwtCustomizerClientCredentialsGuard = jwtCustomizerGuard.extend({
// Use partial token guard since users customization may not rely on all fields.
tokenSample: clientCredentialsPayloadGuard.partial().optional(),
});
export type JwtCustomizerClientCredentials = z.infer<typeof jwtCustomizerClientCredentialsGuard>;
export type JwtCustomizerType = {
[LogtoJwtTokenKey.AccessToken]: JwtCustomizerAccessToken;
[LogtoJwtTokenKey.ClientCredentials]: JwtCustomizerClientCredentials;
};
export const jwtCustomizerConfigGuard: Readonly<{
[key in LogtoJwtTokenKey]: ZodType<JwtCustomizerType[key]>;
}> = Object.freeze({
[LogtoJwtTokenKey.AccessToken]: jwtCustomizerAccessTokenGuard,
[LogtoJwtTokenKey.ClientCredentials]: jwtCustomizerClientCredentialsGuard,
});
/* --- Logto tenant configs --- */
export const adminConsoleDataGuard = z.object({
signInExperienceCustomized: z.boolean(),
@ -101,17 +146,21 @@ export const logtoTenantConfigGuard: Readonly<{
});
/* --- Summary --- */
export type LogtoConfigKey = LogtoOidcConfigKey | LogtoTenantConfigKey;
export type LogtoConfigType = LogtoOidcConfigType | LogtoTenantConfigType;
export type LogtoConfigGuard = typeof logtoOidcConfigGuard & typeof logtoTenantConfigGuard;
export type LogtoConfigKey = LogtoOidcConfigKey | LogtoJwtTokenKey | LogtoTenantConfigKey;
export type LogtoConfigType = LogtoOidcConfigType | JwtCustomizerType | LogtoTenantConfigType;
export type LogtoConfigGuard = typeof logtoOidcConfigGuard &
typeof jwtCustomizerConfigGuard &
typeof logtoTenantConfigGuard;
export const logtoConfigKeys: readonly LogtoConfigKey[] = Object.freeze([
...Object.values(LogtoOidcConfigKey),
...Object.values(LogtoJwtTokenKey),
...Object.values(LogtoTenantConfigKey),
]);
export const logtoConfigGuards: LogtoConfigGuard = Object.freeze({
...logtoOidcConfigGuard,
...jwtCustomizerConfigGuard,
...logtoTenantConfigGuard,
});

View file

@ -0,0 +1,70 @@
/**
* Manually implement zod guards of some node OIDC provider types.
*
* Please note that we defined `accessTokenPayloadGuard` and `clientCredentialsPayloadGuard` in this file, they are used to make the user-defined token
* sample to be aligned with the real token payload given by the OIDC provider in a real use case.
*
* But these token payload is not a pure "claims" payload, it contains some OIDC provider specific fields (e.g. `kind`). These fields could
* be useful when the user relies on them to make conditional logic in the customization code scripts but will be ignored when the OIDC provider
* processes the customized token payload to JWT token.
*
* TODO: @darcyYe LOG-8366
* Find a proper way to "filter" those fields that will be ignored by the OIDC provider when processing the customized token payload.
* So that we can make the "testing" function in the admin console to be more accurate.
*/
import { z } from 'zod';
import { jsonObjectGuard } from '../../foundations/index.js';
/**
* Does not include built-in methods.
* Ref:
* https://github.com/DefinitelyTyped/DefinitelyTyped/blob/0b7b01b70c4c211a4f69caf05008228ac065413c/types/oidc-provider/index.d.ts#L310
* https://github.com/panva/node-oidc-provider/blob/270af1da83dda4c49edb4aaab48908f737d73379/lib/models/base_model.js#L11
* https://github.com/panva/node-oidc-provider/blob/270af1da83dda4c49edb4aaab48908f737d73379/lib/models/base_token.js#L62
*/
const baseTokenPayloadGuardObject = {
jti: z.string(),
iat: z.number(),
exp: z.number().optional(),
clientId: z.string().optional(),
kind: z.string(),
};
/**
* Ref:
* https://github.com/DefinitelyTyped/DefinitelyTyped/blob/0b7b01b70c4c211a4f69caf05008228ac065413c/types/oidc-provider/index.d.ts#L550
* https://github.com/panva/node-oidc-provider/blob/270af1da83dda4c49edb4aaab48908f737d73379/lib/models/access_token.js#L17
*
* We do not include `claims` field in this guard because we did not enabled the `feature.claimsParameter` in the oidc-provider.
* If we enable the `feature.claimsParameter` feature in the future, we should include and implement the `claims` field guard.
* `feature.claimsParameter`: https://github.com/panva/node-oidc-provider/blob/main/docs/README.md#featuresclaimsparameter
* OIDC claims parameter: https://openid.net/specs/openid-connect-core-1_0.html#ClaimsParameter
*/
export const accessTokenPayloadGuard = z.object({
...baseTokenPayloadGuardObject,
kind: z.literal('AccessToken'),
accountId: z.string(),
aud: z.string().or(z.array(z.string())),
extra: jsonObjectGuard.optional(),
grantId: z.string(),
scope: z.string().optional(),
sid: z.string().optional(),
});
export type AccessTokenPayload = z.infer<typeof accessTokenPayloadGuard>;
/**
* Ref:
* https://github.com/DefinitelyTyped/DefinitelyTyped/blob/0b7b01b70c4c211a4f69caf05008228ac065413c/types/oidc-provider/index.d.ts#L515
* https://github.com/panva/node-oidc-provider/blob/270af1da83dda4c49edb4aaab48908f737d73379/lib/models/client_credentials.js#L11
*/
export const clientCredentialsPayloadGuard = z.object({
...baseTokenPayloadGuardObject,
kind: z.literal('ClientCredentials'),
aud: z.string().or(z.array(z.string())),
extra: jsonObjectGuard.optional(),
scope: z.string().optional(),
});
export type ClientCredentialsPayload = z.infer<typeof clientCredentialsPayloadGuard>;