@backstage/plugin-auth-node 0.2.17 → 0.3.0-next.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/CHANGELOG.md +41 -0
- package/dist/index.cjs.js +890 -14
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +605 -24
- package/package.json +17 -5
package/dist/index.d.ts
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
|
+
import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
|
|
2
|
+
import { LoggerService } from '@backstage/backend-plugin-api';
|
|
3
|
+
import { EntityFilterQuery } from '@backstage/catalog-client';
|
|
4
|
+
import { Entity } from '@backstage/catalog-model';
|
|
5
|
+
import { Config } from '@backstage/config';
|
|
6
|
+
import { JsonValue, JsonObject } from '@backstage/types';
|
|
7
|
+
import express, { Request, Response } from 'express';
|
|
8
|
+
import { BackstageSignInResult as BackstageSignInResult$1, BackstageIdentityResponse as BackstageIdentityResponse$1 } from '@backstage/plugin-auth-node';
|
|
1
9
|
import { PluginEndpointDiscovery } from '@backstage/backend-common';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Parses the given authorization header and returns the bearer token, or
|
|
6
|
-
* undefined if no bearer token is given.
|
|
7
|
-
*
|
|
8
|
-
* @remarks
|
|
9
|
-
*
|
|
10
|
-
* This function is explicitly built to tolerate bad inputs safely, so you may
|
|
11
|
-
* call it directly with e.g. the output of `req.header('authorization')`
|
|
12
|
-
* without first checking that it exists.
|
|
13
|
-
*
|
|
14
|
-
* @public
|
|
15
|
-
*/
|
|
16
|
-
declare function getBearerTokenFromAuthorizationHeader(authorizationHeader: unknown): string | undefined;
|
|
10
|
+
import { Profile, Strategy } from 'passport';
|
|
11
|
+
import { ZodSchema, ZodTypeDef } from 'zod';
|
|
17
12
|
|
|
18
13
|
/**
|
|
19
14
|
* A representation of a successful Backstage sign-in.
|
|
@@ -29,14 +24,6 @@ interface BackstageSignInResult {
|
|
|
29
24
|
*/
|
|
30
25
|
token: string;
|
|
31
26
|
}
|
|
32
|
-
/**
|
|
33
|
-
* Options to request the identity from a Backstage backend request
|
|
34
|
-
*
|
|
35
|
-
* @public
|
|
36
|
-
*/
|
|
37
|
-
type IdentityApiGetIdentityRequest = {
|
|
38
|
-
request: Request<unknown>;
|
|
39
|
-
};
|
|
40
27
|
/**
|
|
41
28
|
* Response object containing the {@link BackstageUserIdentity} and the token
|
|
42
29
|
* from the authentication provider.
|
|
@@ -44,6 +31,10 @@ type IdentityApiGetIdentityRequest = {
|
|
|
44
31
|
* @public
|
|
45
32
|
*/
|
|
46
33
|
interface BackstageIdentityResponse extends BackstageSignInResult {
|
|
34
|
+
/**
|
|
35
|
+
* The number of seconds until the token expires. If not set, it can be assumed that the token does not expire.
|
|
36
|
+
*/
|
|
37
|
+
expiresInSeconds?: number;
|
|
47
38
|
/**
|
|
48
39
|
* A plaintext description of the identity that is encapsulated within the token.
|
|
49
40
|
*/
|
|
@@ -70,7 +61,331 @@ type BackstageUserIdentity = {
|
|
|
70
61
|
*/
|
|
71
62
|
ownershipEntityRefs: string[];
|
|
72
63
|
};
|
|
64
|
+
/**
|
|
65
|
+
* A query for a single user in the catalog.
|
|
66
|
+
*
|
|
67
|
+
* If `entityRef` is used, the default kind is `'User'`.
|
|
68
|
+
*
|
|
69
|
+
* If `annotations` are used, all annotations must be present and
|
|
70
|
+
* match the provided value exactly. Only entities of kind `'User'` will be considered.
|
|
71
|
+
*
|
|
72
|
+
* If `filter` are used they are passed on as they are to the `CatalogApi`.
|
|
73
|
+
*
|
|
74
|
+
* Regardless of the query method, the query must match exactly one entity
|
|
75
|
+
* in the catalog, or an error will be thrown.
|
|
76
|
+
*
|
|
77
|
+
* @public
|
|
78
|
+
*/
|
|
79
|
+
type AuthResolverCatalogUserQuery = {
|
|
80
|
+
entityRef: string | {
|
|
81
|
+
kind?: string;
|
|
82
|
+
namespace?: string;
|
|
83
|
+
name: string;
|
|
84
|
+
};
|
|
85
|
+
} | {
|
|
86
|
+
annotations: Record<string, string>;
|
|
87
|
+
} | {
|
|
88
|
+
filter: EntityFilterQuery;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Parameters used to issue new Backstage Tokens
|
|
92
|
+
*
|
|
93
|
+
* @public
|
|
94
|
+
*/
|
|
95
|
+
type TokenParams = {
|
|
96
|
+
/**
|
|
97
|
+
* The claims that will be embedded within the token. At a minimum, this should include
|
|
98
|
+
* the subject claim, `sub`. It is common to also list entity ownership relations in the
|
|
99
|
+
* `ent` list. Additional claims may also be added at the developer's discretion except
|
|
100
|
+
* for the following list, which will be overwritten by the TokenIssuer: `iss`, `aud`,
|
|
101
|
+
* `iat`, and `exp`. The Backstage team also maintains the right add new claims in the future
|
|
102
|
+
* without listing the change as a "breaking change".
|
|
103
|
+
*/
|
|
104
|
+
claims: {
|
|
105
|
+
/** The token subject, i.e. User ID */
|
|
106
|
+
sub: string;
|
|
107
|
+
/** A list of entity references that the user claims ownership through */
|
|
108
|
+
ent?: string[];
|
|
109
|
+
} & Record<string, JsonValue>;
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* The context that is used for auth processing.
|
|
113
|
+
*
|
|
114
|
+
* @public
|
|
115
|
+
*/
|
|
116
|
+
type AuthResolverContext = {
|
|
117
|
+
/**
|
|
118
|
+
* Issues a Backstage token using the provided parameters.
|
|
119
|
+
*/
|
|
120
|
+
issueToken(params: TokenParams): Promise<{
|
|
121
|
+
token: string;
|
|
122
|
+
}>;
|
|
123
|
+
/**
|
|
124
|
+
* Finds a single user in the catalog using the provided query.
|
|
125
|
+
*
|
|
126
|
+
* See {@link AuthResolverCatalogUserQuery} for details.
|
|
127
|
+
*/
|
|
128
|
+
findCatalogUser(query: AuthResolverCatalogUserQuery): Promise<{
|
|
129
|
+
entity: Entity;
|
|
130
|
+
}>;
|
|
131
|
+
/**
|
|
132
|
+
* Finds a single user in the catalog using the provided query, and then
|
|
133
|
+
* issues an identity for that user using default ownership resolution.
|
|
134
|
+
*
|
|
135
|
+
* See {@link AuthResolverCatalogUserQuery} for details.
|
|
136
|
+
*/
|
|
137
|
+
signInWithCatalogUser(query: AuthResolverCatalogUserQuery): Promise<BackstageSignInResult>;
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Any Auth provider needs to implement this interface which handles the routes in the
|
|
141
|
+
* auth backend. Any auth API requests from the frontend reaches these methods.
|
|
142
|
+
*
|
|
143
|
+
* The routes in the auth backend API are tied to these methods like below
|
|
144
|
+
*
|
|
145
|
+
* `/auth/[provider]/start -> start`
|
|
146
|
+
* `/auth/[provider]/handler/frame -> frameHandler`
|
|
147
|
+
* `/auth/[provider]/refresh -> refresh`
|
|
148
|
+
* `/auth/[provider]/logout -> logout`
|
|
149
|
+
*
|
|
150
|
+
* @public
|
|
151
|
+
*/
|
|
152
|
+
interface AuthProviderRouteHandlers {
|
|
153
|
+
/**
|
|
154
|
+
* Handles the start route of the API. This initiates a sign in request with an auth provider.
|
|
155
|
+
*
|
|
156
|
+
* Request
|
|
157
|
+
* - scopes for the auth request (Optional)
|
|
158
|
+
* Response
|
|
159
|
+
* - redirect to the auth provider for the user to sign in or consent.
|
|
160
|
+
* - sets a nonce cookie and also pass the nonce as 'state' query parameter in the redirect request
|
|
161
|
+
*/
|
|
162
|
+
start(req: Request, res: Response): Promise<void>;
|
|
163
|
+
/**
|
|
164
|
+
* Once the user signs in or consents in the OAuth screen, the auth provider redirects to the
|
|
165
|
+
* callbackURL which is handled by this method.
|
|
166
|
+
*
|
|
167
|
+
* Request
|
|
168
|
+
* - to contain a nonce cookie and a 'state' query parameter
|
|
169
|
+
* Response
|
|
170
|
+
* - postMessage to the window with a payload that contains accessToken, expiryInSeconds?, idToken? and scope.
|
|
171
|
+
* - sets a refresh token cookie if the auth provider supports refresh tokens
|
|
172
|
+
*/
|
|
173
|
+
frameHandler(req: Request, res: Response): Promise<void>;
|
|
174
|
+
/**
|
|
175
|
+
* (Optional) If the auth provider supports refresh tokens then this method handles
|
|
176
|
+
* requests to get a new access token.
|
|
177
|
+
*
|
|
178
|
+
* Other types of providers may also use this method to implement its own logic to create new sessions
|
|
179
|
+
* upon request. For example, this can be used to create a new session for a provider that handles requests
|
|
180
|
+
* from an authenticating proxy.
|
|
181
|
+
*
|
|
182
|
+
* Request
|
|
183
|
+
* - to contain a refresh token cookie and scope (Optional) query parameter.
|
|
184
|
+
* Response
|
|
185
|
+
* - payload with accessToken, expiryInSeconds?, idToken?, scope and user profile information.
|
|
186
|
+
*/
|
|
187
|
+
refresh?(req: Request, res: Response): Promise<void>;
|
|
188
|
+
/**
|
|
189
|
+
* (Optional) Handles sign out requests
|
|
190
|
+
*
|
|
191
|
+
* Response
|
|
192
|
+
* - removes the refresh token cookie
|
|
193
|
+
*/
|
|
194
|
+
logout?(req: Request, res: Response): Promise<void>;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* @public
|
|
198
|
+
* @deprecated Use top-level properties passed to `AuthProviderFactory` instead
|
|
199
|
+
*/
|
|
200
|
+
type AuthProviderConfig = {
|
|
201
|
+
/**
|
|
202
|
+
* The protocol://domain[:port] where the app is hosted. This is used to construct the
|
|
203
|
+
* callbackURL to redirect to once the user signs in to the auth provider.
|
|
204
|
+
*/
|
|
205
|
+
baseUrl: string;
|
|
206
|
+
/**
|
|
207
|
+
* The base URL of the app as provided by app.baseUrl
|
|
208
|
+
*/
|
|
209
|
+
appUrl: string;
|
|
210
|
+
/**
|
|
211
|
+
* A function that is called to check whether an origin is allowed to receive the authentication result.
|
|
212
|
+
*/
|
|
213
|
+
isOriginAllowed: (origin: string) => boolean;
|
|
214
|
+
/**
|
|
215
|
+
* The function used to resolve cookie configuration based on the auth provider options.
|
|
216
|
+
*/
|
|
217
|
+
cookieConfigurer?: CookieConfigurer;
|
|
218
|
+
};
|
|
219
|
+
/** @public */
|
|
220
|
+
type AuthProviderFactory = (options: {
|
|
221
|
+
providerId: string;
|
|
222
|
+
/** @deprecated Use top-level properties instead */
|
|
223
|
+
globalConfig: AuthProviderConfig;
|
|
224
|
+
config: Config;
|
|
225
|
+
logger: LoggerService;
|
|
226
|
+
resolverContext: AuthResolverContext;
|
|
227
|
+
/**
|
|
228
|
+
* The protocol://domain[:port] where the app is hosted. This is used to construct the
|
|
229
|
+
* callbackURL to redirect to once the user signs in to the auth provider.
|
|
230
|
+
*/
|
|
231
|
+
baseUrl: string;
|
|
232
|
+
/**
|
|
233
|
+
* The base URL of the app as provided by app.baseUrl
|
|
234
|
+
*/
|
|
235
|
+
appUrl: string;
|
|
236
|
+
/**
|
|
237
|
+
* A function that is called to check whether an origin is allowed to receive the authentication result.
|
|
238
|
+
*/
|
|
239
|
+
isOriginAllowed: (origin: string) => boolean;
|
|
240
|
+
/**
|
|
241
|
+
* The function used to resolve cookie configuration based on the auth provider options.
|
|
242
|
+
*/
|
|
243
|
+
cookieConfigurer?: CookieConfigurer;
|
|
244
|
+
}) => AuthProviderRouteHandlers;
|
|
245
|
+
/** @public */
|
|
246
|
+
type ClientAuthResponse<TProviderInfo> = {
|
|
247
|
+
providerInfo: TProviderInfo;
|
|
248
|
+
profile: ProfileInfo;
|
|
249
|
+
backstageIdentity?: BackstageIdentityResponse;
|
|
250
|
+
};
|
|
251
|
+
/**
|
|
252
|
+
* Type of sign in information context. Includes the profile information and
|
|
253
|
+
* authentication result which contains auth related information.
|
|
254
|
+
*
|
|
255
|
+
* @public
|
|
256
|
+
*/
|
|
257
|
+
type SignInInfo<TAuthResult> = {
|
|
258
|
+
/**
|
|
259
|
+
* The simple profile passed down for use in the frontend.
|
|
260
|
+
*/
|
|
261
|
+
profile: ProfileInfo;
|
|
262
|
+
/**
|
|
263
|
+
* The authentication result that was received from the authentication
|
|
264
|
+
* provider.
|
|
265
|
+
*/
|
|
266
|
+
result: TAuthResult;
|
|
267
|
+
};
|
|
268
|
+
/**
|
|
269
|
+
* Describes the function which handles the result of a successful
|
|
270
|
+
* authentication. Must return a valid {@link @backstage/plugin-auth-node#BackstageSignInResult}.
|
|
271
|
+
*
|
|
272
|
+
* @public
|
|
273
|
+
*/
|
|
274
|
+
type SignInResolver<TAuthResult> = (info: SignInInfo<TAuthResult>, context: AuthResolverContext) => Promise<BackstageSignInResult>;
|
|
275
|
+
/**
|
|
276
|
+
* Describes the function that transforms the result of a successful
|
|
277
|
+
* authentication into a {@link ProfileInfo} object.
|
|
278
|
+
*
|
|
279
|
+
* This function may optionally throw an error in order to reject authentication.
|
|
280
|
+
*
|
|
281
|
+
* @public
|
|
282
|
+
*/
|
|
283
|
+
type ProfileTransform<TResult> = (result: TResult, context: AuthResolverContext) => Promise<{
|
|
284
|
+
profile: ProfileInfo;
|
|
285
|
+
}>;
|
|
286
|
+
/**
|
|
287
|
+
* Used to display login information to user, i.e. sidebar popup.
|
|
288
|
+
*
|
|
289
|
+
* It is also temporarily used as the profile of the signed-in user's Backstage
|
|
290
|
+
* identity, but we want to replace that with data from identity and/org catalog
|
|
291
|
+
* service
|
|
292
|
+
*
|
|
293
|
+
* @public
|
|
294
|
+
*/
|
|
295
|
+
type ProfileInfo = {
|
|
296
|
+
/**
|
|
297
|
+
* Email ID of the signed in user.
|
|
298
|
+
*/
|
|
299
|
+
email?: string;
|
|
300
|
+
/**
|
|
301
|
+
* Display name that can be presented to the signed in user.
|
|
302
|
+
*/
|
|
303
|
+
displayName?: string;
|
|
304
|
+
/**
|
|
305
|
+
* URL to an image that can be used as the display image or avatar of the
|
|
306
|
+
* signed in user.
|
|
307
|
+
*/
|
|
308
|
+
picture?: string;
|
|
309
|
+
};
|
|
310
|
+
/**
|
|
311
|
+
* The callback used to resolve the cookie configuration for auth providers that use cookies.
|
|
312
|
+
* @public
|
|
313
|
+
*/
|
|
314
|
+
type CookieConfigurer = (ctx: {
|
|
315
|
+
/** ID of the auth provider that this configuration applies to */
|
|
316
|
+
providerId: string;
|
|
317
|
+
/** The externally reachable base URL of the auth-backend plugin */
|
|
318
|
+
baseUrl: string;
|
|
319
|
+
/** The configured callback URL of the auth provider */
|
|
320
|
+
callbackUrl: string;
|
|
321
|
+
/** The origin URL of the app */
|
|
322
|
+
appOrigin: string;
|
|
323
|
+
}) => {
|
|
324
|
+
domain: string;
|
|
325
|
+
path: string;
|
|
326
|
+
secure: boolean;
|
|
327
|
+
sameSite?: 'none' | 'lax' | 'strict';
|
|
328
|
+
};
|
|
329
|
+
|
|
330
|
+
/** @public */
|
|
331
|
+
interface AuthProviderRegistrationOptions {
|
|
332
|
+
providerId: string;
|
|
333
|
+
factory: AuthProviderFactory;
|
|
334
|
+
}
|
|
335
|
+
/** @public */
|
|
336
|
+
interface AuthProvidersExtensionPoint {
|
|
337
|
+
registerProvider(options: AuthProviderRegistrationOptions): void;
|
|
338
|
+
}
|
|
339
|
+
/** @public */
|
|
340
|
+
declare const authProvidersExtensionPoint: _backstage_backend_plugin_api.ExtensionPoint<AuthProvidersExtensionPoint>;
|
|
73
341
|
|
|
342
|
+
/**
|
|
343
|
+
* Payload sent as a post message after the auth request is complete.
|
|
344
|
+
* If successful then has a valid payload with Auth information else contains an error.
|
|
345
|
+
*
|
|
346
|
+
* @public
|
|
347
|
+
*/
|
|
348
|
+
type WebMessageResponse = {
|
|
349
|
+
type: 'authorization_response';
|
|
350
|
+
response: ClientAuthResponse<unknown>;
|
|
351
|
+
} | {
|
|
352
|
+
type: 'authorization_response';
|
|
353
|
+
error: Error;
|
|
354
|
+
};
|
|
355
|
+
/** @public */
|
|
356
|
+
declare function sendWebMessageResponse(res: Response, appOrigin: string, response: WebMessageResponse): void;
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Parses a Backstage-issued token and decorates the
|
|
360
|
+
* {@link @backstage/plugin-auth-node#BackstageIdentityResponse} with identity information sourced from the
|
|
361
|
+
* token.
|
|
362
|
+
*
|
|
363
|
+
* @public
|
|
364
|
+
*/
|
|
365
|
+
declare function prepareBackstageIdentityResponse(result: BackstageSignInResult$1): BackstageIdentityResponse$1;
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Parses the given authorization header and returns the bearer token, or
|
|
369
|
+
* undefined if no bearer token is given.
|
|
370
|
+
*
|
|
371
|
+
* @remarks
|
|
372
|
+
*
|
|
373
|
+
* This function is explicitly built to tolerate bad inputs safely, so you may
|
|
374
|
+
* call it directly with e.g. the output of `req.header('authorization')`
|
|
375
|
+
* without first checking that it exists.
|
|
376
|
+
*
|
|
377
|
+
* @public
|
|
378
|
+
*/
|
|
379
|
+
declare function getBearerTokenFromAuthorizationHeader(authorizationHeader: unknown): string | undefined;
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* Options to request the identity from a Backstage backend request
|
|
383
|
+
*
|
|
384
|
+
* @public
|
|
385
|
+
*/
|
|
386
|
+
type IdentityApiGetIdentityRequest = {
|
|
387
|
+
request: Request<unknown>;
|
|
388
|
+
};
|
|
74
389
|
/**
|
|
75
390
|
* An identity client api to authenticate Backstage
|
|
76
391
|
* tokens
|
|
@@ -157,4 +472,270 @@ declare class IdentityClient {
|
|
|
157
472
|
authenticate(token: string | undefined): Promise<BackstageIdentityResponse>;
|
|
158
473
|
}
|
|
159
474
|
|
|
160
|
-
|
|
475
|
+
/**
|
|
476
|
+
* A type for the serialized value in the `state` parameter of the OAuth authorization flow
|
|
477
|
+
* @public
|
|
478
|
+
*/
|
|
479
|
+
type OAuthState = {
|
|
480
|
+
nonce: string;
|
|
481
|
+
env: string;
|
|
482
|
+
origin?: string;
|
|
483
|
+
scope?: string;
|
|
484
|
+
redirectUrl?: string;
|
|
485
|
+
flow?: string;
|
|
486
|
+
};
|
|
487
|
+
/** @public */
|
|
488
|
+
type OAuthStateTransform = (state: OAuthState, context: {
|
|
489
|
+
req: Request;
|
|
490
|
+
}) => Promise<{
|
|
491
|
+
state: OAuthState;
|
|
492
|
+
}>;
|
|
493
|
+
/** @public */
|
|
494
|
+
declare function encodeOAuthState(state: OAuthState): string;
|
|
495
|
+
/** @public */
|
|
496
|
+
declare function decodeOAuthState(encodedState: string): OAuthState;
|
|
497
|
+
|
|
498
|
+
/** @public */
|
|
499
|
+
interface OAuthSession {
|
|
500
|
+
accessToken: string;
|
|
501
|
+
tokenType: string;
|
|
502
|
+
idToken?: string;
|
|
503
|
+
scope: string;
|
|
504
|
+
expiresInSeconds?: number;
|
|
505
|
+
refreshToken?: string;
|
|
506
|
+
refreshTokenExpiresInSeconds?: number;
|
|
507
|
+
}
|
|
508
|
+
/** @public */
|
|
509
|
+
interface OAuthAuthenticatorStartInput {
|
|
510
|
+
scope: string;
|
|
511
|
+
state: string;
|
|
512
|
+
req: Request;
|
|
513
|
+
}
|
|
514
|
+
/** @public */
|
|
515
|
+
interface OAuthAuthenticatorAuthenticateInput {
|
|
516
|
+
req: Request;
|
|
517
|
+
}
|
|
518
|
+
/** @public */
|
|
519
|
+
interface OAuthAuthenticatorRefreshInput {
|
|
520
|
+
scope: string;
|
|
521
|
+
refreshToken: string;
|
|
522
|
+
req: Request;
|
|
523
|
+
}
|
|
524
|
+
/** @public */
|
|
525
|
+
interface OAuthAuthenticatorLogoutInput {
|
|
526
|
+
accessToken?: string;
|
|
527
|
+
refreshToken?: string;
|
|
528
|
+
req: Request;
|
|
529
|
+
}
|
|
530
|
+
/** @public */
|
|
531
|
+
interface OAuthAuthenticatorResult<TProfile> {
|
|
532
|
+
fullProfile: TProfile;
|
|
533
|
+
session: OAuthSession;
|
|
534
|
+
}
|
|
535
|
+
/** @public */
|
|
536
|
+
interface OAuthAuthenticator<TContext, TProfile> {
|
|
537
|
+
defaultProfileTransform: ProfileTransform<OAuthAuthenticatorResult<TProfile>>;
|
|
538
|
+
shouldPersistScopes?: boolean;
|
|
539
|
+
initialize(ctx: {
|
|
540
|
+
callbackUrl: string;
|
|
541
|
+
config: Config;
|
|
542
|
+
}): TContext;
|
|
543
|
+
start(input: OAuthAuthenticatorStartInput, ctx: TContext): Promise<{
|
|
544
|
+
url: string;
|
|
545
|
+
status?: number;
|
|
546
|
+
}>;
|
|
547
|
+
authenticate(input: OAuthAuthenticatorAuthenticateInput, ctx: TContext): Promise<OAuthAuthenticatorResult<TProfile>>;
|
|
548
|
+
refresh(input: OAuthAuthenticatorRefreshInput, ctx: TContext): Promise<OAuthAuthenticatorResult<TProfile>>;
|
|
549
|
+
logout?(input: OAuthAuthenticatorLogoutInput, ctx: TContext): Promise<void>;
|
|
550
|
+
}
|
|
551
|
+
/** @public */
|
|
552
|
+
declare function createOAuthAuthenticator<TContext, TProfile>(authenticator: OAuthAuthenticator<TContext, TProfile>): OAuthAuthenticator<TContext, TProfile>;
|
|
553
|
+
|
|
554
|
+
/** @public */
|
|
555
|
+
interface OAuthRouteHandlersOptions<TProfile> {
|
|
556
|
+
authenticator: OAuthAuthenticator<any, TProfile>;
|
|
557
|
+
appUrl: string;
|
|
558
|
+
baseUrl: string;
|
|
559
|
+
isOriginAllowed: (origin: string) => boolean;
|
|
560
|
+
providerId: string;
|
|
561
|
+
config: Config;
|
|
562
|
+
resolverContext: AuthResolverContext;
|
|
563
|
+
stateTransform?: OAuthStateTransform;
|
|
564
|
+
profileTransform?: ProfileTransform<OAuthAuthenticatorResult<TProfile>>;
|
|
565
|
+
cookieConfigurer?: CookieConfigurer;
|
|
566
|
+
signInResolver?: SignInResolver<OAuthAuthenticatorResult<TProfile>>;
|
|
567
|
+
}
|
|
568
|
+
/** @public */
|
|
569
|
+
declare function createOAuthRouteHandlers<TProfile>(options: OAuthRouteHandlersOptions<TProfile>): AuthProviderRouteHandlers;
|
|
570
|
+
|
|
571
|
+
/** @public */
|
|
572
|
+
type PassportProfile = Profile & {
|
|
573
|
+
avatarUrl?: string;
|
|
574
|
+
};
|
|
575
|
+
/** @public */
|
|
576
|
+
type PassportDoneCallback<TResult, TPrivateInfo = never> = (err?: Error, result?: TResult, privateInfo?: TPrivateInfo) => void;
|
|
577
|
+
|
|
578
|
+
/** @public */
|
|
579
|
+
declare class PassportHelpers {
|
|
580
|
+
private constructor();
|
|
581
|
+
static transformProfile: (profile: PassportProfile, idToken?: string) => ProfileInfo;
|
|
582
|
+
static executeRedirectStrategy(req: Request, providerStrategy: Strategy, options: Record<string, string>): Promise<{
|
|
583
|
+
/**
|
|
584
|
+
* URL to redirect to
|
|
585
|
+
*/
|
|
586
|
+
url: string;
|
|
587
|
+
/**
|
|
588
|
+
* Status code to use for the redirect
|
|
589
|
+
*/
|
|
590
|
+
status?: number;
|
|
591
|
+
}>;
|
|
592
|
+
static executeFrameHandlerStrategy<TResult, TPrivateInfo = never>(req: Request, providerStrategy: Strategy, options?: Record<string, string>): Promise<{
|
|
593
|
+
result: TResult;
|
|
594
|
+
privateInfo: TPrivateInfo;
|
|
595
|
+
}>;
|
|
596
|
+
static executeRefreshTokenStrategy(providerStrategy: Strategy, refreshToken: string, scope: string): Promise<{
|
|
597
|
+
/**
|
|
598
|
+
* An access token issued for the signed in user.
|
|
599
|
+
*/
|
|
600
|
+
accessToken: string;
|
|
601
|
+
/**
|
|
602
|
+
* Optionally, the server can issue a new Refresh Token for the user
|
|
603
|
+
*/
|
|
604
|
+
refreshToken?: string;
|
|
605
|
+
params: any;
|
|
606
|
+
}>;
|
|
607
|
+
static executeFetchUserProfileStrategy(providerStrategy: Strategy, accessToken: string): Promise<PassportProfile>;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/** @public */
|
|
611
|
+
type PassportOAuthResult = {
|
|
612
|
+
fullProfile: PassportProfile;
|
|
613
|
+
params: {
|
|
614
|
+
id_token?: string;
|
|
615
|
+
scope: string;
|
|
616
|
+
token_type?: string;
|
|
617
|
+
expires_in: number;
|
|
618
|
+
};
|
|
619
|
+
accessToken: string;
|
|
620
|
+
};
|
|
621
|
+
/** @public */
|
|
622
|
+
type PassportOAuthPrivateInfo = {
|
|
623
|
+
refreshToken?: string;
|
|
624
|
+
};
|
|
625
|
+
/** @public */
|
|
626
|
+
type PassportOAuthDoneCallback = PassportDoneCallback<PassportOAuthResult, PassportOAuthPrivateInfo>;
|
|
627
|
+
/** @public */
|
|
628
|
+
declare class PassportOAuthAuthenticatorHelper {
|
|
629
|
+
#private;
|
|
630
|
+
static defaultProfileTransform: ProfileTransform<OAuthAuthenticatorResult<PassportProfile>>;
|
|
631
|
+
static from(strategy: Strategy): PassportOAuthAuthenticatorHelper;
|
|
632
|
+
private constructor();
|
|
633
|
+
start(input: OAuthAuthenticatorStartInput, options: Record<string, string>): Promise<{
|
|
634
|
+
url: string;
|
|
635
|
+
status?: number;
|
|
636
|
+
}>;
|
|
637
|
+
authenticate(input: OAuthAuthenticatorAuthenticateInput): Promise<OAuthAuthenticatorResult<PassportProfile>>;
|
|
638
|
+
refresh(input: OAuthAuthenticatorRefreshInput): Promise<OAuthAuthenticatorResult<PassportProfile>>;
|
|
639
|
+
fetchProfile(accessToken: string): Promise<PassportProfile>;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/** @public */
|
|
643
|
+
declare class OAuthEnvironmentHandler implements AuthProviderRouteHandlers {
|
|
644
|
+
private readonly handlers;
|
|
645
|
+
static mapConfig(config: Config, factoryFunc: (envConfig: Config) => AuthProviderRouteHandlers): OAuthEnvironmentHandler;
|
|
646
|
+
constructor(handlers: Map<string, AuthProviderRouteHandlers>);
|
|
647
|
+
start(req: express.Request, res: express.Response): Promise<void>;
|
|
648
|
+
frameHandler(req: express.Request, res: express.Response): Promise<void>;
|
|
649
|
+
refresh(req: express.Request, res: express.Response): Promise<void>;
|
|
650
|
+
logout(req: express.Request, res: express.Response): Promise<void>;
|
|
651
|
+
private getEnvFromRequest;
|
|
652
|
+
private getProviderForEnv;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/** @public */
|
|
656
|
+
interface SignInResolverFactory<TAuthResult, TOptions> {
|
|
657
|
+
(...options: undefined extends TOptions ? [options?: TOptions] : [options: TOptions]): SignInResolver<TAuthResult>;
|
|
658
|
+
optionsJsonSchema?: JsonObject;
|
|
659
|
+
}
|
|
660
|
+
/** @public */
|
|
661
|
+
interface SignInResolverFactoryOptions<TAuthResult, TOptionsOutput, TOptionsInput> {
|
|
662
|
+
optionsSchema?: ZodSchema<TOptionsOutput, ZodTypeDef, TOptionsInput>;
|
|
663
|
+
create(options: TOptionsOutput): SignInResolver<TAuthResult>;
|
|
664
|
+
}
|
|
665
|
+
/** @public */
|
|
666
|
+
declare function createSignInResolverFactory<TAuthResult, TOptionsOutput, TOptionsInput>(options: SignInResolverFactoryOptions<TAuthResult, TOptionsOutput, TOptionsInput>): SignInResolverFactory<TAuthResult, TOptionsInput>;
|
|
667
|
+
|
|
668
|
+
/** @public */
|
|
669
|
+
declare function createOAuthProviderFactory<TProfile>(options: {
|
|
670
|
+
authenticator: OAuthAuthenticator<unknown, TProfile>;
|
|
671
|
+
stateTransform?: OAuthStateTransform;
|
|
672
|
+
profileTransform?: ProfileTransform<OAuthAuthenticatorResult<TProfile>>;
|
|
673
|
+
signInResolver?: SignInResolver<OAuthAuthenticatorResult<TProfile>>;
|
|
674
|
+
signInResolverFactories?: {
|
|
675
|
+
[name in string]: SignInResolverFactory<OAuthAuthenticatorResult<TProfile>, unknown>;
|
|
676
|
+
};
|
|
677
|
+
}): AuthProviderFactory;
|
|
678
|
+
|
|
679
|
+
/** @public */
|
|
680
|
+
interface ProxyAuthenticator<TContext, TResult> {
|
|
681
|
+
defaultProfileTransform: ProfileTransform<TResult>;
|
|
682
|
+
initialize(ctx: {
|
|
683
|
+
config: Config;
|
|
684
|
+
}): Promise<TContext>;
|
|
685
|
+
authenticate(options: {
|
|
686
|
+
req: Request;
|
|
687
|
+
}, ctx: TContext): Promise<{
|
|
688
|
+
result: TResult;
|
|
689
|
+
}>;
|
|
690
|
+
}
|
|
691
|
+
/** @public */
|
|
692
|
+
declare function createProxyAuthenticator<TContext, TResult>(authenticator: ProxyAuthenticator<TContext, TResult>): ProxyAuthenticator<TContext, TResult>;
|
|
693
|
+
|
|
694
|
+
/** @public */
|
|
695
|
+
interface ReadDeclarativeSignInResolverOptions<TAuthResult> {
|
|
696
|
+
config: Config;
|
|
697
|
+
signInResolverFactories: {
|
|
698
|
+
[name in string]: SignInResolverFactory<TAuthResult, unknown>;
|
|
699
|
+
};
|
|
700
|
+
}
|
|
701
|
+
/** @public */
|
|
702
|
+
declare function readDeclarativeSignInResolver<TAuthResult>(options: ReadDeclarativeSignInResolverOptions<TAuthResult>): SignInResolver<TAuthResult> | undefined;
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* A collection of common sign-in resolvers that work with any auth provider.
|
|
706
|
+
*
|
|
707
|
+
* @public
|
|
708
|
+
*/
|
|
709
|
+
declare namespace commonSignInResolvers {
|
|
710
|
+
/**
|
|
711
|
+
* A common sign-in resolver that looks up the user using their email address
|
|
712
|
+
* as email of the entity.
|
|
713
|
+
*/
|
|
714
|
+
const emailMatchingUserEntityProfileEmail: SignInResolverFactory<unknown, unknown>;
|
|
715
|
+
/**
|
|
716
|
+
* A common sign-in resolver that looks up the user using the local part of
|
|
717
|
+
* their email address as the entity name.
|
|
718
|
+
*/
|
|
719
|
+
const emailLocalPartMatchingUserEntityName: SignInResolverFactory<unknown, unknown>;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
/** @public */
|
|
723
|
+
declare function createProxyAuthProviderFactory<TResult>(options: {
|
|
724
|
+
authenticator: ProxyAuthenticator<unknown, TResult>;
|
|
725
|
+
profileTransform?: ProfileTransform<TResult>;
|
|
726
|
+
signInResolver?: SignInResolver<TResult>;
|
|
727
|
+
signInResolverFactories?: Record<string, SignInResolverFactory<TResult, unknown>>;
|
|
728
|
+
}): AuthProviderFactory;
|
|
729
|
+
|
|
730
|
+
/** @public */
|
|
731
|
+
interface ProxyAuthRouteHandlersOptions<TResult> {
|
|
732
|
+
authenticator: ProxyAuthenticator<any, TResult>;
|
|
733
|
+
config: Config;
|
|
734
|
+
resolverContext: AuthResolverContext;
|
|
735
|
+
signInResolver: SignInResolver<TResult>;
|
|
736
|
+
profileTransform?: ProfileTransform<TResult>;
|
|
737
|
+
}
|
|
738
|
+
/** @public */
|
|
739
|
+
declare function createProxyAuthRouteHandlers<TResult>(options: ProxyAuthRouteHandlersOptions<TResult>): AuthProviderRouteHandlers;
|
|
740
|
+
|
|
741
|
+
export { AuthProviderConfig, AuthProviderFactory, AuthProviderRegistrationOptions, AuthProviderRouteHandlers, AuthProvidersExtensionPoint, AuthResolverCatalogUserQuery, AuthResolverContext, BackstageIdentityResponse, BackstageSignInResult, BackstageUserIdentity, ClientAuthResponse, CookieConfigurer, DefaultIdentityClient, IdentityApi, IdentityApiGetIdentityRequest, IdentityClient, IdentityClientOptions, OAuthAuthenticator, OAuthAuthenticatorAuthenticateInput, OAuthAuthenticatorLogoutInput, OAuthAuthenticatorRefreshInput, OAuthAuthenticatorResult, OAuthAuthenticatorStartInput, OAuthEnvironmentHandler, OAuthRouteHandlersOptions, OAuthSession, OAuthState, OAuthStateTransform, PassportDoneCallback, PassportHelpers, PassportOAuthAuthenticatorHelper, PassportOAuthDoneCallback, PassportOAuthPrivateInfo, PassportOAuthResult, PassportProfile, ProfileInfo, ProfileTransform, ProxyAuthRouteHandlersOptions, ProxyAuthenticator, ReadDeclarativeSignInResolverOptions, SignInInfo, SignInResolver, SignInResolverFactory, SignInResolverFactoryOptions, TokenParams, WebMessageResponse, authProvidersExtensionPoint, commonSignInResolvers, createOAuthAuthenticator, createOAuthProviderFactory, createOAuthRouteHandlers, createProxyAuthProviderFactory, createProxyAuthRouteHandlers, createProxyAuthenticator, createSignInResolverFactory, decodeOAuthState, encodeOAuthState, getBearerTokenFromAuthorizationHeader, prepareBackstageIdentityResponse, readDeclarativeSignInResolver, sendWebMessageResponse };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-auth-node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-next.0",
|
|
4
4
|
"main": "dist/index.cjs.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -28,20 +28,32 @@
|
|
|
28
28
|
"start": "backstage-cli package start"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@backstage/backend-common": "^0.19.
|
|
31
|
+
"@backstage/backend-common": "^0.19.4-next.0",
|
|
32
|
+
"@backstage/backend-plugin-api": "^0.6.2-next.0",
|
|
33
|
+
"@backstage/catalog-client": "^1.4.3",
|
|
34
|
+
"@backstage/catalog-model": "^1.4.1",
|
|
32
35
|
"@backstage/config": "^1.0.8",
|
|
33
36
|
"@backstage/errors": "^1.2.1",
|
|
37
|
+
"@backstage/types": "^1.1.0",
|
|
34
38
|
"@types/express": "*",
|
|
39
|
+
"@types/passport": "^1.0.3",
|
|
35
40
|
"express": "^4.17.1",
|
|
36
41
|
"jose": "^4.6.0",
|
|
42
|
+
"lodash": "^4.17.21",
|
|
37
43
|
"node-fetch": "^2.6.7",
|
|
38
|
-
"
|
|
44
|
+
"passport": "^0.6.0",
|
|
45
|
+
"winston": "^3.2.1",
|
|
46
|
+
"zod": "^3.21.4",
|
|
47
|
+
"zod-to-json-schema": "^3.21.4"
|
|
39
48
|
},
|
|
40
49
|
"devDependencies": {
|
|
41
|
-
"@backstage/backend-test-utils": "^0.2.0",
|
|
42
|
-
"@backstage/cli": "^0.22.
|
|
50
|
+
"@backstage/backend-test-utils": "^0.2.2-next.0",
|
|
51
|
+
"@backstage/cli": "^0.22.12-next.0",
|
|
52
|
+
"cookie-parser": "^1.4.6",
|
|
53
|
+
"express-promise-router": "^4.1.1",
|
|
43
54
|
"lodash": "^4.17.21",
|
|
44
55
|
"msw": "^1.0.0",
|
|
56
|
+
"supertest": "^6.1.3",
|
|
45
57
|
"uuid": "^8.0.0"
|
|
46
58
|
},
|
|
47
59
|
"files": [
|