@crossauth/fastify 0.0.2
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 +203 -0
- package/README.md +12 -0
- package/dist/fastifyadminclientendpoints.d.ts +149 -0
- package/dist/fastifyadminendpoints.d.ts +126 -0
- package/dist/fastifyapikey.d.ts +42 -0
- package/dist/fastifyoauthclient.d.ts +429 -0
- package/dist/fastifyoauthserver.d.ts +248 -0
- package/dist/fastifyresserver.d.ts +93 -0
- package/dist/fastifyserver.d.ts +293 -0
- package/dist/fastifysession.d.ts +767 -0
- package/dist/fastifysessionadapter.d.ts +48 -0
- package/dist/fastifyuserclientendpoints.d.ts +61 -0
- package/dist/fastifyuserendpoints.d.ts +193 -0
- package/dist/index.cjs +9085 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +9085 -0
- package/dist/tests/admincommon.d.ts +20 -0
- package/dist/tests/fastifyadminapiendpoints.test.d.ts +13 -0
- package/dist/tests/fastifyadminclientapiendpoints.test.d.ts +13 -0
- package/dist/tests/fastifyadminclientendpoints.test.d.ts +13 -0
- package/dist/tests/fastifyadminendpoints.test.d.ts +13 -0
- package/dist/tests/fastifyapikeyserver.test.d.ts +13 -0
- package/dist/tests/fastifyapiserver.test.d.ts +11 -0
- package/dist/tests/fastifyapitwofactor.test.d.ts +11 -0
- package/dist/tests/fastifyauthserver.test.d.ts +17 -0
- package/dist/tests/fastifyclient.test.d.ts +1 -0
- package/dist/tests/fastifymfaclient.test.d.ts +4 -0
- package/dist/tests/fastifyresserver.test.d.ts +1 -0
- package/dist/tests/fastifysessionserver.test.d.ts +13 -0
- package/dist/tests/fastifytwofactorserver.test.d.ts +17 -0
- package/dist/tests/fastifyuserclientapiendpoints.test.d.ts +13 -0
- package/dist/tests/fastifyuserclientendpoints.test.d.ts +13 -0
- package/dist/tests/inmemorytestdata.d.ts +3 -0
- package/dist/tests/oauthcommon.d.ts +45 -0
- package/package.json +75 -0
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
import { FastifyRequest, FastifyReply } from 'fastify';
|
|
2
|
+
import { OAuthTokenResponse, OAuthDeviceAuthorizationResponse, User } from '@crossauth/common';
|
|
3
|
+
import { OAuthClientBackend, OAuthClientOptions } from '@crossauth/backend';
|
|
4
|
+
import { FastifyServer, FastifyErrorFn } from './fastifyserver';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Options for {@link FastifyOAuthClient}.
|
|
8
|
+
*/
|
|
9
|
+
export interface FastifyOAuthClientOptions extends OAuthClientOptions {
|
|
10
|
+
/** The base URL for endpoints served by this class.
|
|
11
|
+
* THe only endpoint that is created is the redirect Uri, which is
|
|
12
|
+
* `siteUrl` + `prefix` + `authzcode`,
|
|
13
|
+
*/
|
|
14
|
+
siteUrl?: string;
|
|
15
|
+
/**
|
|
16
|
+
* The prefix between the `siteUrl` and endpoints created by this
|
|
17
|
+
* class. See {@link FastifyOAuthClientOptions.siteUrl}.
|
|
18
|
+
*/
|
|
19
|
+
prefix?: string;
|
|
20
|
+
/**
|
|
21
|
+
* When using the BFF (backend-for-frontend) pattern, tokens are saved
|
|
22
|
+
* in the `data` field of the session ID. They are saved in the JSON
|
|
23
|
+
* object with this field name. Default `oauth`.
|
|
24
|
+
*/
|
|
25
|
+
sessionDataName?: string;
|
|
26
|
+
/**
|
|
27
|
+
* The template file for rendering error messages
|
|
28
|
+
* when {@link FastifyOAuthClientOptions.errorResponseType}
|
|
29
|
+
* is `errorPage`.
|
|
30
|
+
*/
|
|
31
|
+
errorPage?: string;
|
|
32
|
+
/**
|
|
33
|
+
* The template file for asking the user for username and password
|
|
34
|
+
* in the password flow,
|
|
35
|
+
*
|
|
36
|
+
* Default `passwordflow.njk`
|
|
37
|
+
*/
|
|
38
|
+
passwordFlowPage?: string;
|
|
39
|
+
/**
|
|
40
|
+
* The template file to tell users the url to go to to complete the
|
|
41
|
+
* device code flow.
|
|
42
|
+
*
|
|
43
|
+
* Default `devicecodeflow.njk`
|
|
44
|
+
*/
|
|
45
|
+
deviceCodeFlowPage?: string;
|
|
46
|
+
/**
|
|
47
|
+
* The template file to show the result in the `deletetokens` endpoint.
|
|
48
|
+
*
|
|
49
|
+
* Default `deletetokens.njk`
|
|
50
|
+
*/
|
|
51
|
+
deleteTokensPage?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Tthe `deletetokens` GET endpoint.
|
|
54
|
+
*
|
|
55
|
+
* Default undefined - don't create the endpoint
|
|
56
|
+
*/
|
|
57
|
+
deleteTokensGetUrl?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Whether to add the `deletetokens` POST endpoint.
|
|
60
|
+
*
|
|
61
|
+
* Default undefined - don't create the endpoint
|
|
62
|
+
*/
|
|
63
|
+
deleteTokensPostUrl?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Whether to add the `api/deletetokens` POST endpoint.
|
|
66
|
+
*
|
|
67
|
+
* Default undefined - don't create the endpoint
|
|
68
|
+
*/
|
|
69
|
+
apiDeleteTokensPostUrl?: string;
|
|
70
|
+
/**
|
|
71
|
+
* The template file for asking the user for an OTP in the password MFA
|
|
72
|
+
* flow.
|
|
73
|
+
*/
|
|
74
|
+
mfaOtpPage?: string;
|
|
75
|
+
/**
|
|
76
|
+
* The template file for asking the user for an OOB in the password MFA
|
|
77
|
+
* flow.
|
|
78
|
+
*/
|
|
79
|
+
mfaOobPage?: string;
|
|
80
|
+
/**
|
|
81
|
+
* The template file for telling the user that authorization was successful.
|
|
82
|
+
*/
|
|
83
|
+
authorizedPage?: string;
|
|
84
|
+
/**
|
|
85
|
+
* If the {@link FastifyOAuthClientOptions.tokenResponseType} is
|
|
86
|
+
* `saveInSessionAndRedirect`, this is the relative URL that the usder
|
|
87
|
+
* will be redirected to after authorization is complete.
|
|
88
|
+
*/
|
|
89
|
+
authorizedUrl?: string;
|
|
90
|
+
/**
|
|
91
|
+
* Relative URL to redirect user to if login is required.
|
|
92
|
+
*/
|
|
93
|
+
loginUrl?: string;
|
|
94
|
+
/**
|
|
95
|
+
* All flows listed here will require the user to login (here at the client).
|
|
96
|
+
* If if a flow is not listed here, there does not need to be a user
|
|
97
|
+
* logged in here at the client.
|
|
98
|
+
* See {@link @crossauth/common!OAuthFlows}.
|
|
99
|
+
*/
|
|
100
|
+
loginProtectedFlows?: string[];
|
|
101
|
+
/**
|
|
102
|
+
* The URL to create the password flow under. Default `passwordflow`.
|
|
103
|
+
*/
|
|
104
|
+
passwordFlowUrl?: string;
|
|
105
|
+
/**
|
|
106
|
+
* The URL to to create the device code flow under. Default `devicecodeflow`.
|
|
107
|
+
*/
|
|
108
|
+
deviceCodeFlowUrl?: string;
|
|
109
|
+
/**
|
|
110
|
+
* The URL to to for polling until the device code flow completes.
|
|
111
|
+
* Default `devicecodepoll`.
|
|
112
|
+
*/
|
|
113
|
+
deviceCodePollUrl?: string;
|
|
114
|
+
/**
|
|
115
|
+
* The URL to create the otp endpoint for the password mfa flow under.
|
|
116
|
+
* This endpoint asks the user for his or her OTP.
|
|
117
|
+
* Default `passwordflowotp`.
|
|
118
|
+
*/
|
|
119
|
+
passwordOtpUrl?: string;
|
|
120
|
+
/**
|
|
121
|
+
* The URL to create the otp endpoint for the password mfa flow under.
|
|
122
|
+
* This endpoint asks the user for his or her OOB.
|
|
123
|
+
* Default `passwordflowoob`.
|
|
124
|
+
*/
|
|
125
|
+
passwordOobUrl?: string;
|
|
126
|
+
/**
|
|
127
|
+
* This function is called after successful authorization to pass the
|
|
128
|
+
* new tokens to.
|
|
129
|
+
* @param oauthResponse the response from the OAuth `token` endpoint.
|
|
130
|
+
* @param client the fastify OAuth client
|
|
131
|
+
* @param request the Fastify request
|
|
132
|
+
* @param reply the Fastify reply
|
|
133
|
+
* @returns the Fastify reply
|
|
134
|
+
*/
|
|
135
|
+
receiveTokenFn?: (oauthResponse: OAuthTokenResponse, client: FastifyOAuthClient, request: FastifyRequest, reply?: FastifyReply) => Promise<FastifyReply | undefined>;
|
|
136
|
+
/**
|
|
137
|
+
* The function to call when there is an OAuth error and
|
|
138
|
+
* {@link FastifyOAuthClientOptions.errorResponseType}
|
|
139
|
+
* is `custom`.
|
|
140
|
+
* See {@link FastifyErrorFn}.
|
|
141
|
+
*/
|
|
142
|
+
errorFn?: FastifyErrorFn;
|
|
143
|
+
/**
|
|
144
|
+
* What to do when receiving tokens.
|
|
145
|
+
* See {@link FastifyOAuthClient} class documentation for full description.
|
|
146
|
+
*/
|
|
147
|
+
tokenResponseType?: "sendJson" | "saveInSessionAndLoad" | "saveInSessionAndRedirect" | "sendInPage" | "custom";
|
|
148
|
+
/**
|
|
149
|
+
* What do do on receiving an OAuth error.
|
|
150
|
+
* See lass documentation for full description.
|
|
151
|
+
*/
|
|
152
|
+
errorResponseType?: "sendJson" | "errorPage" | "custom";
|
|
153
|
+
/**
|
|
154
|
+
* Array of resource server endppints to serve through the
|
|
155
|
+
* BFF (backend-for-frontend) mechanism.
|
|
156
|
+
* See {@link FastifyOAuthClient} class documentation for full description.
|
|
157
|
+
*/
|
|
158
|
+
bffEndpoints?: {
|
|
159
|
+
url: string;
|
|
160
|
+
methods: ("GET" | "POST" | "PUT" | "DELETE" | "PATCH")[];
|
|
161
|
+
matchSubUrls?: boolean;
|
|
162
|
+
}[];
|
|
163
|
+
/**
|
|
164
|
+
* Prefix for BFF endpoints. Default "bff".
|
|
165
|
+
* See {@link FastifyOAuthClient} class documentation for full description.
|
|
166
|
+
*/
|
|
167
|
+
bffEndpointName?: string;
|
|
168
|
+
/**
|
|
169
|
+
* Base URL for resource server endpoints called through the BFF
|
|
170
|
+
* mechanism.
|
|
171
|
+
* See {@link FastifyOAuthClient} class documentation for full description.
|
|
172
|
+
*/
|
|
173
|
+
bffBaseUrl?: string;
|
|
174
|
+
/**
|
|
175
|
+
* Endpoints to provide to acces tokens through the BFF mechanism,
|
|
176
|
+
* See {@link FastifyOAuthClient} class documentation for full description.
|
|
177
|
+
*/
|
|
178
|
+
tokenEndpoints?: ("access_token" | "refresh_token" | "id_token" | "have_access_token" | "have_refresh_token" | "have_id_token")[];
|
|
179
|
+
/**
|
|
180
|
+
* Set of flows to enable (see {@link @crossauth/common!OAuthFlows}).
|
|
181
|
+
*
|
|
182
|
+
* Defaults to empty.
|
|
183
|
+
*/
|
|
184
|
+
validFlows?: string[];
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Query type for the `authorize` Fastify request.
|
|
188
|
+
*/
|
|
189
|
+
export interface ClientAuthorizeQueryType {
|
|
190
|
+
scope?: string;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Query type for the redirect Uri Fastify request.
|
|
194
|
+
*/
|
|
195
|
+
export interface RedirectUriQueryType {
|
|
196
|
+
code?: string;
|
|
197
|
+
state?: string;
|
|
198
|
+
error?: string;
|
|
199
|
+
error_description?: string;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Query type for the password flow Fastify request.
|
|
203
|
+
*/
|
|
204
|
+
export interface PasswordQueryType {
|
|
205
|
+
scope?: string;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Query type for the client cresentials flow Fastify request.
|
|
209
|
+
*/
|
|
210
|
+
export interface ClientCredentialsBodyType {
|
|
211
|
+
scope?: string;
|
|
212
|
+
csrfToken?: string;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Query type for the refresh token flow Fastify request.
|
|
216
|
+
*/
|
|
217
|
+
export interface RefreshTokenBodyType {
|
|
218
|
+
refreshToken?: string;
|
|
219
|
+
csrfToken?: string;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Body type for the password flow Fastify request.
|
|
223
|
+
*/
|
|
224
|
+
export interface PasswordBodyType {
|
|
225
|
+
username: string;
|
|
226
|
+
password: string;
|
|
227
|
+
scope?: string;
|
|
228
|
+
csrfToken?: string;
|
|
229
|
+
}
|
|
230
|
+
export interface DeviceCodeFlowResponse extends OAuthDeviceAuthorizationResponse {
|
|
231
|
+
user?: User;
|
|
232
|
+
scope?: string;
|
|
233
|
+
verification_uri_qrdata?: string;
|
|
234
|
+
errorMessage?: string;
|
|
235
|
+
errorCode?: number;
|
|
236
|
+
errorCodeName?: string;
|
|
237
|
+
csrfToken?: string;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Body type for the device code flow Fastify request.
|
|
241
|
+
*/
|
|
242
|
+
export interface DeviceCodeBodyType {
|
|
243
|
+
scope?: string;
|
|
244
|
+
csrfToken?: string;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Body type for the device code flow Fastify request.
|
|
248
|
+
*/
|
|
249
|
+
export interface DeviceCodePollBodyType {
|
|
250
|
+
device_code: string;
|
|
251
|
+
csrfToken?: string;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Query type for the OTP endpoint on the password mfa flow Fastify request.
|
|
255
|
+
*/
|
|
256
|
+
export interface PasswordOtpType {
|
|
257
|
+
scope?: string;
|
|
258
|
+
mfa_token: string;
|
|
259
|
+
otp: string;
|
|
260
|
+
challenge_type?: string;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Query type for the OOB endpoint on the password mfa flow Fastify request.
|
|
264
|
+
*/
|
|
265
|
+
export interface PasswordOobType {
|
|
266
|
+
scope?: string;
|
|
267
|
+
mfa_token: string;
|
|
268
|
+
oob_code: string;
|
|
269
|
+
binding_code: string;
|
|
270
|
+
challenge_type?: string;
|
|
271
|
+
name?: string;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* The Fastify implementation of the OAuth client.
|
|
275
|
+
*
|
|
276
|
+
* Makes requests to an authorization server, using a configurable set
|
|
277
|
+
* of flows, which sends back errors or tokens,
|
|
278
|
+
*
|
|
279
|
+
* When constructing this class, you define what happens with tokens that
|
|
280
|
+
* are returned, or errors that are returned. You do this with the
|
|
281
|
+
* configuration options {@link FastifyOAuthClientOptions.tokenResponseType}
|
|
282
|
+
* and {@link FastifyOAuthClientOptions.errorResponseType}.
|
|
283
|
+
*
|
|
284
|
+
* **{@link FastifyOAuthClientOptions.tokenResponseType}**
|
|
285
|
+
*
|
|
286
|
+
* - `sendJson` the token response is sent as-is in the reply to the Fastify
|
|
287
|
+
* request. In addition to the `token` endpoint response fields,
|
|
288
|
+
* `ok: true` and `id_payload` with the decoded
|
|
289
|
+
* payload of the ID token are retruned.
|
|
290
|
+
* - `saveInSessionAndLoad` the response fields are saved in the `data`
|
|
291
|
+
* field of the session ID in key storage. In addition, `expires_at` is
|
|
292
|
+
* set to the number of seconds since Epoch that the access token expires
|
|
293
|
+
* at. After saving, page defined in `authorizedPage` is displayed.
|
|
294
|
+
* A consequence is the query parameters passed to the
|
|
295
|
+
* redirect Uri are displayed in the address bar, as the response
|
|
296
|
+
* is to the redirect to the redirect Uri.
|
|
297
|
+
* - saveInSessionAndRedirect` same as `saveInSessionAndLoad` except that
|
|
298
|
+
* a redirect is done to the `authorizedUrl` rather than displaying
|
|
299
|
+
* `authorizedPage` template.
|
|
300
|
+
* - `sendInPage` the `token` endpoint response is not saved in the session
|
|
301
|
+
* but just sent as template arguments when rendering the
|
|
302
|
+
* template in `authorizedPage`. The JSON response fields are sent
|
|
303
|
+
* verbatim, with the additional fild of `id_payload` which is the
|
|
304
|
+
* decoded payload from the ID token, if present.
|
|
305
|
+
* - `custom` the function in
|
|
306
|
+
* {@link FastifyOAuthClientOptions.receiveTokenFn} is called.
|
|
307
|
+
*
|
|
308
|
+
* **{@link FastifyOAuthClientOptions.errorResponseType}**
|
|
309
|
+
*
|
|
310
|
+
* - `sendJson` a JSON response is sent with fields
|
|
311
|
+
* `status`, `errorMessage`,
|
|
312
|
+
* `errorMessages` and `errorCodeName`.
|
|
313
|
+
* - `errorPage` the template in {@link FastifyOAuthClientOptions.errorPage}
|
|
314
|
+
* is displayed with template parameters `status`, `errorMessage`,
|
|
315
|
+
* `errorMessages` and `errorCodeName`.
|
|
316
|
+
* - `custom` {@link FastifyOAuthClientOptions.errorFn} is called.
|
|
317
|
+
*
|
|
318
|
+
* **Backend-for-Frontend (BFF)**
|
|
319
|
+
*
|
|
320
|
+
* This class supports the backend-for-frontend (BFF) model. You create an
|
|
321
|
+
* endpoint for every resource server endpoint you want to be able to call, by
|
|
322
|
+
* setting them in {@link FastifyOAuthClientOptions.bffEbdpoints}. You set the
|
|
323
|
+
* {@link FastifyOAuthClientOptions.tokenResponseType} to `saveInSessionAndLoad`
|
|
324
|
+
* or `saveInSessionAndRedirect` so that tokens are saved in the session.
|
|
325
|
+
* You also set `bffBaseUrl` to the base URL of the resource server.
|
|
326
|
+
* When you want to call a resource server endpoint, you call
|
|
327
|
+
* `siteUrl` + `prefix` + `bffEndpointName` + *`url`*. The client will
|
|
328
|
+
* pull the access token from the session, put it in the `Authorization` header
|
|
329
|
+
* and called `bffBaseUrl` + *`url`* using fetch, and return the
|
|
330
|
+
* response verbatim.
|
|
331
|
+
*
|
|
332
|
+
* This pattern avoids you having to store the access token in the frontend.
|
|
333
|
+
*
|
|
334
|
+
* **Endpoints provided by this class**
|
|
335
|
+
*
|
|
336
|
+
* In addition to the BFF endpoints above, this class provides the following
|
|
337
|
+
* endpoints. The ENDPOINT column values can be overridden in
|
|
338
|
+
* {@link FastifyOAuthClientOptions}.
|
|
339
|
+
* All POST endpoints also require `csrfToken`.
|
|
340
|
+
* The Flow endpoints are only enabled if the corresponding flow is set
|
|
341
|
+
* in {@link FastifyOAuthClientOptions.validFlows}.
|
|
342
|
+
* Token endpoints are only enabled if the corresponding endpoint is set
|
|
343
|
+
* in {@link FastifyOAuthClientOptions.tokenEndpoints}.
|
|
344
|
+
*
|
|
345
|
+
* | METHOD | ENDPOINT |Description | GET/BODY PARAMS | VARIABLES PASSED/RESPONSE | FILE |
|
|
346
|
+
* | ------ | --------------------| ------------------------------------------------------------ | --------------------------------------------------- | --------------------------------------------------------- | ------------------------ |
|
|
347
|
+
* | GET | `authzcode` | Redirect URI for receiving authz code | *See OAuth authorization code flow spec* | *See docs for`tokenResponseType`* | |
|
|
348
|
+
* | GET | `passwordflow` | Displays page to request username/password for password flow | scope | user, scope | passwordFlowPage |
|
|
349
|
+
* | POST | `passwordflow` | Initiates the password flow | *See OAuth password flow spec* | *See docs for`tokenResponseType`* | |
|
|
350
|
+
* | | | Requests an OTP from the user for the Password MFA OTP flow | `mfa_token`, `scope`, `otp` | `mfa_token`, `scope`, `error`, `errorMessage` | mfaOtpPage |
|
|
351
|
+
* | | | Requests an OOB from the user for the Password MFA OOB flow | `mfa_token`, `oob_code`, `scope`, `oob` | `mfa_token`, `oob_code`, `scope`, `error`, `errorMessage` | mfaOobPage |
|
|
352
|
+
* | POST | `passwordotp` | Token request with the MFA OTP | *See Password MFA flow spec* | *See docs for`tokenResponseType`* | |
|
|
353
|
+
* | POST | `passwordoob` | Token request with the MFA OOB | *See Password MFA flow spec* | *See docs for`tokenResponseType`* | |
|
|
354
|
+
* | POST | `authzcodeflow` | Initiates the authorization code flow | *See OAuth authorization code flow spec* | *See docs for`tokenResponseType`* | |
|
|
355
|
+
* | POST | `authzcodeflowpkce` | Initiates the authorization code flow with PKCE | *See OAuth authorization code flow with PKCE spec* | *See docs for`tokenResponseType`* | |
|
|
356
|
+
* | POST | `clientcredflow` | Initiates the client credentials flow | *See OAuth client credentials flow spec* | *See docs for`tokenResponseType`* | |
|
|
357
|
+
* | POST | `refreshtokenflow` | Initiates the refresh token flow | *See OAuth refresh token flow spec* | *See docs for`tokenResponseType`* | |
|
|
358
|
+
* | POST | `devicecodeflow` | Initiates the device code flow | See {@link DeviceCodeBodyType} | See {@link DeviceCodeFlowResponse} | `deviceCodeFlowPage` |
|
|
359
|
+
* | POST | `api/devicecodeflow` | Initiates the device code flow | See {@link DeviceCodeBodyType} | See {@link DeviceCodeFlowResponse} | |
|
|
360
|
+
* | POST | `devicecodepoll` | Initiates the device code flow | See {@link DeviceCodePollBodyType} | Authorization complete: See docs for`tokenResponseType`. Other cases, {@link @crossauth/common!OAuthTokenResponse} | |
|
|
361
|
+
* | POST | `api/devicecodepoll` | Initiates the device code flow | See {@link DeviceCodePollBodyType} | {@link @crossauth/common!OAuthTokenResponse} | |
|
|
362
|
+
* | POST | `access_token` | For BFF mode, returns the saved access token | | *Access token payload* | |
|
|
363
|
+
* | POST | `refresh_token` | For BFF mode, returns the saved refresh token | | `token` containing the refresh token | |
|
|
364
|
+
* | POST | `id_token ` | For BFF mode, returns the saved ID token | | *ID token payload* | |
|
|
365
|
+
* | POST | `have_access_token` | For BFF mode, returns whether an acccess token is saved | | `ok` | |
|
|
366
|
+
* | POST | `have_refresh_token`| For BFF mode, returns whether a refresh token is saved | | `ok` | |
|
|
367
|
+
* | POST | `have_id_token` | For BFF mode, returns whether an ID token is saved | | `ok` | |
|
|
368
|
+
* | POST | `deletetokens` | Deletes all BFF tokens and displays a page | None | `ok` | `deleteTokensPage` |
|
|
369
|
+
* | POST | `api/deletetokens` | Delertes all tokens and returns JSON | None | `ok` | |
|
|
370
|
+
*/
|
|
371
|
+
export declare class FastifyOAuthClient extends OAuthClientBackend {
|
|
372
|
+
server: FastifyServer;
|
|
373
|
+
private siteUrl;
|
|
374
|
+
private prefix;
|
|
375
|
+
errorPage: string;
|
|
376
|
+
passwordFlowPage: string;
|
|
377
|
+
deviceCodeFlowPage: string;
|
|
378
|
+
deleteTokensPage: string;
|
|
379
|
+
deleteTokensGetUrl: string | undefined;
|
|
380
|
+
deleteTokensPostUrl: string | undefined;
|
|
381
|
+
apiDeleteTokensPostUrl: string | undefined;
|
|
382
|
+
mfaOtpPage: string;
|
|
383
|
+
mfaOobPage: string;
|
|
384
|
+
authorizedPage: string;
|
|
385
|
+
authorizedUrl: string;
|
|
386
|
+
sessionDataName: string;
|
|
387
|
+
private receiveTokenFn;
|
|
388
|
+
private errorFn;
|
|
389
|
+
private loginUrl;
|
|
390
|
+
private validFlows;
|
|
391
|
+
/**
|
|
392
|
+
* See {@link FastifyOAuthClientOptions}
|
|
393
|
+
*/
|
|
394
|
+
loginProtectedFlows: string[];
|
|
395
|
+
private tokenResponseType;
|
|
396
|
+
private errorResponseType;
|
|
397
|
+
private passwordFlowUrl;
|
|
398
|
+
private passwordOtpUrl;
|
|
399
|
+
private passwordOobUrl;
|
|
400
|
+
private deviceCodeFlowUrl;
|
|
401
|
+
private deviceCodePollUrl;
|
|
402
|
+
private bffEndpoints;
|
|
403
|
+
private bffEndpointName;
|
|
404
|
+
private bffBaseUrl?;
|
|
405
|
+
private tokenEndpoints;
|
|
406
|
+
/**
|
|
407
|
+
* Constructor
|
|
408
|
+
* @param server the {@link FastifyServer} instance
|
|
409
|
+
* @param authServerBaseUrl the `iss` claim in the access token must match this value
|
|
410
|
+
* @param options See {@link FastifyOAuthClientOptions}
|
|
411
|
+
*/
|
|
412
|
+
constructor(server: FastifyServer, authServerBaseUrl: string, options: FastifyOAuthClientOptions);
|
|
413
|
+
private passwordPost;
|
|
414
|
+
private passwordMfa;
|
|
415
|
+
private passwordOtp;
|
|
416
|
+
private passwordOob;
|
|
417
|
+
private deviceCodePost;
|
|
418
|
+
private deviceCodePoll;
|
|
419
|
+
refresh(request: FastifyRequest, reply: FastifyReply, silent: boolean, onlyIfExpired: boolean, refreshToken?: string, expiresAt?: number): Promise<{
|
|
420
|
+
refresh_token?: string;
|
|
421
|
+
access_token?: string;
|
|
422
|
+
expires_in?: number;
|
|
423
|
+
expires_at?: number;
|
|
424
|
+
error?: string;
|
|
425
|
+
error_description?: string;
|
|
426
|
+
} | FastifyReply | undefined>;
|
|
427
|
+
private refreshTokens;
|
|
428
|
+
private deleteTokens;
|
|
429
|
+
}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { FastifyInstance } from 'fastify';
|
|
2
|
+
import { Server, IncomingMessage, ServerResponse } from 'http';
|
|
3
|
+
import { OAuthClientStorage, KeyStorage, OAuthAuthorizationServer, Authenticator, OAuthAuthorizationServerOptions, DoubleSubmitCsrfTokenOptions } from '@crossauth/backend';
|
|
4
|
+
import { OpenIdConfiguration } from '@crossauth/common';
|
|
5
|
+
import { FastifyServer } from './fastifyserver';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Options for {@link FastifyAuthorizationServer}
|
|
9
|
+
*/
|
|
10
|
+
export interface FastifyAuthorizationServerOptions extends OAuthAuthorizationServerOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Template file to display on error. It receives the following parameters;
|
|
13
|
+
* - `httpStatus`,
|
|
14
|
+
* - `errorCode`,
|
|
15
|
+
* - `errorCodeName`
|
|
16
|
+
* - `errorMessage`
|
|
17
|
+
* Default `error.njk`
|
|
18
|
+
*/
|
|
19
|
+
errorPage?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Template file for the device endpoint. It receives the following parameters;
|
|
22
|
+
* - `httpStatus`,
|
|
23
|
+
* - `errorCode`,
|
|
24
|
+
* - `errorCodeName`
|
|
25
|
+
* - `errorMessage`
|
|
26
|
+
* - `ok`
|
|
27
|
+
* - `authorizationNeeded`
|
|
28
|
+
* - `client_id`
|
|
29
|
+
* - `client_name`
|
|
30
|
+
* - `scope`
|
|
31
|
+
* - `scopes`
|
|
32
|
+
* - `user`
|
|
33
|
+
* - `user_code`
|
|
34
|
+
* - `retryAlllowed`
|
|
35
|
+
* - `csrfToken`
|
|
36
|
+
* Default `device.njk`
|
|
37
|
+
*/
|
|
38
|
+
devicePage?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Template file for page asking user to authorize a client.
|
|
41
|
+
* It receives the following parameters;
|
|
42
|
+
* - `user`
|
|
43
|
+
* - `response_type`
|
|
44
|
+
* - `client_id`
|
|
45
|
+
* - `client_name`
|
|
46
|
+
* - `redirect_uri`
|
|
47
|
+
* - `scope`
|
|
48
|
+
* - `scopes`
|
|
49
|
+
* - `state`
|
|
50
|
+
* - `code_challenge`
|
|
51
|
+
* - `code_challenge_method`
|
|
52
|
+
* - `csrfToken`
|
|
53
|
+
* Default `userauthorize.njk`
|
|
54
|
+
*/
|
|
55
|
+
oauthAuthorizePage?: string;
|
|
56
|
+
/**
|
|
57
|
+
* Prefix for URLs. Default `/`
|
|
58
|
+
*/
|
|
59
|
+
prefix?: string;
|
|
60
|
+
/**
|
|
61
|
+
* The login URL (provided by {@link FastifySessionServer}). Default `/login`
|
|
62
|
+
*/
|
|
63
|
+
loginUrl?: string;
|
|
64
|
+
/**
|
|
65
|
+
* How to send the refresh token.
|
|
66
|
+
* - `json` sent in the JSON response as per the OAuth specification
|
|
67
|
+
* - `cookie` sent as a cookie called `refreshTokenCookieName`.
|
|
68
|
+
* - `both` both of the above
|
|
69
|
+
* Default `json`
|
|
70
|
+
*/
|
|
71
|
+
refreshTokenType?: "json" | "cookie" | "both";
|
|
72
|
+
/**
|
|
73
|
+
* If `refreshTokenType` is `cookie` or `both`, this will be the cookie
|
|
74
|
+
* name. Default `CROSSAUTH_REFRESH_TOKEN`
|
|
75
|
+
*/
|
|
76
|
+
refreshTokenCookieName?: string;
|
|
77
|
+
/**
|
|
78
|
+
* Domain to set when sending a refresh token cookie.
|
|
79
|
+
* Only used if `refreshTokenType` is not `json`
|
|
80
|
+
*/
|
|
81
|
+
refreshTokenCookieDomain?: string | undefined;
|
|
82
|
+
/**
|
|
83
|
+
* Whether to set `httpOnly` when sending a refresh token cookie.
|
|
84
|
+
* Only used if `refreshTokenType` is not `json`
|
|
85
|
+
*/
|
|
86
|
+
refreshTokenCookieHttpOnly?: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Path to set when sending a refresh token cookie.
|
|
89
|
+
* Only used if `refreshTokenType` is not `json`
|
|
90
|
+
*/
|
|
91
|
+
refreshTokenCookiePath?: string;
|
|
92
|
+
/**
|
|
93
|
+
* Whether to set the `secure` flag when sending a refresh token cookie.
|
|
94
|
+
* Only used if `refreshTokenType` is not `json`
|
|
95
|
+
*/
|
|
96
|
+
refreshTokenCookieSecure?: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* SameSite value to set when sending a refresh token cookie.
|
|
99
|
+
* Only used if `refreshTokenType` is not `json`
|
|
100
|
+
*/
|
|
101
|
+
refreshTokenCookieSameSite?: boolean | "lax" | "strict" | "none" | undefined;
|
|
102
|
+
/** If true, create a `getcsrftoken` endpoint.
|
|
103
|
+
* You will only need to do this is you don't have session management
|
|
104
|
+
* enabled on your server, which provides an identical `api/getcsrftoken`,
|
|
105
|
+
* and if `refreshTokenType` is not `json`.
|
|
106
|
+
* Default `false`
|
|
107
|
+
*/
|
|
108
|
+
createGetCsrfTokenEndpoint?: false;
|
|
109
|
+
/** options for csrf cookie manager */
|
|
110
|
+
doubleSubmitCookieOptions?: DoubleSubmitCsrfTokenOptions;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Query parameters for the `authorize` Fastify request.
|
|
114
|
+
*/
|
|
115
|
+
export interface AuthorizeQueryType {
|
|
116
|
+
response_type: string;
|
|
117
|
+
client_id: string;
|
|
118
|
+
redirect_uri: string;
|
|
119
|
+
scope?: string;
|
|
120
|
+
state: string;
|
|
121
|
+
code_challenge?: string;
|
|
122
|
+
code_challenge_method: string;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Body parameters for the `userauthorize` endpoint
|
|
126
|
+
* Fastify request requesting the user
|
|
127
|
+
* to authorize a client.
|
|
128
|
+
*/
|
|
129
|
+
export interface UserAuthorizeBodyType {
|
|
130
|
+
csrfToken: string;
|
|
131
|
+
response_type: string;
|
|
132
|
+
client_id: string;
|
|
133
|
+
redirect_uri: string;
|
|
134
|
+
scope?: string;
|
|
135
|
+
state: string;
|
|
136
|
+
code_challenge?: string;
|
|
137
|
+
code_challenge_method: string;
|
|
138
|
+
authorized: string;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* The body parameters for the `mfa/challenge` endpoint.
|
|
142
|
+
*/
|
|
143
|
+
export interface MfaChallengeBodyType {
|
|
144
|
+
client_id: string;
|
|
145
|
+
client_secret?: string;
|
|
146
|
+
challenge_type: string;
|
|
147
|
+
mfa_token: string;
|
|
148
|
+
authenticator_id: string;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Query parameters for the `device` Fastify request.
|
|
152
|
+
*/
|
|
153
|
+
export interface DeviceQueryType {
|
|
154
|
+
user_code?: string;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* The body for the `device` Fastify request.
|
|
158
|
+
*/
|
|
159
|
+
export interface DeviceBodyType {
|
|
160
|
+
authorized: string;
|
|
161
|
+
user_code: string;
|
|
162
|
+
client_id: string;
|
|
163
|
+
scope?: string;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* The body for the `device_authorization` Fastify request.
|
|
167
|
+
*/
|
|
168
|
+
export interface DeviceAuthorizationBodyType {
|
|
169
|
+
client_id: string;
|
|
170
|
+
client_secret?: string;
|
|
171
|
+
scope?: string;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* This class implements an OAuth authorization server, serving endpoints
|
|
175
|
+
* with Fastify.
|
|
176
|
+
*
|
|
177
|
+
* You shouldn't have to instantiate this directly. It is instantiated
|
|
178
|
+
* by {@link FastifyServer} if you enable the authorization server there.
|
|
179
|
+
*
|
|
180
|
+
* | METHOD | ENDPOINT | GET/BODY PARAMS | RESPONSE/TEMPLATE FILE |
|
|
181
|
+
* | ------ | -------------------------- | --------------------------------------------------------------------------------- | -------------------------------------------------- |
|
|
182
|
+
* | GET | `authorize` | See OAuth spec | See OAuth spec |
|
|
183
|
+
* | GET | `userauthorize` | See {@link UserAuthorizeBodyType} | oauthAuthorizePage |
|
|
184
|
+
* | GET | `csrftoken` | | ok, csrfToken (and Set-Cookie) |
|
|
185
|
+
* | POST | `token` | See OAuth spec | See OAuth spec |
|
|
186
|
+
* | GET | `mfa/authenticators` | See {@link https://auth0.com/docs/api/authentication#multi-factor-authentication} | See link to the left |
|
|
187
|
+
* | POST | `mfa/authenticators` | See {@link https://auth0.com/docs/api/authentication#multi-factor-authentication} | See link to the left |
|
|
188
|
+
* | POST | `mfa/challenge` | See {@link https://auth0.com/docs/api/authentication#multi-factor-authentication} | See link to the left |
|
|
189
|
+
* | POST | `device_authorization` | See {@link https://datatracker.ietf.org/doc/html/rfc8628} | See link to the left |
|
|
190
|
+
* | GET | `device` | `user_code` (optional). | `devicePage` |
|
|
191
|
+
* | POST | `device` | See {@link DeviceBodyType}. | `devicePage` |
|
|
192
|
+
*
|
|
193
|
+
*/
|
|
194
|
+
export declare class FastifyAuthorizationServer {
|
|
195
|
+
/** The Fastify app passed to the constructor */
|
|
196
|
+
readonly app: FastifyInstance<Server, IncomingMessage, ServerResponse>;
|
|
197
|
+
/** The underlying framework-independent authorization server */
|
|
198
|
+
readonly authServer: OAuthAuthorizationServer;
|
|
199
|
+
private fastifyServer;
|
|
200
|
+
private prefix;
|
|
201
|
+
private loginUrl;
|
|
202
|
+
private oauthAuthorizePage;
|
|
203
|
+
private errorPage;
|
|
204
|
+
private devicePage;
|
|
205
|
+
private clientStorage;
|
|
206
|
+
private refreshTokenType;
|
|
207
|
+
private refreshTokenCookieName;
|
|
208
|
+
private refreshTokenCookieDomain;
|
|
209
|
+
private refreshTokenCookieHttpOnly;
|
|
210
|
+
private refreshTokenCookiePath;
|
|
211
|
+
private refreshTokenCookieSecure;
|
|
212
|
+
private refreshTokenCookieSameSite;
|
|
213
|
+
private csrfTokens;
|
|
214
|
+
private createGetCsrfTokenEndpoint;
|
|
215
|
+
/**
|
|
216
|
+
* Constructor
|
|
217
|
+
* @param app the Fastify app
|
|
218
|
+
* @param fastifyServer the Fastify server this belongs to
|
|
219
|
+
* @param clientStorage where OAuth clients are stored
|
|
220
|
+
* @param keyStorage where refresh tokens, authorization cods, etc are temporarily stored
|
|
221
|
+
* @param authenticators The authenticators (factor1 and factor2) to enable
|
|
222
|
+
* for the password flow
|
|
223
|
+
* @param options see {@link FastifyAuthorizationServerOptions}
|
|
224
|
+
*/
|
|
225
|
+
constructor(app: FastifyInstance<Server, IncomingMessage, ServerResponse>, fastifyServer: FastifyServer, clientStorage: OAuthClientStorage, keyStorage: KeyStorage, authenticators?: {
|
|
226
|
+
[key: string]: Authenticator;
|
|
227
|
+
}, options?: FastifyAuthorizationServerOptions);
|
|
228
|
+
/**
|
|
229
|
+
* Creates and returns a signed CSRF token based on the session ID
|
|
230
|
+
* @returns a CSRF cookie and value to put in the form or CSRF header
|
|
231
|
+
*/
|
|
232
|
+
private createCsrfToken;
|
|
233
|
+
private addApiGetCsrfTokenEndpoints;
|
|
234
|
+
private authorizeEndpoint;
|
|
235
|
+
private authorize;
|
|
236
|
+
private mfaAuthenticatorsEndpoint;
|
|
237
|
+
private mfaChallengeEndpoint;
|
|
238
|
+
private setRefreshTokenCookie;
|
|
239
|
+
/**
|
|
240
|
+
* Returns this server's OIDC configuration. Just wraps
|
|
241
|
+
* {@link @crossauth/backend!OAuthAuthorizationServer.oidcConfiguration}
|
|
242
|
+
* @returns An {@link @crossauth/common!OpenIdConfiguration} object
|
|
243
|
+
*/
|
|
244
|
+
oidcConfiguration(): OpenIdConfiguration;
|
|
245
|
+
private applyUserCode;
|
|
246
|
+
private deviceGet;
|
|
247
|
+
private deviceCodePost;
|
|
248
|
+
}
|