@depup/express-openid-connect 2.19.4-depup.0
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/LICENSE +22 -0
- package/README.md +37 -0
- package/changes.json +34 -0
- package/index.d.ts +1055 -0
- package/index.js +9 -0
- package/lib/appSession.js +420 -0
- package/lib/client.js +167 -0
- package/lib/config.js +326 -0
- package/lib/context.js +498 -0
- package/lib/cookies.js +3 -0
- package/lib/crypto.js +119 -0
- package/lib/debug.js +2 -0
- package/lib/hooks/backchannelLogout/isLoggedOut.js +22 -0
- package/lib/hooks/backchannelLogout/onLogIn.js +21 -0
- package/lib/hooks/backchannelLogout/onLogoutToken.js +37 -0
- package/lib/hooks/getLoginState.js +51 -0
- package/lib/once.js +19 -0
- package/lib/transientHandler.js +155 -0
- package/lib/utils/promisifyCompat.js +90 -0
- package/lib/weakCache.js +8 -0
- package/middleware/attemptSilentLogin.js +66 -0
- package/middleware/auth.js +129 -0
- package/middleware/requiresAuth.js +133 -0
- package/middleware/unauthorizedHandler.js +15 -0
- package/package.json +129 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,1055 @@
|
|
|
1
|
+
// Type definitions for express-openid-connect
|
|
2
|
+
|
|
3
|
+
import type { Agent as HttpAgent } from 'http';
|
|
4
|
+
import type { Agent as HttpsAgent } from 'https';
|
|
5
|
+
import {
|
|
6
|
+
AuthorizationParameters,
|
|
7
|
+
IdTokenClaims,
|
|
8
|
+
UserinfoResponse,
|
|
9
|
+
} from 'openid-client';
|
|
10
|
+
import { Request, Response, RequestHandler } from 'express';
|
|
11
|
+
import type { JSONWebKey, KeyInput } from 'jose';
|
|
12
|
+
import type { KeyObject } from 'crypto';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Session object
|
|
16
|
+
*/
|
|
17
|
+
interface Session {
|
|
18
|
+
/**
|
|
19
|
+
* Values stored in an authentication session
|
|
20
|
+
*/
|
|
21
|
+
id_token: string;
|
|
22
|
+
access_token: string;
|
|
23
|
+
refresh_token: string;
|
|
24
|
+
token_type: string;
|
|
25
|
+
expires_at: string;
|
|
26
|
+
[key: string]: any;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The Express.js Request with `oidc` context added by the `auth` middleware.
|
|
31
|
+
*
|
|
32
|
+
* ```js
|
|
33
|
+
* app.use(auth());
|
|
34
|
+
*
|
|
35
|
+
* app.get('/profile', (req, res) => {
|
|
36
|
+
* const user = req.oidc.user;
|
|
37
|
+
* ...
|
|
38
|
+
* })
|
|
39
|
+
* ```
|
|
40
|
+
*
|
|
41
|
+
* @deprecated use the native the `Request` interface of `express` instead; it has
|
|
42
|
+
* been extended and now includes a built in `oidc` param.
|
|
43
|
+
*/
|
|
44
|
+
interface OpenidRequest extends Request {
|
|
45
|
+
/**
|
|
46
|
+
* Library namespace for authentication methods and data.
|
|
47
|
+
*/
|
|
48
|
+
oidc: RequestContext;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The Express.js Response with `oidc` context added by the `auth` middleware.
|
|
53
|
+
*
|
|
54
|
+
* ```js
|
|
55
|
+
* app.use(auth());
|
|
56
|
+
*
|
|
57
|
+
* app.get('/login', (req, res) => {
|
|
58
|
+
* res.oidc.login();
|
|
59
|
+
* })
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* @deprecated use the native the `Response` interface of `express` instead; it has
|
|
63
|
+
* been extended and now includes a built in `oidc` param.
|
|
64
|
+
*/
|
|
65
|
+
interface OpenidResponse extends Response {
|
|
66
|
+
/**
|
|
67
|
+
* Library namespace for authentication methods and data.
|
|
68
|
+
*/
|
|
69
|
+
oidc: ResponseContext;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The request authentication context found on the Express request when
|
|
74
|
+
* OpenID Connect auth middleware is added to your application.
|
|
75
|
+
*
|
|
76
|
+
* ```js
|
|
77
|
+
* app.use(auth());
|
|
78
|
+
*
|
|
79
|
+
* app.get('/profile', (req, res) => {
|
|
80
|
+
* const user = req.oidc.user;
|
|
81
|
+
* ...
|
|
82
|
+
* })
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
interface RequestContext {
|
|
86
|
+
/**
|
|
87
|
+
* Method to check the user's authenticated state, returns `true` if logged in.
|
|
88
|
+
*/
|
|
89
|
+
isAuthenticated: () => boolean;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The OpenID Connect ID Token.
|
|
93
|
+
*
|
|
94
|
+
* See: https://auth0.com/docs/protocols/oidc#id-tokens
|
|
95
|
+
*/
|
|
96
|
+
idToken?: string;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Credentials that can be used by an application to access an API.
|
|
100
|
+
*
|
|
101
|
+
* See: https://auth0.com/docs/protocols/oidc#access-tokens
|
|
102
|
+
*/
|
|
103
|
+
accessToken?: AccessToken;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Credentials that can be used to refresh an access token.
|
|
107
|
+
*
|
|
108
|
+
* See: https://auth0.com/docs/tokens/concepts/refresh-tokens
|
|
109
|
+
*/
|
|
110
|
+
refreshToken?: string;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* An object containing all the claims of the ID Token.
|
|
114
|
+
*/
|
|
115
|
+
idTokenClaims?: IdTokenClaims;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* An object containing all the claims of the ID Token with the claims
|
|
119
|
+
* specified in {@link ConfigParams.identityClaimFilter identityClaimFilter} removed.
|
|
120
|
+
*/
|
|
121
|
+
user?: Record<string, any>;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Fetches the OIDC userinfo response.
|
|
125
|
+
*
|
|
126
|
+
* ```js
|
|
127
|
+
* app.use(auth());
|
|
128
|
+
*
|
|
129
|
+
* app.get('/user-info', async (req, res) => {
|
|
130
|
+
* const userInfo = await req.oidc.fetchUserInfo();
|
|
131
|
+
* res.json(userInfo);
|
|
132
|
+
* })
|
|
133
|
+
* ```
|
|
134
|
+
*
|
|
135
|
+
*/
|
|
136
|
+
fetchUserInfo(): Promise<UserinfoResponse>;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* The response authentication context found on the Express response when
|
|
141
|
+
* OpenID Connect auth middleware is added to your application.
|
|
142
|
+
*
|
|
143
|
+
* ```js
|
|
144
|
+
* app.use(auth());
|
|
145
|
+
*
|
|
146
|
+
* app.get('/admin-login', (req, res) => {
|
|
147
|
+
* res.oidc.login({ returnTo: '/admin' })
|
|
148
|
+
* })
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
interface ResponseContext {
|
|
152
|
+
/**
|
|
153
|
+
* Provided by default via the `/login` route. Call this to override or have other
|
|
154
|
+
* login routes with custom {@link ConfigParams.authorizationParams authorizationParams} or returnTo
|
|
155
|
+
*
|
|
156
|
+
* ```js
|
|
157
|
+
* app.get('/admin-login', (req, res) => {
|
|
158
|
+
* res.oidc.login({
|
|
159
|
+
* returnTo: '/admin',
|
|
160
|
+
* authorizationParams: {
|
|
161
|
+
* scope: 'openid profile email admin:user',
|
|
162
|
+
* }
|
|
163
|
+
* });
|
|
164
|
+
* });
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
login: (opts?: LoginOptions) => Promise<void>;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Provided by default via the `/logout` route. Call this to override or have other
|
|
171
|
+
* logout routes with custom returnTo
|
|
172
|
+
*
|
|
173
|
+
* ```js
|
|
174
|
+
* app.get('/admin-logout', (req, res) => {
|
|
175
|
+
* res.oidc.logout({ returnTo: '/admin-welcome' })
|
|
176
|
+
* });
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
logout: (opts?: LogoutOptions) => Promise<void>;
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Provided by default via the `/callback` route. Call this to override or have other
|
|
183
|
+
* callback routes with
|
|
184
|
+
*
|
|
185
|
+
* ```js
|
|
186
|
+
* app.get('/callback', (req, res) => {
|
|
187
|
+
* res.oidc.callback({ redirectUri: 'https://example.com/callback' });
|
|
188
|
+
* });
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
191
|
+
callback: (opts?: CallbackOptions) => Promise<void>;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Extend express interfaces (Response/Request) to support oidc param
|
|
196
|
+
*/
|
|
197
|
+
declare global {
|
|
198
|
+
namespace Express {
|
|
199
|
+
interface Request {
|
|
200
|
+
oidc: RequestContext;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
interface Response {
|
|
204
|
+
oidc: ResponseContext;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Custom options to pass to login.
|
|
211
|
+
*/
|
|
212
|
+
interface LoginOptions {
|
|
213
|
+
/**
|
|
214
|
+
* Override the default {@link ConfigParams.authorizationParams authorizationParams}, if also passing a custom callback
|
|
215
|
+
* route then {@link AuthorizationParameters.redirect_uri redirect_uri} must be provided here or in
|
|
216
|
+
* {@link ConfigParams.authorizationParams config}
|
|
217
|
+
*/
|
|
218
|
+
authorizationParams?: AuthorizationParameters;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* URL to return to after login, overrides the Default is {@link express!Request.originalUrl Request.originalUrl}
|
|
222
|
+
*/
|
|
223
|
+
returnTo?: string;
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Used by {@link ConfigParams.attemptSilentLogin} to swallow callback errors on silent login.
|
|
227
|
+
*/
|
|
228
|
+
silent?: boolean;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Custom options to pass to logout.
|
|
233
|
+
*/
|
|
234
|
+
interface LogoutOptions {
|
|
235
|
+
/**
|
|
236
|
+
* URL to returnTo after logout, overrides the Default in {@link ConfigParams.routes routes.postLogoutRedirect}
|
|
237
|
+
*/
|
|
238
|
+
returnTo?: string;
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Additional custom parameters to pass to the logout endpoint.
|
|
242
|
+
*/
|
|
243
|
+
logoutParams?: { [key: string]: any };
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
interface CallbackOptions {
|
|
247
|
+
/**
|
|
248
|
+
* This is useful to specify in addition to {@link ConfigParams.baseURL} when your app runs on multiple domains,
|
|
249
|
+
* it should match {@link LoginOptions.authorizationParams.redirect_uri}
|
|
250
|
+
*/
|
|
251
|
+
redirectUri: string;
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Additional request body properties to be sent to the `token_endpoint.
|
|
255
|
+
*/
|
|
256
|
+
tokenEndpointParams?: TokenParameters;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Custom options to configure Back-Channel Logout on your application.
|
|
261
|
+
*/
|
|
262
|
+
interface BackchannelLogoutOptions {
|
|
263
|
+
/**
|
|
264
|
+
* Used to store Back-Channel Logout entries, you can specify a separate store
|
|
265
|
+
* for this or just reuse {@link SessionConfigParams.store} if you are using one already.
|
|
266
|
+
*
|
|
267
|
+
* The store should have `get`, `set` and `destroy` methods, making it compatible
|
|
268
|
+
* with [express-session stores](https://github.com/expressjs/session#session-store-implementation).
|
|
269
|
+
*/
|
|
270
|
+
store?: SessionStore<Pick<SessionStorePayload, 'cookie'>>;
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* On receipt of a Logout Token the SDK validates the token then by default stores 2 entries: one
|
|
274
|
+
* by the token's `sid` claim (if available) and one by the token's `sub` claim (if available).
|
|
275
|
+
*
|
|
276
|
+
* If a session subsequently shows up with either the same `sid` or `sub`, the user if forbidden access and
|
|
277
|
+
* their cookie is deleted.
|
|
278
|
+
*
|
|
279
|
+
* You can override this to implement your own Back-Channel Logout logic
|
|
280
|
+
* (See {@link https://github.com/auth0/express-openid-connect/tree/master/examples/examples/backchannel-logout-custom-genid.js} or {@link https://github.com/auth0/express-openid-connect/tree/master/examples/examples/backchannel-logout-custom-query-store.js})
|
|
281
|
+
*/
|
|
282
|
+
onLogoutToken?: (
|
|
283
|
+
decodedToken: object,
|
|
284
|
+
config: ConfigParams
|
|
285
|
+
) => Promise<void> | void;
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* When {@link backchannelLogout} is enabled all requests that have a session
|
|
289
|
+
* will be checked for a previous Back-Channel logout. By default, this
|
|
290
|
+
* uses the `sub` and the `sid` (if available) from the session's ID token to look up a previous logout and
|
|
291
|
+
* logs the user out if one is found.
|
|
292
|
+
*
|
|
293
|
+
* You can override this to implement your own Back-Channel Logout logic
|
|
294
|
+
* (See {@link https://github.com/auth0/express-openid-connect/tree/master/examples/examples/backchannel-logout-custom-genid.js} or {@link https://github.com/auth0/express-openid-connect/tree/master/examples/examples/backchannel-logout-custom-query-store.js})
|
|
295
|
+
*/
|
|
296
|
+
isLoggedOut?:
|
|
297
|
+
| false
|
|
298
|
+
| ((req: Request, config: ConfigParams) => Promise<boolean> | boolean);
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* When {@link backchannelLogout} is enabled, upon successful login the SDK will remove any existing Back-Channel
|
|
302
|
+
* logout entries for the same `sub`, to prevent the user from being logged out by an old Back-Channel logout.
|
|
303
|
+
*
|
|
304
|
+
* You can override this to implement your own Back-Channel Logout logic
|
|
305
|
+
* (See {@link https://github.com/auth0/express-openid-connect/tree/master/examples/examples/backchannel-logout-custom-genid.js} or {@link https://github.com/auth0/express-openid-connect/tree/master/examples/examples/backchannel-logout-custom-query-store.js})
|
|
306
|
+
*/
|
|
307
|
+
onLogin?:
|
|
308
|
+
| false
|
|
309
|
+
| ((req: Request, config: ConfigParams) => Promise<void> | void);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Configuration parameters passed to the `auth()` middleware.
|
|
314
|
+
*
|
|
315
|
+
* {@link ConfigParams.issuerBaseURL issuerBaseURL}, {@link ConfigParams.baseURL baseURL}, {@link ConfigParams.clientID clientID}
|
|
316
|
+
* and {@link ConfigParams.secret secret} are required but can be configured with environmental variables. {@link ConfigParams.clientSecret clientSecret} is not required but can also be configured this way.
|
|
317
|
+
*
|
|
318
|
+
* ```js
|
|
319
|
+
* # Required
|
|
320
|
+
* ISSUER_BASE_URL=https://YOUR_DOMAIN
|
|
321
|
+
* BASE_URL=https://YOUR_APPLICATION_ROOT_URL
|
|
322
|
+
* CLIENT_ID=YOUR_CLIENT_ID
|
|
323
|
+
* SECRET=LONG_RANDOM_VALUE
|
|
324
|
+
*
|
|
325
|
+
* # Not required
|
|
326
|
+
* CLIENT_SECRET=YOUR_CLIENT_SECRET
|
|
327
|
+
* ```
|
|
328
|
+
*/
|
|
329
|
+
interface ConfigParams {
|
|
330
|
+
/**
|
|
331
|
+
* REQUIRED. The secret(s) used to derive an encryption key for the user identity in a stateless session cookie,
|
|
332
|
+
* to sign the transient cookies used by the login callback and to sign the custom session store cookies if
|
|
333
|
+
* {@Link signSessionStoreCookie} is `true`. Use a single string key or array of keys. Secrets must be at least 8 characters long.
|
|
334
|
+
* If an array of secrets is provided, only the first element will be used to sign or encrypt the values, while all
|
|
335
|
+
* the elements will be considered when decrypting or verifying the values.
|
|
336
|
+
*
|
|
337
|
+
* Can use env key SECRET instead.
|
|
338
|
+
*/
|
|
339
|
+
secret?: string | Array<string>;
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Object defining application session cookie attributes.
|
|
343
|
+
*/
|
|
344
|
+
session?: SessionConfigParams;
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Boolean value to enable idpLogout with an Auth0 custom domain
|
|
348
|
+
*/
|
|
349
|
+
auth0Logout?: boolean;
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* URL parameters used when redirecting users to the authorization server to log in.
|
|
353
|
+
*
|
|
354
|
+
* If this property is not provided by your application, its default values will be:
|
|
355
|
+
*
|
|
356
|
+
* ```js
|
|
357
|
+
* {
|
|
358
|
+
* response_type: 'id_token',
|
|
359
|
+
* response_mode: 'form_post',
|
|
360
|
+
* scope: 'openid profile email'
|
|
361
|
+
* }
|
|
362
|
+
* ```
|
|
363
|
+
*
|
|
364
|
+
* New values can be passed in to change what is returned from the authorization server depending on your specific scenario.
|
|
365
|
+
*
|
|
366
|
+
* For example, to receive an access token for an API, you could initialize like the sample below. Note that `response_mode` can be omitted because the OAuth2 default mode of `query` is fine:
|
|
367
|
+
*
|
|
368
|
+
* ```js
|
|
369
|
+
* app.use(
|
|
370
|
+
* auth({
|
|
371
|
+
* authorizationParams: {
|
|
372
|
+
* response_type: 'code',
|
|
373
|
+
* scope: 'openid profile email read:reports',
|
|
374
|
+
* audience: 'https://your-api-identifier',
|
|
375
|
+
* },
|
|
376
|
+
* })
|
|
377
|
+
* );
|
|
378
|
+
* ```
|
|
379
|
+
*
|
|
380
|
+
* Additional custom parameters can be added as well:
|
|
381
|
+
*
|
|
382
|
+
* ```js
|
|
383
|
+
* app.use(auth({
|
|
384
|
+
* authorizationParams: {
|
|
385
|
+
* // Note: you need to provide required parameters if this object is set.
|
|
386
|
+
* response_type: "id_token",
|
|
387
|
+
* response_mode: "form_post",
|
|
388
|
+
* scope: "openid profile email"
|
|
389
|
+
* // Additional parameters
|
|
390
|
+
* acr_value: "tenant:test-tenant",
|
|
391
|
+
* custom_param: "custom-value"
|
|
392
|
+
* }
|
|
393
|
+
* }));
|
|
394
|
+
* ```
|
|
395
|
+
*/
|
|
396
|
+
authorizationParams?: AuthorizationParameters;
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Additional custom parameters to pass to the logout endpoint.
|
|
400
|
+
*/
|
|
401
|
+
logoutParams?: { [key: string]: any };
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* REQUIRED. The root URL for the application router, eg https://localhost
|
|
405
|
+
* Can use env key BASE_URL instead.
|
|
406
|
+
*
|
|
407
|
+
* Note: In the event that the URL has a path at the end, the `auth` middleware
|
|
408
|
+
* will need to be bound relative to that path. I.e
|
|
409
|
+
*
|
|
410
|
+
* ```js
|
|
411
|
+
* app.use('/some/path', auth({
|
|
412
|
+
* baseURL: "https://example.com/some/path"
|
|
413
|
+
* [...]
|
|
414
|
+
* })
|
|
415
|
+
* ```
|
|
416
|
+
*/
|
|
417
|
+
baseURL?: string;
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* REQUIRED. The Client ID for your application.
|
|
421
|
+
* Can use env key CLIENT_ID instead.
|
|
422
|
+
*/
|
|
423
|
+
clientID?: string;
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* The Client Secret for your application.
|
|
427
|
+
* Required when requesting access tokens.
|
|
428
|
+
* Can use env key CLIENT_SECRET instead.
|
|
429
|
+
*/
|
|
430
|
+
clientSecret?: string;
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Integer value for the system clock's tolerance (leeway) in seconds for ID token verification.`
|
|
434
|
+
* Default is 60
|
|
435
|
+
*/
|
|
436
|
+
clockTolerance?: number;
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* To opt-out of sending the library and node version to your authorization server
|
|
440
|
+
* via the `Auth0-Client` header. Default is `true
|
|
441
|
+
*/
|
|
442
|
+
enableTelemetry?: boolean;
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* Throw a 401 error instead of triggering the login process for routes that require authentication.
|
|
446
|
+
* Default is `false`
|
|
447
|
+
*/
|
|
448
|
+
errorOnRequiredAuth?: boolean;
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Attempt silent login (`prompt: 'none'`) on the first unauthenticated route the user visits.
|
|
452
|
+
* For protected routes this can be useful if your Identity Provider does not default to
|
|
453
|
+
* `prompt: 'none'` and you'd like to attempt this before requiring the user to interact with a login prompt.
|
|
454
|
+
* For unprotected routes this can be useful if you want to check the user's logged in state on their IDP, to
|
|
455
|
+
* show them a login/logout button for example.
|
|
456
|
+
* Default is `false`
|
|
457
|
+
*/
|
|
458
|
+
attemptSilentLogin?: boolean;
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Function that returns an object with URL-safe state values for `res.oidc.login()`.
|
|
462
|
+
* Used for passing custom state parameters to your authorization server.
|
|
463
|
+
*
|
|
464
|
+
* ```js
|
|
465
|
+
* app.use(auth({
|
|
466
|
+
* ...
|
|
467
|
+
* getLoginState(req, options) {
|
|
468
|
+
* return {
|
|
469
|
+
* returnTo: options.returnTo || req.originalUrl,
|
|
470
|
+
* customState: 'foo'
|
|
471
|
+
* };
|
|
472
|
+
* }
|
|
473
|
+
* }))
|
|
474
|
+
* ``
|
|
475
|
+
*/
|
|
476
|
+
getLoginState?: (req: OpenidRequest, options: LoginOptions) => object;
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Function for custom callback handling after receiving and validating the ID Token and before redirecting.
|
|
480
|
+
* This can be used for handling token storage, making userinfo calls, claim validation, etc.
|
|
481
|
+
*
|
|
482
|
+
* ```js
|
|
483
|
+
* app.use(auth({
|
|
484
|
+
* ...
|
|
485
|
+
* afterCallback: async (req, res, session, decodedState) => {
|
|
486
|
+
* const userProfile = await request(`${issuerBaseURL}/userinfo`);
|
|
487
|
+
* return {
|
|
488
|
+
* ...session,
|
|
489
|
+
* userProfile // access using `req.appSession.userProfile`
|
|
490
|
+
* };
|
|
491
|
+
* }
|
|
492
|
+
* }))
|
|
493
|
+
* ``
|
|
494
|
+
*/
|
|
495
|
+
afterCallback?: (
|
|
496
|
+
req: OpenidRequest,
|
|
497
|
+
res: OpenidResponse,
|
|
498
|
+
session: Session,
|
|
499
|
+
decodedState: { [key: string]: any }
|
|
500
|
+
) => Promise<Session> | Session;
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Array value of claims to remove from the ID token before storing the cookie session.
|
|
504
|
+
* Default is `['aud', 'iss', 'iat', 'exp', 'nbf', 'nonce', 'azp', 'auth_time', 's_hash', 'at_hash', 'c_hash' ]`
|
|
505
|
+
*/
|
|
506
|
+
identityClaimFilter?: string[];
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* Boolean value to log the user out from the identity provider on application logout. Default is `false`
|
|
510
|
+
*/
|
|
511
|
+
idpLogout?: boolean;
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* String value for the expected ID token algorithm. Default is 'RS256'
|
|
515
|
+
*/
|
|
516
|
+
idTokenSigningAlg?: string;
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* REQUIRED. The root URL for the token issuer with no trailing slash.
|
|
520
|
+
* Can use env key ISSUER_BASE_URL instead.
|
|
521
|
+
*/
|
|
522
|
+
issuerBaseURL?: string;
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Set a fallback cookie with no SameSite attribute when response_mode is form_post.
|
|
526
|
+
* Default is true
|
|
527
|
+
*/
|
|
528
|
+
legacySameSiteCookie?: boolean;
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* Require authentication for all routes.
|
|
532
|
+
*/
|
|
533
|
+
authRequired?: boolean;
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Perform a Pushed Authorization Request at the issuer's pushed_authorization_request_endpoint at login.
|
|
537
|
+
*/
|
|
538
|
+
pushedAuthorizationRequests?: boolean;
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
* Set to `true` to enable Back-Channel Logout in your application.
|
|
542
|
+
* This will set up a web hook on your app at {@link ConfigParams.routes routes.backchannelLogout}
|
|
543
|
+
* On receipt of a Logout Token the webhook will store the token, then on any
|
|
544
|
+
* subsequent requests, will check the store for a Logout Token that corresponds to the
|
|
545
|
+
* current session. If it finds one, it will log the user out.
|
|
546
|
+
*
|
|
547
|
+
* In order for this to work you need to specify a {@link ConfigParams.backchannelLogout.store},
|
|
548
|
+
* which can be any `express-session` compatible store, or you can
|
|
549
|
+
* reuse {@link SessionConfigParams.store} if you are using one already.
|
|
550
|
+
*
|
|
551
|
+
* See: https://openid.net/specs/openid-connect-backchannel-1_0.html
|
|
552
|
+
*/
|
|
553
|
+
backchannelLogout?: boolean | BackchannelLogoutOptions;
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Configuration for the login, logout, callback and postLogoutRedirect routes.
|
|
557
|
+
*/
|
|
558
|
+
routes?: {
|
|
559
|
+
/**
|
|
560
|
+
* Relative path to application login.
|
|
561
|
+
*/
|
|
562
|
+
login?: string | false;
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Relative path to application logout.
|
|
566
|
+
*/
|
|
567
|
+
logout?: string | false;
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* Either a relative path to the application or a valid URI to an external domain.
|
|
571
|
+
* This value must be registered on the authorization server.
|
|
572
|
+
* The user will be redirected to this after a logout has been performed.
|
|
573
|
+
*/
|
|
574
|
+
postLogoutRedirect?: string;
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* Relative path to the application callback to process the response from the authorization server.
|
|
578
|
+
*/
|
|
579
|
+
callback?: string | false;
|
|
580
|
+
|
|
581
|
+
/**
|
|
582
|
+
* Relative path to the application's Back-Channel Logout web hook.
|
|
583
|
+
*/
|
|
584
|
+
backchannelLogout?: string;
|
|
585
|
+
};
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Configuration parameters used for the transaction cookie.
|
|
589
|
+
*/
|
|
590
|
+
transactionCookie?: Pick<CookieConfigParams, 'sameSite'> & { name?: string };
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* String value for the client's authentication method. Default is `none` when using response_type='id_token', `private_key_jwt` when using a `clientAssertionSigningKey`, otherwise `client_secret_basic`.
|
|
594
|
+
*/
|
|
595
|
+
clientAuthMethod?: string;
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Private key for use with 'private_key_jwt' clients.
|
|
599
|
+
*
|
|
600
|
+
* Can be a PEM:
|
|
601
|
+
*
|
|
602
|
+
* ```js
|
|
603
|
+
* app.use(auth({
|
|
604
|
+
* ...
|
|
605
|
+
* clientAssertionSigningKey: '-----BEGIN PRIVATE KEY-----\nMIIEo...PgCaw\n-----END PRIVATE KEY-----',
|
|
606
|
+
* }))
|
|
607
|
+
* ```
|
|
608
|
+
*
|
|
609
|
+
* Or JWK:
|
|
610
|
+
*
|
|
611
|
+
* ```js
|
|
612
|
+
* app.use(auth({
|
|
613
|
+
* ...
|
|
614
|
+
* clientAssertionSigningKey: {
|
|
615
|
+
* kty: 'RSA',
|
|
616
|
+
* n: 'u2fhZ...XIqhQ',
|
|
617
|
+
* e: 'AQAB',
|
|
618
|
+
* d: 'Cmvt9...g__Jw',
|
|
619
|
+
* p: 'y5iuh...dIMwM',
|
|
620
|
+
* q: '66Rex...IZcdc',
|
|
621
|
+
* dp: 'GVGVc...La4a0',
|
|
622
|
+
* dq: 'SyER8...Dnaes',
|
|
623
|
+
* qi: 'JTtu5...P2HMw'
|
|
624
|
+
* },
|
|
625
|
+
* }))
|
|
626
|
+
* ```
|
|
627
|
+
*
|
|
628
|
+
* Or KeyObject:
|
|
629
|
+
*
|
|
630
|
+
* ```js
|
|
631
|
+
* app.use(auth({
|
|
632
|
+
* ...
|
|
633
|
+
* clientAssertionSigningKey: crypto.createPrivateKey({ key: '-----BEGIN PRIVATE KEY-----\nMIIEo...PgCaw\n-----END PRIVATE KEY-----' }),
|
|
634
|
+
* }))
|
|
635
|
+
* ```
|
|
636
|
+
*/
|
|
637
|
+
clientAssertionSigningKey?: KeyInput | KeyObject | JSONWebKey;
|
|
638
|
+
|
|
639
|
+
/**
|
|
640
|
+
* The algorithm to sign the client assertion JWT.
|
|
641
|
+
* Uses one of `token_endpoint_auth_signing_alg_values_supported` if not specified.
|
|
642
|
+
* If the Authorization Server discovery document does not list `token_endpoint_auth_signing_alg_values_supported`
|
|
643
|
+
* this property will be required.
|
|
644
|
+
*/
|
|
645
|
+
clientAssertionSigningAlg?:
|
|
646
|
+
| 'RS256'
|
|
647
|
+
| 'RS384'
|
|
648
|
+
| 'RS512'
|
|
649
|
+
| 'PS256'
|
|
650
|
+
| 'PS384'
|
|
651
|
+
| 'PS512'
|
|
652
|
+
| 'ES256'
|
|
653
|
+
| 'ES256K'
|
|
654
|
+
| 'ES384'
|
|
655
|
+
| 'ES512'
|
|
656
|
+
| 'EdDSA';
|
|
657
|
+
|
|
658
|
+
/**
|
|
659
|
+
* Additional request body properties to be sent to the `token_endpoint` during authorization code exchange or token refresh.
|
|
660
|
+
*/
|
|
661
|
+
tokenEndpointParams?: TokenParameters;
|
|
662
|
+
|
|
663
|
+
/**
|
|
664
|
+
* Maximum time (in milliseconds) to wait before fetching the Identity Provider's Discovery document again. Default is 600000 (10 minutes).
|
|
665
|
+
*/
|
|
666
|
+
discoveryCacheMaxAge?: number;
|
|
667
|
+
|
|
668
|
+
/**
|
|
669
|
+
* Http timeout for oidc client requests in milliseconds. Default is 5000. Minimum is 500.
|
|
670
|
+
*/
|
|
671
|
+
httpTimeout?: number;
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Specify an Agent or Agents to pass to the underlying http client https://github.com/sindresorhus/got/
|
|
675
|
+
*
|
|
676
|
+
* An object representing `http`, `https` and `http2` keys for [`http.Agent`](https://nodejs.org/api/http.html#http_class_http_agent),
|
|
677
|
+
* [`https.Agent`](https://nodejs.org/api/https.html#https_class_https_agent) and [`http2wrapper.Agent`](https://github.com/szmarczak/http2-wrapper#new-http2agentoptions) instance.
|
|
678
|
+
*
|
|
679
|
+
* See https://github.com/sindresorhus/got/blob/v11.8.6/readme.md#agent
|
|
680
|
+
*
|
|
681
|
+
* For a proxy agent see https://www.npmjs.com/package/proxy-agent
|
|
682
|
+
*/
|
|
683
|
+
httpAgent?: {
|
|
684
|
+
http?: HttpAgent | false;
|
|
685
|
+
https?: HttpsAgent | false;
|
|
686
|
+
http2?: unknown | false;
|
|
687
|
+
};
|
|
688
|
+
|
|
689
|
+
/**
|
|
690
|
+
* Optional User-Agent header value for oidc client requests. Default is `express-openid-connect/{version}`.
|
|
691
|
+
*/
|
|
692
|
+
httpUserAgent?: string;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
interface SessionStorePayload<Data = Session> {
|
|
696
|
+
header: {
|
|
697
|
+
/**
|
|
698
|
+
* timestamp (in secs) when the session was created.
|
|
699
|
+
*/
|
|
700
|
+
iat: number;
|
|
701
|
+
/**
|
|
702
|
+
* timestamp (in secs) when the session was last touched.
|
|
703
|
+
*/
|
|
704
|
+
uat: number;
|
|
705
|
+
/**
|
|
706
|
+
* timestamp (in secs) when the session expires.
|
|
707
|
+
*/
|
|
708
|
+
exp: number;
|
|
709
|
+
};
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* The session data.
|
|
713
|
+
*/
|
|
714
|
+
data: Data;
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* This makes it compatible with some `express-session` stores that use this
|
|
718
|
+
* to set their ttl.
|
|
719
|
+
*/
|
|
720
|
+
cookie: {
|
|
721
|
+
expires: number;
|
|
722
|
+
maxAge: number;
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
interface SessionStore<Data = Session> {
|
|
727
|
+
/**
|
|
728
|
+
* Gets the session from the store given a session ID and passes it to `callback`.
|
|
729
|
+
*/
|
|
730
|
+
get(
|
|
731
|
+
sid: string,
|
|
732
|
+
callback: (err: any, session?: SessionStorePayload<Data> | null) => void
|
|
733
|
+
): void;
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* Upsert a session in the store given a session ID and `SessionData`
|
|
737
|
+
*/
|
|
738
|
+
set(
|
|
739
|
+
sid: string,
|
|
740
|
+
session: SessionStorePayload<Data>,
|
|
741
|
+
callback?: (err?: any) => void
|
|
742
|
+
): void;
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* Destroys the session with the given session ID.
|
|
746
|
+
*/
|
|
747
|
+
destroy(sid: string, callback?: (err?: any) => void): void;
|
|
748
|
+
|
|
749
|
+
[key: string]: any;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* Configuration parameters used for the application session.
|
|
754
|
+
*/
|
|
755
|
+
interface SessionConfigParams {
|
|
756
|
+
/**
|
|
757
|
+
* String value for the cookie name used for the internal session.
|
|
758
|
+
* This value must only include letters, numbers, and underscores.
|
|
759
|
+
* Default is `appSession`.
|
|
760
|
+
*/
|
|
761
|
+
name?: string;
|
|
762
|
+
|
|
763
|
+
/**
|
|
764
|
+
* By default the session is stored in an encrypted cookie. But when the session
|
|
765
|
+
* gets too large it can bump up against the limits of cookie storage.
|
|
766
|
+
* In these instances you can use a custom session store. The store should
|
|
767
|
+
* have `get`, `set` and `destroy` methods, making it compatible
|
|
768
|
+
* with [express-session stores](https://github.com/expressjs/session#session-store-implementation).
|
|
769
|
+
*/
|
|
770
|
+
store?: SessionStore;
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* A Function for generating a session id when using a custom session store.
|
|
774
|
+
* For full details see the documentation for express-session
|
|
775
|
+
* at [genid](https://github.com/expressjs/session/blob/master/README.md#genid).
|
|
776
|
+
*
|
|
777
|
+
* Be aware the default implementation is slightly different in this library as
|
|
778
|
+
* compared to the default session id generation used in express-session.
|
|
779
|
+
*
|
|
780
|
+
* **IMPORTANT** If you override this method you should be careful to generate
|
|
781
|
+
* unique IDs so your sessions do not conflict. Also, to reduce the ability
|
|
782
|
+
* to hijack a session by guessing the session ID, you must use a suitable
|
|
783
|
+
* cryptographically strong random value of sufficient size or sign the cookie
|
|
784
|
+
* by setting {@Link signSessionStoreCookie} to `true`.
|
|
785
|
+
*/
|
|
786
|
+
genid?: (req: OpenidRequest) => Promise<string> | string;
|
|
787
|
+
|
|
788
|
+
/**
|
|
789
|
+
* Sign the session store cookies to reduce the chance of collisions
|
|
790
|
+
* and reduce the ability to hijack a session by guessing the session ID.
|
|
791
|
+
*
|
|
792
|
+
* This is required if you override {@Link genid} and don't use a suitable
|
|
793
|
+
* cryptographically strong random value of sufficient size.
|
|
794
|
+
*/
|
|
795
|
+
signSessionStoreCookie?: boolean;
|
|
796
|
+
|
|
797
|
+
/**
|
|
798
|
+
* If you enable {@Link signSessionStoreCookie} your existing sessions will
|
|
799
|
+
* be invalidated. You can use this flag to temporarily allow unsigned cookies
|
|
800
|
+
* while you sign your user's session cookies. For example:
|
|
801
|
+
*
|
|
802
|
+
* Set {@Link signSessionStoreCookie} to `true` and {@Link requireSignedSessionStoreCookie} to `false`.
|
|
803
|
+
* Wait for your {@Link rollingDuration} (default 1 day) or {@Link absoluteDuration} (default 1 week)
|
|
804
|
+
* to pass (which ever comes first). By this time all your sessions cookies will either be signed or
|
|
805
|
+
* have expired, then you can remove the {@Link requireSignedSessionStoreCookie} config option which
|
|
806
|
+
* will set it to `true`.
|
|
807
|
+
*
|
|
808
|
+
* Signed session store cookies will be mandatory in the next major release.
|
|
809
|
+
*/
|
|
810
|
+
requireSignedSessionStoreCookie?: boolean;
|
|
811
|
+
|
|
812
|
+
/**
|
|
813
|
+
* If you want your session duration to be rolling, eg reset everytime the
|
|
814
|
+
* user is active on your site, set this to a `true`. If you want the session
|
|
815
|
+
* duration to be absolute, where the user is logged out a fixed time after login,
|
|
816
|
+
* regardless of activity, set this to `false`
|
|
817
|
+
* Default is `true`.
|
|
818
|
+
*/
|
|
819
|
+
rolling?: boolean;
|
|
820
|
+
|
|
821
|
+
/**
|
|
822
|
+
* Integer value, in seconds, for application session rolling duration.
|
|
823
|
+
* The amount of time for which the user must be idle for then to be logged out.
|
|
824
|
+
* Default is 86400 seconds (1 day).
|
|
825
|
+
*/
|
|
826
|
+
rollingDuration?: number;
|
|
827
|
+
|
|
828
|
+
/**
|
|
829
|
+
* Integer value, in seconds, for application absolute rolling duration.
|
|
830
|
+
* The amount of time after the user has logged in that they will be logged out.
|
|
831
|
+
* Set this to `false` if you don't want an absolute duration on your session.
|
|
832
|
+
* Default is 604800 seconds (7 days).
|
|
833
|
+
*/
|
|
834
|
+
absoluteDuration?: boolean | number;
|
|
835
|
+
|
|
836
|
+
/**
|
|
837
|
+
* Configuration parameters used for the session cookie and transient cookies.
|
|
838
|
+
*/
|
|
839
|
+
cookie?: CookieConfigParams;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
interface CookieConfigParams {
|
|
843
|
+
/**
|
|
844
|
+
* Domain name for the cookie.
|
|
845
|
+
* Passed to the [Response cookie](https://expressjs.com/en/api.html#res.cookie) as `domain`
|
|
846
|
+
*/
|
|
847
|
+
domain?: string;
|
|
848
|
+
|
|
849
|
+
/**
|
|
850
|
+
* Path for the cookie.
|
|
851
|
+
* Passed to the [Response cookie](https://expressjs.com/en/api.html#res.cookie) as `path`
|
|
852
|
+
*/
|
|
853
|
+
path?: string;
|
|
854
|
+
|
|
855
|
+
/**
|
|
856
|
+
* Set to true to use a transient cookie (cookie without an explicit expiration).
|
|
857
|
+
* Default is `false`
|
|
858
|
+
*/
|
|
859
|
+
transient?: boolean;
|
|
860
|
+
|
|
861
|
+
/**
|
|
862
|
+
* Flags the cookie to be accessible only by the web server.
|
|
863
|
+
* Passed to the [Response cookie](https://expressjs.com/en/api.html#res.cookie) as `httponly`.
|
|
864
|
+
* Defaults to `true`.
|
|
865
|
+
*/
|
|
866
|
+
httpOnly?: boolean;
|
|
867
|
+
|
|
868
|
+
/**
|
|
869
|
+
* Marks the cookie to be used over secure channels only.
|
|
870
|
+
* Passed to the [Response cookie](https://expressjs.com/en/api.html#res.cookie) as `secure`.
|
|
871
|
+
* Defaults to the protocol of {@link ConfigParams.baseURL}.
|
|
872
|
+
*/
|
|
873
|
+
secure?: boolean;
|
|
874
|
+
|
|
875
|
+
/**
|
|
876
|
+
* Value of the SameSite Set-Cookie attribute.
|
|
877
|
+
* Passed to the [Response cookie](https://expressjs.com/en/api.html#res.cookie) as `samesite`.
|
|
878
|
+
* Defaults to "Lax" but will be adjusted based on {@link AuthorizationParameters.response_type}.
|
|
879
|
+
* When setting to 'None' (uncommon), you should implement CSRF protection on your own routes
|
|
880
|
+
*/
|
|
881
|
+
sameSite?: string;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
interface AccessToken {
|
|
885
|
+
/**
|
|
886
|
+
* The access token itself, can be an opaque string, JWT, or non-JWT token.
|
|
887
|
+
*/
|
|
888
|
+
access_token: string;
|
|
889
|
+
|
|
890
|
+
/**
|
|
891
|
+
* The type of access token, Usually "Bearer".
|
|
892
|
+
*/
|
|
893
|
+
token_type: string;
|
|
894
|
+
|
|
895
|
+
/**
|
|
896
|
+
* Number of seconds until the access token expires.
|
|
897
|
+
*/
|
|
898
|
+
expires_in: number;
|
|
899
|
+
|
|
900
|
+
/**
|
|
901
|
+
* Returns `true` if the access_token has expired.
|
|
902
|
+
*/
|
|
903
|
+
isExpired: () => boolean;
|
|
904
|
+
|
|
905
|
+
/**
|
|
906
|
+
* Performs refresh_token grant type exchange and updates the session's access token.
|
|
907
|
+
*
|
|
908
|
+
* ```js
|
|
909
|
+
* let accessToken = req.oidc.accessToken;
|
|
910
|
+
* if (accessToken.isExpired()) {
|
|
911
|
+
* accessToken = await accessToken.refresh();
|
|
912
|
+
* }
|
|
913
|
+
* ```
|
|
914
|
+
*/
|
|
915
|
+
refresh(params?: RefreshParams): Promise<AccessToken>;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
interface RefreshParams {
|
|
919
|
+
tokenEndpointParams?: TokenParameters;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
interface TokenParameters {
|
|
923
|
+
[key: string]: unknown;
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
/**
|
|
927
|
+
* Express JS middleware implementing sign on for Express web apps using OpenID Connect.
|
|
928
|
+
*
|
|
929
|
+
* The `auth()` middleware requires {@link ConfigParams.secret secret}, {@link ConfigParams.baseURL baseURL}, {@link ConfigParams.clientID clientID}
|
|
930
|
+
* and {@link ConfigParams.issuerBaseURL issuerBaseURL}.
|
|
931
|
+
*
|
|
932
|
+
* If you are using a response type that includes `code`, you will also need: {@link ConfigParams.clientSecret clientSecret}
|
|
933
|
+
* ```
|
|
934
|
+
* const express = require('express');
|
|
935
|
+
* const { auth } = require('express-openid-connect');
|
|
936
|
+
*
|
|
937
|
+
* const app = express();
|
|
938
|
+
*
|
|
939
|
+
* app.use(
|
|
940
|
+
* auth({
|
|
941
|
+
* issuerBaseURL: 'https://YOUR_DOMAIN',
|
|
942
|
+
* baseURL: 'https://YOUR_APPLICATION_ROOT_URL',
|
|
943
|
+
* clientID: 'YOUR_CLIENT_ID',
|
|
944
|
+
* secret: 'LONG_RANDOM_STRING',
|
|
945
|
+
* })
|
|
946
|
+
* );
|
|
947
|
+
*
|
|
948
|
+
* app.get('/', (req, res) => {
|
|
949
|
+
* res.send(`hello ${req.oidc.user.name}`);
|
|
950
|
+
* });
|
|
951
|
+
*
|
|
952
|
+
* app.listen(3000, () => console.log('listening at http://localhost:3000'))
|
|
953
|
+
* ```
|
|
954
|
+
*/
|
|
955
|
+
export function auth(params?: ConfigParams): RequestHandler;
|
|
956
|
+
|
|
957
|
+
/**
|
|
958
|
+
* Set {@link ConfigParams.authRequired authRequired} to `false` then require authentication
|
|
959
|
+
* on specific routes.
|
|
960
|
+
*
|
|
961
|
+
* ```js
|
|
962
|
+
* const { auth, requiresAuth } = require('express-openid-connect');
|
|
963
|
+
*
|
|
964
|
+
* app.use(
|
|
965
|
+
* auth({
|
|
966
|
+
* ...
|
|
967
|
+
* authRequired: false
|
|
968
|
+
* })
|
|
969
|
+
* );
|
|
970
|
+
*
|
|
971
|
+
* app.get('/profile', requiresAuth(), (req, res) => {
|
|
972
|
+
* res.send(`hello ${req.oidc.user.name}`);
|
|
973
|
+
* });
|
|
974
|
+
*
|
|
975
|
+
* ```
|
|
976
|
+
*/
|
|
977
|
+
export function requiresAuth(
|
|
978
|
+
requiresLoginCheck?: (req: OpenidRequest) => boolean
|
|
979
|
+
): RequestHandler;
|
|
980
|
+
|
|
981
|
+
/**
|
|
982
|
+
* Use this MW to protect a route based on the value of a specific claim.
|
|
983
|
+
*
|
|
984
|
+
* ```js
|
|
985
|
+
* const { claimEquals } = require('express-openid-connect');
|
|
986
|
+
*
|
|
987
|
+
* app.get('/admin', claimEquals('isAdmin', true), (req, res) => {
|
|
988
|
+
* res.send(...);
|
|
989
|
+
* });
|
|
990
|
+
*
|
|
991
|
+
* ```
|
|
992
|
+
*
|
|
993
|
+
* @param claim The name of the claim
|
|
994
|
+
* @param value The value of the claim, should be a primitive
|
|
995
|
+
*/
|
|
996
|
+
export function claimEquals(
|
|
997
|
+
claim: string,
|
|
998
|
+
value: boolean | number | string | null
|
|
999
|
+
): RequestHandler;
|
|
1000
|
+
|
|
1001
|
+
/**
|
|
1002
|
+
* Use this MW to protect a route, checking that _all_ values are in a claim.
|
|
1003
|
+
*
|
|
1004
|
+
* ```js
|
|
1005
|
+
* const { claimIncludes } = require('express-openid-connect');
|
|
1006
|
+
*
|
|
1007
|
+
* app.get('/admin/delete', claimIncludes('roles', 'admin', 'superadmin'), (req, res) => {
|
|
1008
|
+
* res.send(...);
|
|
1009
|
+
* });
|
|
1010
|
+
*
|
|
1011
|
+
* ```
|
|
1012
|
+
*
|
|
1013
|
+
* @param claim The name of the claim
|
|
1014
|
+
* @param args Claim values that must all be included
|
|
1015
|
+
*/
|
|
1016
|
+
export function claimIncludes(
|
|
1017
|
+
claim: string,
|
|
1018
|
+
...args: (boolean | number | string | null)[]
|
|
1019
|
+
): RequestHandler;
|
|
1020
|
+
|
|
1021
|
+
/**
|
|
1022
|
+
* Use this MW to protect a route, providing a custom function to check.
|
|
1023
|
+
*
|
|
1024
|
+
* ```js
|
|
1025
|
+
* const { claimCheck } = require('express-openid-connect');
|
|
1026
|
+
*
|
|
1027
|
+
* app.get('/admin/community', claimCheck((req, claims) => {
|
|
1028
|
+
* return claims.isAdmin && claims.roles.includes('community');
|
|
1029
|
+
* }), (req, res) => {
|
|
1030
|
+
* res.send(...);
|
|
1031
|
+
* });
|
|
1032
|
+
*
|
|
1033
|
+
* ```
|
|
1034
|
+
*/
|
|
1035
|
+
export function claimCheck(
|
|
1036
|
+
checkFn: (req: OpenidRequest, claims: IdTokenClaims) => boolean
|
|
1037
|
+
): RequestHandler;
|
|
1038
|
+
|
|
1039
|
+
/**
|
|
1040
|
+
* Use this MW to attempt silent login (`prompt=none`) but not require authentication.
|
|
1041
|
+
*
|
|
1042
|
+
* See {@link ConfigParams.attemptSilentLogin attemptSilentLogin}
|
|
1043
|
+
*
|
|
1044
|
+
* ```js
|
|
1045
|
+
* const { attemptSilentLogin } = require('express-openid-connect');
|
|
1046
|
+
*
|
|
1047
|
+
* app.get('/', attemptSilentLogin(), (req, res) => {
|
|
1048
|
+
* res.render('homepage', {
|
|
1049
|
+
* isAuthenticated: req.isAuthenticated() // show a login or logout button
|
|
1050
|
+
* });
|
|
1051
|
+
* });
|
|
1052
|
+
*
|
|
1053
|
+
* ```
|
|
1054
|
+
*/
|
|
1055
|
+
export function attemptSilentLogin(): RequestHandler;
|