0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-30 20:33:54 -05:00

fix(core): remove grant id of token exchange (#6497)

This commit is contained in:
wangsijie 2024-08-22 11:45:50 +08:00 committed by GitHub
parent f0bbc2a1f4
commit 06f98634c1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 22 additions and 10 deletions

View file

@ -10,6 +10,7 @@ import {
import { generateStandardId } from '@logto/shared';
import { conditional, trySafe } from '@silverhand/essentials';
import { type KoaContextWithOIDC, type UnknownObject } from 'oidc-provider';
import { z } from 'zod';
import { EnvSet } from '#src/env-set/index.js';
import { type CloudConnectionLibrary } from '#src/libraries/cloud-connection.js';
@ -142,10 +143,17 @@ export const getExtraTokenClaimsForJwtCustomization = async (
(await libraries.jwtCustomizers.getUserContext(token.accountId))
);
const subjectTokenResult = z
.object({
subjectTokenId: z.string(),
})
.safeParse(token.extra);
const subjectToken =
isTokenClientCredentials || token.gty !== GrantType.TokenExchange
? undefined
: await trySafe(async () => queries.subjectTokens.findSubjectToken(token.grantId));
: subjectTokenResult.success
? await queries.subjectTokens.findSubjectToken(subjectTokenResult.data.subjectTokenId)
: undefined;
const payload: CustomJwtFetcher = {
script,

View file

@ -1,4 +1,3 @@
import { generateStandardShortId } from '@logto/shared';
import { trySafe } from '@silverhand/essentials';
import { errors } from 'oidc-provider';
@ -13,7 +12,7 @@ export const validateSubjectToken = async (
queries: Queries,
subjectToken: string,
type: string
): Promise<{ userId: string; grantId: string; subjectTokenId?: string }> => {
): Promise<{ userId: string; subjectTokenId?: string }> => {
const {
subjectTokens: { findSubjectToken },
personalAccessTokens: { findByValue },
@ -27,7 +26,6 @@ export const validateSubjectToken = async (
return {
userId: token.userId,
grantId: token.id,
subjectTokenId: token.id,
};
}
@ -39,7 +37,7 @@ export const validateSubjectToken = async (
new InvalidGrant('subject token is expired')
);
return { userId: token.userId, grantId: generateStandardShortId() };
return { userId: token.userId };
}
throw new InvalidGrant('unsupported subject token type');
};

View file

@ -180,7 +180,6 @@ describe('token exchange', () => {
expect(value).toMatchObject({
accountId,
clientId,
grantId: subjectTokenId,
gty: 'urn:ietf:params:oauth:grant-type:token-exchange',
});
});
@ -244,7 +243,6 @@ describe('token exchange', () => {
expect(value).toMatchObject({
accountId,
clientId,
grantId: subjectTokenId,
aud: 'urn:logto:organization:some_org_id',
});
});

View file

@ -82,7 +82,7 @@ export const buildHandler: (
scopes: oidcScopes,
} = providerInstance.configuration();
const { userId, grantId, subjectTokenId } = await validateSubjectToken(
const { userId, subjectTokenId } = await validateSubjectToken(
queries,
String(params.subject_token),
String(params.subject_token_type)
@ -103,9 +103,14 @@ export const buildHandler: (
clientId: client.clientId,
gty: GrantType.TokenExchange,
client,
grantId,
// The token exchange grant type does not have a grant ID or grant object,
// so we use an empty string here.
grantId: '',
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
scope: undefined!,
extra: {
...(subjectTokenId ? { subjectTokenId } : {}),
},
});
await handleDPoP(ctx, accessToken);
@ -184,7 +189,10 @@ export const buildHandler: (
// @see https://github.com/panva/node-oidc-provider/blob/main/lib/models/formats/jwt.js#L118
// We save the `act` data in the `extra` field temporarily,
// so that we can get this context it in the `extraTokenClaims` function and add it to the JWT.
accessToken.extra = { act: { sub: actorId } } satisfies TokenExchangeAct;
accessToken.extra = {
...accessToken.extra,
...({ act: { sub: actorId } } satisfies TokenExchangeAct),
};
}
ctx.oidc.entity('AccessToken', accessToken);