-
Notifications
You must be signed in to change notification settings - Fork 475
fix(shared): type JWT aud as string or string array #9585
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
878c1ca
11f97b7
622a958
7096d62
7611b5a
ff09c98
b08236b
e5d6f96
16ce935
c24bb0b
4f5da4a
a03fa0b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| '@clerk/backend': minor | ||
| --- | ||
|
|
||
| Expose the optional `aud` audience on verified OAuth access tokens. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ import type { JwtPayload } from '@clerk/shared/types'; | |
| import type { IdPOAuthAccessTokenJSON } from './JSON'; | ||
|
|
||
| type OAuthJwtPayload = JwtPayload & { | ||
| aud?: string | string[]; | ||
| jti?: string; | ||
| client_id?: string; | ||
| scope?: string; | ||
|
|
@@ -19,12 +20,14 @@ export class IdPOAuthAccessToken { | |
| readonly revoked: boolean, | ||
| readonly revocationReason: string | null, | ||
| readonly expired: boolean, | ||
| /** The Unix timestamp (in milliseconds) when the access token expires. */ | ||
| /** The Unix timestamp (in seconds) when the access token expires. */ | ||
| readonly expiration: number | null, | ||
| /** The Unix timestamp (in milliseconds) when the access token was created. */ | ||
| /** The Unix timestamp (in seconds) when the access token was created. */ | ||
| readonly createdAt: number, | ||
| /** The Unix timestamp (in milliseconds) when the access token was last updated. */ | ||
| /** The Unix timestamp (in seconds) when the access token was last updated. */ | ||
|
Comment on lines
+23
to
+27
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These are indeed // import { createClerkClient, type ClerkClient } from "@clerk/backend";
const res = await this.clerk.idPOAuthAccessToken.verify(token);
console.log(res);
// _IdPOAuthAccessToken {
// id: 'oat_3Je6nsrhV3q0O0iaa1XoIZQaG8j',
// clientId: 'Ggdsp1aBiyjnuXmO',
// type: undefined,
// subject: 'user_35foINd28ksQr65MyKacPf0APEZ',
// scopes: [ 'email', 'offline_access', 'openid', 'profile' ],
// revoked: false,
// revocationReason: null,
// expired: false,
// expiration: 1790095756,
// createdAt: 1790009356,
// updatedAt: 1790009356,
// aud: [ 'http://localhost:8787/mcp' ]
// } |
||
| readonly updatedAt: number, | ||
| /** The intended audience for the access token. */ | ||
| readonly aud?: string[], | ||
| ) {} | ||
|
|
||
| static fromJSON(data: IdPOAuthAccessTokenJSON) { | ||
|
|
@@ -40,12 +43,14 @@ export class IdPOAuthAccessToken { | |
| data.expiration, | ||
| data.created_at, | ||
| data.updated_at, | ||
| data.aud, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [MEDIUM] The opaque This line makes A resource server B that calls Running the returned — Comment generated 🤖 with @dominic-clerk's supervision (
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be handled in #9724 |
||
| ); | ||
| } | ||
|
|
||
| /** | ||
| * Creates an IdPOAuthAccessToken from a JWT payload. | ||
| * Maps standard JWT claims and OAuth-specific fields to token properties. | ||
| * The raw JWT `aud` claim can be a string, string[], or undefined. It is normalized to string[]. | ||
| */ | ||
| static fromJwtPayload(payload: JwtPayload, clockSkewInMs = 5000): IdPOAuthAccessToken { | ||
| const oauthPayload = payload as OAuthJwtPayload; | ||
|
|
@@ -63,6 +68,7 @@ export class IdPOAuthAccessToken { | |
| payload.exp * 1000, // milliseconds: expiration, converted from JWT exp claim | ||
| payload.iat * 1000, // milliseconds: createdAt, converted from JWT iat claim | ||
| payload.iat * 1000, // milliseconds: updatedAt, no JWT equivalent, defaults to iat | ||
| oauthPayload.aud === undefined ? undefined : [oauthPayload.aud].flat(), | ||
| ); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Raw JWT access token can hold
stringorstring[](or omitted)And the SDK will normalize it to
string[](or omitted)