Skip to content

Commit ccd61c8

Browse files
fix: ensure authorization_details is correctly returned as an array
1 parent d03b8fc commit ccd61c8

File tree

2 files changed

+36
-11
lines changed

2 files changed

+36
-11
lines changed

src/auth/backchannel.ts

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ const getLoginHint = (userId: string, domain: string): string => {
7373
/**
7474
* Options for the authorize request.
7575
*/
76-
export type AuthorizeOptions = {
76+
export interface AuthorizeOptions<
77+
TAuthorizationDetails extends AuthorizationDetails = AuthorizationDetails
78+
> {
7779
/**
7880
* A human-readable string intended to be displayed on both the device calling /bc-authorize and the user’s authentication device.
7981
*/
@@ -102,18 +104,28 @@ export type AuthorizeOptions = {
102104
* Optional authorization details to use Rich Authorization Requests (RAR).
103105
* @see https://auth0.com/docs/get-started/apis/configure-rich-authorization-requests
104106
*/
105-
authorization_details?: string;
106-
} & Record<string, string>;
107+
authorization_details?: string | TAuthorizationDetails[];
108+
109+
[key: string]: unknown;
110+
}
107111

108112
type AuthorizeRequest = Omit<AuthorizeOptions, 'userId'> &
109113
AuthorizeCredentialsPartial & {
110114
login_hint: string;
111-
};
115+
authorization_details?: string;
116+
} & Record<string, string>;
117+
118+
interface AuthorizationDetails {
119+
readonly type: string;
120+
readonly [parameter: string]: unknown;
121+
}
112122

113123
/**
114124
* The response from the token endpoint.
115125
*/
116-
export type TokenResponse = {
126+
export interface TokenResponse<
127+
TAuthorizationDetails extends AuthorizationDetails = AuthorizationDetails
128+
> {
117129
/**
118130
* The access token.
119131
*/
@@ -142,8 +154,8 @@ export type TokenResponse = {
142154
* Optional authorization details when using Rich Authorization Requests (RAR).
143155
* @see https://auth0.com/docs/get-started/apis/configure-rich-authorization-requests
144156
*/
145-
authorization_details?: string;
146-
};
157+
authorization_details?: TAuthorizationDetails[];
158+
}
147159

148160
/**
149161
* Options for the token request.
@@ -185,8 +197,18 @@ export class Backchannel extends BaseAuthAPI implements IBackchannel {
185197
* @throws {Error} - If the request fails.
186198
*/
187199
async authorize({ userId, ...options }: AuthorizeOptions): Promise<AuthorizeResponse> {
200+
const { authorization_details, ...authorizeOptions } = options;
201+
202+
if (authorization_details) {
203+
// Convert to string if not already
204+
authorizeOptions.authorization_details =
205+
typeof authorization_details !== 'string'
206+
? JSON.stringify(authorization_details)
207+
: authorization_details;
208+
}
209+
188210
const body: AuthorizeRequest = {
189-
...options,
211+
...authorizeOptions,
190212
login_hint: getLoginHint(userId, this.domain),
191213
client_id: this.clientId,
192214
};
@@ -239,7 +261,9 @@ export class Backchannel extends BaseAuthAPI implements IBackchannel {
239261
* }
240262
* ```
241263
*/
242-
async backchannelGrant({ auth_req_id }: TokenOptions): Promise<TokenResponse> {
264+
async backchannelGrant<
265+
TAuthorizationDetails extends AuthorizationDetails = AuthorizationDetails
266+
>({ auth_req_id }: TokenOptions): Promise<TokenResponse<TAuthorizationDetails>> {
243267
const body: TokenRequestBody = {
244268
client_id: this.clientId,
245269
auth_req_id,
@@ -258,7 +282,8 @@ export class Backchannel extends BaseAuthAPI implements IBackchannel {
258282
{}
259283
);
260284

261-
const r: JSONApiResponse<TokenResponse> = await JSONApiResponse.fromResponse(response);
285+
const r: JSONApiResponse<TokenResponse<TAuthorizationDetails>> =
286+
await JSONApiResponse.fromResponse(response);
262287
return r.data;
263288
}
264289
}

test/auth/backchannel.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ describe('Backchannel', () => {
238238
});
239239

240240
it('should return token response, including authorization_details when available', async () => {
241-
const authorization_details = JSON.stringify([{ type: 'test-type' }]);
241+
const authorization_details = [{ type: 'test-type' }];
242242
nock(`https://${opts.domain}`).post('/oauth/token').reply(200, {
243243
access_token: 'test-access-token',
244244
id_token: 'test-id-token',

0 commit comments

Comments
 (0)