@axinom/mosaic-user-auth 0.29.0-rc.6 → 0.29.0-rc.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/UserServiceClient/UserServiceClient.d.ts +75 -1
- package/dist/cjs/UserServiceClient/UserServiceClient.d.ts.map +1 -1
- package/dist/cjs/index.d.ts +3 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +368 -27
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/util/deviceAuth.d.ts +65 -0
- package/dist/cjs/util/deviceAuth.d.ts.map +1 -0
- package/dist/esm/UserServiceClient/UserServiceClient.d.ts +75 -1
- package/dist/esm/UserServiceClient/UserServiceClient.d.ts.map +1 -1
- package/dist/esm/index.d.ts +3 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +355 -14
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/util/deviceAuth.d.ts +65 -0
- package/dist/esm/util/deviceAuth.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/UserServiceClient/UserServiceClient.ts +158 -0
- package/src/index.ts +18 -1
- package/src/util/deviceAuth.spec.ts +286 -0
- package/src/util/deviceAuth.ts +295 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type CheckPasswordResetOtpResponse, type CheckUserSignUpOtpResponse, type CompletePasswordResetResponse, type CompleteUserSignUpResponse, type DecryptNativeCookieResponse, type IdpConfiguration, type InitiatePasswordResetResponse, type SignInResponse, type UserSignUpResponse } from '@axinom/mosaic-user-auth-utils';
|
|
1
|
+
import { type CheckPasswordResetOtpResponse, type CheckUserSignUpOtpResponse, type CompletePasswordResetResponse, type CompleteUserSignUpResponse, type DecryptNativeCookieResponse, type DeviceApprovalResponse, type DeviceAuthorizationRequest, type DeviceAuthorizationResponse, type DevicePollResponse, type DeviceVerificationResponse, type IdpConfiguration, type InitiatePasswordResetResponse, type SignInResponse, type TokenResponse as UserAuthTokenResponse, type UserSignUpResponse } from '@axinom/mosaic-user-auth-utils';
|
|
2
2
|
import { TokenRenewalMethod } from '../common/enums.js';
|
|
3
3
|
import type { AuthenticateEndUserApplicationResponse, SignInRequest, TokenChangedCallback, TokenResponse, UserAuthConfig, UserProfileActivateResponse, UserProfileCreateResponse, UserProfileDeleteResponse, UserProfileResponse, UserProfileUpdateInput, UserProfileUpdateResponse, UserProfilesResponse, UserServiceConfig } from '../common/types.js';
|
|
4
4
|
import type { CheckEndUserPasswordResetOtpInput, CheckEndUserSignUpOtpInput, CompleteEndUserPasswordResetInput, CompleteEndUserSignUpInput, InitiateEndUserSignUpInput } from '../generated/ax-auth-management-graphql.types.js';
|
|
@@ -25,6 +25,17 @@ export interface IUserServiceClient {
|
|
|
25
25
|
deleteUserProfile(endUserAccessToken: string, userProfileId: string): Promise<UserProfileDeleteResponse>;
|
|
26
26
|
authenticateEndUserApplication(authenticateEndUserApplicationRequest: AuthenticateEndUserApplicationInput): Promise<AuthenticateEndUserApplicationResponse>;
|
|
27
27
|
decryptNativeCookie(encryptedCookie: string, key: string): Promise<DecryptNativeCookieResponse>;
|
|
28
|
+
requestDeviceAuthorization(request?: DeviceAuthorizationRequest): Promise<DeviceAuthorizationResponse>;
|
|
29
|
+
requestDeviceRefreshToken(deviceCode: string): Promise<DevicePollResponse>;
|
|
30
|
+
pollDeviceRefreshToken(deviceCode: string, options: {
|
|
31
|
+
intervalSeconds: number;
|
|
32
|
+
signal?: AbortSignal;
|
|
33
|
+
onPending?: (response: DevicePollResponse) => void;
|
|
34
|
+
}): Promise<DevicePollResponse>;
|
|
35
|
+
getDeviceAccessToken(refreshToken: string): Promise<UserAuthTokenResponse>;
|
|
36
|
+
getDeviceVerification(userCode: string): Promise<DeviceVerificationResponse>;
|
|
37
|
+
approveDevice(endUserAccessToken: string, userCode: string): Promise<DeviceApprovalResponse>;
|
|
38
|
+
denyDevice(endUserAccessToken: string, userCode: string): Promise<DeviceApprovalResponse>;
|
|
28
39
|
getAuthUrl(idpConnectionId: string, redirectUrl: string): URL;
|
|
29
40
|
getNativeAuthUrl(idpConnectionId: string, redirectUri: string, encryptionKey: string): URL;
|
|
30
41
|
}
|
|
@@ -186,6 +197,69 @@ export declare class UserServiceClient implements IUserServiceClient {
|
|
|
186
197
|
* @returns
|
|
187
198
|
*/
|
|
188
199
|
decryptNativeCookie: (encryptedCookie: string, key: string) => Promise<DecryptNativeCookieResponse>;
|
|
200
|
+
/**
|
|
201
|
+
* Starts the Device Authorization grant for the device (a NATIVE application).
|
|
202
|
+
* Returns the `userCode` / `verificationUri` to show the user and the `deviceCode` to poll with.
|
|
203
|
+
*
|
|
204
|
+
* NOTE: The device flow is headless and does NOT use the `AX_REFRESH_TOKEN` cookie — the
|
|
205
|
+
* device's tokens are carried explicitly. @see {@link pollDeviceRefreshToken} / {@link getDeviceAccessToken}.
|
|
206
|
+
*
|
|
207
|
+
* @param request Optional request body (a display-only `deviceLabel`).
|
|
208
|
+
*/
|
|
209
|
+
requestDeviceAuthorization: (request?: DeviceAuthorizationRequest) => Promise<DeviceAuthorizationResponse>;
|
|
210
|
+
/**
|
|
211
|
+
* Performs a single poll. Prefer {@link pollDeviceRefreshToken} for the polling loop. On SUCCESS
|
|
212
|
+
* the response carries the device `refreshToken`; pass it to {@link getDeviceAccessToken}.
|
|
213
|
+
*
|
|
214
|
+
* @param deviceCode The secret returned by {@link requestDeviceAuthorization}.
|
|
215
|
+
*/
|
|
216
|
+
requestDeviceRefreshToken: (deviceCode: string) => Promise<DevicePollResponse>;
|
|
217
|
+
/**
|
|
218
|
+
* Polls `device/poll` honouring the server interval and `SLOW_DOWN` back-off until the
|
|
219
|
+
* authorization reaches a terminal state (SUCCESS / ACCESS_DENIED / EXPIRED). On SUCCESS the
|
|
220
|
+
* response carries the device `refreshToken` — store it, then call {@link getDeviceAccessToken}
|
|
221
|
+
* to obtain an access token.
|
|
222
|
+
*
|
|
223
|
+
* @param deviceCode The secret returned by {@link requestDeviceAuthorization}.
|
|
224
|
+
* @param options.intervalSeconds Initial seconds between polls (from the authorize response).
|
|
225
|
+
* @param options.signal Optional `AbortSignal` to cancel polling.
|
|
226
|
+
* @param options.onPending Optional callback invoked on each non-terminal poll.
|
|
227
|
+
*/
|
|
228
|
+
pollDeviceRefreshToken: (deviceCode: string, options: {
|
|
229
|
+
intervalSeconds: number;
|
|
230
|
+
signal?: AbortSignal;
|
|
231
|
+
onPending?: (response: DevicePollResponse) => void;
|
|
232
|
+
}) => Promise<DevicePollResponse>;
|
|
233
|
+
/**
|
|
234
|
+
* Gets an access token for a device session from its refresh token — used for the
|
|
235
|
+
* first access token (right after the poll succeeds) and for every renewal. The refresh token is
|
|
236
|
+
* presented as a `Bearer` header, since the device cannot use the browser cookie.
|
|
237
|
+
*
|
|
238
|
+
* @param refreshToken The device refresh token from the SUCCESS device poll.
|
|
239
|
+
*/
|
|
240
|
+
getDeviceAccessToken: (refreshToken: string) => Promise<UserAuthTokenResponse>;
|
|
241
|
+
/**
|
|
242
|
+
* Reads what a given `userCode` is about to authorize (for the activation page). Anonymous and
|
|
243
|
+
* read-only — it never approves anything.
|
|
244
|
+
*
|
|
245
|
+
* @param userCode The short code the user typed on the activation page.
|
|
246
|
+
*/
|
|
247
|
+
getDeviceVerification: (userCode: string) => Promise<DeviceVerificationResponse>;
|
|
248
|
+
/**
|
|
249
|
+
* Approves a device authorization on behalf of the signed-in user. Requires the end-user
|
|
250
|
+
* access token (the same `Bearer` credential used for every other end-user API).
|
|
251
|
+
*
|
|
252
|
+
* @param endUserAccessToken The signed-in user's access token (JWT).
|
|
253
|
+
* @param userCode The short code shown on the device.
|
|
254
|
+
*/
|
|
255
|
+
approveDevice: (endUserAccessToken: string, userCode: string) => Promise<DeviceApprovalResponse>;
|
|
256
|
+
/**
|
|
257
|
+
* Denies a device authorization on behalf of the signed-in user.
|
|
258
|
+
*
|
|
259
|
+
* @param endUserAccessToken The signed-in user's access token (JWT).
|
|
260
|
+
* @param userCode The short code shown on the device.
|
|
261
|
+
*/
|
|
262
|
+
denyDevice: (endUserAccessToken: string, userCode: string) => Promise<DeviceApprovalResponse>;
|
|
189
263
|
/**
|
|
190
264
|
* Returns the authentication URL for web based applications.
|
|
191
265
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserServiceClient.d.ts","sourceRoot":"","sources":["../../../src/UserServiceClient/UserServiceClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,6BAA6B,EAClC,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EAClC,KAAK,0BAA0B,EAE/B,KAAK,2BAA2B,EAChC,KAAK,gBAAgB,EACrB,KAAK,6BAA6B,EAElC,KAAK,cAAc,EAGnB,KAAK,kBAAkB,EAExB,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EACV,sCAAsC,EACtC,aAAa,EAEb,oBAAoB,EACpB,aAAa,EACb,cAAc,EACd,2BAA2B,EAC3B,yBAAyB,EACzB,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,yBAAyB,EACzB,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EACV,iCAAiC,EACjC,0BAA0B,EAC1B,iCAAiC,EACjC,0BAA0B,EAC1B,0BAA0B,EAC3B,MAAM,kDAAkD,CAAC;AAC1D,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,uDAAuD,CAAC;
|
|
1
|
+
{"version":3,"file":"UserServiceClient.d.ts","sourceRoot":"","sources":["../../../src/UserServiceClient/UserServiceClient.ts"],"names":[],"mappings":"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"}
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export type { IdpConfiguration } from '@axinom/mosaic-user-auth-utils';
|
|
1
|
+
export type { DeviceApprovalRequest, DeviceApprovalResponse, DeviceAuthorizationRequest, DeviceAuthorizationResponse, DevicePollRequest, DevicePollResponse, DeviceVerificationResponse, IdpConfiguration, } from '@axinom/mosaic-user-auth-utils';
|
|
2
|
+
export { DeviceApprovalResponseCode, DeviceAuthorizationResponseCode, DeviceAuthorizationStatus, DevicePollResponseCode, DeviceVerificationResponseCode, } from '@axinom/mosaic-user-auth-utils';
|
|
2
3
|
export * from './common/enums.js';
|
|
3
4
|
export * from './common/types.js';
|
|
5
|
+
export type { IUserServiceClient } from './UserServiceClient/UserServiceClient.js';
|
|
4
6
|
export * from './UserServiceProvider/UserServiceProvider.js';
|
|
5
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/cjs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,EAC3B,iBAAiB,EACjB,kBAAkB,EAClB,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,0BAA0B,EAC1B,+BAA+B,EAC/B,yBAAyB,EACzB,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,gCAAgC,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,YAAY,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC;AACnF,cAAc,8CAA8C,CAAC"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -5,38 +5,25 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var React = require('react');
|
|
6
6
|
|
|
7
7
|
function _interopNamespace(e) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
if (e && e.__esModule) return e;
|
|
9
|
+
var n = Object.create(null);
|
|
10
|
+
if (e) {
|
|
11
|
+
Object.keys(e).forEach(function (k) {
|
|
12
|
+
if (k !== 'default') {
|
|
13
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
14
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return e[k]; }
|
|
17
|
+
});
|
|
18
|
+
}
|
|
17
19
|
});
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
n["default"] = e;
|
|
22
|
-
return Object.freeze(n);
|
|
20
|
+
}
|
|
21
|
+
n["default"] = e;
|
|
22
|
+
return Object.freeze(n);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
26
26
|
|
|
27
|
-
exports.TokenRenewalMethod = void 0;
|
|
28
|
-
(function (TokenRenewalMethod) {
|
|
29
|
-
/**
|
|
30
|
-
* The token is continuously renewed just before expiry.
|
|
31
|
-
* A `TokenChangedCallback` can be registered using `addTokenChangedHandler` method to get notified when the token changes.
|
|
32
|
-
*/
|
|
33
|
-
TokenRenewalMethod[TokenRenewalMethod["PRE_EMPTIVE"] = 0] = "PRE_EMPTIVE";
|
|
34
|
-
/**
|
|
35
|
-
* The token is renewed only if needed upon calling `getToken` method.
|
|
36
|
-
*/
|
|
37
|
-
TokenRenewalMethod[TokenRenewalMethod["ON_DEMAND"] = 1] = "ON_DEMAND";
|
|
38
|
-
})(exports.TokenRenewalMethod || (exports.TokenRenewalMethod = {}));
|
|
39
|
-
|
|
40
27
|
/**
|
|
41
28
|
* This is the Error Type that the REST middleware will respond when there's an error
|
|
42
29
|
* from the User Service that does not belong to Token/SignOut or IDPConfiguration responses.
|
|
@@ -137,6 +124,67 @@ var CheckOtpResponseCode;
|
|
|
137
124
|
CheckOtpResponseCode["ERROR"] = "ERROR";
|
|
138
125
|
CheckOtpResponseCode["SERVICE_CONFIGURATION_ERROR"] = "SERVICE_CONFIGURATION_ERROR";
|
|
139
126
|
})(CheckOtpResponseCode || (CheckOtpResponseCode = {}));
|
|
127
|
+
/**
|
|
128
|
+
* Response code for the Device Authorization request (the device starts the flow).
|
|
129
|
+
*/
|
|
130
|
+
exports.DeviceAuthorizationResponseCode = void 0;
|
|
131
|
+
(function (DeviceAuthorizationResponseCode) {
|
|
132
|
+
DeviceAuthorizationResponseCode["SUCCESS"] = "SUCCESS";
|
|
133
|
+
DeviceAuthorizationResponseCode["DEVICE_FLOW_NOT_ENABLED"] = "DEVICE_FLOW_NOT_ENABLED";
|
|
134
|
+
DeviceAuthorizationResponseCode["APPLICATION_NOT_ACTIVE"] = "APPLICATION_NOT_ACTIVE";
|
|
135
|
+
DeviceAuthorizationResponseCode["BAD_REQUEST"] = "BAD_REQUEST";
|
|
136
|
+
DeviceAuthorizationResponseCode["INTERNAL_SERVER_ERROR"] = "INTERNAL_SERVER_ERROR";
|
|
137
|
+
})(exports.DeviceAuthorizationResponseCode || (exports.DeviceAuthorizationResponseCode = {}));
|
|
138
|
+
/**
|
|
139
|
+
* Response code for the Device poll (the device polls until the user approves; on approval it
|
|
140
|
+
* receives its refresh token).
|
|
141
|
+
*/
|
|
142
|
+
exports.DevicePollResponseCode = void 0;
|
|
143
|
+
(function (DevicePollResponseCode) {
|
|
144
|
+
DevicePollResponseCode["SUCCESS"] = "SUCCESS";
|
|
145
|
+
DevicePollResponseCode["AUTHORIZATION_PENDING"] = "AUTHORIZATION_PENDING";
|
|
146
|
+
DevicePollResponseCode["SLOW_DOWN"] = "SLOW_DOWN";
|
|
147
|
+
DevicePollResponseCode["ACCESS_DENIED"] = "ACCESS_DENIED";
|
|
148
|
+
DevicePollResponseCode["EXPIRED"] = "EXPIRED";
|
|
149
|
+
DevicePollResponseCode["BAD_REQUEST"] = "BAD_REQUEST";
|
|
150
|
+
DevicePollResponseCode["INTERNAL_SERVER_ERROR"] = "INTERNAL_SERVER_ERROR";
|
|
151
|
+
})(exports.DevicePollResponseCode || (exports.DevicePollResponseCode = {}));
|
|
152
|
+
/**
|
|
153
|
+
* Response code for the Device Verification lookup (the activation page reads what a user code authorizes).
|
|
154
|
+
*/
|
|
155
|
+
exports.DeviceVerificationResponseCode = void 0;
|
|
156
|
+
(function (DeviceVerificationResponseCode) {
|
|
157
|
+
DeviceVerificationResponseCode["SUCCESS"] = "SUCCESS";
|
|
158
|
+
DeviceVerificationResponseCode["NOT_FOUND"] = "NOT_FOUND";
|
|
159
|
+
DeviceVerificationResponseCode["EXPIRED"] = "EXPIRED";
|
|
160
|
+
DeviceVerificationResponseCode["BAD_REQUEST"] = "BAD_REQUEST";
|
|
161
|
+
DeviceVerificationResponseCode["INTERNAL_SERVER_ERROR"] = "INTERNAL_SERVER_ERROR";
|
|
162
|
+
})(exports.DeviceVerificationResponseCode || (exports.DeviceVerificationResponseCode = {}));
|
|
163
|
+
/**
|
|
164
|
+
* Response code for Device Approval / Denial (the signed-in user approves or denies a device).
|
|
165
|
+
*/
|
|
166
|
+
exports.DeviceApprovalResponseCode = void 0;
|
|
167
|
+
(function (DeviceApprovalResponseCode) {
|
|
168
|
+
DeviceApprovalResponseCode["SUCCESS"] = "SUCCESS";
|
|
169
|
+
DeviceApprovalResponseCode["NOT_FOUND"] = "NOT_FOUND";
|
|
170
|
+
DeviceApprovalResponseCode["EXPIRED"] = "EXPIRED";
|
|
171
|
+
DeviceApprovalResponseCode["ALREADY_USED"] = "ALREADY_USED";
|
|
172
|
+
DeviceApprovalResponseCode["ACCESS_TOKEN_EXPIRED"] = "ACCESS_TOKEN_EXPIRED";
|
|
173
|
+
DeviceApprovalResponseCode["NEEDS_LOGIN"] = "NEEDS_LOGIN";
|
|
174
|
+
DeviceApprovalResponseCode["BAD_REQUEST"] = "BAD_REQUEST";
|
|
175
|
+
DeviceApprovalResponseCode["INTERNAL_SERVER_ERROR"] = "INTERNAL_SERVER_ERROR";
|
|
176
|
+
})(exports.DeviceApprovalResponseCode || (exports.DeviceApprovalResponseCode = {}));
|
|
177
|
+
/**
|
|
178
|
+
* Lifecycle status of a device authorization record.
|
|
179
|
+
*/
|
|
180
|
+
exports.DeviceAuthorizationStatus = void 0;
|
|
181
|
+
(function (DeviceAuthorizationStatus) {
|
|
182
|
+
DeviceAuthorizationStatus["PENDING"] = "PENDING";
|
|
183
|
+
DeviceAuthorizationStatus["APPROVED"] = "APPROVED";
|
|
184
|
+
DeviceAuthorizationStatus["DENIED"] = "DENIED";
|
|
185
|
+
DeviceAuthorizationStatus["EXPIRED"] = "EXPIRED";
|
|
186
|
+
DeviceAuthorizationStatus["REDEEMED"] = "REDEEMED";
|
|
187
|
+
})(exports.DeviceAuthorizationStatus || (exports.DeviceAuthorizationStatus = {}));
|
|
140
188
|
/**
|
|
141
189
|
* IDP Protocol categories
|
|
142
190
|
*/
|
|
@@ -209,6 +257,19 @@ var AuthenticateEndUserApplicationResponseCode;
|
|
|
209
257
|
},
|
|
210
258
|
});
|
|
211
259
|
|
|
260
|
+
exports.TokenRenewalMethod = void 0;
|
|
261
|
+
(function (TokenRenewalMethod) {
|
|
262
|
+
/**
|
|
263
|
+
* The token is continuously renewed just before expiry.
|
|
264
|
+
* A `TokenChangedCallback` can be registered using `addTokenChangedHandler` method to get notified when the token changes.
|
|
265
|
+
*/
|
|
266
|
+
TokenRenewalMethod[TokenRenewalMethod["PRE_EMPTIVE"] = 0] = "PRE_EMPTIVE";
|
|
267
|
+
/**
|
|
268
|
+
* The token is renewed only if needed upon calling `getToken` method.
|
|
269
|
+
*/
|
|
270
|
+
TokenRenewalMethod[TokenRenewalMethod["ON_DEMAND"] = 1] = "ON_DEMAND";
|
|
271
|
+
})(exports.TokenRenewalMethod || (exports.TokenRenewalMethod = {}));
|
|
272
|
+
|
|
212
273
|
/**
|
|
213
274
|
* Ensures that an error is an actual instance of an error.
|
|
214
275
|
*
|
|
@@ -245,6 +306,213 @@ class UserAuthError extends Error {
|
|
|
245
306
|
}
|
|
246
307
|
}
|
|
247
308
|
|
|
309
|
+
/**
|
|
310
|
+
* Builds an application-scoped User Service Auth endpoint URL.
|
|
311
|
+
*
|
|
312
|
+
* NOTE: The device flow is headless — none of these calls rely on the `AX_REFRESH_TOKEN`
|
|
313
|
+
* cookie that the web flow uses. The device's refresh token is carried explicitly (in the
|
|
314
|
+
* response body / a `Bearer` header), which is why every fetch here uses `credentials: 'omit'`.
|
|
315
|
+
* This keeps the device token path fully separate from the browser cookie path.
|
|
316
|
+
*/
|
|
317
|
+
const buildDeviceEndpointUrl = (userAuthConfig, action) => new URL(`${userAuthConfig.tenantId}/${userAuthConfig.environmentId}/${userAuthConfig.applicationId}/${action}`, userAuthConfig.userAuthBaseUrl);
|
|
318
|
+
/**
|
|
319
|
+
* Starts the device authorization flow (called by the device — a NATIVE application). Returns the
|
|
320
|
+
* `deviceCode` to poll with and the `userCode` / `verificationUri` to show the user.
|
|
321
|
+
*
|
|
322
|
+
* @param userAuthConfig An object containing user authentication info.
|
|
323
|
+
* @param request Optional request body (a display-only `deviceLabel`).
|
|
324
|
+
*/
|
|
325
|
+
const requestDeviceAuthorization = async (userAuthConfig, request = {}) => {
|
|
326
|
+
try {
|
|
327
|
+
return (await (await fetch(buildDeviceEndpointUrl(userAuthConfig, 'device/authorize').href, {
|
|
328
|
+
method: 'POST',
|
|
329
|
+
cache: 'no-cache',
|
|
330
|
+
credentials: 'omit',
|
|
331
|
+
redirect: 'follow',
|
|
332
|
+
referrerPolicy: 'origin',
|
|
333
|
+
headers: { 'content-type': 'application/json' },
|
|
334
|
+
body: JSON.stringify(request),
|
|
335
|
+
})).json());
|
|
336
|
+
}
|
|
337
|
+
catch (e) {
|
|
338
|
+
return {
|
|
339
|
+
code: exports.DeviceAuthorizationResponseCode.INTERNAL_SERVER_ERROR,
|
|
340
|
+
message: ensureError(e).message,
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
/**
|
|
345
|
+
* Performs a single poll (called by the device). The endpoint always returns HTTP 200
|
|
346
|
+
* with a `{ code }` body — poll states (AUTHORIZATION_PENDING / SLOW_DOWN) are NOT HTTP errors.
|
|
347
|
+
* On SUCCESS it returns the device's `refreshToken`; call {@link getDeviceAccessToken} with it to
|
|
348
|
+
* obtain an access token. Use {@link pollDeviceRefreshToken} for the convenience polling loop.
|
|
349
|
+
*
|
|
350
|
+
* @param userAuthConfig An object containing user authentication info.
|
|
351
|
+
* @param deviceCode The secret returned by {@link requestDeviceAuthorization}.
|
|
352
|
+
*/
|
|
353
|
+
const requestDeviceRefreshToken = async (userAuthConfig, deviceCode) => {
|
|
354
|
+
try {
|
|
355
|
+
const request = { deviceCode };
|
|
356
|
+
return (await (await fetch(buildDeviceEndpointUrl(userAuthConfig, 'device/poll').href, {
|
|
357
|
+
method: 'POST',
|
|
358
|
+
cache: 'no-cache',
|
|
359
|
+
credentials: 'omit',
|
|
360
|
+
redirect: 'follow',
|
|
361
|
+
referrerPolicy: 'origin',
|
|
362
|
+
headers: { 'content-type': 'application/json' },
|
|
363
|
+
body: JSON.stringify(request),
|
|
364
|
+
})).json());
|
|
365
|
+
}
|
|
366
|
+
catch (e) {
|
|
367
|
+
return {
|
|
368
|
+
code: exports.DevicePollResponseCode.INTERNAL_SERVER_ERROR,
|
|
369
|
+
message: ensureError(e).message,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
const sleep = (ms, signal) => new Promise((resolve, reject) => {
|
|
374
|
+
if (signal?.aborted === true) {
|
|
375
|
+
reject(new DOMException('Aborted', 'AbortError'));
|
|
376
|
+
return;
|
|
377
|
+
}
|
|
378
|
+
const timer = setTimeout(() => {
|
|
379
|
+
signal?.removeEventListener('abort', onAbort);
|
|
380
|
+
resolve();
|
|
381
|
+
}, ms);
|
|
382
|
+
const onAbort = () => {
|
|
383
|
+
clearTimeout(timer);
|
|
384
|
+
reject(new DOMException('Aborted', 'AbortError'));
|
|
385
|
+
};
|
|
386
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
387
|
+
});
|
|
388
|
+
/**
|
|
389
|
+
* Convenience poller for the device: repeatedly polls `device/poll` honouring the
|
|
390
|
+
* server's `interval`, backing off on `SLOW_DOWN`, until the authorization reaches a terminal
|
|
391
|
+
* state (SUCCESS / ACCESS_DENIED / EXPIRED) or an error occurs. Resolves with that terminal
|
|
392
|
+
* response; on SUCCESS it carries the `refreshToken` (pass it to {@link getDeviceAccessToken}).
|
|
393
|
+
*
|
|
394
|
+
* @param userAuthConfig An object containing user authentication info.
|
|
395
|
+
* @param deviceCode The secret returned by {@link requestDeviceAuthorization}.
|
|
396
|
+
* @param options.intervalSeconds Initial seconds between polls (from the authorize response).
|
|
397
|
+
* @param options.signal Optional `AbortSignal` to cancel polling (rejects with `AbortError`).
|
|
398
|
+
* @param options.onPending Optional callback invoked on each non-terminal poll.
|
|
399
|
+
*/
|
|
400
|
+
const pollDeviceRefreshToken = async (userAuthConfig, deviceCode, options) => {
|
|
401
|
+
// On SLOW_DOWN, back off by an extra 5 seconds (common device-flow convention).
|
|
402
|
+
const slowDownIncrementSeconds = 5;
|
|
403
|
+
let intervalSeconds = options.intervalSeconds;
|
|
404
|
+
// eslint-disable-next-line no-constant-condition
|
|
405
|
+
while (true) {
|
|
406
|
+
await sleep(intervalSeconds * 1000, options.signal);
|
|
407
|
+
const response = await requestDeviceRefreshToken(userAuthConfig, deviceCode);
|
|
408
|
+
if (response.code === exports.DevicePollResponseCode.AUTHORIZATION_PENDING ||
|
|
409
|
+
response.code === exports.DevicePollResponseCode.SLOW_DOWN) {
|
|
410
|
+
if (response.code === exports.DevicePollResponseCode.SLOW_DOWN) {
|
|
411
|
+
intervalSeconds += slowDownIncrementSeconds;
|
|
412
|
+
}
|
|
413
|
+
options.onPending?.(response);
|
|
414
|
+
continue;
|
|
415
|
+
}
|
|
416
|
+
// SUCCESS / ACCESS_DENIED / EXPIRED / BAD_REQUEST / INTERNAL_SERVER_ERROR are terminal.
|
|
417
|
+
return response;
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
/**
|
|
421
|
+
* Gets an access token for a device session from its refresh token — used both for
|
|
422
|
+
* the first access token (right after {@link pollDeviceRefreshToken} succeeds) and for every
|
|
423
|
+
* subsequent renewal. The device cannot use the `AX_REFRESH_TOKEN` cookie, so it presents the
|
|
424
|
+
* refresh token as an `Authorization: Bearer <refreshToken>` header against the standard `/token`
|
|
425
|
+
* endpoint. The refresh token itself is not rotated, so it can be reused for each renewal.
|
|
426
|
+
*
|
|
427
|
+
* @param userAuthConfig An object containing user authentication info.
|
|
428
|
+
* @param refreshToken The device refresh token (returned by the SUCCESS device poll).
|
|
429
|
+
*/
|
|
430
|
+
const getDeviceAccessToken = async (userAuthConfig, refreshToken) => {
|
|
431
|
+
try {
|
|
432
|
+
return (await (await fetch(buildDeviceEndpointUrl(userAuthConfig, 'token').href, {
|
|
433
|
+
method: 'GET',
|
|
434
|
+
cache: 'no-cache',
|
|
435
|
+
credentials: 'omit',
|
|
436
|
+
redirect: 'follow',
|
|
437
|
+
referrerPolicy: 'origin',
|
|
438
|
+
headers: { authorization: `Bearer ${refreshToken}` },
|
|
439
|
+
})).json());
|
|
440
|
+
}
|
|
441
|
+
catch (e) {
|
|
442
|
+
return {
|
|
443
|
+
code: TokenResponseCode.INTERNAL_SERVER_ERROR,
|
|
444
|
+
message: ensureError(e).message,
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
};
|
|
448
|
+
/**
|
|
449
|
+
* Reads what a given `userCode` is about to authorize (called by the activation page). Anonymous
|
|
450
|
+
* and read-only — it never approves anything. Returns the device label and status.
|
|
451
|
+
*
|
|
452
|
+
* @param userAuthConfig An object containing user authentication info.
|
|
453
|
+
* @param userCode The short code the user typed on the activation page.
|
|
454
|
+
*/
|
|
455
|
+
const getDeviceVerification = async (userAuthConfig, userCode) => {
|
|
456
|
+
try {
|
|
457
|
+
const url = buildDeviceEndpointUrl(userAuthConfig, 'device/verify');
|
|
458
|
+
url.searchParams.set('userCode', userCode);
|
|
459
|
+
return (await (await fetch(url.href, {
|
|
460
|
+
method: 'GET',
|
|
461
|
+
cache: 'no-cache',
|
|
462
|
+
credentials: 'omit',
|
|
463
|
+
redirect: 'follow',
|
|
464
|
+
referrerPolicy: 'origin',
|
|
465
|
+
})).json());
|
|
466
|
+
}
|
|
467
|
+
catch (e) {
|
|
468
|
+
return {
|
|
469
|
+
code: exports.DeviceVerificationResponseCode.INTERNAL_SERVER_ERROR,
|
|
470
|
+
message: ensureError(e).message,
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
};
|
|
474
|
+
/**
|
|
475
|
+
* Approves or denies a device authorization (called from the activation page by the signed-in user). Requires the
|
|
476
|
+
* end-user access token — the same `Bearer` credential used for every other end-user API —
|
|
477
|
+
* which the server resolves to the approving user's session.
|
|
478
|
+
*
|
|
479
|
+
* @param userAuthConfig An object containing user authentication info.
|
|
480
|
+
* @param endUserAccessToken The signed-in user's access token (JWT).
|
|
481
|
+
* @param userCode The short code shown on the device.
|
|
482
|
+
* @param action Whether to `approve` or `deny` the device.
|
|
483
|
+
*/
|
|
484
|
+
const submitDeviceApproval = async (userAuthConfig, endUserAccessToken, userCode, action) => {
|
|
485
|
+
try {
|
|
486
|
+
const request = { userCode };
|
|
487
|
+
return (await (await fetch(buildDeviceEndpointUrl(userAuthConfig, `device/${action}`).href, {
|
|
488
|
+
method: 'POST',
|
|
489
|
+
cache: 'no-cache',
|
|
490
|
+
credentials: 'omit',
|
|
491
|
+
redirect: 'follow',
|
|
492
|
+
referrerPolicy: 'origin',
|
|
493
|
+
headers: {
|
|
494
|
+
'content-type': 'application/json',
|
|
495
|
+
authorization: `Bearer ${endUserAccessToken}`,
|
|
496
|
+
},
|
|
497
|
+
body: JSON.stringify(request),
|
|
498
|
+
})).json());
|
|
499
|
+
}
|
|
500
|
+
catch (e) {
|
|
501
|
+
return {
|
|
502
|
+
code: exports.DeviceApprovalResponseCode.INTERNAL_SERVER_ERROR,
|
|
503
|
+
message: ensureError(e).message,
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
/**
|
|
508
|
+
* Approves a device authorization on behalf of the signed-in user. @see {@link submitDeviceApproval}
|
|
509
|
+
*/
|
|
510
|
+
const approveDevice = (userAuthConfig, endUserAccessToken, userCode) => submitDeviceApproval(userAuthConfig, endUserAccessToken, userCode, 'approve');
|
|
511
|
+
/**
|
|
512
|
+
* Denies a device authorization on behalf of the signed-in user. @see {@link submitDeviceApproval}
|
|
513
|
+
*/
|
|
514
|
+
const denyDevice = (userAuthConfig, endUserAccessToken, userCode) => submitDeviceApproval(userAuthConfig, endUserAccessToken, userCode, 'deny');
|
|
515
|
+
|
|
248
516
|
// istanbul ignore next (See: 'https://github.com/graphql/graphql-js/issues/2317')
|
|
249
517
|
var nodejsCustomInspectSymbol = typeof Symbol === 'function' && typeof Symbol.for === 'function' ? Symbol.for('nodejs.util.inspect.custom') : undefined;
|
|
250
518
|
var nodejsCustomInspectSymbol$1 = nodejsCustomInspectSymbol;
|
|
@@ -3028,6 +3296,79 @@ class UserServiceClient {
|
|
|
3028
3296
|
decryptNativeCookie = async (encryptedCookie, key) => {
|
|
3029
3297
|
return decryptNativeCookie(encryptedCookie, key, `${this.userServiceConfig.userServiceBaseUrl}/graphql-management`);
|
|
3030
3298
|
};
|
|
3299
|
+
/**
|
|
3300
|
+
* Starts the Device Authorization grant for the device (a NATIVE application).
|
|
3301
|
+
* Returns the `userCode` / `verificationUri` to show the user and the `deviceCode` to poll with.
|
|
3302
|
+
*
|
|
3303
|
+
* NOTE: The device flow is headless and does NOT use the `AX_REFRESH_TOKEN` cookie — the
|
|
3304
|
+
* device's tokens are carried explicitly. @see {@link pollDeviceRefreshToken} / {@link getDeviceAccessToken}.
|
|
3305
|
+
*
|
|
3306
|
+
* @param request Optional request body (a display-only `deviceLabel`).
|
|
3307
|
+
*/
|
|
3308
|
+
requestDeviceAuthorization = async (request = {}) => {
|
|
3309
|
+
return requestDeviceAuthorization(this.userAuthConfig, request);
|
|
3310
|
+
};
|
|
3311
|
+
/**
|
|
3312
|
+
* Performs a single poll. Prefer {@link pollDeviceRefreshToken} for the polling loop. On SUCCESS
|
|
3313
|
+
* the response carries the device `refreshToken`; pass it to {@link getDeviceAccessToken}.
|
|
3314
|
+
*
|
|
3315
|
+
* @param deviceCode The secret returned by {@link requestDeviceAuthorization}.
|
|
3316
|
+
*/
|
|
3317
|
+
requestDeviceRefreshToken = async (deviceCode) => {
|
|
3318
|
+
return requestDeviceRefreshToken(this.userAuthConfig, deviceCode);
|
|
3319
|
+
};
|
|
3320
|
+
/**
|
|
3321
|
+
* Polls `device/poll` honouring the server interval and `SLOW_DOWN` back-off until the
|
|
3322
|
+
* authorization reaches a terminal state (SUCCESS / ACCESS_DENIED / EXPIRED). On SUCCESS the
|
|
3323
|
+
* response carries the device `refreshToken` — store it, then call {@link getDeviceAccessToken}
|
|
3324
|
+
* to obtain an access token.
|
|
3325
|
+
*
|
|
3326
|
+
* @param deviceCode The secret returned by {@link requestDeviceAuthorization}.
|
|
3327
|
+
* @param options.intervalSeconds Initial seconds between polls (from the authorize response).
|
|
3328
|
+
* @param options.signal Optional `AbortSignal` to cancel polling.
|
|
3329
|
+
* @param options.onPending Optional callback invoked on each non-terminal poll.
|
|
3330
|
+
*/
|
|
3331
|
+
pollDeviceRefreshToken = async (deviceCode, options) => {
|
|
3332
|
+
return pollDeviceRefreshToken(this.userAuthConfig, deviceCode, options);
|
|
3333
|
+
};
|
|
3334
|
+
/**
|
|
3335
|
+
* Gets an access token for a device session from its refresh token — used for the
|
|
3336
|
+
* first access token (right after the poll succeeds) and for every renewal. The refresh token is
|
|
3337
|
+
* presented as a `Bearer` header, since the device cannot use the browser cookie.
|
|
3338
|
+
*
|
|
3339
|
+
* @param refreshToken The device refresh token from the SUCCESS device poll.
|
|
3340
|
+
*/
|
|
3341
|
+
getDeviceAccessToken = async (refreshToken) => {
|
|
3342
|
+
return getDeviceAccessToken(this.userAuthConfig, refreshToken);
|
|
3343
|
+
};
|
|
3344
|
+
/**
|
|
3345
|
+
* Reads what a given `userCode` is about to authorize (for the activation page). Anonymous and
|
|
3346
|
+
* read-only — it never approves anything.
|
|
3347
|
+
*
|
|
3348
|
+
* @param userCode The short code the user typed on the activation page.
|
|
3349
|
+
*/
|
|
3350
|
+
getDeviceVerification = async (userCode) => {
|
|
3351
|
+
return getDeviceVerification(this.userAuthConfig, userCode);
|
|
3352
|
+
};
|
|
3353
|
+
/**
|
|
3354
|
+
* Approves a device authorization on behalf of the signed-in user. Requires the end-user
|
|
3355
|
+
* access token (the same `Bearer` credential used for every other end-user API).
|
|
3356
|
+
*
|
|
3357
|
+
* @param endUserAccessToken The signed-in user's access token (JWT).
|
|
3358
|
+
* @param userCode The short code shown on the device.
|
|
3359
|
+
*/
|
|
3360
|
+
approveDevice = async (endUserAccessToken, userCode) => {
|
|
3361
|
+
return approveDevice(this.userAuthConfig, endUserAccessToken, userCode);
|
|
3362
|
+
};
|
|
3363
|
+
/**
|
|
3364
|
+
* Denies a device authorization on behalf of the signed-in user.
|
|
3365
|
+
*
|
|
3366
|
+
* @param endUserAccessToken The signed-in user's access token (JWT).
|
|
3367
|
+
* @param userCode The short code shown on the device.
|
|
3368
|
+
*/
|
|
3369
|
+
denyDevice = async (endUserAccessToken, userCode) => {
|
|
3370
|
+
return denyDevice(this.userAuthConfig, endUserAccessToken, userCode);
|
|
3371
|
+
};
|
|
3031
3372
|
/**
|
|
3032
3373
|
* Returns the authentication URL for web based applications.
|
|
3033
3374
|
*
|