Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/grants/abstract/abstract.grant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,9 @@ export abstract class AbstractGrant implements GrantInterface {
req: RequestInterface,
client: OAuthClient,
user?: OAuthUser | null,
originatingAuthCodeId?: string,
): Promise<ExtraAccessTokenFields> {
const extraJwtFields = await this.jwt.extraTokenFields?.({ user, client });
const extraJwtFields = await this.jwt.extraTokenFields?.({ user, client, originatingAuthCodeId });
const aud: string[] | string | undefined =
this.getQueryStringParameter("audience", req) ??
this.getRequestParameter("audience", req) ??
Expand Down
2 changes: 1 addition & 1 deletion src/grants/auth_code.grant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export class AuthCodeGrant extends AbstractAuthorizedGrant {

await this.authCodeRepository.revoke(validatedPayload.auth_code_id);

const extraJwtFields = await this.extraJwtFields(req, client, user);
const extraJwtFields = await this.extraJwtFields(req, client, user, accessToken.originatingAuthCodeId);

return await this.makeBearerTokenResponse(client, accessToken, scopes, extraJwtFields);
}
Expand Down
2 changes: 1 addition & 1 deletion src/grants/refresh_token.grant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class RefreshTokenGrant extends AbstractGrant {

newToken = await this.issueRefreshToken(newToken, client);

const extraJwtFields = await this.extraJwtFields(req, client, user);
const extraJwtFields = await this.extraJwtFields(req, client, user, newToken.originatingAuthCodeId);

return await this.makeBearerTokenResponse(client, newToken, scopes, extraJwtFields);
}
Expand Down
1 change: 1 addition & 0 deletions src/utils/jwt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export type ExtraAccessTokenFields = Record<string, string | number | boolean |
export type ExtraAccessTokenFieldArgs = {
user?: OAuthUser | null;
client: OAuthClient;
originatingAuthCodeId?: string;
};
export interface JwtInterface {
verify(token: string, options?: VerifyOptions): Promise<Record<string, unknown>>;
Expand Down
21 changes: 20 additions & 1 deletion test/e2e/grants/auth_code.grant.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { beforeEach, describe, expect, it } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";

import { decode } from "jsonwebtoken";

Expand Down Expand Up @@ -471,6 +471,25 @@ describe("authorization_code grant", () => {
authorizationCode = String(authorizeResponseQuery.get("code"));
});

it("provides originatingAuthCodeId as argument to extraJwtFields", async () => {
request = new OAuthRequest({
body: {
grant_type: "authorization_code",
code: authorizationCode,
redirect_uri: authorizationRequest.redirectUri,
client_id: client.id,
code_verifier: codeVerifier,
},
});

const extraJwtFieldsSpy = vi.spyOn(grant as any, "extraJwtFields");

const accessTokenResponse = await grant.respondToAccessTokenRequest(request, new DateInterval("1h"));

expectTokenResponse(accessTokenResponse);
expect(extraJwtFieldsSpy).toHaveBeenCalledWith(request, client, user, "my-super-secret-auth-code");
});

it("is successful with pkce S256", async () => {
// act
request = new OAuthRequest({
Expand Down
25 changes: 24 additions & 1 deletion test/e2e/grants/refresh_token.grant.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,30 @@ describe("refresh_token grant", () => {
expectTokenResponse(tokenResponse);
expect(tokenResponse.body.scope).toBe("scope-1");
expect(tokenResponse.body.refresh_token).toMatch(REGEX_ACCESS_TOKEN);
expect(extraJwtFieldsSpy).toHaveBeenCalledWith(request, client, user);
expect(extraJwtFieldsSpy).toHaveBeenCalledWith(request, client, user, undefined);
});

it("provides originatingAuthCodeId as argument to extraJwtFields", async () => {
accessToken.originatingAuthCodeId = "my-super-secret-auth-code";

// arrange
const bearerResponse = await grant.makeBearerTokenResponse(client, accessToken);
request = new OAuthRequest({
body: {
grant_type: "refresh_token",
client_id: client.id,
client_secret: client.secret,
refresh_token: bearerResponse.body.refresh_token,
scope: "scope-1",
},
});
const accessTokenTTL = new DateInterval("1h");

const extraJwtFieldsSpy = vi.spyOn(grant as any, "extraJwtFields");

await grant.respondToAccessTokenRequest(request, accessTokenTTL);

expect(extraJwtFieldsSpy).toHaveBeenCalledWith(request, client, user, "my-super-secret-auth-code");
});

it("successful without scope", async () => {
Expand Down