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:
parent
f0bbc2a1f4
commit
06f98634c1
4 changed files with 22 additions and 10 deletions
|
@ -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,
|
||||
|
|
|
@ -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');
|
||||
};
|
||||
|
|
|
@ -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',
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue