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

chore(schemas,core): update custom JWT sample token payload guard

This commit is contained in:
Darcy Ye 2024-03-26 15:30:09 +08:00
parent ba966fdefe
commit e0123fd415
No known key found for this signature in database
GPG key ID: B46F4C07EDEFC610
3 changed files with 26 additions and 55 deletions

View file

@ -185,9 +185,7 @@ export const environmentVariablesCodeExample = `exports.getCustomJwtClaims = asy
*/
const standardTokenPayloadData = {
jti: 'f1d3d2d1-1f2d-3d4e-5d6f-7d8a9d0e1d2',
iat: 1_516_235_022,
exp: 1_516_235_022 + 3600,
clientId: 'my_app',
client_id: 'my_app',
scope: 'read write',
aud: 'http://localhost:3000/api/test',
};
@ -197,6 +195,7 @@ export const defaultAccessTokenPayload: AccessTokenPayload = {
grantId: 'grant_123',
accountId: 'uid_123',
kind: 'AccessToken',
gty: 'authorization_code',
};
export const defaultClientCredentialsPayload: ClientCredentialsPayload = {

View file

@ -232,7 +232,9 @@ export default function initOidc(
? ctx.oidc.provider.ClientCredentials.IN_PAYLOAD
: ctx.oidc.provider.AccessToken.IN_PAYLOAD;
const readOnlyToken = Object.fromEntries(
pickedFields.map((field) => [field, Reflect.get(token, field)])
pickedFields
.filter((field) => Reflect.get(token, field) !== undefined)
.map((field) => [field, Reflect.get(token, field)])
);
const client = await cloudConnection.getClient();

View file

@ -4,67 +4,37 @@
* 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.
* Only keep the least necessary fields in the guards to align with the raw token payload that can be used for `extraTokenClaims` method.
*/
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(),
aud: z.union([z.string(), z.string().array()]),
scope: z.string().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 const accessTokenPayloadGuard = z
.object({
...baseTokenPayloadGuardObject,
accountId: z.string(),
expiresWithSession: z.boolean().optional(),
grantId: z.string(),
gty: z.string(),
sessionUid: z.string().optional(),
sid: z.string().optional(),
kind: z.literal('AccessToken'),
})
.strict();
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 const clientCredentialsPayloadGuard = z
.object({
...baseTokenPayloadGuardObject,
kind: z.literal('ClientCredentials'),
})
.strict();
export type ClientCredentialsPayload = z.infer<typeof clientCredentialsPayloadGuard>;