Skip to content

Commit

Permalink
fix: authts#167 round tripping "state" is missing
Browse files Browse the repository at this point in the history
  • Loading branch information
pamapa committed Nov 2, 2021
1 parent db6a72e commit 2d5da0f
Show file tree
Hide file tree
Showing 10 changed files with 38 additions and 17 deletions.
7 changes: 5 additions & 2 deletions docs/oidc-client-ts.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export interface CreateSigninRequestArgs {
// (undocumented)
skipUserInfo?: boolean;
// (undocumented)
state?: any;
state?: unknown;
// (undocumented)
ui_locales?: string;
}
Expand Down Expand Up @@ -194,7 +194,7 @@ export class OidcClient {
}>;
// (undocumented)
readSignoutResponseState(url?: string, removeState?: boolean): Promise<{
state: undefined | State;
state: State | undefined;
response: SignoutResponse;
}>;
// (undocumented)
Expand Down Expand Up @@ -329,6 +329,7 @@ export class User {
scope?: string;
profile: UserProfile;
expires_at?: number;
state?: unknown;
});
// (undocumented)
access_token: string;
Expand Down Expand Up @@ -356,6 +357,8 @@ export class User {
// (undocumented)
session_state: string | undefined;
// (undocumented)
readonly state: unknown | undefined;
// (undocumented)
token_type: string;
// (undocumented)
toStorageString(): string;
Expand Down
2 changes: 1 addition & 1 deletion samples/Parcel/src/user-manager/sample.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ function removeUser() {
}

function startSigninMainWindow() {
mgr.signinRedirect().then(function() {
mgr.signinRedirect({ state: { some: "data" } }).then(function() {
log("signinRedirect done");
}).catch(function(err) {
log(err);
Expand Down
6 changes: 4 additions & 2 deletions src/ErrorResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ export class ErrorResponse extends Error {
public readonly error_description: string | undefined;
public readonly error_uri: string | undefined;

public readonly state: any;
public readonly session_state: string | undefined;

// custom "state", which can be used by a caller to have "data" round tripped
public state: unknown | undefined;

public constructor(args: {
error?: string; error_description?: string; error_uri?: string; state?: any; session_state?: string;
error?: string; error_description?: string; error_uri?: string; state?: unknown; session_state?: string;
}) {
if (!args.error) {
Log.error("No error passed to ErrorResponse");
Expand Down
10 changes: 5 additions & 5 deletions src/OidcClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ export interface CreateSigninRequestArgs {
response_type?: string;
scope?: string;

// state can be used by a caller to have data round tripped
state?: any;
// custom "state", which can be used by a caller to have "data" round tripped
state?: unknown;

prompt?: string;
display?: string;
Expand Down Expand Up @@ -127,7 +127,7 @@ export class OidcClient {
const stateStore = this.settings.stateStore;
const stateApi = removeState ? stateStore.remove.bind(stateStore) : stateStore.get.bind(stateStore);

const storedStateString = await stateApi(response.state);
const storedStateString = await stateApi(response.state as string);
if (!storedStateString) {
Log.error("OidcClient.readSigninResponseState: No matching state found in storage");
throw new Error("No matching state found in storage");
Expand Down Expand Up @@ -180,7 +180,7 @@ export class OidcClient {
return request;
}

public async readSignoutResponseState(url?: string, removeState = false): Promise<{ state: undefined | State; response: SignoutResponse }> {
public async readSignoutResponseState(url?: string, removeState = false): Promise<{ state: State | undefined; response: SignoutResponse }> {
Log.debug("OidcClient.readSignoutResponseState");

const response = new SignoutResponse(url);
Expand All @@ -199,7 +199,7 @@ export class OidcClient {
const stateStore = this.settings.stateStore;

const stateApi = removeState ? stateStore.remove.bind(stateStore) : stateStore.get.bind(stateStore);
const storedStateString = await stateApi(stateKey);
const storedStateString = await stateApi(stateKey as string);
if (!storedStateString) {
Log.error("OidcClient.readSignoutResponseState: No matching state found in storage");
throw new Error("No matching state found in storage");
Expand Down
4 changes: 3 additions & 1 deletion src/SigninRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ export interface SigninRequestArgs {
scope: string;

// optional
state_data?: any;
prompt?: string;
display?: string;
max_age?: number;
Expand All @@ -31,6 +30,9 @@ export interface SigninRequestArgs {
client_secret?: string;
extraTokenParams?: Record<string, any>;
skipUserInfo?: boolean;

// custom "state", which can be used by a caller to have "data" round tripped
state_data?: unknown;
}

export class SigninRequest {
Expand Down
4 changes: 3 additions & 1 deletion src/SigninResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ export class SigninResponse {
public readonly code: string;

// updated by ResponseValidator
public state: any | undefined;
// first state id, then
// custom "state", which can be used by a caller to have "data" round tripped
public state: string | unknown | undefined;

// updated by ResponseValidator
public error: string | undefined;
Expand Down
5 changes: 4 additions & 1 deletion src/SignoutResponse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ export class SignoutResponse {
public error_description: string | undefined;
public error_uri: string | undefined;

public state: any | undefined;
// updated by ResponseValidator
// first state id, then
// custom "state", which can be used by a caller to have "data" round tripped
public state: string | unknown | undefined;

public constructor(url?: string) {
const values = UrlUtils.parseUrlFragment(url, "?");
Expand Down
6 changes: 4 additions & 2 deletions src/State.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import type { StateStore } from "./StateStore";

export class State {
public readonly id: string;
public readonly data: any;
public readonly created: number;
public readonly request_type: string | undefined;

// custom "state", which can be used by a caller to have "data" round tripped
public readonly data: unknown | undefined;

public constructor(args: {
id?: string;
data?: any;
data?: unknown;
created?: number;
request_type?: string;
}) {
Expand Down
7 changes: 7 additions & 0 deletions src/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,31 @@ export class User {
public session_state: string | undefined;
public access_token: string;
public refresh_token: string | undefined;

public token_type: string;
public scope: string | undefined;
public profile: UserProfile;
public expires_at: number | undefined;

// custom "state", which can be used by a caller to have "data" round tripped
public readonly state: unknown | undefined;

public constructor(args: {
id_token?: string; session_state?: string;
access_token: string; refresh_token?: string;
token_type: string; scope?: string; profile: UserProfile; expires_at?: number;
state?: unknown;
}) {
this.id_token = args.id_token;
this.session_state = args.session_state;
this.access_token = args.access_token;
this.refresh_token = args.refresh_token;

this.token_type = args.token_type;
this.scope = args.scope;
this.profile = args.profile;
this.expires_at = args.expires_at;
this.state = args.state;
}

public get expires_in(): number | undefined {
Expand Down
4 changes: 2 additions & 2 deletions src/UserManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import type { SignoutResponse } from "./SignoutResponse";
import { ErrorResponse } from "./ErrorResponse";
import type { MetadataService } from "./MetadataService";

type ExtraSigninRequestArgs = Pick<CreateSigninRequestArgs, "extraQueryParams" | "extraTokenParams">
type ExtraSignoutRequestArgs = Pick<CreateSignoutRequestArgs, "extraQueryParams">
type ExtraSigninRequestArgs = Pick<CreateSigninRequestArgs, "extraQueryParams" | "extraTokenParams" | "state">
type ExtraSignoutRequestArgs = Pick<CreateSignoutRequestArgs, "extraQueryParams" | "state">

/**
* @public
Expand Down

0 comments on commit 2d5da0f

Please sign in to comment.