@crossauth/common 0.0.1

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.
@@ -0,0 +1,475 @@
1
+ import { OpenIdConfiguration, OAuthTokenConsumerBase, GrantType } from '..';
2
+
3
+ /**
4
+ * Crossauth allows you to define which flows are valid for a given client.
5
+ */
6
+ export declare class OAuthFlows {
7
+ /** All flows are allowed */
8
+ static readonly All = "all";
9
+ /** OAuth authorization code flow (without PKCE) */
10
+ static readonly AuthorizationCode = "authorizationCode";
11
+ /** OAuth authorization code flow with PKCE */
12
+ static readonly AuthorizationCodeWithPKCE = "authorizationCodeWithPKCE";
13
+ /** Auth client credentials flow */
14
+ static readonly ClientCredentials = "clientCredentials";
15
+ /** OAuth refresh token flow */
16
+ static readonly RefreshToken = "refreshToken";
17
+ /** OAuth device code flow */
18
+ static readonly DeviceCode = "deviceCode";
19
+ /** OAuth password flow */
20
+ static readonly Password = "password";
21
+ /** The Auth0 password MFA extension to the password flow */
22
+ static readonly PasswordMfa = "passwordMfa";
23
+ /** The OpenID Connect authorization code flow, with or without
24
+ * PKCE.
25
+ */
26
+ static readonly OidcAuthorizationCode = "oidcAuthorizationCode";
27
+ /** A user friendly name for the given flow ID
28
+ *
29
+ * For example, if you pass "authorizationCode"
30
+ * (`OAuthFlows.AuthorizationCode`) you will get `"Authorization Code"`.
31
+ */
32
+ static readonly flowName: {
33
+ [key: string]: string;
34
+ };
35
+ /**
36
+ * Returns a user-friendly name for the given flow strings.
37
+ *
38
+ * The value returned is the one in `flowName`.
39
+ * @param flows the flows to return the names of
40
+ * @returns an array of strings
41
+ */
42
+ static flowNames(flows: string[]): {
43
+ [key: string]: string;
44
+ };
45
+ /**
46
+ * Returns true if the given string is a valid flow name.
47
+ * @param flow the flow to check
48
+ * @returns true or false.
49
+ */
50
+ static isValidFlow(flow: string): boolean;
51
+ /**
52
+ * Returns true only if all given strings are valid flows
53
+ * @param flows the flows to check
54
+ * @returns true or false.
55
+ */
56
+ static areAllValidFlows(flows: string[]): boolean;
57
+ static allFlows(): string[];
58
+ /**
59
+ * Returns the OAuth grant types that are valid for a given flow, or
60
+ * `undefined` if it is not a valid flow.
61
+ * @param oauthFlow the flow to get the grant type for.
62
+ * @returns a {@link GrantType} value
63
+ */
64
+ static grantType(oauthFlow: string): GrantType[] | undefined;
65
+ }
66
+ /**
67
+ * These are the fields that can be returned in the JSON from an OAuth
68
+ * call.
69
+ */
70
+ export interface OAuthTokenResponse {
71
+ access_token?: string;
72
+ refresh_token?: string;
73
+ id_token?: string;
74
+ token_type?: string;
75
+ expires_in?: number;
76
+ error?: string;
77
+ error_description?: string;
78
+ scope?: string;
79
+ mfa_token?: string;
80
+ oob_channel?: string;
81
+ oob_code?: string;
82
+ challenge_type?: string;
83
+ binding_method?: string;
84
+ name?: string;
85
+ }
86
+ /**
87
+ * These are the fields that can be returned in the device_authorization
88
+ * device code flow endpoint.
89
+ */
90
+ export interface OAuthDeviceAuthorizationResponse {
91
+ device_code?: string;
92
+ user_code?: string;
93
+ verification_uri?: string;
94
+ verification_uri_complete?: string;
95
+ expires_in?: number;
96
+ interval?: number;
97
+ error?: string;
98
+ error_description?: string;
99
+ }
100
+ /**
101
+ * These are the fields that can be returned in the device
102
+ * device code flow endpoint.
103
+ */
104
+ export interface OAuthDeviceResponse {
105
+ ok: boolean;
106
+ client_id?: string;
107
+ scopeAuthorizationNeeded?: boolean;
108
+ scope?: string;
109
+ error?: string;
110
+ error_description?: string;
111
+ }
112
+ /**
113
+ * An abstract base class for OAuth clients.
114
+ *
115
+ * Crossauth provides OAuth clients that work in the browser as well as in
116
+ * Node. This base class contains all the non-interpreter specific
117
+ * functionality. What is missing is the cryptography which is included
118
+ * in derived Node-only and Browser-only classes.
119
+ * See {@link @crossauth/backend!OAuthClientBackend}.
120
+ *
121
+ * Flows supported are Authorization Code Flow with and without PKCE,
122
+ * Client Credentials, Refresh Token, Password and Password MFA. The
123
+ * latter is defined at
124
+ * {@link https://auth0.com/docs/secure/multi-factor-authentication/multi-factor-authentication-factors}.
125
+ *
126
+ * It also supports the OpenID Connect Authorization Code Flow, with and
127
+ * without PKCE.
128
+ */
129
+ export declare abstract class OAuthClientBase {
130
+ #private;
131
+ protected authServerBaseUrl: string;
132
+ protected codeChallengeMethod: "plain" | "S256";
133
+ protected verifierLength: number;
134
+ protected redirect_uri: string | undefined;
135
+ protected stateLength: number;
136
+ protected authzCode: string;
137
+ protected oidcConfig: (OpenIdConfiguration & {
138
+ [key: string]: any;
139
+ }) | undefined;
140
+ protected tokenConsumer: OAuthTokenConsumerBase;
141
+ protected authServerHeaders: {
142
+ [key: string]: string;
143
+ };
144
+ protected authServerMode: "no-cors" | "cors" | "same-origin" | undefined;
145
+ protected authServerCredentials: "include" | "omit" | "same-origin" | undefined;
146
+ /**
147
+ * Constructor.
148
+ *
149
+ * @param options options:
150
+ * - `authServerBaseUrl` the base URI for OAuth calls. This is
151
+ * the value in the isser field of a JWT. The client will
152
+ * reject any JWTs that are not from this issuer.
153
+ * - `client_id` the client ID for this client.
154
+ * - `redriectUri` when making OAuth calls, this value is put
155
+ * in the redirect_uri field.
156
+ * - `number` of characters (before base64-url-encoding) for generating
157
+ * state values in OAuth calls.
158
+ * - `verifierLength` of characters (before base64-url-encoding) for
159
+ * generating PKCE values in OAuth calls.
160
+ * - `tokenConsumer` to keep this class independent of frontend
161
+ * and backend specific funtionality (eg classes not available
162
+ * in browsers), the token consumer, which determines if a token
163
+ * is valid or not, is abstracted out.
164
+ * - authServerCredentials credentials flag for fetch calls to the
165
+ * authorization server
166
+ * - authServerMode mode flag for fetch calls to the
167
+ * authorization server
168
+ * - authServerHeaders headers flag for calls to the
169
+ * authorization server
170
+ * - `receiveTokensFn` if defined, this will be called when tokens
171
+ * are received
172
+ */
173
+ constructor({ authServerBaseUrl, client_id, client_secret, redirect_uri, codeChallengeMethod, stateLength, verifierLength, tokenConsumer, authServerCredentials, authServerMode, authServerHeaders, }: {
174
+ authServerBaseUrl: string;
175
+ stateLength?: number;
176
+ verifierLength?: number;
177
+ client_id?: string;
178
+ client_secret?: string;
179
+ redirect_uri?: string;
180
+ codeChallengeMethod?: "plain" | "S256";
181
+ tokenConsumer: OAuthTokenConsumerBase;
182
+ authServerHeaders?: {
183
+ [key: string]: string;
184
+ };
185
+ authServerCredentials?: "include" | "omit" | "same-origin" | undefined;
186
+ authServerMode?: "no-cors" | "cors" | "same-origin" | undefined;
187
+ });
188
+ set client_id(value: string);
189
+ set client_secret(value: string);
190
+ set codeVerifier(value: string);
191
+ set codeChallenge(value: string);
192
+ set state(value: string);
193
+ /**
194
+ * Loads OpenID Connect configuration so that the client can determine
195
+ * the URLs it can call and the features the authorization server provides.
196
+ *
197
+ * @param oidcConfig if defined, loadsa the config from this object.
198
+ * Otherwise, performs a fetch by appending
199
+ * `/.well-known/openid-configuration` to the
200
+ * `authServerBaseUrl`.
201
+ * @throws {@link @crossauth/common!CrossauthError} with the following {@link @crossauth/common!ErrorCode}s
202
+ * - `Connection` if data from the URL could not be fetched or parsed.
203
+ */
204
+ loadConfig(oidcConfig?: OpenIdConfiguration): Promise<void>;
205
+ getOidcConfig(): (OpenIdConfiguration & {
206
+ [key: string]: any;
207
+ }) | undefined;
208
+ /**
209
+ * Produce a random Base64-url-encoded string, whose length before
210
+ * base64-url-encoding is the given length,
211
+ * @param length the length of the random array before base64-url-encoding.
212
+ * @returns the random value as a Base64-url-encoded srting
213
+ */
214
+ protected abstract randomValue(length: number): string;
215
+ /**
216
+ * SHA256 and Base64-url-encodes the given test
217
+ * @param plaintext the text to encode
218
+ * @returns the SHA256 hash, Base64-url-encode
219
+ */
220
+ protected abstract sha256(plaintext: string): Promise<string>;
221
+ /**
222
+ * Starts the authorizatuin code flow, optionally with PKCE.
223
+ *
224
+ * Doesn't actually call the endpoint but rather returns its URL
225
+ *
226
+ * @param scope optionally specify the scopes to ask the user to
227
+ * authorize (space separated, non URL-encoded)
228
+ * @param pkce if true, initiate the Authorization Code Flow with PKCE,
229
+ * otherwiswe without PKCE.
230
+ * @returns an object with
231
+ * - `url` - the full `authorize` URL to fetch, if there was no
232
+ * error, undefined otherwise
233
+ * - `error` OAuth error if there was an error, undefined
234
+ * otherwise. See OAuth specification for authorize endpoint
235
+ * - `error_description` friendly error message or undefined
236
+ * if no error
237
+ */
238
+ startAuthorizationCodeFlow(scope?: string, pkce?: boolean): Promise<{
239
+ url?: string;
240
+ error?: string;
241
+ error_description?: string;
242
+ }>;
243
+ /**
244
+ * This implements the functionality behind the redirect URI
245
+ *
246
+ * Does not throw exceptions.
247
+ *
248
+ * If an error wasn't reported, a POST request to the `token` endpoint with
249
+ * the authorization code to get an access token, etc. If there was
250
+ * an error, this is just passed through without calling and further
251
+ * endpoints.
252
+ *
253
+ * @param code the authorization code
254
+ * @param state the random state variable
255
+ * @param error if defined, it will be returned as an error. This is
256
+ * for cascading errors from previous requests.
257
+ * @param errorDescription if error is defined, this text is returned
258
+ * as the `error_description` It is set to `Unknown error`
259
+ * otherwise
260
+ * @returns The {@link OAuthTokenResponse} from the `token` endpoint
261
+ * request, or `error` and `error_description`.
262
+ */
263
+ protected redirectEndpoint(code?: string, state?: string, error?: string, errorDescription?: string): Promise<OAuthTokenResponse>;
264
+ /**
265
+ * Performs the client credentials flow.
266
+ *
267
+ * Does not throw exceptions.
268
+ *
269
+ * Makes a POST request to the `token` endpoint with the
270
+ * authorization code to get an access token, etc.
271
+ *
272
+ * @param scope the scopes to authorize for the client (optional)
273
+ * @returns The {@link OAuthTokenResponse} from the `token` endpoint
274
+ * request, or `error` and `error_description`.
275
+ */
276
+ clientCredentialsFlow(scope?: string): Promise<OAuthTokenResponse>;
277
+ /** Initiates the Password Flow.
278
+ *
279
+ * Does not throw exceptions.
280
+ *
281
+ * @param username the username
282
+ * @param password the user's password
283
+ * @param scope the scopes to authorize (optional)
284
+ * @returns An {@link OAuthTokenResponse} which may contain data or
285
+ * the OAuth error fields. If 2FA is enabled for this user on the
286
+ * authorization server, the Password MFA flow is followed. See
287
+ * {@link https://auth0.com/docs/secure/multi-factor-authentication/multi-factor-authentication-factors}.
288
+ *
289
+ */
290
+ passwordFlow(username: string, password: string, scope?: string): Promise<OAuthTokenResponse>;
291
+ /** Request valid authenticators using the Password MFA flow,
292
+ * after the Password flow has been initiated.
293
+ *
294
+ * Does not throw exceptions.
295
+ *
296
+ * @param mfaToken the MFA token that was returned by the authorization
297
+ * server in the response from the Password Flow.
298
+ * @returns Either
299
+ * - authenticators an array of {@link MfaAuthenticatorResponse} objects,
300
+ * as per Auth0's Password MFA documentation
301
+ * - an `error` and `error_description`, also as per Auth0's Password MFA
302
+ * documentation
303
+ */
304
+ mfaAuthenticators(mfaToken: string): Promise<{
305
+ authenticators?: MfaAuthenticatorResponse[];
306
+ error?: string;
307
+ error_description?: string;
308
+ }>;
309
+ /**
310
+ * This is part of the Auth0 Password MFA flow. Once the client has
311
+ * received a list of valid authenticators, if it wishes to initiate
312
+ * OTP, call this function
313
+ *
314
+ * Does not throw exceptions.
315
+ *
316
+ * @param mfaToken the MFA token that was returned by the authorization
317
+ * server in the response from the Password Flow.
318
+ * @param authenticatorId the authenticator ID, as returned in the response
319
+ * from the `mfaAuthenticators` request.
320
+ */
321
+ mfaOtpRequest(mfaToken: string, authenticatorId: string): Promise<{
322
+ challenge_type?: string;
323
+ error?: string;
324
+ error_description?: string;
325
+ }>;
326
+ /**
327
+ * Completes the Password MFA OTP flow.
328
+ * @param mfaToken the MFA token that was returned by the authorization
329
+ * server in the response from the Password Flow.
330
+ * @param otp the OTP entered by the user
331
+ * @returns an object with some of the following fields, depending on
332
+ * authorization server configuration and whether there were
333
+ * errors:
334
+ * - `access_token` an OAuth access token
335
+ * - `refresh_token` an OAuth access token
336
+ * - `id_token` an OpenID Connect ID token
337
+ * - `expires_in` number of seconds when the access token expires
338
+ * - `scope` the scopes the user authorized
339
+ * - `token_type` the OAuth token type
340
+ * - `error` as per Auth0 Password MFA documentation
341
+ * - `error_description` friendly error message
342
+ */
343
+ mfaOtpComplete(mfaToken: string, otp: string, scope?: string): Promise<{
344
+ access_token?: string;
345
+ refresh_token?: string;
346
+ id_token?: string;
347
+ expires_in?: number;
348
+ scope?: string;
349
+ token_type?: string;
350
+ error?: string;
351
+ error_description?: string;
352
+ }>;
353
+ /**
354
+ * This is part of the Auth0 Password MFA flow. Once the client has
355
+ * received a list of valid authenticators, if it wishes to initiate
356
+ * OOB (out of band) login, call this function
357
+ *
358
+ * Does not throw exceptions.
359
+ *
360
+ * @param mfaToken the MFA token that was returned by the authorization
361
+ * server in the response from the Password Flow.
362
+ * @param authenticatorId the authenticator ID, as returned in the response
363
+ * from the `mfaAuthenticators` request.
364
+ * @returns an object with one or more of the following defined:
365
+ * - `challenge_type` as per the Auth0 MFA documentation
366
+ * - `oob_code` as per the Auth0 MFA documentation
367
+ * - `binding_method` as per the Auth0 MFA documentation
368
+ * - `error` as per Auth0 Password MFA documentation
369
+ * - `error_description` friendly error message
370
+ */
371
+ mfaOobRequest(mfaToken: string, authenticatorId: string): Promise<{
372
+ challenge_type?: string;
373
+ oob_code?: string;
374
+ binding_method?: string;
375
+ error?: string;
376
+ error_description?: string;
377
+ }>;
378
+ /**
379
+ * Completes the Password MFA OTP flow.
380
+ *
381
+ * Does not throw exceptions.
382
+ *
383
+ * @param mfaToken the MFA token that was returned by the authorization
384
+ * server in the response from the Password Flow.
385
+ * @param oobCode the code entered by the user
386
+ * @returns an {@link OAuthTokenResponse} object, which may contain
387
+ * an error instead of the response fields.
388
+ */
389
+ mfaOobComplete(mfaToken: string, oobCode: string, bindingCode: string, scope?: string): Promise<OAuthTokenResponse>;
390
+ refreshTokenFlow(refreshToken: string): Promise<OAuthTokenResponse>;
391
+ /**
392
+ * Starts the Device Code Flow on the primary device (the one wanting an access token)
393
+ * @param url The URl for the device_authorization endpoint, as it is not defined in the OIDC configuration
394
+ * @param scope optional scope to request authorization for
395
+ * @returns See {@link OAuthDeviceAuthorizationResponse}
396
+ */
397
+ startDeviceCodeFlow(url: string, scope?: string): Promise<OAuthDeviceAuthorizationResponse>;
398
+ /**
399
+ * Polls the device endpoint to check if the device code flow has been
400
+ * authorized by the user.
401
+ *
402
+ * @param deviceCode the device code to poll
403
+ * @returns See {@link OAuthDeviceResponse}
404
+ */
405
+ pollDeviceCodeFlow(deviceCode: string): Promise<OAuthTokenResponse>;
406
+ /**
407
+ * Makes a POST request to the given URL using `fetch()`.
408
+ *
409
+ * @param url the URL to fetch
410
+ * @param params the body parameters, which are passed as JSON.
411
+ * @returns the parsed JSON response as an object.
412
+ * @throws any exception raised by `fetch()`
413
+ */
414
+ protected post(url: string, params: {
415
+ [key: string]: any;
416
+ }, headers?: {
417
+ [key: string]: any;
418
+ }): Promise<{
419
+ [key: string]: any;
420
+ }>;
421
+ /**
422
+ * Makes a GET request to the given URL using `fetch()`.
423
+ *
424
+ * @param url the URL to fetch
425
+ * @param headers any headers to add to the request
426
+ * @returns the parsed JSON response as an object.
427
+ * @throws any exception raised by `fetch()`
428
+ */
429
+ protected get(url: string, headers?: {
430
+ [key: string]: any;
431
+ }): Promise<{
432
+ [key: string]: any;
433
+ } | {
434
+ [key: string]: any;
435
+ }[]>;
436
+ /**
437
+ * Validates an OpenID ID token, returning undefined if it is invalid.
438
+ *
439
+ * Does not raise exceptions.
440
+ *
441
+ * @param token the token to validate. To be valid, the signature must
442
+ * be valid and the `type` claim in the payload must be set to `id`.
443
+ * @returns the parsed payload or undefined if the token is invalid.
444
+ */
445
+ validateIdToken(token: string): Promise<{
446
+ [key: string]: any;
447
+ } | undefined>;
448
+ /**
449
+ * Validatesd a token using the token consumer.
450
+ *
451
+ * @param idToken the token to validate
452
+ * @returns the parsed JSON of the payload, or undefinedf if it is not
453
+ * valid.
454
+ */
455
+ idTokenAuthorized(idToken: string): Promise<{
456
+ [key: string]: any;
457
+ } | undefined>;
458
+ getTokenPayload(token: string): {
459
+ [key: string]: any;
460
+ };
461
+ }
462
+ /**
463
+ * Fields that canb be returned by the `mfaAuthenticators` function call
464
+ * if {@link OAuthClientBase}.
465
+ *
466
+ * See Auth0's documentation for the password MFA flow.
467
+ */
468
+ export interface MfaAuthenticatorResponse {
469
+ authenticator_type: string;
470
+ id: string;
471
+ active: boolean;
472
+ oob_channel?: string;
473
+ name?: string;
474
+ }
475
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/oauth/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,115 @@
1
+ import { OpenIdConfiguration } from './wellknown';
2
+ import * as jose from 'jose';
3
+ /** Allows passing either a Jose KeyLike object or a key as a binary array */
4
+ export type EncryptionKey = jose.KeyLike | Uint8Array;
5
+ /**
6
+ * Options that can be passed to {@link OAuthTokenConsumerBase}.
7
+ */
8
+ export interface OAuthTokenConsumerBaseOptions {
9
+ /** Secret key if using a symmetric cipher for signing the JWT.
10
+ * Either this or `jwtSecretKeyFile` is required when using this kind of cipher*/
11
+ jwtKeyType?: string;
12
+ /** Secret key if using a symmetric cipher for signing the JWT.
13
+ * Either this or `jwtSecretKeyFile` is required when using this kind of cipher*/
14
+ jwtSecretKey?: string;
15
+ /** The public key if using a public key cipher for signing the JWT.
16
+ * Either this or `jwtPublicKeyFile` is required when using this kind of
17
+ * cipher. privateKey or privateKeyFile is also required. */
18
+ jwtPublicKey?: string;
19
+ /** Number of seconds tolerance when checking expiration. Default 10 */
20
+ clockTolerance?: number;
21
+ /** The value to expect in the iss
22
+ * claim. If the iss does not match this, the token is rejected.
23
+ * No default (required) */
24
+ authServerBaseUrl?: string;
25
+ /**
26
+ * For initializing the token consumer with a static OpenID Connect
27
+ * configuration.
28
+ */
29
+ oidcConfig?: (OpenIdConfiguration & {
30
+ [key: string]: any;
31
+ }) | undefined;
32
+ }
33
+ /**
34
+ * This abstract class is for validating OAuth JWTs.
35
+ */
36
+ export declare abstract class OAuthTokenConsumerBase {
37
+ protected audience: string;
38
+ protected jwtKeyType: string | undefined;
39
+ protected jwtSecretKey: string | undefined;
40
+ protected jwtPublicKey: string | undefined;
41
+ protected clockTolerance: number;
42
+ readonly authServerBaseUrl: string;
43
+ /**
44
+ * The OpenID Connect configuration for the authorization server,
45
+ * either passed to the constructor or fetched from the authorization
46
+ * server.
47
+ */
48
+ oidcConfig: (OpenIdConfiguration & {
49
+ [key: string]: any;
50
+ }) | undefined;
51
+ /**
52
+ * The RSA public keys or symmetric keys for the authorization server,
53
+ * either passed to the constructor or fetched from the authorization
54
+ * server.
55
+ */
56
+ keys: {
57
+ [key: string]: EncryptionKey;
58
+ };
59
+ /**
60
+ * Constrctor
61
+ *
62
+ * @param audience : this is the value expected in the `aud` field
63
+ * of the JWT. The token is rejected if it doesn't match.
64
+ * @param options See {@link OAuthTokenConsumerBaseOptions}.
65
+ */
66
+ constructor(audience: string, options?: OAuthTokenConsumerBaseOptions);
67
+ /**
68
+ * This loads keys either from the ones passed in the constructor
69
+ * or by fetching from the authorization server.
70
+ *
71
+ * Note that even if you pass the keys to the constructor, you must
72
+ * still call this function. This is because key loading is
73
+ * asynchronous, and constructors may not be async.
74
+ */
75
+ loadKeys(): Promise<void>;
76
+ /**
77
+ * Loads OpenID Connect configuration, or fetches it from the
78
+ * authorization server (using the well-known enpoint appended
79
+ * to `authServerBaseUrl` )
80
+ * @param oidcConfig the configuration, or undefined to load it from
81
+ * the authorization server
82
+ * @throws a {@link @crossauth/common!CrossauthError} object with {@link @crossauth/common!ErrorCode} of
83
+ * - `Connection` if the fetch to the authorization server failed.
84
+ */
85
+ loadConfig(oidcConfig?: OpenIdConfiguration): Promise<void>;
86
+ /**
87
+ * Loads the JWT signature validation keys, or fetches them from the
88
+ * authorization server (using the URL in the OIDC configuration).
89
+ * @param jwks the keys to load, or undefined to fetch them from
90
+ * the authorization server.
91
+ * @throws a {@link @crossauth/common!CrossauthError} object with {@link @crossauth/common!ErrorCode} of
92
+ * - `Connection` if the fetch to the authorization server failed,
93
+ * the OIDC configuration wasn't set or the keys could not be parsed.
94
+ */
95
+ loadJwks(jwks?: {
96
+ keys: jose.JWK[];
97
+ }): Promise<void>;
98
+ /**
99
+ * Returns JWT payload if the token is valid, undefined otherwise.
100
+ *
101
+ * Doesn't throw exceptions.
102
+ *
103
+ * @param token the token to validate
104
+ * @param tokenType either `access`, `refresh` or `id`. If the
105
+ * `type` field in the JWT payload doesn't match this, validation
106
+ * fails.
107
+ * @returns the JWT payload if the token is valid, `undefined` otherwise.
108
+ */
109
+ tokenAuthorized(token: string, tokenType: "access" | "refresh" | "id"): Promise<{
110
+ [key: string]: any;
111
+ } | undefined>;
112
+ private validateToken;
113
+ abstract hash(plaintext: string): Promise<string>;
114
+ }
115
+ //# sourceMappingURL=tokenconsumer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokenconsumer.d.ts","sourceRoot":"","sources":["../../src/oauth/tokenconsumer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAI5B,OAAO,EAAE,KAAK,mBAAmB,EAAsB,MAAM,aAAa,CAAC;AAE3E,6EAA6E;AAC7E,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,GAAG,UAAU,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAE1C;qFACiF;IACjF,UAAU,CAAC,EAAG,MAAM,CAAC;IAErB;qFACiF;IACjF,YAAY,CAAC,EAAG,MAAM,CAAC;IAEvB;;iEAE6D;IAC7D,YAAY,CAAC,EAAG,MAAM,CAAC;IAEvB,wEAAwE;IACxE,cAAc,CAAC,EAAG,MAAM,CAAC;IAEzB;;+BAE2B;IAC3B,iBAAiB,CAAC,EAAG,MAAM,CAAC;IAE5B;;;OAGG;IACH,UAAU,CAAC,EAAG,CAAC,mBAAmB,GAAC;QAAC,CAAC,GAAG,EAAC,MAAM,GAAE,GAAG,CAAA;KAAC,CAAC,GAAC,SAAS,CAAC;CAEpE;AAED;;GAEG;AACH,8BAAsB,sBAAsB;IAExC,SAAS,CAAC,QAAQ,EAAG,MAAM,CAAC;IAC5B,SAAS,CAAC,UAAU,EAAI,MAAM,GAAG,SAAS,CAAC;IAC3C,SAAS,CAAC,YAAY,EAAG,MAAM,GAAG,SAAS,CAAC;IAC5C,SAAS,CAAC,YAAY,EAAI,MAAM,GAAG,SAAS,CAAC;IAC7C,SAAS,CAAC,cAAc,EAAG,MAAM,CAAM;IACvC,QAAQ,CAAC,iBAAiB,EAAG,MAAM,CAAM;IAEzC;;;;OAIG;IACH,UAAU,EAAG,CAAC,mBAAmB,GAAC;QAAC,CAAC,GAAG,EAAC,MAAM,GAAE,GAAG,CAAA;KAAC,CAAC,GAAC,SAAS,CAAC;IAEhE;;;;OAIG;IACH,IAAI,EAAG;QAAC,CAAC,GAAG,EAAC,MAAM,GAAG,aAAa,CAAA;KAAC,CAAM;IAE1C;;;;;;OAMG;gBACS,QAAQ,EAAG,MAAM,EAAE,OAAO,GAAG,6BAAkC;IAiB3E;;;;;;;OAOG;IACG,QAAQ;IAkCd;;;;;;;;OAQG;IACG,UAAU,CAAC,UAAU,CAAC,EAAG,mBAAmB,GAAI,OAAO,CAAC,IAAI,CAAC;IAgCnE;;;;;;;;OAQG;IACG,QAAQ,CAAC,IAAI,CAAC,EAAG;QAAC,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,CAAA;KAAC;IA6CzC;;;;;;;;;;OAUG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,EAC/B,SAAS,EAAE,QAAQ,GAAG,SAAS,GAAG,IAAI,GAAI,OAAO,CAAC;QAAC,CAAC,GAAG,EAAC,MAAM,GAAG,GAAG,CAAA;KAAC,GAAC,SAAS,CAAC;YAuBtE,aAAa;IAuC3B,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAG,MAAM,GAAI,OAAO,CAAC,MAAM,CAAC;CACtD"}
@@ -0,0 +1,59 @@
1
+ import { JsonWebKey } from 'crypto';
2
+
3
+ export type TokenEndpointAuthMethod = "client_secret_post" | "client_secret_basic" | "client_secret_jwt" | "private_key_jwt";
4
+ export type ResponseMode = "query" | "fragment";
5
+ export type GrantType = "authorization_code" | "implicit" | "client_credentials" | "password" | "refresh_token" | "http://auth0.com/oauth/grant-type/mfa-otp" | "http://auth0.com/oauth/grant-type/mfa-oob" | "urn:ietf:params:oauth:grant-type:device_code";
6
+ export type SubjectType = "pairwise" | "public";
7
+ export type ClaimType = "normal" | "aggregated" | "distributed";
8
+ /** This class encapsulate the data returned by the `oidc-configuration`
9
+ * well-known endpoint. For further details, see the OpenID Connect
10
+ * specification.
11
+ */
12
+ export interface OpenIdConfiguration {
13
+ issuer: string;
14
+ authorization_endpoint: string;
15
+ token_endpoint: string;
16
+ userinfo_endpoint?: string;
17
+ jwks_uri: string;
18
+ registration_endpoint?: string;
19
+ scopes_supported?: string[];
20
+ response_types_supported: string[];
21
+ response_modes_supported: ResponseMode[];
22
+ grant_types_supported: GrantType[];
23
+ check_session_iframe?: string;
24
+ end_session_endpoint?: string;
25
+ acr_values_supported?: string[];
26
+ subject_types_supported: SubjectType[];
27
+ id_token_signing_alg_values_supported: string[];
28
+ id_token_encryption_alg_values_supported?: string[];
29
+ id_token_encryption_enc_values_supported?: string[];
30
+ userinfo_signing_alg_values_supported?: string[];
31
+ userinfo_encryption_alg_values_supported?: string[];
32
+ userinfo_encryption_enc_values_supported?: string[];
33
+ request_object_signing_alg_values_supported?: string[];
34
+ request_object_encryption_alg_values_supported?: string[];
35
+ request_object_encryption_enc_values_supported?: string[];
36
+ token_endpoint_auth_methods_supported?: TokenEndpointAuthMethod[];
37
+ token_endpoint_auth_signing_alg_values_supported?: string[];
38
+ display_values_supported?: string[];
39
+ claim_types_supported?: ClaimType[];
40
+ claims_supported?: string[];
41
+ service_documentation?: string;
42
+ claims_locales_supported?: string[];
43
+ ui_locales_supported?: string[];
44
+ claims_parameter_supported?: boolean;
45
+ request_parameter_supported?: boolean;
46
+ request_uri_parameter_supported?: boolean;
47
+ require_request_uri_registration?: boolean;
48
+ op_policy_uri?: string;
49
+ op_tos_uri?: string;
50
+ }
51
+ export interface Jwks {
52
+ keys: JsonWebKey[];
53
+ }
54
+ /**
55
+ * This is the detault configuration for
56
+ * {@link @crossauth/backend!OAuthAuthorizationServer}.wellknown
57
+ */
58
+ export declare const DEFAULT_OIDCCONFIG: OpenIdConfiguration;
59
+ //# sourceMappingURL=wellknown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wellknown.d.ts","sourceRoot":"","sources":["../../src/oauth/wellknown.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,MAAM,MAAM,uBAAuB,GAAG,oBAAoB,GAAG,qBAAqB,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAC7H,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,UAAU,CAAC;AAChD,MAAM,MAAM,SAAS,GAAG,oBAAoB,GAAG,UAAU,GAAG,oBAAoB,GAAG,UAAU,GAAG,eAAe,GAAG,2CAA2C,GAAG,2CAA2C,GAAG,8CAA8C,CAAC;AAC7P,MAAM,MAAM,WAAW,GAAG,UAAU,GAAG,QAAQ,CAAC;AAChD,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,YAAY,GAAG,aAAa,CAAC;AAEhE;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAChC,MAAM,EAAG,MAAM,CAAC;IAChB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAG,MAAM,CAAC;IAC5B,QAAQ,EAAG,MAAM,CAAC;IAClB,qBAAqB,CAAC,EAAG,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAG,MAAM,EAAE,CAAC;IAC7B,wBAAwB,EAAE,MAAM,EAAE,CAAC;IACnC,wBAAwB,EAAE,YAAY,EAAE,CAAC;IACzC,qBAAqB,EAAG,SAAS,EAAE,CAAC;IACpC,oBAAoB,CAAC,EAAG,MAAM,CAAC;IAC/B,oBAAoB,CAAC,EAAG,MAAM,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,uBAAuB,EAAE,WAAW,EAAE,CAAC;IACvC,qCAAqC,EAAE,MAAM,EAAE,CAAC;IAChD,wCAAwC,CAAC,EAAG,MAAM,EAAE,CAAC;IACrD,wCAAwC,CAAC,EAAG,MAAM,EAAE,CAAC;IACrD,qCAAqC,CAAC,EAAG,MAAM,EAAE,CAAC;IAClD,wCAAwC,CAAC,EAAG,MAAM,EAAE,CAAC;IACrD,wCAAwC,CAAC,EAAG,MAAM,EAAE,CAAC;IACrD,2CAA2C,CAAC,EAAG,MAAM,EAAE,CAAC;IACxD,8CAA8C,CAAC,EAAG,MAAM,EAAE,CAAC;IAC3D,8CAA8C,CAAC,EAAG,MAAM,EAAE,CAAC;IAC3D,qCAAqC,CAAC,EAAE,uBAAuB,EAAE,CAAC;IAClE,gDAAgD,CAAC,EAAG,MAAM,EAAE,CAAC;IAC7D,wBAAwB,CAAC,EAAG,MAAM,EAAE,CAAC;IACrC,qBAAqB,CAAC,EAAG,SAAS,EAAE,CAAC;IACrC,gBAAgB,CAAC,EAAG,MAAM,EAAE,CAAC;IAC7B,qBAAqB,CAAC,EAAG,MAAM,CAAC;IAChC,wBAAwB,CAAC,EAAG,MAAM,EAAE,CAAC;IACrC,oBAAoB,CAAC,EAAG,MAAM,EAAE,CAAC;IACjC,0BAA0B,CAAC,EAAG,OAAO,CAAC;IACtC,2BAA2B,CAAC,EAAG,OAAO,CAAC;IACvC,+BAA+B,CAAC,EAAG,OAAO,CAAC;IAC3C,gCAAgC,CAAC,EAAG,OAAO,CAAC;IAC5C,aAAa,CAAC,EAAG,MAAM,CAAC;IACxB,UAAU,CAAC,EAAG,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,IAAI;IACjB,IAAI,EAAE,UAAU,EAAE,CAAC;CACtB;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAG,mBAejC,CAAC"}