Skip to content

Commit 1a36b87

Browse files
authored
Merge pull request #1104 from Annouar/feat/add-resource-to-refresh-token
Add resource param to signinSilent request
2 parents 9c86813 + e5946f6 commit 1a36b87

7 files changed

+51
-6
lines changed

docs/oidc-client-ts.api.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ export class ErrorTimeout extends Error {
9191
export type ExtraHeader = string | (() => string);
9292

9393
// @public (undocumented)
94-
export type ExtraSigninRequestArgs = Pick<CreateSigninRequestArgs, "nonce" | "extraQueryParams" | "extraTokenParams" | "state" | "redirect_uri" | "prompt" | "acr_values" | "login_hint" | "scope" | "max_age" | "ui_locales">;
94+
export type ExtraSigninRequestArgs = Pick<CreateSigninRequestArgs, "nonce" | "extraQueryParams" | "extraTokenParams" | "state" | "redirect_uri" | "prompt" | "acr_values" | "login_hint" | "scope" | "max_age" | "ui_locales" | "resource">;
9595

9696
// @public (undocumented)
9797
export type ExtraSignoutRequestArgs = Pick<CreateSignoutRequestArgs, "extraQueryParams" | "state" | "id_token_hint" | "post_logout_redirect_uri">;

src/OidcClient.test.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ describe("OidcClient", () => {
422422
session_state: "session_state",
423423
scope: "openid",
424424
profile: {} as UserProfile,
425-
});
425+
}, "resource");
426426

427427
// act
428428
const response = await subject.useRefreshToken({ state });
@@ -432,6 +432,7 @@ describe("OidcClient", () => {
432432
refresh_token: "refresh_token",
433433
scope: "openid",
434434
timeoutInSeconds: undefined,
435+
resource: "resource",
435436
});
436437
expect(response).toBeInstanceOf(SigninResponse);
437438
expect(response).toMatchObject(tokenResponse);

src/OidcClient.ts

+1
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ export class OidcClient {
201201

202202
const result = await this._tokenClient.exchangeRefreshToken({
203203
refresh_token: state.refresh_token,
204+
resource: state.resource,
204205
// provide the (possible filtered) scope list
205206
scope,
206207
timeoutInSeconds,

src/RefreshState.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export class RefreshState {
1717
public readonly session_state: string | null;
1818
public readonly scope?: string;
1919
public readonly profile: UserProfile;
20+
public readonly resource?: string | string[];
2021

2122
constructor(args: {
2223
refresh_token: string;
@@ -26,13 +27,15 @@ export class RefreshState {
2627
profile: UserProfile;
2728

2829
state?: unknown;
29-
}) {
30+
}, resource?: string | string[]) {
3031
this.refresh_token = args.refresh_token;
3132
this.id_token = args.id_token;
3233
this.session_state = args.session_state;
3334
this.scope = args.scope;
3435
this.profile = args.profile;
36+
this.resource = resource;
3537

3638
this.data = args.state;
39+
3740
}
3841
}

src/TokenClient.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export interface ExchangeRefreshTokenArgs {
4343
grant_type?: string;
4444
refresh_token: string;
4545
scope?: string;
46+
resource?: string | string[];
4647

4748
timeoutInSeconds?: number;
4849
}
@@ -201,7 +202,10 @@ export class TokenClient {
201202

202203
const params = new URLSearchParams({ grant_type });
203204
for (const [key, value] of Object.entries(args)) {
204-
if (value != null) {
205+
if (Array.isArray(value)) {
206+
value.forEach(param => params.append(key, param));
207+
}
208+
else if (value != null) {
205209
params.set(key, value);
206210
}
207211
}

src/UserManager.test.ts

+35
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,41 @@ describe("UserManager", () => {
505505
}),
506506
);
507507
});
508+
509+
it("should use the resource from settings when a refresh token is present", async () => {
510+
// arrange
511+
const user = new User({
512+
access_token: "access_token",
513+
token_type: "token_type",
514+
refresh_token: "refresh_token",
515+
profile: {
516+
sub: "sub",
517+
nickname: "Nick",
518+
} as UserProfile,
519+
});
520+
521+
const useRefreshTokenSpy = jest.spyOn(subject["_client"], "useRefreshToken").mockResolvedValue({
522+
access_token: "new_access_token",
523+
profile: {
524+
sub: "sub",
525+
nickname: "Nicholas",
526+
},
527+
} as unknown as SigninResponse);
528+
subject["_loadUser"] = jest.fn().mockResolvedValue(user);
529+
530+
// act
531+
await subject.signinSilent({ resource: "resource" });
532+
expect(useRefreshTokenSpy).toBeCalledWith(
533+
expect.objectContaining({
534+
state: {
535+
resource: "resource",
536+
refresh_token: user.refresh_token,
537+
session_state: null,
538+
"profile": { "nickname": "Nick", "sub": "sub" },
539+
},
540+
}),
541+
);
542+
});
508543
});
509544

510545
describe("signinSilentCallback", () => {

src/UserManager.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import type { SigninResponse } from "./SigninResponse";
2020
/**
2121
* @public
2222
*/
23-
export type ExtraSigninRequestArgs = Pick<CreateSigninRequestArgs, "nonce" | "extraQueryParams" | "extraTokenParams" | "state" | "redirect_uri" | "prompt" | "acr_values" | "login_hint" | "scope" | "max_age" | "ui_locales" >;
23+
export type ExtraSigninRequestArgs = Pick<CreateSigninRequestArgs, "nonce" | "extraQueryParams" | "extraTokenParams" | "state" | "redirect_uri" | "prompt" | "acr_values" | "login_hint" | "scope" | "max_age" | "ui_locales" | "resource">;
2424
/**
2525
* @public
2626
*/
@@ -256,13 +256,14 @@ export class UserManager {
256256
const logger = this._logger.create("signinSilent");
257257
const {
258258
silentRequestTimeoutInSeconds,
259+
resource,
259260
...requestArgs
260261
} = args;
261262
// first determine if we have a refresh token, or need to use iframe
262263
let user = await this._loadUser();
263264
if (user?.refresh_token) {
264265
logger.debug("using refresh token");
265-
const state = new RefreshState(user as Required<User>);
266+
const state = new RefreshState(user as Required<User>, resource);
266267
return await this._useRefreshToken(state);
267268
}
268269

0 commit comments

Comments
 (0)