@backstage/plugin-auth-node 0.2.19 → 0.3.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -5
- 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 +18 -6
package/dist/index.cjs.js
CHANGED
|
@@ -2,8 +2,82 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
6
|
+
var crypto = require('crypto');
|
|
5
7
|
var errors = require('@backstage/errors');
|
|
6
8
|
var jose = require('jose');
|
|
9
|
+
var url = require('url');
|
|
10
|
+
var pickBy = require('lodash/pickBy');
|
|
11
|
+
var zodToJsonSchema = require('zod-to-json-schema');
|
|
12
|
+
|
|
13
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
14
|
+
|
|
15
|
+
var crypto__default = /*#__PURE__*/_interopDefaultLegacy(crypto);
|
|
16
|
+
var pickBy__default = /*#__PURE__*/_interopDefaultLegacy(pickBy);
|
|
17
|
+
var zodToJsonSchema__default = /*#__PURE__*/_interopDefaultLegacy(zodToJsonSchema);
|
|
18
|
+
|
|
19
|
+
const authProvidersExtensionPoint = backendPluginApi.createExtensionPoint({
|
|
20
|
+
id: "auth.providers"
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
function safelyEncodeURIComponent(value) {
|
|
24
|
+
return encodeURIComponent(value).replace(/'/g, "%27");
|
|
25
|
+
}
|
|
26
|
+
function sendWebMessageResponse(res, appOrigin, response) {
|
|
27
|
+
const jsonData = JSON.stringify(response, (_, value) => {
|
|
28
|
+
if (value instanceof Error) {
|
|
29
|
+
return errors.serializeError(value);
|
|
30
|
+
}
|
|
31
|
+
return value;
|
|
32
|
+
});
|
|
33
|
+
const base64Data = safelyEncodeURIComponent(jsonData);
|
|
34
|
+
const base64Origin = safelyEncodeURIComponent(appOrigin);
|
|
35
|
+
const script = `
|
|
36
|
+
var authResponse = decodeURIComponent('${base64Data}');
|
|
37
|
+
var origin = decodeURIComponent('${base64Origin}');
|
|
38
|
+
var originInfo = {'type': 'config_info', 'targetOrigin': origin};
|
|
39
|
+
(window.opener || window.parent).postMessage(originInfo, '*');
|
|
40
|
+
(window.opener || window.parent).postMessage(JSON.parse(authResponse), origin);
|
|
41
|
+
setTimeout(() => {
|
|
42
|
+
window.close();
|
|
43
|
+
}, 100); // same as the interval of the core-app-api lib/loginPopup.ts (to address race conditions)
|
|
44
|
+
`;
|
|
45
|
+
const hash = crypto__default["default"].createHash("sha256").update(script).digest("base64");
|
|
46
|
+
res.setHeader("Content-Type", "text/html");
|
|
47
|
+
res.setHeader("X-Frame-Options", "sameorigin");
|
|
48
|
+
res.setHeader("Content-Security-Policy", `script-src 'sha256-${hash}'`);
|
|
49
|
+
res.end(`<html><body><script>${script}<\/script></body></html>`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function parseJwtPayload(token) {
|
|
53
|
+
const [_header, payload, _signature] = token.split(".");
|
|
54
|
+
return JSON.parse(Buffer.from(payload, "base64").toString());
|
|
55
|
+
}
|
|
56
|
+
function prepareBackstageIdentityResponse(result) {
|
|
57
|
+
if (!result.token) {
|
|
58
|
+
throw new errors.InputError(`Identity response must return a token`);
|
|
59
|
+
}
|
|
60
|
+
const { sub, ent = [], exp: expStr } = parseJwtPayload(result.token);
|
|
61
|
+
if (!sub) {
|
|
62
|
+
throw new errors.InputError(
|
|
63
|
+
`Identity response must return a token with subject claim`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
const expAt = Number(expStr);
|
|
67
|
+
const exp = expAt ? Math.round(expAt - Date.now() / 1e3) : void 0;
|
|
68
|
+
if (exp && exp < 0) {
|
|
69
|
+
throw new errors.InputError(`Identity response must not return an expired token`);
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
...result,
|
|
73
|
+
expiresInSeconds: exp,
|
|
74
|
+
identity: {
|
|
75
|
+
type: "user",
|
|
76
|
+
userEntityRef: sub,
|
|
77
|
+
ownershipEntityRefs: ent
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
7
81
|
|
|
8
82
|
function getBearerTokenFromAuthorizationHeader(authorizationHeader) {
|
|
9
83
|
if (typeof authorizationHeader !== "string") {
|
|
@@ -13,20 +87,20 @@ function getBearerTokenFromAuthorizationHeader(authorizationHeader) {
|
|
|
13
87
|
return matches == null ? void 0 : matches[1];
|
|
14
88
|
}
|
|
15
89
|
|
|
16
|
-
var __defProp$
|
|
17
|
-
var __defNormalProp$
|
|
18
|
-
var __publicField$
|
|
19
|
-
__defNormalProp$
|
|
90
|
+
var __defProp$4 = Object.defineProperty;
|
|
91
|
+
var __defNormalProp$4 = (obj, key, value) => key in obj ? __defProp$4(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
92
|
+
var __publicField$4 = (obj, key, value) => {
|
|
93
|
+
__defNormalProp$4(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
20
94
|
return value;
|
|
21
95
|
};
|
|
22
96
|
const CLOCK_MARGIN_S = 10;
|
|
23
97
|
class DefaultIdentityClient {
|
|
24
98
|
constructor(options) {
|
|
25
|
-
__publicField$
|
|
26
|
-
__publicField$
|
|
27
|
-
__publicField$
|
|
28
|
-
__publicField$
|
|
29
|
-
__publicField$
|
|
99
|
+
__publicField$4(this, "discovery");
|
|
100
|
+
__publicField$4(this, "issuer");
|
|
101
|
+
__publicField$4(this, "algorithms");
|
|
102
|
+
__publicField$4(this, "keyStore");
|
|
103
|
+
__publicField$4(this, "keyStoreUpdated", 0);
|
|
30
104
|
this.discovery = options.discovery;
|
|
31
105
|
this.issuer = options.issuer;
|
|
32
106
|
this.algorithms = options.hasOwnProperty("algorithms") ? options.algorithms : ["ES256"];
|
|
@@ -114,15 +188,15 @@ class DefaultIdentityClient {
|
|
|
114
188
|
}
|
|
115
189
|
}
|
|
116
190
|
|
|
117
|
-
var __defProp = Object.defineProperty;
|
|
118
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
119
|
-
var __publicField = (obj, key, value) => {
|
|
120
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
191
|
+
var __defProp$3 = Object.defineProperty;
|
|
192
|
+
var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
193
|
+
var __publicField$3 = (obj, key, value) => {
|
|
194
|
+
__defNormalProp$3(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
121
195
|
return value;
|
|
122
196
|
};
|
|
123
197
|
class IdentityClient {
|
|
124
198
|
constructor(defaultIdentityClient) {
|
|
125
|
-
__publicField(this, "defaultIdentityClient");
|
|
199
|
+
__publicField$3(this, "defaultIdentityClient");
|
|
126
200
|
this.defaultIdentityClient = defaultIdentityClient;
|
|
127
201
|
}
|
|
128
202
|
static create(options) {
|
|
@@ -141,7 +215,809 @@ class IdentityClient {
|
|
|
141
215
|
}
|
|
142
216
|
}
|
|
143
217
|
|
|
218
|
+
function encodeOAuthState(state) {
|
|
219
|
+
const stateString = new URLSearchParams(
|
|
220
|
+
pickBy__default["default"](state, (value) => value !== void 0)
|
|
221
|
+
).toString();
|
|
222
|
+
return Buffer.from(stateString, "utf-8").toString("hex");
|
|
223
|
+
}
|
|
224
|
+
function decodeOAuthState(encodedState) {
|
|
225
|
+
var _a, _b;
|
|
226
|
+
const state = Object.fromEntries(
|
|
227
|
+
new URLSearchParams(Buffer.from(encodedState, "hex").toString("utf-8"))
|
|
228
|
+
);
|
|
229
|
+
if (!state.env || ((_a = state.env) == null ? void 0 : _a.length) === 0) {
|
|
230
|
+
throw new errors.NotAllowedError("OAuth state is invalid, missing env");
|
|
231
|
+
}
|
|
232
|
+
if (!state.nonce || ((_b = state.nonce) == null ? void 0 : _b.length) === 0) {
|
|
233
|
+
throw new errors.NotAllowedError("OAuth state is invalid, missing nonce");
|
|
234
|
+
}
|
|
235
|
+
return state;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
var __defProp$2 = Object.defineProperty;
|
|
239
|
+
var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
240
|
+
var __publicField$2 = (obj, key, value) => {
|
|
241
|
+
__defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
242
|
+
return value;
|
|
243
|
+
};
|
|
244
|
+
const THOUSAND_DAYS_MS = 1e3 * 24 * 60 * 60 * 1e3;
|
|
245
|
+
const TEN_MINUTES_MS = 600 * 1e3;
|
|
246
|
+
const defaultCookieConfigurer = ({
|
|
247
|
+
callbackUrl,
|
|
248
|
+
providerId,
|
|
249
|
+
appOrigin
|
|
250
|
+
}) => {
|
|
251
|
+
const { hostname: domain, pathname, protocol } = new URL(callbackUrl);
|
|
252
|
+
const secure = protocol === "https:";
|
|
253
|
+
let sameSite = "lax";
|
|
254
|
+
if (new URL(appOrigin).hostname !== domain && secure) {
|
|
255
|
+
sameSite = "none";
|
|
256
|
+
}
|
|
257
|
+
const path = pathname.endsWith(`${providerId}/handler/frame`) ? pathname.slice(0, -"/handler/frame".length) : `${pathname}/${providerId}`;
|
|
258
|
+
return { domain, path, secure, sameSite };
|
|
259
|
+
};
|
|
260
|
+
class OAuthCookieManager {
|
|
261
|
+
constructor(options) {
|
|
262
|
+
this.options = options;
|
|
263
|
+
__publicField$2(this, "cookieConfigurer");
|
|
264
|
+
__publicField$2(this, "nonceCookie");
|
|
265
|
+
__publicField$2(this, "refreshTokenCookie");
|
|
266
|
+
__publicField$2(this, "grantedScopeCookie");
|
|
267
|
+
var _a;
|
|
268
|
+
this.cookieConfigurer = (_a = options.cookieConfigurer) != null ? _a : defaultCookieConfigurer;
|
|
269
|
+
this.nonceCookie = `${options.providerId}-nonce`;
|
|
270
|
+
this.refreshTokenCookie = `${options.providerId}-refresh-token`;
|
|
271
|
+
this.grantedScopeCookie = `${options.providerId}-granted-scope`;
|
|
272
|
+
}
|
|
273
|
+
getConfig(origin, pathSuffix = "") {
|
|
274
|
+
const cookieConfig = this.cookieConfigurer({
|
|
275
|
+
providerId: this.options.providerId,
|
|
276
|
+
baseUrl: this.options.baseUrl,
|
|
277
|
+
callbackUrl: this.options.callbackUrl,
|
|
278
|
+
appOrigin: origin != null ? origin : this.options.defaultAppOrigin
|
|
279
|
+
});
|
|
280
|
+
return {
|
|
281
|
+
httpOnly: true,
|
|
282
|
+
sameSite: "lax",
|
|
283
|
+
...cookieConfig,
|
|
284
|
+
path: cookieConfig.path + pathSuffix
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
setNonce(res, nonce, origin) {
|
|
288
|
+
res.cookie(this.nonceCookie, nonce, {
|
|
289
|
+
maxAge: TEN_MINUTES_MS,
|
|
290
|
+
...this.getConfig(origin, "/handler")
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
setRefreshToken(res, refreshToken, origin) {
|
|
294
|
+
res.cookie(this.refreshTokenCookie, refreshToken, {
|
|
295
|
+
maxAge: THOUSAND_DAYS_MS,
|
|
296
|
+
...this.getConfig(origin)
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
removeRefreshToken(res, origin) {
|
|
300
|
+
res.cookie(this.refreshTokenCookie, "", {
|
|
301
|
+
maxAge: 0,
|
|
302
|
+
...this.getConfig(origin)
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
setGrantedScopes(res, scope, origin) {
|
|
306
|
+
res.cookie(this.grantedScopeCookie, scope, {
|
|
307
|
+
maxAge: THOUSAND_DAYS_MS,
|
|
308
|
+
...this.getConfig(origin)
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
getNonce(req) {
|
|
312
|
+
return req.cookies[this.nonceCookie];
|
|
313
|
+
}
|
|
314
|
+
getRefreshToken(req) {
|
|
315
|
+
return req.cookies[this.refreshTokenCookie];
|
|
316
|
+
}
|
|
317
|
+
getGrantedScopes(req) {
|
|
318
|
+
return req.cookies[this.grantedScopeCookie];
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
function createOAuthRouteHandlers(options) {
|
|
323
|
+
var _a, _b, _c;
|
|
324
|
+
const {
|
|
325
|
+
authenticator,
|
|
326
|
+
config,
|
|
327
|
+
baseUrl,
|
|
328
|
+
appUrl,
|
|
329
|
+
providerId,
|
|
330
|
+
isOriginAllowed,
|
|
331
|
+
cookieConfigurer,
|
|
332
|
+
resolverContext,
|
|
333
|
+
signInResolver
|
|
334
|
+
} = options;
|
|
335
|
+
const defaultAppOrigin = new url.URL(appUrl).origin;
|
|
336
|
+
const callbackUrl = (_a = config.getOptionalString("callbackUrl")) != null ? _a : `${baseUrl}/${providerId}/handler/frame`;
|
|
337
|
+
const stateTransform = (_b = options.stateTransform) != null ? _b : (state) => ({ state });
|
|
338
|
+
const profileTransform = (_c = options.profileTransform) != null ? _c : authenticator.defaultProfileTransform;
|
|
339
|
+
const authenticatorCtx = authenticator.initialize({ config, callbackUrl });
|
|
340
|
+
const cookieManager = new OAuthCookieManager({
|
|
341
|
+
baseUrl,
|
|
342
|
+
callbackUrl,
|
|
343
|
+
defaultAppOrigin,
|
|
344
|
+
providerId,
|
|
345
|
+
cookieConfigurer
|
|
346
|
+
});
|
|
347
|
+
return {
|
|
348
|
+
async start(req, res) {
|
|
349
|
+
var _a2, _b2, _c2, _d, _e, _f;
|
|
350
|
+
const scope = (_b2 = (_a2 = req.query.scope) == null ? void 0 : _a2.toString()) != null ? _b2 : "";
|
|
351
|
+
const env = (_c2 = req.query.env) == null ? void 0 : _c2.toString();
|
|
352
|
+
const origin = (_d = req.query.origin) == null ? void 0 : _d.toString();
|
|
353
|
+
const redirectUrl = (_e = req.query.redirectUrl) == null ? void 0 : _e.toString();
|
|
354
|
+
const flow = (_f = req.query.flow) == null ? void 0 : _f.toString();
|
|
355
|
+
if (!env) {
|
|
356
|
+
throw new errors.InputError("No env provided in request query parameters");
|
|
357
|
+
}
|
|
358
|
+
const nonce = crypto__default["default"].randomBytes(16).toString("base64");
|
|
359
|
+
cookieManager.setNonce(res, nonce, origin);
|
|
360
|
+
const state = { nonce, env, origin, redirectUrl, flow };
|
|
361
|
+
if (authenticator.shouldPersistScopes) {
|
|
362
|
+
state.scope = scope;
|
|
363
|
+
}
|
|
364
|
+
const { state: transformedState } = await stateTransform(state, { req });
|
|
365
|
+
const encodedState = encodeOAuthState(transformedState);
|
|
366
|
+
const { url, status } = await options.authenticator.start(
|
|
367
|
+
{ req, scope, state: encodedState },
|
|
368
|
+
authenticatorCtx
|
|
369
|
+
);
|
|
370
|
+
res.statusCode = status || 302;
|
|
371
|
+
res.setHeader("Location", url);
|
|
372
|
+
res.setHeader("Content-Length", "0");
|
|
373
|
+
res.end();
|
|
374
|
+
},
|
|
375
|
+
async frameHandler(req, res) {
|
|
376
|
+
var _a2, _b2;
|
|
377
|
+
let appOrigin = defaultAppOrigin;
|
|
378
|
+
try {
|
|
379
|
+
const state = decodeOAuthState((_b2 = (_a2 = req.query.state) == null ? void 0 : _a2.toString()) != null ? _b2 : "");
|
|
380
|
+
if (state.origin) {
|
|
381
|
+
try {
|
|
382
|
+
appOrigin = new url.URL(state.origin).origin;
|
|
383
|
+
} catch {
|
|
384
|
+
throw new errors.NotAllowedError("App origin is invalid, failed to parse");
|
|
385
|
+
}
|
|
386
|
+
if (!isOriginAllowed(appOrigin)) {
|
|
387
|
+
throw new errors.NotAllowedError(`Origin '${appOrigin}' is not allowed`);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
const cookieNonce = cookieManager.getNonce(req);
|
|
391
|
+
const stateNonce = state.nonce;
|
|
392
|
+
if (!cookieNonce) {
|
|
393
|
+
throw new errors.NotAllowedError("Auth response is missing cookie nonce");
|
|
394
|
+
}
|
|
395
|
+
if (cookieNonce !== stateNonce) {
|
|
396
|
+
throw new errors.NotAllowedError("Invalid nonce");
|
|
397
|
+
}
|
|
398
|
+
const result = await authenticator.authenticate(
|
|
399
|
+
{ req },
|
|
400
|
+
authenticatorCtx
|
|
401
|
+
);
|
|
402
|
+
const { profile } = await profileTransform(result, resolverContext);
|
|
403
|
+
const response = {
|
|
404
|
+
profile,
|
|
405
|
+
providerInfo: {
|
|
406
|
+
idToken: result.session.idToken,
|
|
407
|
+
accessToken: result.session.accessToken,
|
|
408
|
+
scope: result.session.scope,
|
|
409
|
+
expiresInSeconds: result.session.expiresInSeconds
|
|
410
|
+
}
|
|
411
|
+
};
|
|
412
|
+
if (signInResolver) {
|
|
413
|
+
const identity = await signInResolver(
|
|
414
|
+
{ profile, result },
|
|
415
|
+
resolverContext
|
|
416
|
+
);
|
|
417
|
+
response.backstageIdentity = prepareBackstageIdentityResponse(identity);
|
|
418
|
+
}
|
|
419
|
+
if (authenticator.shouldPersistScopes && state.scope) {
|
|
420
|
+
cookieManager.setGrantedScopes(res, state.scope, appOrigin);
|
|
421
|
+
result.session.scope = state.scope;
|
|
422
|
+
}
|
|
423
|
+
if (result.session.refreshToken) {
|
|
424
|
+
cookieManager.setRefreshToken(
|
|
425
|
+
res,
|
|
426
|
+
result.session.refreshToken,
|
|
427
|
+
appOrigin
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
if (state.flow === "redirect") {
|
|
431
|
+
if (!state.redirectUrl) {
|
|
432
|
+
throw new errors.InputError(
|
|
433
|
+
"No redirectUrl provided in request query parameters"
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
res.redirect(state.redirectUrl);
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
sendWebMessageResponse(res, appOrigin, {
|
|
440
|
+
type: "authorization_response",
|
|
441
|
+
response
|
|
442
|
+
});
|
|
443
|
+
} catch (error) {
|
|
444
|
+
const { name, message } = errors.isError(error) ? error : new Error("Encountered invalid error");
|
|
445
|
+
sendWebMessageResponse(res, appOrigin, {
|
|
446
|
+
type: "authorization_response",
|
|
447
|
+
error: { name, message }
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
},
|
|
451
|
+
async logout(req, res) {
|
|
452
|
+
if (req.header("X-Requested-With") !== "XMLHttpRequest") {
|
|
453
|
+
throw new errors.AuthenticationError("Invalid X-Requested-With header");
|
|
454
|
+
}
|
|
455
|
+
if (authenticator.logout) {
|
|
456
|
+
const refreshToken = cookieManager.getRefreshToken(req);
|
|
457
|
+
await authenticator.logout({ req, refreshToken }, authenticatorCtx);
|
|
458
|
+
}
|
|
459
|
+
cookieManager.removeRefreshToken(res, req.get("origin"));
|
|
460
|
+
res.status(200).end();
|
|
461
|
+
},
|
|
462
|
+
async refresh(req, res) {
|
|
463
|
+
var _a2, _b2;
|
|
464
|
+
if (req.header("X-Requested-With") !== "XMLHttpRequest") {
|
|
465
|
+
throw new errors.AuthenticationError("Invalid X-Requested-With header");
|
|
466
|
+
}
|
|
467
|
+
try {
|
|
468
|
+
const refreshToken = cookieManager.getRefreshToken(req);
|
|
469
|
+
if (!refreshToken) {
|
|
470
|
+
throw new errors.InputError("Missing session cookie");
|
|
471
|
+
}
|
|
472
|
+
let scope = (_b2 = (_a2 = req.query.scope) == null ? void 0 : _a2.toString()) != null ? _b2 : "";
|
|
473
|
+
if (authenticator.shouldPersistScopes) {
|
|
474
|
+
scope = cookieManager.getGrantedScopes(req);
|
|
475
|
+
}
|
|
476
|
+
const result = await authenticator.refresh(
|
|
477
|
+
{ req, scope, refreshToken },
|
|
478
|
+
authenticatorCtx
|
|
479
|
+
);
|
|
480
|
+
const { profile } = await profileTransform(result, resolverContext);
|
|
481
|
+
const newRefreshToken = result.session.refreshToken;
|
|
482
|
+
if (newRefreshToken && newRefreshToken !== refreshToken) {
|
|
483
|
+
cookieManager.setRefreshToken(
|
|
484
|
+
res,
|
|
485
|
+
newRefreshToken,
|
|
486
|
+
req.get("origin")
|
|
487
|
+
);
|
|
488
|
+
}
|
|
489
|
+
const response = {
|
|
490
|
+
profile,
|
|
491
|
+
providerInfo: {
|
|
492
|
+
idToken: result.session.idToken,
|
|
493
|
+
accessToken: result.session.accessToken,
|
|
494
|
+
scope: result.session.scope,
|
|
495
|
+
expiresInSeconds: result.session.expiresInSeconds
|
|
496
|
+
}
|
|
497
|
+
};
|
|
498
|
+
if (signInResolver) {
|
|
499
|
+
const identity = await signInResolver(
|
|
500
|
+
{ profile, result },
|
|
501
|
+
resolverContext
|
|
502
|
+
);
|
|
503
|
+
response.backstageIdentity = prepareBackstageIdentityResponse(identity);
|
|
504
|
+
}
|
|
505
|
+
res.status(200).json(response);
|
|
506
|
+
} catch (error) {
|
|
507
|
+
throw new errors.AuthenticationError("Refresh failed", error);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
var __defProp$1 = Object.defineProperty;
|
|
514
|
+
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
515
|
+
var __publicField$1 = (obj, key, value) => {
|
|
516
|
+
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
517
|
+
return value;
|
|
518
|
+
};
|
|
519
|
+
function decodeJwtPayload(token) {
|
|
520
|
+
const payloadStr = token.split(".")[1];
|
|
521
|
+
if (!payloadStr) {
|
|
522
|
+
throw new Error("Invalid JWT token");
|
|
523
|
+
}
|
|
524
|
+
let payload;
|
|
525
|
+
try {
|
|
526
|
+
payload = JSON.parse(
|
|
527
|
+
Buffer.from(
|
|
528
|
+
payloadStr.replace(/-/g, "+").replace(/_/g, "/"),
|
|
529
|
+
"base64"
|
|
530
|
+
).toString("utf8")
|
|
531
|
+
);
|
|
532
|
+
} catch (e) {
|
|
533
|
+
throw new Error("Invalid JWT token");
|
|
534
|
+
}
|
|
535
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
536
|
+
throw new Error("Invalid JWT token");
|
|
537
|
+
}
|
|
538
|
+
return payload;
|
|
539
|
+
}
|
|
540
|
+
class PassportHelpers {
|
|
541
|
+
constructor() {
|
|
542
|
+
}
|
|
543
|
+
static async executeRedirectStrategy(req, providerStrategy, options) {
|
|
544
|
+
return new Promise((resolve) => {
|
|
545
|
+
const strategy = Object.create(providerStrategy);
|
|
546
|
+
strategy.redirect = (url, status) => {
|
|
547
|
+
resolve({ url, status: status != null ? status : void 0 });
|
|
548
|
+
};
|
|
549
|
+
strategy.authenticate(req, { ...options });
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
static async executeFrameHandlerStrategy(req, providerStrategy, options) {
|
|
553
|
+
return new Promise((resolve, reject) => {
|
|
554
|
+
const strategy = Object.create(providerStrategy);
|
|
555
|
+
strategy.success = (result, privateInfo) => {
|
|
556
|
+
resolve({ result, privateInfo });
|
|
557
|
+
};
|
|
558
|
+
strategy.fail = (info) => {
|
|
559
|
+
var _a;
|
|
560
|
+
reject(new Error(`Authentication rejected, ${(_a = info.message) != null ? _a : ""}`));
|
|
561
|
+
};
|
|
562
|
+
strategy.error = (error) => {
|
|
563
|
+
var _a;
|
|
564
|
+
let message = `Authentication failed, ${error.message}`;
|
|
565
|
+
if ((_a = error.oauthError) == null ? void 0 : _a.data) {
|
|
566
|
+
try {
|
|
567
|
+
const errorData = JSON.parse(error.oauthError.data);
|
|
568
|
+
if (errorData.message) {
|
|
569
|
+
message += ` - ${errorData.message}`;
|
|
570
|
+
}
|
|
571
|
+
} catch (parseError) {
|
|
572
|
+
message += ` - ${error.oauthError}`;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
reject(new Error(message));
|
|
576
|
+
};
|
|
577
|
+
strategy.redirect = () => {
|
|
578
|
+
reject(new Error("Unexpected redirect"));
|
|
579
|
+
};
|
|
580
|
+
strategy.authenticate(req, { ...options != null ? options : {} });
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
static async executeRefreshTokenStrategy(providerStrategy, refreshToken, scope) {
|
|
584
|
+
return new Promise((resolve, reject) => {
|
|
585
|
+
const anyStrategy = providerStrategy;
|
|
586
|
+
const OAuth2 = anyStrategy._oauth2.constructor;
|
|
587
|
+
const oauth2 = new OAuth2(
|
|
588
|
+
anyStrategy._oauth2._clientId,
|
|
589
|
+
anyStrategy._oauth2._clientSecret,
|
|
590
|
+
anyStrategy._oauth2._baseSite,
|
|
591
|
+
anyStrategy._oauth2._authorizeUrl,
|
|
592
|
+
anyStrategy._refreshURL || anyStrategy._oauth2._accessTokenUrl,
|
|
593
|
+
anyStrategy._oauth2._customHeaders
|
|
594
|
+
);
|
|
595
|
+
oauth2.getOAuthAccessToken(
|
|
596
|
+
refreshToken,
|
|
597
|
+
{
|
|
598
|
+
scope,
|
|
599
|
+
grant_type: "refresh_token"
|
|
600
|
+
},
|
|
601
|
+
(err, accessToken, newRefreshToken, params) => {
|
|
602
|
+
if (err) {
|
|
603
|
+
reject(
|
|
604
|
+
new Error(`Failed to refresh access token ${err.toString()}`)
|
|
605
|
+
);
|
|
606
|
+
}
|
|
607
|
+
if (!accessToken) {
|
|
608
|
+
reject(
|
|
609
|
+
new Error(
|
|
610
|
+
`Failed to refresh access token, no access token received`
|
|
611
|
+
)
|
|
612
|
+
);
|
|
613
|
+
}
|
|
614
|
+
resolve({
|
|
615
|
+
accessToken,
|
|
616
|
+
refreshToken: newRefreshToken,
|
|
617
|
+
params
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
);
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
static async executeFetchUserProfileStrategy(providerStrategy, accessToken) {
|
|
624
|
+
return new Promise((resolve, reject) => {
|
|
625
|
+
const anyStrategy = providerStrategy;
|
|
626
|
+
anyStrategy.userProfile(
|
|
627
|
+
accessToken,
|
|
628
|
+
(error, rawProfile) => {
|
|
629
|
+
if (error) {
|
|
630
|
+
reject(error);
|
|
631
|
+
} else {
|
|
632
|
+
resolve(rawProfile);
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
);
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
__publicField$1(PassportHelpers, "transformProfile", (profile, idToken) => {
|
|
640
|
+
var _a, _b;
|
|
641
|
+
let email = void 0;
|
|
642
|
+
if (profile.emails && profile.emails.length > 0) {
|
|
643
|
+
const [firstEmail] = profile.emails;
|
|
644
|
+
email = firstEmail.value;
|
|
645
|
+
}
|
|
646
|
+
let picture = void 0;
|
|
647
|
+
if (profile.avatarUrl) {
|
|
648
|
+
picture = profile.avatarUrl;
|
|
649
|
+
} else if (profile.photos && profile.photos.length > 0) {
|
|
650
|
+
const [firstPhoto] = profile.photos;
|
|
651
|
+
picture = firstPhoto.value;
|
|
652
|
+
}
|
|
653
|
+
let displayName = (_b = (_a = profile.displayName) != null ? _a : profile.username) != null ? _b : profile.id;
|
|
654
|
+
if ((!email || !picture || !displayName) && idToken) {
|
|
655
|
+
try {
|
|
656
|
+
const decoded = decodeJwtPayload(idToken);
|
|
657
|
+
if (!email && decoded.email) {
|
|
658
|
+
email = decoded.email;
|
|
659
|
+
}
|
|
660
|
+
if (!picture && decoded.picture) {
|
|
661
|
+
picture = decoded.picture;
|
|
662
|
+
}
|
|
663
|
+
if (!displayName && decoded.name) {
|
|
664
|
+
displayName = decoded.name;
|
|
665
|
+
}
|
|
666
|
+
} catch (e) {
|
|
667
|
+
throw new Error(`Failed to parse id token and get profile info, ${e}`);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
return {
|
|
671
|
+
email,
|
|
672
|
+
picture,
|
|
673
|
+
displayName
|
|
674
|
+
};
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
var __defProp = Object.defineProperty;
|
|
678
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
679
|
+
var __publicField = (obj, key, value) => {
|
|
680
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
681
|
+
return value;
|
|
682
|
+
};
|
|
683
|
+
var __accessCheck = (obj, member, msg) => {
|
|
684
|
+
if (!member.has(obj))
|
|
685
|
+
throw TypeError("Cannot " + msg);
|
|
686
|
+
};
|
|
687
|
+
var __privateGet = (obj, member, getter) => {
|
|
688
|
+
__accessCheck(obj, member, "read from private field");
|
|
689
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
690
|
+
};
|
|
691
|
+
var __privateAdd = (obj, member, value) => {
|
|
692
|
+
if (member.has(obj))
|
|
693
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
694
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
695
|
+
};
|
|
696
|
+
var __privateSet = (obj, member, value, setter) => {
|
|
697
|
+
__accessCheck(obj, member, "write to private field");
|
|
698
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
699
|
+
return value;
|
|
700
|
+
};
|
|
701
|
+
var _strategy;
|
|
702
|
+
const _PassportOAuthAuthenticatorHelper = class _PassportOAuthAuthenticatorHelper {
|
|
703
|
+
constructor(strategy) {
|
|
704
|
+
__privateAdd(this, _strategy, void 0);
|
|
705
|
+
__privateSet(this, _strategy, strategy);
|
|
706
|
+
}
|
|
707
|
+
static from(strategy) {
|
|
708
|
+
return new _PassportOAuthAuthenticatorHelper(strategy);
|
|
709
|
+
}
|
|
710
|
+
async start(input, options) {
|
|
711
|
+
return PassportHelpers.executeRedirectStrategy(input.req, __privateGet(this, _strategy), {
|
|
712
|
+
scope: input.scope,
|
|
713
|
+
state: input.state,
|
|
714
|
+
...options
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
async authenticate(input) {
|
|
718
|
+
var _a;
|
|
719
|
+
const { result, privateInfo } = await PassportHelpers.executeFrameHandlerStrategy(input.req, __privateGet(this, _strategy));
|
|
720
|
+
return {
|
|
721
|
+
fullProfile: result.fullProfile,
|
|
722
|
+
session: {
|
|
723
|
+
accessToken: result.accessToken,
|
|
724
|
+
tokenType: (_a = result.params.token_type) != null ? _a : "bearer",
|
|
725
|
+
scope: result.params.scope,
|
|
726
|
+
expiresInSeconds: result.params.expires_in,
|
|
727
|
+
idToken: result.params.id_token,
|
|
728
|
+
refreshToken: privateInfo.refreshToken
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
async refresh(input) {
|
|
733
|
+
var _a;
|
|
734
|
+
const result = await PassportHelpers.executeRefreshTokenStrategy(
|
|
735
|
+
__privateGet(this, _strategy),
|
|
736
|
+
input.refreshToken,
|
|
737
|
+
input.scope
|
|
738
|
+
);
|
|
739
|
+
const fullProfile = await this.fetchProfile(result.accessToken);
|
|
740
|
+
return {
|
|
741
|
+
fullProfile,
|
|
742
|
+
session: {
|
|
743
|
+
accessToken: result.accessToken,
|
|
744
|
+
tokenType: (_a = result.params.token_type) != null ? _a : "bearer",
|
|
745
|
+
scope: result.params.scope,
|
|
746
|
+
expiresInSeconds: result.params.expires_in,
|
|
747
|
+
idToken: result.params.id_token,
|
|
748
|
+
refreshToken: result.refreshToken
|
|
749
|
+
}
|
|
750
|
+
};
|
|
751
|
+
}
|
|
752
|
+
async fetchProfile(accessToken) {
|
|
753
|
+
const profile = await PassportHelpers.executeFetchUserProfileStrategy(
|
|
754
|
+
__privateGet(this, _strategy),
|
|
755
|
+
accessToken
|
|
756
|
+
);
|
|
757
|
+
return profile;
|
|
758
|
+
}
|
|
759
|
+
};
|
|
760
|
+
_strategy = new WeakMap();
|
|
761
|
+
__publicField(_PassportOAuthAuthenticatorHelper, "defaultProfileTransform", async (input) => ({
|
|
762
|
+
profile: PassportHelpers.transformProfile(
|
|
763
|
+
input.fullProfile,
|
|
764
|
+
input.session.idToken
|
|
765
|
+
)
|
|
766
|
+
}));
|
|
767
|
+
let PassportOAuthAuthenticatorHelper = _PassportOAuthAuthenticatorHelper;
|
|
768
|
+
|
|
769
|
+
class OAuthEnvironmentHandler {
|
|
770
|
+
constructor(handlers) {
|
|
771
|
+
this.handlers = handlers;
|
|
772
|
+
}
|
|
773
|
+
static mapConfig(config, factoryFunc) {
|
|
774
|
+
const envs = config.keys();
|
|
775
|
+
const handlers = /* @__PURE__ */ new Map();
|
|
776
|
+
for (const env of envs) {
|
|
777
|
+
const envConfig = config.getConfig(env);
|
|
778
|
+
const handler = factoryFunc(envConfig);
|
|
779
|
+
handlers.set(env, handler);
|
|
780
|
+
}
|
|
781
|
+
return new OAuthEnvironmentHandler(handlers);
|
|
782
|
+
}
|
|
783
|
+
async start(req, res) {
|
|
784
|
+
const provider = this.getProviderForEnv(req);
|
|
785
|
+
await provider.start(req, res);
|
|
786
|
+
}
|
|
787
|
+
async frameHandler(req, res) {
|
|
788
|
+
const provider = this.getProviderForEnv(req);
|
|
789
|
+
await provider.frameHandler(req, res);
|
|
790
|
+
}
|
|
791
|
+
async refresh(req, res) {
|
|
792
|
+
var _a;
|
|
793
|
+
const provider = this.getProviderForEnv(req);
|
|
794
|
+
await ((_a = provider.refresh) == null ? void 0 : _a.call(provider, req, res));
|
|
795
|
+
}
|
|
796
|
+
async logout(req, res) {
|
|
797
|
+
var _a;
|
|
798
|
+
const provider = this.getProviderForEnv(req);
|
|
799
|
+
await ((_a = provider.logout) == null ? void 0 : _a.call(provider, req, res));
|
|
800
|
+
}
|
|
801
|
+
getEnvFromRequest(req) {
|
|
802
|
+
var _a, _b;
|
|
803
|
+
const reqEnv = (_a = req.query.env) == null ? void 0 : _a.toString();
|
|
804
|
+
if (reqEnv) {
|
|
805
|
+
return reqEnv;
|
|
806
|
+
}
|
|
807
|
+
const stateParams = (_b = req.query.state) == null ? void 0 : _b.toString();
|
|
808
|
+
if (!stateParams) {
|
|
809
|
+
return void 0;
|
|
810
|
+
}
|
|
811
|
+
const { env } = decodeOAuthState(stateParams);
|
|
812
|
+
return env;
|
|
813
|
+
}
|
|
814
|
+
getProviderForEnv(req) {
|
|
815
|
+
const env = this.getEnvFromRequest(req);
|
|
816
|
+
if (!env) {
|
|
817
|
+
throw new errors.InputError(`Must specify 'env' query to select environment`);
|
|
818
|
+
}
|
|
819
|
+
const handler = this.handlers.get(env);
|
|
820
|
+
if (!handler) {
|
|
821
|
+
throw new errors.NotFoundError(
|
|
822
|
+
`No configuration available for the '${env}' environment of this provider.`
|
|
823
|
+
);
|
|
824
|
+
}
|
|
825
|
+
return handler;
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
function createSignInResolverFactory(options) {
|
|
830
|
+
const { optionsSchema } = options;
|
|
831
|
+
if (!optionsSchema) {
|
|
832
|
+
return (resolverOptions) => {
|
|
833
|
+
if (resolverOptions) {
|
|
834
|
+
throw new errors.InputError("sign-in resolver does not accept options");
|
|
835
|
+
}
|
|
836
|
+
return options.create(void 0);
|
|
837
|
+
};
|
|
838
|
+
}
|
|
839
|
+
const factory = (...[resolverOptions]) => {
|
|
840
|
+
const parsedOptions = optionsSchema.parse(resolverOptions);
|
|
841
|
+
return options.create(parsedOptions);
|
|
842
|
+
};
|
|
843
|
+
factory.optionsJsonSchema = zodToJsonSchema__default["default"](optionsSchema);
|
|
844
|
+
return factory;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
function readDeclarativeSignInResolver(options) {
|
|
848
|
+
var _a, _b;
|
|
849
|
+
const resolvers = (_b = (_a = options.config.getOptionalConfigArray("signIn.resolvers")) == null ? void 0 : _a.map((resolverConfig) => {
|
|
850
|
+
const resolverName = resolverConfig.getString("resolver");
|
|
851
|
+
if (!Object.hasOwn(options.signInResolverFactories, resolverName)) {
|
|
852
|
+
throw new Error(
|
|
853
|
+
`Sign-in resolver '${resolverName}' is not available`
|
|
854
|
+
);
|
|
855
|
+
}
|
|
856
|
+
const resolver = options.signInResolverFactories[resolverName];
|
|
857
|
+
const { resolver: _ignored, ...resolverOptions } = resolverConfig.get();
|
|
858
|
+
return resolver(
|
|
859
|
+
Object.keys(resolverOptions).length > 0 ? resolverOptions : void 0
|
|
860
|
+
);
|
|
861
|
+
})) != null ? _b : [];
|
|
862
|
+
if (resolvers.length === 0) {
|
|
863
|
+
return void 0;
|
|
864
|
+
}
|
|
865
|
+
return async (profile, context) => {
|
|
866
|
+
for (const resolver of resolvers) {
|
|
867
|
+
try {
|
|
868
|
+
return await resolver(profile, context);
|
|
869
|
+
} catch (error) {
|
|
870
|
+
if ((error == null ? void 0 : error.name) === "NotFoundError") {
|
|
871
|
+
continue;
|
|
872
|
+
}
|
|
873
|
+
throw error;
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
throw new Error("Failed to sign-in, unable to resolve user identity");
|
|
877
|
+
};
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
exports.commonSignInResolvers = void 0;
|
|
881
|
+
((commonSignInResolvers2) => {
|
|
882
|
+
commonSignInResolvers2.emailMatchingUserEntityProfileEmail = createSignInResolverFactory({
|
|
883
|
+
create() {
|
|
884
|
+
return async (info, ctx) => {
|
|
885
|
+
const { profile } = info;
|
|
886
|
+
if (!profile.email) {
|
|
887
|
+
throw new Error(
|
|
888
|
+
"Login failed, user profile does not contain an email"
|
|
889
|
+
);
|
|
890
|
+
}
|
|
891
|
+
return ctx.signInWithCatalogUser({
|
|
892
|
+
filter: {
|
|
893
|
+
"spec.profile.email": profile.email
|
|
894
|
+
}
|
|
895
|
+
});
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
});
|
|
899
|
+
commonSignInResolvers2.emailLocalPartMatchingUserEntityName = createSignInResolverFactory({
|
|
900
|
+
create() {
|
|
901
|
+
return async (info, ctx) => {
|
|
902
|
+
const { profile } = info;
|
|
903
|
+
if (!profile.email) {
|
|
904
|
+
throw new Error(
|
|
905
|
+
"Login failed, user profile does not contain an email"
|
|
906
|
+
);
|
|
907
|
+
}
|
|
908
|
+
const [localPart] = profile.email.split("@");
|
|
909
|
+
return ctx.signInWithCatalogUser({
|
|
910
|
+
entityRef: { name: localPart }
|
|
911
|
+
});
|
|
912
|
+
};
|
|
913
|
+
}
|
|
914
|
+
});
|
|
915
|
+
})(exports.commonSignInResolvers || (exports.commonSignInResolvers = {}));
|
|
916
|
+
|
|
917
|
+
function createOAuthProviderFactory(options) {
|
|
918
|
+
return (ctx) => {
|
|
919
|
+
return OAuthEnvironmentHandler.mapConfig(ctx.config, (envConfig) => {
|
|
920
|
+
var _a, _b;
|
|
921
|
+
const signInResolver = (_b = options.signInResolver) != null ? _b : readDeclarativeSignInResolver({
|
|
922
|
+
config: envConfig,
|
|
923
|
+
signInResolverFactories: (_a = options.signInResolverFactories) != null ? _a : {}
|
|
924
|
+
});
|
|
925
|
+
return createOAuthRouteHandlers({
|
|
926
|
+
authenticator: options.authenticator,
|
|
927
|
+
appUrl: ctx.appUrl,
|
|
928
|
+
baseUrl: ctx.baseUrl,
|
|
929
|
+
config: envConfig,
|
|
930
|
+
isOriginAllowed: ctx.isOriginAllowed,
|
|
931
|
+
cookieConfigurer: ctx.cookieConfigurer,
|
|
932
|
+
providerId: ctx.providerId,
|
|
933
|
+
resolverContext: ctx.resolverContext,
|
|
934
|
+
stateTransform: options.stateTransform,
|
|
935
|
+
profileTransform: options.profileTransform,
|
|
936
|
+
signInResolver
|
|
937
|
+
});
|
|
938
|
+
});
|
|
939
|
+
};
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
function createOAuthAuthenticator(authenticator) {
|
|
943
|
+
return authenticator;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
function createProxyAuthenticator(authenticator) {
|
|
947
|
+
return authenticator;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
function createProxyAuthRouteHandlers(options) {
|
|
951
|
+
var _a;
|
|
952
|
+
const { authenticator, config, resolverContext, signInResolver } = options;
|
|
953
|
+
const profileTransform = (_a = options.profileTransform) != null ? _a : authenticator.defaultProfileTransform;
|
|
954
|
+
const authenticatorCtx = authenticator.initialize({ config });
|
|
955
|
+
return {
|
|
956
|
+
async start() {
|
|
957
|
+
throw new errors.NotImplementedError("Not implemented");
|
|
958
|
+
},
|
|
959
|
+
async frameHandler() {
|
|
960
|
+
throw new errors.NotImplementedError("Not implemented");
|
|
961
|
+
},
|
|
962
|
+
async refresh(req, res) {
|
|
963
|
+
const { result } = await authenticator.authenticate(
|
|
964
|
+
{ req },
|
|
965
|
+
authenticatorCtx
|
|
966
|
+
);
|
|
967
|
+
const { profile } = await profileTransform(result, resolverContext);
|
|
968
|
+
const identity = await signInResolver(
|
|
969
|
+
{ profile, result },
|
|
970
|
+
resolverContext
|
|
971
|
+
);
|
|
972
|
+
const response = {
|
|
973
|
+
profile,
|
|
974
|
+
providerInfo: {},
|
|
975
|
+
backstageIdentity: prepareBackstageIdentityResponse(identity)
|
|
976
|
+
};
|
|
977
|
+
res.status(200).json(response);
|
|
978
|
+
}
|
|
979
|
+
};
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
function createProxyAuthProviderFactory(options) {
|
|
983
|
+
return (ctx) => {
|
|
984
|
+
var _a, _b;
|
|
985
|
+
const signInResolver = (_b = options.signInResolver) != null ? _b : readDeclarativeSignInResolver({
|
|
986
|
+
config: ctx.config,
|
|
987
|
+
signInResolverFactories: (_a = options.signInResolverFactories) != null ? _a : {}
|
|
988
|
+
});
|
|
989
|
+
if (!signInResolver) {
|
|
990
|
+
throw new Error(
|
|
991
|
+
`No sign-in resolver configured for proxy auth provider '${ctx.providerId}'`
|
|
992
|
+
);
|
|
993
|
+
}
|
|
994
|
+
return createProxyAuthRouteHandlers({
|
|
995
|
+
signInResolver,
|
|
996
|
+
config: ctx.config,
|
|
997
|
+
authenticator: options.authenticator,
|
|
998
|
+
resolverContext: ctx.resolverContext,
|
|
999
|
+
profileTransform: options.profileTransform
|
|
1000
|
+
});
|
|
1001
|
+
};
|
|
1002
|
+
}
|
|
1003
|
+
|
|
144
1004
|
exports.DefaultIdentityClient = DefaultIdentityClient;
|
|
145
1005
|
exports.IdentityClient = IdentityClient;
|
|
1006
|
+
exports.OAuthEnvironmentHandler = OAuthEnvironmentHandler;
|
|
1007
|
+
exports.PassportHelpers = PassportHelpers;
|
|
1008
|
+
exports.PassportOAuthAuthenticatorHelper = PassportOAuthAuthenticatorHelper;
|
|
1009
|
+
exports.authProvidersExtensionPoint = authProvidersExtensionPoint;
|
|
1010
|
+
exports.createOAuthAuthenticator = createOAuthAuthenticator;
|
|
1011
|
+
exports.createOAuthProviderFactory = createOAuthProviderFactory;
|
|
1012
|
+
exports.createOAuthRouteHandlers = createOAuthRouteHandlers;
|
|
1013
|
+
exports.createProxyAuthProviderFactory = createProxyAuthProviderFactory;
|
|
1014
|
+
exports.createProxyAuthRouteHandlers = createProxyAuthRouteHandlers;
|
|
1015
|
+
exports.createProxyAuthenticator = createProxyAuthenticator;
|
|
1016
|
+
exports.createSignInResolverFactory = createSignInResolverFactory;
|
|
1017
|
+
exports.decodeOAuthState = decodeOAuthState;
|
|
1018
|
+
exports.encodeOAuthState = encodeOAuthState;
|
|
146
1019
|
exports.getBearerTokenFromAuthorizationHeader = getBearerTokenFromAuthorizationHeader;
|
|
1020
|
+
exports.prepareBackstageIdentityResponse = prepareBackstageIdentityResponse;
|
|
1021
|
+
exports.readDeclarativeSignInResolver = readDeclarativeSignInResolver;
|
|
1022
|
+
exports.sendWebMessageResponse = sendWebMessageResponse;
|
|
147
1023
|
//# sourceMappingURL=index.cjs.js.map
|