@backstage/plugin-auth-backend 0.0.0-nightly-202111222339 → 0.0.0-nightly-202111922557
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 +26 -6
- package/dist/index.cjs.js +438 -327
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +119 -20
- package/package.json +7 -7
package/dist/index.cjs.js
CHANGED
|
@@ -17,12 +17,12 @@ var passportGoogleOauth20 = require('passport-google-oauth20');
|
|
|
17
17
|
var passportMicrosoft = require('passport-microsoft');
|
|
18
18
|
var got = require('got');
|
|
19
19
|
var OAuth2Strategy = require('passport-oauth2');
|
|
20
|
+
var openidClient = require('openid-client');
|
|
20
21
|
var passportOktaOauth = require('passport-okta-oauth');
|
|
21
22
|
var passportBitbucketOauth2 = require('passport-bitbucket-oauth2');
|
|
22
23
|
var fetch = require('node-fetch');
|
|
23
24
|
var NodeCache = require('node-cache');
|
|
24
25
|
var jose = require('jose');
|
|
25
|
-
var openidClient = require('openid-client');
|
|
26
26
|
var passportSaml = require('passport-saml');
|
|
27
27
|
var passportOneloginOauth = require('passport-onelogin-oauth');
|
|
28
28
|
var catalogClient = require('@backstage/catalog-client');
|
|
@@ -46,14 +46,12 @@ function _interopNamespace(e) {
|
|
|
46
46
|
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
47
47
|
Object.defineProperty(n, k, d.get ? d : {
|
|
48
48
|
enumerable: true,
|
|
49
|
-
get: function () {
|
|
50
|
-
return e[k];
|
|
51
|
-
}
|
|
49
|
+
get: function () { return e[k]; }
|
|
52
50
|
});
|
|
53
51
|
}
|
|
54
52
|
});
|
|
55
53
|
}
|
|
56
|
-
n[
|
|
54
|
+
n["default"] = e;
|
|
57
55
|
return Object.freeze(n);
|
|
58
56
|
}
|
|
59
57
|
|
|
@@ -88,7 +86,7 @@ const makeProfileInfo = (profile, idToken) => {
|
|
|
88
86
|
let displayName = (_b = (_a = profile.displayName) != null ? _a : profile.username) != null ? _b : profile.id;
|
|
89
87
|
if ((!email || !picture || !displayName) && idToken) {
|
|
90
88
|
try {
|
|
91
|
-
const decoded = jwtDecoder__default[
|
|
89
|
+
const decoded = jwtDecoder__default["default"](idToken);
|
|
92
90
|
if (!email && decoded.email) {
|
|
93
91
|
email = decoded.email;
|
|
94
92
|
}
|
|
@@ -112,16 +110,16 @@ const executeRedirectStrategy = async (req, providerStrategy, options) => {
|
|
|
112
110
|
return new Promise((resolve) => {
|
|
113
111
|
const strategy = Object.create(providerStrategy);
|
|
114
112
|
strategy.redirect = (url, status) => {
|
|
115
|
-
resolve({url, status: status != null ? status : void 0});
|
|
113
|
+
resolve({ url, status: status != null ? status : void 0 });
|
|
116
114
|
};
|
|
117
|
-
strategy.authenticate(req, {...options});
|
|
115
|
+
strategy.authenticate(req, { ...options });
|
|
118
116
|
});
|
|
119
117
|
};
|
|
120
118
|
const executeFrameHandlerStrategy = async (req, providerStrategy) => {
|
|
121
119
|
return new Promise((resolve, reject) => {
|
|
122
120
|
const strategy = Object.create(providerStrategy);
|
|
123
121
|
strategy.success = (result, privateInfo) => {
|
|
124
|
-
resolve({result, privateInfo});
|
|
122
|
+
resolve({ result, privateInfo });
|
|
125
123
|
};
|
|
126
124
|
strategy.fail = (info) => {
|
|
127
125
|
var _a;
|
|
@@ -193,7 +191,7 @@ const readState = (stateString) => {
|
|
|
193
191
|
return state;
|
|
194
192
|
};
|
|
195
193
|
const encodeState = (state) => {
|
|
196
|
-
const stateString = new URLSearchParams(pickBy__default[
|
|
194
|
+
const stateString = new URLSearchParams(pickBy__default["default"](state, (value) => value !== void 0)).toString();
|
|
197
195
|
return Buffer.from(stateString, "utf-8").toString("hex");
|
|
198
196
|
};
|
|
199
197
|
const verifyNonce = (req, providerId) => {
|
|
@@ -218,7 +216,7 @@ class OAuthEnvironmentHandler {
|
|
|
218
216
|
}
|
|
219
217
|
static mapConfig(config, factoryFunc) {
|
|
220
218
|
const envs = config.keys();
|
|
221
|
-
const handlers = new Map();
|
|
219
|
+
const handlers = /* @__PURE__ */ new Map();
|
|
222
220
|
for (const env of envs) {
|
|
223
221
|
const envConfig = config.getConfig(env);
|
|
224
222
|
const handler = factoryFunc(envConfig);
|
|
@@ -287,11 +285,11 @@ const postMessageResponse = (res, appOrigin, response) => {
|
|
|
287
285
|
window.close();
|
|
288
286
|
}, 100); // same as the interval of the core-app-api lib/loginPopup.ts (to address race conditions)
|
|
289
287
|
`;
|
|
290
|
-
const hash = crypto__default[
|
|
288
|
+
const hash = crypto__default["default"].createHash("sha256").update(script).digest("base64");
|
|
291
289
|
res.setHeader("Content-Type", "text/html");
|
|
292
290
|
res.setHeader("X-Frame-Options", "sameorigin");
|
|
293
291
|
res.setHeader("Content-Security-Policy", `script-src 'sha256-${hash}'`);
|
|
294
|
-
res.end(`<html><body><script>${script}
|
|
292
|
+
res.end(`<html><body><script>${script}<\/script></body></html>`);
|
|
295
293
|
};
|
|
296
294
|
const ensuresXRequestedWith = (req) => {
|
|
297
295
|
const requiredHeader = req.header("X-Requested-With");
|
|
@@ -301,6 +299,25 @@ const ensuresXRequestedWith = (req) => {
|
|
|
301
299
|
return true;
|
|
302
300
|
};
|
|
303
301
|
|
|
302
|
+
function parseJwtPayload(token) {
|
|
303
|
+
const [_header, payload, _signature] = token.split(".");
|
|
304
|
+
return JSON.parse(Buffer.from(payload, "base64").toString());
|
|
305
|
+
}
|
|
306
|
+
function prepareBackstageIdentityResponse(result) {
|
|
307
|
+
const { sub, ent } = parseJwtPayload(result.token);
|
|
308
|
+
return {
|
|
309
|
+
...{
|
|
310
|
+
idToken: result.token,
|
|
311
|
+
...result
|
|
312
|
+
},
|
|
313
|
+
identity: {
|
|
314
|
+
type: "user",
|
|
315
|
+
userEntityRef: sub,
|
|
316
|
+
ownershipEntityRefs: ent != null ? ent : []
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
304
321
|
const THOUSAND_DAYS_MS = 1e3 * 24 * 60 * 60 * 1e3;
|
|
305
322
|
const TEN_MINUTES_MS = 600 * 1e3;
|
|
306
323
|
class OAuthAdapter {
|
|
@@ -352,7 +369,7 @@ class OAuthAdapter {
|
|
|
352
369
|
};
|
|
353
370
|
}
|
|
354
371
|
static fromConfig(config, handlers, options) {
|
|
355
|
-
const {origin: appOrigin} = new url.URL(config.appUrl);
|
|
372
|
+
const { origin: appOrigin } = new url.URL(config.appUrl);
|
|
356
373
|
const secure = config.baseUrl.startsWith("https://");
|
|
357
374
|
const url$1 = new url.URL(config.baseUrl);
|
|
358
375
|
const cookiePath = `${url$1.pathname}/${options.providerId}`;
|
|
@@ -376,11 +393,11 @@ class OAuthAdapter {
|
|
|
376
393
|
if (this.options.persistScopes) {
|
|
377
394
|
this.setScopesCookie(res, scope);
|
|
378
395
|
}
|
|
379
|
-
const nonce = crypto__default[
|
|
396
|
+
const nonce = crypto__default["default"].randomBytes(16).toString("base64");
|
|
380
397
|
this.setNonceCookie(res, nonce);
|
|
381
|
-
const state = {nonce, env, origin};
|
|
382
|
-
const forwardReq = Object.assign(req, {scope, state});
|
|
383
|
-
const {url, status} = await this.handlers.start(forwardReq);
|
|
398
|
+
const state = { nonce, env, origin };
|
|
399
|
+
const forwardReq = Object.assign(req, { scope, state });
|
|
400
|
+
const { url, status } = await this.handlers.start(forwardReq);
|
|
384
401
|
res.statusCode = status || 302;
|
|
385
402
|
res.setHeader("Location", url);
|
|
386
403
|
res.setHeader("Content-Length", "0");
|
|
@@ -402,7 +419,7 @@ class OAuthAdapter {
|
|
|
402
419
|
}
|
|
403
420
|
}
|
|
404
421
|
verifyNonce(req, this.options.providerId);
|
|
405
|
-
const {response, refreshToken} = await this.handlers.handler(req);
|
|
422
|
+
const { response, refreshToken } = await this.handlers.handler(req);
|
|
406
423
|
if (this.options.persistScopes) {
|
|
407
424
|
const grantedScopes = this.getScopesFromCookie(req, this.options.providerId);
|
|
408
425
|
response.providerInfo.scope = grantedScopes;
|
|
@@ -410,16 +427,16 @@ class OAuthAdapter {
|
|
|
410
427
|
if (refreshToken && !this.options.disableRefresh) {
|
|
411
428
|
this.setRefreshTokenCookie(res, refreshToken);
|
|
412
429
|
}
|
|
413
|
-
await this.populateIdentity(response.backstageIdentity);
|
|
430
|
+
const identity = await this.populateIdentity(response.backstageIdentity);
|
|
414
431
|
return postMessageResponse(res, appOrigin, {
|
|
415
432
|
type: "authorization_response",
|
|
416
|
-
response
|
|
433
|
+
response: { ...response, backstageIdentity: identity }
|
|
417
434
|
});
|
|
418
435
|
} catch (error) {
|
|
419
|
-
const {name, message} = errors.isError(error) ? error : new Error("Encountered invalid error");
|
|
436
|
+
const { name, message } = errors.isError(error) ? error : new Error("Encountered invalid error");
|
|
420
437
|
return postMessageResponse(res, appOrigin, {
|
|
421
438
|
type: "authorization_response",
|
|
422
|
-
error: {name, message}
|
|
439
|
+
error: { name, message }
|
|
423
440
|
});
|
|
424
441
|
}
|
|
425
442
|
}
|
|
@@ -444,28 +461,28 @@ class OAuthAdapter {
|
|
|
444
461
|
throw new errors.InputError("Missing session cookie");
|
|
445
462
|
}
|
|
446
463
|
const scope = (_b = (_a = req.query.scope) == null ? void 0 : _a.toString()) != null ? _b : "";
|
|
447
|
-
const forwardReq = Object.assign(req, {scope, refreshToken});
|
|
464
|
+
const forwardReq = Object.assign(req, { scope, refreshToken });
|
|
448
465
|
const response = await this.handlers.refresh(forwardReq);
|
|
449
|
-
await this.populateIdentity(response.backstageIdentity);
|
|
466
|
+
const backstageIdentity = await this.populateIdentity(response.backstageIdentity);
|
|
450
467
|
if (response.providerInfo.refreshToken && response.providerInfo.refreshToken !== refreshToken) {
|
|
451
468
|
this.setRefreshTokenCookie(res, response.providerInfo.refreshToken);
|
|
452
469
|
}
|
|
453
|
-
res.status(200).json(response);
|
|
470
|
+
res.status(200).json({ ...response, backstageIdentity });
|
|
454
471
|
} catch (error) {
|
|
455
472
|
throw new errors.AuthenticationError("Refresh failed", error);
|
|
456
473
|
}
|
|
457
474
|
}
|
|
458
475
|
async populateIdentity(identity) {
|
|
459
476
|
if (!identity) {
|
|
460
|
-
return;
|
|
477
|
+
return void 0;
|
|
461
478
|
}
|
|
462
|
-
if (
|
|
463
|
-
|
|
464
|
-
claims: {sub: identity.id}
|
|
465
|
-
});
|
|
466
|
-
} else if (!identity.token && identity.idToken) {
|
|
467
|
-
identity.token = identity.idToken;
|
|
479
|
+
if (identity.token) {
|
|
480
|
+
return prepareBackstageIdentityResponse(identity);
|
|
468
481
|
}
|
|
482
|
+
const token = await this.options.tokenIssuer.issueToken({
|
|
483
|
+
claims: { sub: identity.id }
|
|
484
|
+
});
|
|
485
|
+
return prepareBackstageIdentityResponse({ ...identity, token });
|
|
469
486
|
}
|
|
470
487
|
}
|
|
471
488
|
|
|
@@ -482,9 +499,9 @@ class CatalogIdentityClient {
|
|
|
482
499
|
filter[`metadata.annotations.${key}`] = value;
|
|
483
500
|
}
|
|
484
501
|
const token = await this.tokenIssuer.issueToken({
|
|
485
|
-
claims: {sub: "backstage.io/auth-backend"}
|
|
502
|
+
claims: { sub: "backstage.io/auth-backend" }
|
|
486
503
|
});
|
|
487
|
-
const {items} = await this.catalogApi.getEntities({filter}, {token});
|
|
504
|
+
const { items } = await this.catalogApi.getEntities({ filter }, { token });
|
|
488
505
|
if (items.length !== 1) {
|
|
489
506
|
if (items.length > 1) {
|
|
490
507
|
throw new errors.ConflictError("User lookup resulted in multiple matches");
|
|
@@ -494,10 +511,8 @@ class CatalogIdentityClient {
|
|
|
494
511
|
}
|
|
495
512
|
return items[0];
|
|
496
513
|
}
|
|
497
|
-
async resolveCatalogMembership({
|
|
498
|
-
entityRefs,
|
|
499
|
-
logger
|
|
500
|
-
}) {
|
|
514
|
+
async resolveCatalogMembership(query) {
|
|
515
|
+
const { entityRefs, logger } = query;
|
|
501
516
|
const resolvedEntityRefs = entityRefs.map((ref) => {
|
|
502
517
|
try {
|
|
503
518
|
const parsedRef = catalogModel.parseEntityRef(ref.toLocaleLowerCase("en-US"), {
|
|
@@ -515,7 +530,7 @@ class CatalogIdentityClient {
|
|
|
515
530
|
"metadata.namespace": ref.namespace,
|
|
516
531
|
"metadata.name": ref.name
|
|
517
532
|
}));
|
|
518
|
-
const entities = await this.catalogApi.getEntities({filter}).then((r) => r.items);
|
|
533
|
+
const entities = await this.catalogApi.getEntities({ filter }).then((r) => r.items);
|
|
519
534
|
if (entityRefs.length !== entities.length) {
|
|
520
535
|
const foundEntityNames = entities.map(catalogModel.stringifyEntityRef);
|
|
521
536
|
const missingEntityNames = resolvedEntityRefs.map(catalogModel.stringifyEntityRef).filter((s) => !foundEntityNames.includes(s));
|
|
@@ -559,7 +574,7 @@ class GithubAuthProvider {
|
|
|
559
574
|
userProfileURL: options.userProfileUrl,
|
|
560
575
|
authorizationURL: options.authorizationUrl
|
|
561
576
|
}, (accessToken, refreshToken, params, fullProfile, done) => {
|
|
562
|
-
done(void 0, {fullProfile, params, accessToken}, {refreshToken});
|
|
577
|
+
done(void 0, { fullProfile, params, accessToken }, { refreshToken });
|
|
563
578
|
});
|
|
564
579
|
}
|
|
565
580
|
async start(req) {
|
|
@@ -569,7 +584,7 @@ class GithubAuthProvider {
|
|
|
569
584
|
});
|
|
570
585
|
}
|
|
571
586
|
async handler(req) {
|
|
572
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
587
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
573
588
|
return {
|
|
574
589
|
response: await this.handleResult(result),
|
|
575
590
|
refreshToken: privateInfo.refreshToken
|
|
@@ -590,7 +605,7 @@ class GithubAuthProvider {
|
|
|
590
605
|
});
|
|
591
606
|
}
|
|
592
607
|
async handleResult(result) {
|
|
593
|
-
const {profile} = await this.authHandler(result);
|
|
608
|
+
const { profile } = await this.authHandler(result);
|
|
594
609
|
const expiresInStr = result.params.expires_in;
|
|
595
610
|
const response = {
|
|
596
611
|
providerInfo: {
|
|
@@ -615,12 +630,12 @@ class GithubAuthProvider {
|
|
|
615
630
|
}
|
|
616
631
|
}
|
|
617
632
|
const githubDefaultSignInResolver = async (info, ctx) => {
|
|
618
|
-
const {fullProfile} = info.result;
|
|
633
|
+
const { fullProfile } = info.result;
|
|
619
634
|
const userId = fullProfile.username || fullProfile.id;
|
|
620
635
|
const token = await ctx.tokenIssuer.issueToken({
|
|
621
|
-
claims: {sub: userId, ent: [`user:default/${userId}`]}
|
|
636
|
+
claims: { sub: userId, ent: [`user:default/${userId}`] }
|
|
622
637
|
});
|
|
623
|
-
return {id: userId, token};
|
|
638
|
+
return { id: userId, token };
|
|
624
639
|
};
|
|
625
640
|
const createGithubProvider = (options) => {
|
|
626
641
|
return ({
|
|
@@ -644,7 +659,7 @@ const createGithubProvider = (options) => {
|
|
|
644
659
|
catalogApi,
|
|
645
660
|
tokenIssuer
|
|
646
661
|
});
|
|
647
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile}) => ({
|
|
662
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
648
663
|
profile: makeProfileInfo(fullProfile)
|
|
649
664
|
});
|
|
650
665
|
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : githubDefaultSignInResolver;
|
|
@@ -654,7 +669,7 @@ const createGithubProvider = (options) => {
|
|
|
654
669
|
logger
|
|
655
670
|
});
|
|
656
671
|
const stateEncoder = (_c = options == null ? void 0 : options.stateEncoder) != null ? _c : async (req) => {
|
|
657
|
-
return {encodedState: encodeState(req.state)};
|
|
672
|
+
return { encodedState: encodeState(req.state) };
|
|
658
673
|
};
|
|
659
674
|
const provider = new GithubAuthProvider({
|
|
660
675
|
clientId,
|
|
@@ -679,15 +694,15 @@ const createGithubProvider = (options) => {
|
|
|
679
694
|
};
|
|
680
695
|
|
|
681
696
|
const gitlabDefaultSignInResolver = async (info, ctx) => {
|
|
682
|
-
const {profile, result} = info;
|
|
697
|
+
const { profile, result } = info;
|
|
683
698
|
let id = result.fullProfile.id;
|
|
684
699
|
if (profile.email) {
|
|
685
700
|
id = profile.email.split("@")[0];
|
|
686
701
|
}
|
|
687
702
|
const token = await ctx.tokenIssuer.issueToken({
|
|
688
|
-
claims: {sub: id, ent: [`user:default/${id}`]}
|
|
703
|
+
claims: { sub: id, ent: [`user:default/${id}`] }
|
|
689
704
|
});
|
|
690
|
-
return {id, token};
|
|
705
|
+
return { id, token };
|
|
691
706
|
};
|
|
692
707
|
const gitlabDefaultAuthHandler = async ({
|
|
693
708
|
fullProfile,
|
|
@@ -708,7 +723,7 @@ class GitlabAuthProvider {
|
|
|
708
723
|
callbackURL: options.callbackUrl,
|
|
709
724
|
baseURL: options.baseUrl
|
|
710
725
|
}, (accessToken, refreshToken, params, fullProfile, done) => {
|
|
711
|
-
done(void 0, {fullProfile, params, accessToken}, {
|
|
726
|
+
done(void 0, { fullProfile, params, accessToken }, {
|
|
712
727
|
refreshToken
|
|
713
728
|
});
|
|
714
729
|
});
|
|
@@ -720,7 +735,7 @@ class GitlabAuthProvider {
|
|
|
720
735
|
});
|
|
721
736
|
}
|
|
722
737
|
async handler(req) {
|
|
723
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
738
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
724
739
|
return {
|
|
725
740
|
response: await this.handleResult(result),
|
|
726
741
|
refreshToken: privateInfo.refreshToken
|
|
@@ -741,7 +756,7 @@ class GitlabAuthProvider {
|
|
|
741
756
|
});
|
|
742
757
|
}
|
|
743
758
|
async handleResult(result) {
|
|
744
|
-
const {profile} = await this.authHandler(result);
|
|
759
|
+
const { profile } = await this.authHandler(result);
|
|
745
760
|
const response = {
|
|
746
761
|
providerInfo: {
|
|
747
762
|
idToken: result.params.id_token,
|
|
@@ -842,14 +857,14 @@ class GoogleAuthProvider {
|
|
|
842
857
|
});
|
|
843
858
|
}
|
|
844
859
|
async handler(req) {
|
|
845
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
860
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
846
861
|
return {
|
|
847
862
|
response: await this.handleResult(result),
|
|
848
863
|
refreshToken: privateInfo.refreshToken
|
|
849
864
|
};
|
|
850
865
|
}
|
|
851
866
|
async refresh(req) {
|
|
852
|
-
const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
867
|
+
const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
853
868
|
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
|
|
854
869
|
return this.handleResult({
|
|
855
870
|
fullProfile,
|
|
@@ -859,7 +874,7 @@ class GoogleAuthProvider {
|
|
|
859
874
|
});
|
|
860
875
|
}
|
|
861
876
|
async handleResult(result) {
|
|
862
|
-
const {profile} = await this.authHandler(result);
|
|
877
|
+
const { profile } = await this.authHandler(result);
|
|
863
878
|
const response = {
|
|
864
879
|
providerInfo: {
|
|
865
880
|
idToken: result.params.id_token,
|
|
@@ -883,7 +898,7 @@ class GoogleAuthProvider {
|
|
|
883
898
|
}
|
|
884
899
|
}
|
|
885
900
|
const googleEmailSignInResolver = async (info, ctx) => {
|
|
886
|
-
const {profile} = info;
|
|
901
|
+
const { profile } = info;
|
|
887
902
|
if (!profile.email) {
|
|
888
903
|
throw new Error("Google profile contained no email");
|
|
889
904
|
}
|
|
@@ -893,11 +908,11 @@ const googleEmailSignInResolver = async (info, ctx) => {
|
|
|
893
908
|
}
|
|
894
909
|
});
|
|
895
910
|
const claims = getEntityClaims(entity);
|
|
896
|
-
const token = await ctx.tokenIssuer.issueToken({claims});
|
|
897
|
-
return {id: entity.metadata.name, entity, token};
|
|
911
|
+
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
912
|
+
return { id: entity.metadata.name, entity, token };
|
|
898
913
|
};
|
|
899
914
|
const googleDefaultSignInResolver = async (info, ctx) => {
|
|
900
|
-
const {profile} = info;
|
|
915
|
+
const { profile } = info;
|
|
901
916
|
if (!profile.email) {
|
|
902
917
|
throw new Error("Google profile contained no email");
|
|
903
918
|
}
|
|
@@ -914,9 +929,9 @@ const googleDefaultSignInResolver = async (info, ctx) => {
|
|
|
914
929
|
userId = profile.email.split("@")[0];
|
|
915
930
|
}
|
|
916
931
|
const token = await ctx.tokenIssuer.issueToken({
|
|
917
|
-
claims: {sub: userId, ent: [`user:default/${userId}`]}
|
|
932
|
+
claims: { sub: userId, ent: [`user:default/${userId}`] }
|
|
918
933
|
});
|
|
919
|
-
return {id: userId, token};
|
|
934
|
+
return { id: userId, token };
|
|
920
935
|
};
|
|
921
936
|
const createGoogleProvider = (options) => {
|
|
922
937
|
return ({
|
|
@@ -935,7 +950,7 @@ const createGoogleProvider = (options) => {
|
|
|
935
950
|
catalogApi,
|
|
936
951
|
tokenIssuer
|
|
937
952
|
});
|
|
938
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile, params}) => ({
|
|
953
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
939
954
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
940
955
|
});
|
|
941
956
|
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : googleDefaultSignInResolver;
|
|
@@ -977,7 +992,7 @@ class MicrosoftAuthProvider {
|
|
|
977
992
|
tokenURL: options.tokenUrl,
|
|
978
993
|
passReqToCallback: false
|
|
979
994
|
}, (accessToken, refreshToken, params, fullProfile, done) => {
|
|
980
|
-
done(void 0, {fullProfile, accessToken, params}, {refreshToken});
|
|
995
|
+
done(void 0, { fullProfile, accessToken, params }, { refreshToken });
|
|
981
996
|
});
|
|
982
997
|
}
|
|
983
998
|
async start(req) {
|
|
@@ -987,14 +1002,14 @@ class MicrosoftAuthProvider {
|
|
|
987
1002
|
});
|
|
988
1003
|
}
|
|
989
1004
|
async handler(req) {
|
|
990
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1005
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
991
1006
|
return {
|
|
992
1007
|
response: await this.handleResult(result),
|
|
993
1008
|
refreshToken: privateInfo.refreshToken
|
|
994
1009
|
};
|
|
995
1010
|
}
|
|
996
1011
|
async refresh(req) {
|
|
997
|
-
const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
1012
|
+
const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
998
1013
|
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
|
|
999
1014
|
return this.handleResult({
|
|
1000
1015
|
fullProfile,
|
|
@@ -1005,8 +1020,8 @@ class MicrosoftAuthProvider {
|
|
|
1005
1020
|
}
|
|
1006
1021
|
async handleResult(result) {
|
|
1007
1022
|
const photo = await this.getUserPhoto(result.accessToken);
|
|
1008
|
-
result.fullProfile.photos = photo ? [{value: photo}] : void 0;
|
|
1009
|
-
const {profile} = await this.authHandler(result);
|
|
1023
|
+
result.fullProfile.photos = photo ? [{ value: photo }] : void 0;
|
|
1024
|
+
const { profile } = await this.authHandler(result);
|
|
1010
1025
|
const response = {
|
|
1011
1026
|
providerInfo: {
|
|
1012
1027
|
idToken: result.params.id_token,
|
|
@@ -1030,7 +1045,7 @@ class MicrosoftAuthProvider {
|
|
|
1030
1045
|
}
|
|
1031
1046
|
getUserPhoto(accessToken) {
|
|
1032
1047
|
return new Promise((resolve) => {
|
|
1033
|
-
got__default[
|
|
1048
|
+
got__default["default"].get("https://graph.microsoft.com/v1.0/me/photos/48x48/$value", {
|
|
1034
1049
|
encoding: "binary",
|
|
1035
1050
|
responseType: "buffer",
|
|
1036
1051
|
headers: {
|
|
@@ -1047,7 +1062,7 @@ class MicrosoftAuthProvider {
|
|
|
1047
1062
|
}
|
|
1048
1063
|
}
|
|
1049
1064
|
const microsoftEmailSignInResolver = async (info, ctx) => {
|
|
1050
|
-
const {profile} = info;
|
|
1065
|
+
const { profile } = info;
|
|
1051
1066
|
if (!profile.email) {
|
|
1052
1067
|
throw new Error("Microsoft profile contained no email");
|
|
1053
1068
|
}
|
|
@@ -1057,19 +1072,19 @@ const microsoftEmailSignInResolver = async (info, ctx) => {
|
|
|
1057
1072
|
}
|
|
1058
1073
|
});
|
|
1059
1074
|
const claims = getEntityClaims(entity);
|
|
1060
|
-
const token = await ctx.tokenIssuer.issueToken({claims});
|
|
1061
|
-
return {id: entity.metadata.name, entity, token};
|
|
1075
|
+
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
1076
|
+
return { id: entity.metadata.name, entity, token };
|
|
1062
1077
|
};
|
|
1063
1078
|
const microsoftDefaultSignInResolver = async (info, ctx) => {
|
|
1064
|
-
const {profile} = info;
|
|
1079
|
+
const { profile } = info;
|
|
1065
1080
|
if (!profile.email) {
|
|
1066
1081
|
throw new Error("Profile contained no email");
|
|
1067
1082
|
}
|
|
1068
1083
|
const userId = profile.email.split("@")[0];
|
|
1069
1084
|
const token = await ctx.tokenIssuer.issueToken({
|
|
1070
|
-
claims: {sub: userId, ent: [`user:default/${userId}`]}
|
|
1085
|
+
claims: { sub: userId, ent: [`user:default/${userId}`] }
|
|
1071
1086
|
});
|
|
1072
|
-
return {id: userId, token};
|
|
1087
|
+
return { id: userId, token };
|
|
1073
1088
|
};
|
|
1074
1089
|
const createMicrosoftProvider = (options) => {
|
|
1075
1090
|
return ({
|
|
@@ -1091,7 +1106,7 @@ const createMicrosoftProvider = (options) => {
|
|
|
1091
1106
|
catalogApi,
|
|
1092
1107
|
tokenIssuer
|
|
1093
1108
|
});
|
|
1094
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile, params}) => ({
|
|
1109
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1095
1110
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1096
1111
|
});
|
|
1097
1112
|
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : microsoftDefaultSignInResolver;
|
|
@@ -1134,7 +1149,10 @@ class OAuth2AuthProvider {
|
|
|
1134
1149
|
authorizationURL: options.authorizationUrl,
|
|
1135
1150
|
tokenURL: options.tokenUrl,
|
|
1136
1151
|
passReqToCallback: false,
|
|
1137
|
-
scope: options.scope
|
|
1152
|
+
scope: options.scope,
|
|
1153
|
+
customHeaders: options.includeBasicAuth ? {
|
|
1154
|
+
Authorization: `Basic ${this.encodeClientCredentials(options.clientId, options.clientSecret)}`
|
|
1155
|
+
} : void 0
|
|
1138
1156
|
}, (accessToken, refreshToken, params, fullProfile, done) => {
|
|
1139
1157
|
done(void 0, {
|
|
1140
1158
|
fullProfile,
|
|
@@ -1155,7 +1173,7 @@ class OAuth2AuthProvider {
|
|
|
1155
1173
|
});
|
|
1156
1174
|
}
|
|
1157
1175
|
async handler(req) {
|
|
1158
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1176
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1159
1177
|
return {
|
|
1160
1178
|
response: await this.handleResult(result),
|
|
1161
1179
|
refreshToken: privateInfo.refreshToken
|
|
@@ -1177,7 +1195,7 @@ class OAuth2AuthProvider {
|
|
|
1177
1195
|
});
|
|
1178
1196
|
}
|
|
1179
1197
|
async handleResult(result) {
|
|
1180
|
-
const {profile} = await this.authHandler(result);
|
|
1198
|
+
const { profile } = await this.authHandler(result);
|
|
1181
1199
|
const response = {
|
|
1182
1200
|
providerInfo: {
|
|
1183
1201
|
idToken: result.params.id_token,
|
|
@@ -1200,17 +1218,20 @@ class OAuth2AuthProvider {
|
|
|
1200
1218
|
}
|
|
1201
1219
|
return response;
|
|
1202
1220
|
}
|
|
1221
|
+
encodeClientCredentials(clientID, clientSecret) {
|
|
1222
|
+
return Buffer.from(`${clientID}:${clientSecret}`).toString("base64");
|
|
1223
|
+
}
|
|
1203
1224
|
}
|
|
1204
|
-
const oAuth2DefaultSignInResolver = async (info, ctx) => {
|
|
1205
|
-
const {profile} = info;
|
|
1225
|
+
const oAuth2DefaultSignInResolver$1 = async (info, ctx) => {
|
|
1226
|
+
const { profile } = info;
|
|
1206
1227
|
if (!profile.email) {
|
|
1207
1228
|
throw new Error("Profile contained no email");
|
|
1208
1229
|
}
|
|
1209
1230
|
const userId = profile.email.split("@")[0];
|
|
1210
1231
|
const token = await ctx.tokenIssuer.issueToken({
|
|
1211
|
-
claims: {sub: userId, ent: [`user:default/${userId}`]}
|
|
1232
|
+
claims: { sub: userId, ent: [`user:default/${userId}`] }
|
|
1212
1233
|
});
|
|
1213
|
-
return {id: userId, token};
|
|
1234
|
+
return { id: userId, token };
|
|
1214
1235
|
};
|
|
1215
1236
|
const createOAuth2Provider = (options) => {
|
|
1216
1237
|
return ({
|
|
@@ -1228,15 +1249,16 @@ const createOAuth2Provider = (options) => {
|
|
|
1228
1249
|
const authorizationUrl = envConfig.getString("authorizationUrl");
|
|
1229
1250
|
const tokenUrl = envConfig.getString("tokenUrl");
|
|
1230
1251
|
const scope = envConfig.getOptionalString("scope");
|
|
1252
|
+
const includeBasicAuth = envConfig.getOptionalBoolean("includeBasicAuth");
|
|
1231
1253
|
const disableRefresh = (_a = envConfig.getOptionalBoolean("disableRefresh")) != null ? _a : false;
|
|
1232
1254
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1233
1255
|
catalogApi,
|
|
1234
1256
|
tokenIssuer
|
|
1235
1257
|
});
|
|
1236
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile, params}) => ({
|
|
1258
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1237
1259
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1238
1260
|
});
|
|
1239
|
-
const signInResolverFn = (_c = (_b = options == null ? void 0 : options.signIn) == null ? void 0 : _b.resolver) != null ? _c : oAuth2DefaultSignInResolver;
|
|
1261
|
+
const signInResolverFn = (_c = (_b = options == null ? void 0 : options.signIn) == null ? void 0 : _b.resolver) != null ? _c : oAuth2DefaultSignInResolver$1;
|
|
1240
1262
|
const signInResolver = (info) => signInResolverFn(info, {
|
|
1241
1263
|
catalogIdentityClient,
|
|
1242
1264
|
tokenIssuer,
|
|
@@ -1253,7 +1275,8 @@ const createOAuth2Provider = (options) => {
|
|
|
1253
1275
|
authorizationUrl,
|
|
1254
1276
|
tokenUrl,
|
|
1255
1277
|
scope,
|
|
1256
|
-
logger
|
|
1278
|
+
logger,
|
|
1279
|
+
includeBasicAuth
|
|
1257
1280
|
});
|
|
1258
1281
|
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1259
1282
|
disableRefresh,
|
|
@@ -1263,6 +1286,168 @@ const createOAuth2Provider = (options) => {
|
|
|
1263
1286
|
});
|
|
1264
1287
|
};
|
|
1265
1288
|
|
|
1289
|
+
class OidcAuthProvider {
|
|
1290
|
+
constructor(options) {
|
|
1291
|
+
this.implementation = this.setupStrategy(options);
|
|
1292
|
+
this.scope = options.scope;
|
|
1293
|
+
this.prompt = options.prompt;
|
|
1294
|
+
this.signInResolver = options.signInResolver;
|
|
1295
|
+
this.authHandler = options.authHandler;
|
|
1296
|
+
this.tokenIssuer = options.tokenIssuer;
|
|
1297
|
+
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
1298
|
+
this.logger = options.logger;
|
|
1299
|
+
}
|
|
1300
|
+
async start(req) {
|
|
1301
|
+
const { strategy } = await this.implementation;
|
|
1302
|
+
const options = {
|
|
1303
|
+
scope: req.scope || this.scope || "openid profile email",
|
|
1304
|
+
state: encodeState(req.state)
|
|
1305
|
+
};
|
|
1306
|
+
const prompt = this.prompt || "none";
|
|
1307
|
+
if (prompt !== "auto") {
|
|
1308
|
+
options.prompt = prompt;
|
|
1309
|
+
}
|
|
1310
|
+
return await executeRedirectStrategy(req, strategy, options);
|
|
1311
|
+
}
|
|
1312
|
+
async handler(req) {
|
|
1313
|
+
const { strategy } = await this.implementation;
|
|
1314
|
+
const strategyResponse = await executeFrameHandlerStrategy(req, strategy);
|
|
1315
|
+
const {
|
|
1316
|
+
result: { userinfo, tokenset },
|
|
1317
|
+
privateInfo
|
|
1318
|
+
} = strategyResponse;
|
|
1319
|
+
const identityResponse = await this.handleResult({ tokenset, userinfo });
|
|
1320
|
+
return {
|
|
1321
|
+
response: identityResponse,
|
|
1322
|
+
refreshToken: privateInfo.refreshToken
|
|
1323
|
+
};
|
|
1324
|
+
}
|
|
1325
|
+
async refresh(req) {
|
|
1326
|
+
const { client } = await this.implementation;
|
|
1327
|
+
const tokenset = await client.refresh(req.refreshToken);
|
|
1328
|
+
if (!tokenset.access_token) {
|
|
1329
|
+
throw new Error("Refresh failed");
|
|
1330
|
+
}
|
|
1331
|
+
const profile = await client.userinfo(tokenset.access_token);
|
|
1332
|
+
return this.handleResult({ tokenset, userinfo: profile });
|
|
1333
|
+
}
|
|
1334
|
+
async setupStrategy(options) {
|
|
1335
|
+
const issuer = await openidClient.Issuer.discover(options.metadataUrl);
|
|
1336
|
+
const client = new issuer.Client({
|
|
1337
|
+
access_type: "offline",
|
|
1338
|
+
client_id: options.clientId,
|
|
1339
|
+
client_secret: options.clientSecret,
|
|
1340
|
+
redirect_uris: [options.callbackUrl],
|
|
1341
|
+
response_types: ["code"],
|
|
1342
|
+
id_token_signed_response_alg: options.tokenSignedResponseAlg || "RS256",
|
|
1343
|
+
scope: options.scope || ""
|
|
1344
|
+
});
|
|
1345
|
+
const strategy = new openidClient.Strategy({
|
|
1346
|
+
client,
|
|
1347
|
+
passReqToCallback: false
|
|
1348
|
+
}, (tokenset, userinfo, done) => {
|
|
1349
|
+
if (typeof done !== "function") {
|
|
1350
|
+
throw new Error("OIDC IdP must provide a userinfo_endpoint in the metadata response");
|
|
1351
|
+
}
|
|
1352
|
+
done(void 0, { tokenset, userinfo }, {
|
|
1353
|
+
refreshToken: tokenset.refresh_token
|
|
1354
|
+
});
|
|
1355
|
+
});
|
|
1356
|
+
strategy.error = console.error;
|
|
1357
|
+
return { strategy, client };
|
|
1358
|
+
}
|
|
1359
|
+
async handleResult(result) {
|
|
1360
|
+
const { profile } = await this.authHandler(result);
|
|
1361
|
+
const response = {
|
|
1362
|
+
providerInfo: {
|
|
1363
|
+
idToken: result.tokenset.id_token,
|
|
1364
|
+
accessToken: result.tokenset.access_token,
|
|
1365
|
+
refreshToken: result.tokenset.refresh_token,
|
|
1366
|
+
scope: result.tokenset.scope,
|
|
1367
|
+
expiresInSeconds: result.tokenset.expires_in
|
|
1368
|
+
},
|
|
1369
|
+
profile
|
|
1370
|
+
};
|
|
1371
|
+
if (this.signInResolver) {
|
|
1372
|
+
response.backstageIdentity = await this.signInResolver({
|
|
1373
|
+
result,
|
|
1374
|
+
profile
|
|
1375
|
+
}, {
|
|
1376
|
+
tokenIssuer: this.tokenIssuer,
|
|
1377
|
+
catalogIdentityClient: this.catalogIdentityClient,
|
|
1378
|
+
logger: this.logger
|
|
1379
|
+
});
|
|
1380
|
+
}
|
|
1381
|
+
return response;
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
const oAuth2DefaultSignInResolver = async (info, ctx) => {
|
|
1385
|
+
const { profile } = info;
|
|
1386
|
+
if (!profile.email) {
|
|
1387
|
+
throw new Error("Profile contained no email");
|
|
1388
|
+
}
|
|
1389
|
+
const userId = profile.email.split("@")[0];
|
|
1390
|
+
const token = await ctx.tokenIssuer.issueToken({
|
|
1391
|
+
claims: { sub: userId, ent: [`user:default/${userId}`] }
|
|
1392
|
+
});
|
|
1393
|
+
return { id: userId, token };
|
|
1394
|
+
};
|
|
1395
|
+
const createOidcProvider = (options) => {
|
|
1396
|
+
return ({
|
|
1397
|
+
providerId,
|
|
1398
|
+
globalConfig,
|
|
1399
|
+
config,
|
|
1400
|
+
tokenIssuer,
|
|
1401
|
+
catalogApi,
|
|
1402
|
+
logger
|
|
1403
|
+
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1404
|
+
var _a, _b;
|
|
1405
|
+
const clientId = envConfig.getString("clientId");
|
|
1406
|
+
const clientSecret = envConfig.getString("clientSecret");
|
|
1407
|
+
const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1408
|
+
const metadataUrl = envConfig.getString("metadataUrl");
|
|
1409
|
+
const tokenSignedResponseAlg = envConfig.getOptionalString("tokenSignedResponseAlg");
|
|
1410
|
+
const scope = envConfig.getOptionalString("scope");
|
|
1411
|
+
const prompt = envConfig.getOptionalString("prompt");
|
|
1412
|
+
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1413
|
+
catalogApi,
|
|
1414
|
+
tokenIssuer
|
|
1415
|
+
});
|
|
1416
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ userinfo }) => ({
|
|
1417
|
+
profile: {
|
|
1418
|
+
displayName: userinfo.name,
|
|
1419
|
+
email: userinfo.email,
|
|
1420
|
+
picture: userinfo.picture
|
|
1421
|
+
}
|
|
1422
|
+
});
|
|
1423
|
+
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : oAuth2DefaultSignInResolver;
|
|
1424
|
+
const signInResolver = (info) => signInResolverFn(info, {
|
|
1425
|
+
catalogIdentityClient,
|
|
1426
|
+
tokenIssuer,
|
|
1427
|
+
logger
|
|
1428
|
+
});
|
|
1429
|
+
const provider = new OidcAuthProvider({
|
|
1430
|
+
clientId,
|
|
1431
|
+
clientSecret,
|
|
1432
|
+
callbackUrl,
|
|
1433
|
+
tokenSignedResponseAlg,
|
|
1434
|
+
metadataUrl,
|
|
1435
|
+
scope,
|
|
1436
|
+
prompt,
|
|
1437
|
+
signInResolver,
|
|
1438
|
+
authHandler,
|
|
1439
|
+
logger,
|
|
1440
|
+
tokenIssuer,
|
|
1441
|
+
catalogIdentityClient
|
|
1442
|
+
});
|
|
1443
|
+
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1444
|
+
disableRefresh: false,
|
|
1445
|
+
providerId,
|
|
1446
|
+
tokenIssuer
|
|
1447
|
+
});
|
|
1448
|
+
});
|
|
1449
|
+
};
|
|
1450
|
+
|
|
1266
1451
|
class OktaAuthProvider {
|
|
1267
1452
|
constructor(options) {
|
|
1268
1453
|
this._store = {
|
|
@@ -1306,14 +1491,14 @@ class OktaAuthProvider {
|
|
|
1306
1491
|
});
|
|
1307
1492
|
}
|
|
1308
1493
|
async handler(req) {
|
|
1309
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1494
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1310
1495
|
return {
|
|
1311
1496
|
response: await this.handleResult(result),
|
|
1312
1497
|
refreshToken: privateInfo.refreshToken
|
|
1313
1498
|
};
|
|
1314
1499
|
}
|
|
1315
1500
|
async refresh(req) {
|
|
1316
|
-
const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
1501
|
+
const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
1317
1502
|
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
|
|
1318
1503
|
return this.handleResult({
|
|
1319
1504
|
fullProfile,
|
|
@@ -1323,7 +1508,7 @@ class OktaAuthProvider {
|
|
|
1323
1508
|
});
|
|
1324
1509
|
}
|
|
1325
1510
|
async handleResult(result) {
|
|
1326
|
-
const {profile} = await this._authHandler(result);
|
|
1511
|
+
const { profile } = await this._authHandler(result);
|
|
1327
1512
|
const response = {
|
|
1328
1513
|
providerInfo: {
|
|
1329
1514
|
idToken: result.params.id_token,
|
|
@@ -1347,7 +1532,7 @@ class OktaAuthProvider {
|
|
|
1347
1532
|
}
|
|
1348
1533
|
}
|
|
1349
1534
|
const oktaEmailSignInResolver = async (info, ctx) => {
|
|
1350
|
-
const {profile} = info;
|
|
1535
|
+
const { profile } = info;
|
|
1351
1536
|
if (!profile.email) {
|
|
1352
1537
|
throw new Error("Okta profile contained no email");
|
|
1353
1538
|
}
|
|
@@ -1357,19 +1542,19 @@ const oktaEmailSignInResolver = async (info, ctx) => {
|
|
|
1357
1542
|
}
|
|
1358
1543
|
});
|
|
1359
1544
|
const claims = getEntityClaims(entity);
|
|
1360
|
-
const token = await ctx.tokenIssuer.issueToken({claims});
|
|
1361
|
-
return {id: entity.metadata.name, entity, token};
|
|
1545
|
+
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
1546
|
+
return { id: entity.metadata.name, entity, token };
|
|
1362
1547
|
};
|
|
1363
1548
|
const oktaDefaultSignInResolver = async (info, ctx) => {
|
|
1364
|
-
const {profile} = info;
|
|
1549
|
+
const { profile } = info;
|
|
1365
1550
|
if (!profile.email) {
|
|
1366
1551
|
throw new Error("Okta profile contained no email");
|
|
1367
1552
|
}
|
|
1368
1553
|
const userId = profile.email.split("@")[0];
|
|
1369
1554
|
const token = await ctx.tokenIssuer.issueToken({
|
|
1370
|
-
claims: {sub: userId, ent: [`user:default/${userId}`]}
|
|
1555
|
+
claims: { sub: userId, ent: [`user:default/${userId}`] }
|
|
1371
1556
|
});
|
|
1372
|
-
return {id: userId, token};
|
|
1557
|
+
return { id: userId, token };
|
|
1373
1558
|
};
|
|
1374
1559
|
const createOktaProvider = (_options) => {
|
|
1375
1560
|
return ({
|
|
@@ -1392,7 +1577,7 @@ const createOktaProvider = (_options) => {
|
|
|
1392
1577
|
catalogApi,
|
|
1393
1578
|
tokenIssuer
|
|
1394
1579
|
});
|
|
1395
|
-
const authHandler = (_options == null ? void 0 : _options.authHandler) ? _options.authHandler : async ({fullProfile, params}) => ({
|
|
1580
|
+
const authHandler = (_options == null ? void 0 : _options.authHandler) ? _options.authHandler : async ({ fullProfile, params }) => ({
|
|
1396
1581
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1397
1582
|
});
|
|
1398
1583
|
const signInResolverFn = (_b = (_a = _options == null ? void 0 : _options.signIn) == null ? void 0 : _a.resolver) != null ? _b : oktaDefaultSignInResolver;
|
|
@@ -1452,14 +1637,14 @@ class BitbucketAuthProvider {
|
|
|
1452
1637
|
});
|
|
1453
1638
|
}
|
|
1454
1639
|
async handler(req) {
|
|
1455
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1640
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1456
1641
|
return {
|
|
1457
1642
|
response: await this.handleResult(result),
|
|
1458
1643
|
refreshToken: privateInfo.refreshToken
|
|
1459
1644
|
};
|
|
1460
1645
|
}
|
|
1461
1646
|
async refresh(req) {
|
|
1462
|
-
const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
1647
|
+
const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
1463
1648
|
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
|
|
1464
1649
|
return this.handleResult({
|
|
1465
1650
|
fullProfile,
|
|
@@ -1470,7 +1655,7 @@ class BitbucketAuthProvider {
|
|
|
1470
1655
|
}
|
|
1471
1656
|
async handleResult(result) {
|
|
1472
1657
|
result.fullProfile.avatarUrl = result.fullProfile._json.links.avatar.href;
|
|
1473
|
-
const {profile} = await this.authHandler(result);
|
|
1658
|
+
const { profile } = await this.authHandler(result);
|
|
1474
1659
|
const response = {
|
|
1475
1660
|
providerInfo: {
|
|
1476
1661
|
idToken: result.params.id_token,
|
|
@@ -1494,7 +1679,7 @@ class BitbucketAuthProvider {
|
|
|
1494
1679
|
}
|
|
1495
1680
|
}
|
|
1496
1681
|
const bitbucketUsernameSignInResolver = async (info, ctx) => {
|
|
1497
|
-
const {result} = info;
|
|
1682
|
+
const { result } = info;
|
|
1498
1683
|
if (!result.fullProfile.username) {
|
|
1499
1684
|
throw new Error("Bitbucket profile contained no Username");
|
|
1500
1685
|
}
|
|
@@ -1504,11 +1689,11 @@ const bitbucketUsernameSignInResolver = async (info, ctx) => {
|
|
|
1504
1689
|
}
|
|
1505
1690
|
});
|
|
1506
1691
|
const claims = getEntityClaims(entity);
|
|
1507
|
-
const token = await ctx.tokenIssuer.issueToken({claims});
|
|
1508
|
-
return {id: entity.metadata.name, entity, token};
|
|
1692
|
+
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
1693
|
+
return { id: entity.metadata.name, entity, token };
|
|
1509
1694
|
};
|
|
1510
1695
|
const bitbucketUserIdSignInResolver = async (info, ctx) => {
|
|
1511
|
-
const {result} = info;
|
|
1696
|
+
const { result } = info;
|
|
1512
1697
|
if (!result.fullProfile.id) {
|
|
1513
1698
|
throw new Error("Bitbucket profile contained no User ID");
|
|
1514
1699
|
}
|
|
@@ -1518,8 +1703,8 @@ const bitbucketUserIdSignInResolver = async (info, ctx) => {
|
|
|
1518
1703
|
}
|
|
1519
1704
|
});
|
|
1520
1705
|
const claims = getEntityClaims(entity);
|
|
1521
|
-
const token = await ctx.tokenIssuer.issueToken({claims});
|
|
1522
|
-
return {id: entity.metadata.name, entity, token};
|
|
1706
|
+
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
1707
|
+
return { id: entity.metadata.name, entity, token };
|
|
1523
1708
|
};
|
|
1524
1709
|
const createBitbucketProvider = (options) => {
|
|
1525
1710
|
return ({
|
|
@@ -1538,7 +1723,7 @@ const createBitbucketProvider = (options) => {
|
|
|
1538
1723
|
catalogApi,
|
|
1539
1724
|
tokenIssuer
|
|
1540
1725
|
});
|
|
1541
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile, params}) => ({
|
|
1726
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1542
1727
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1543
1728
|
});
|
|
1544
1729
|
const provider = new BitbucketAuthProvider({
|
|
@@ -1560,7 +1745,7 @@ const createBitbucketProvider = (options) => {
|
|
|
1560
1745
|
};
|
|
1561
1746
|
|
|
1562
1747
|
const defaultScopes = ["offline_access", "read:me"];
|
|
1563
|
-
class AtlassianStrategy extends OAuth2Strategy__default[
|
|
1748
|
+
class AtlassianStrategy extends OAuth2Strategy__default["default"] {
|
|
1564
1749
|
constructor(options, verify) {
|
|
1565
1750
|
if (!options.scope) {
|
|
1566
1751
|
throw new TypeError("Atlassian requires a scope option");
|
|
@@ -1570,7 +1755,7 @@ class AtlassianStrategy extends OAuth2Strategy__default['default'] {
|
|
|
1570
1755
|
...options,
|
|
1571
1756
|
authorizationURL: `https://auth.atlassian.com/authorize`,
|
|
1572
1757
|
tokenURL: `https://auth.atlassian.com/oauth/token`,
|
|
1573
|
-
scope: Array.from(new Set([...defaultScopes, ...scopes]))
|
|
1758
|
+
scope: Array.from(/* @__PURE__ */ new Set([...defaultScopes, ...scopes]))
|
|
1574
1759
|
};
|
|
1575
1760
|
super(optionsWithURLs, verify);
|
|
1576
1761
|
this.profileURL = "https://api.atlassian.com/me";
|
|
@@ -1607,8 +1792,8 @@ class AtlassianStrategy extends OAuth2Strategy__default['default'] {
|
|
|
1607
1792
|
provider: "atlassian",
|
|
1608
1793
|
username: resp.nickname,
|
|
1609
1794
|
displayName: resp.name,
|
|
1610
|
-
emails: [{value: resp.email}],
|
|
1611
|
-
photos: [{value: resp.picture}]
|
|
1795
|
+
emails: [{ value: resp.email }],
|
|
1796
|
+
photos: [{ value: resp.picture }]
|
|
1612
1797
|
};
|
|
1613
1798
|
}
|
|
1614
1799
|
}
|
|
@@ -1647,14 +1832,14 @@ class AtlassianAuthProvider {
|
|
|
1647
1832
|
}
|
|
1648
1833
|
async handler(req) {
|
|
1649
1834
|
var _a;
|
|
1650
|
-
const {result} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1835
|
+
const { result } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1651
1836
|
return {
|
|
1652
1837
|
response: await this.handleResult(result),
|
|
1653
1838
|
refreshToken: (_a = result.refreshToken) != null ? _a : ""
|
|
1654
1839
|
};
|
|
1655
1840
|
}
|
|
1656
1841
|
async handleResult(result) {
|
|
1657
|
-
const {profile} = await this.authHandler(result);
|
|
1842
|
+
const { profile } = await this.authHandler(result);
|
|
1658
1843
|
const response = {
|
|
1659
1844
|
providerInfo: {
|
|
1660
1845
|
idToken: result.params.id_token,
|
|
@@ -1745,7 +1930,7 @@ class AwsAlbAuthProvider {
|
|
|
1745
1930
|
this.tokenIssuer = options.tokenIssuer;
|
|
1746
1931
|
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
1747
1932
|
this.logger = options.logger;
|
|
1748
|
-
this.keyCache = new NodeCache__default[
|
|
1933
|
+
this.keyCache = new NodeCache__default["default"]({ stdTTL: 3600 });
|
|
1749
1934
|
}
|
|
1750
1935
|
frameHandler() {
|
|
1751
1936
|
return Promise.resolve(void 0);
|
|
@@ -1789,8 +1974,8 @@ class AwsAlbAuthProvider {
|
|
|
1789
1974
|
familyName: claims.family_name,
|
|
1790
1975
|
givenName: claims.given_name
|
|
1791
1976
|
},
|
|
1792
|
-
emails: [{value: claims.email.toLowerCase()}],
|
|
1793
|
-
photos: [{value: claims.picture}]
|
|
1977
|
+
emails: [{ value: claims.email.toLowerCase() }],
|
|
1978
|
+
photos: [{ value: claims.picture }]
|
|
1794
1979
|
};
|
|
1795
1980
|
return {
|
|
1796
1981
|
fullProfile,
|
|
@@ -1802,7 +1987,7 @@ class AwsAlbAuthProvider {
|
|
|
1802
1987
|
}
|
|
1803
1988
|
}
|
|
1804
1989
|
async handleResult(result) {
|
|
1805
|
-
const {profile} = await this.authHandler(result);
|
|
1990
|
+
const { profile } = await this.authHandler(result);
|
|
1806
1991
|
const backstageIdentity = await this.signInResolver({
|
|
1807
1992
|
result,
|
|
1808
1993
|
profile
|
|
@@ -1816,7 +2001,7 @@ class AwsAlbAuthProvider {
|
|
|
1816
2001
|
accessToken: result.accessToken,
|
|
1817
2002
|
expiresInSeconds: result.expiresInSeconds
|
|
1818
2003
|
},
|
|
1819
|
-
backstageIdentity,
|
|
2004
|
+
backstageIdentity: prepareBackstageIdentityResponse(backstageIdentity),
|
|
1820
2005
|
profile
|
|
1821
2006
|
};
|
|
1822
2007
|
}
|
|
@@ -1825,14 +2010,14 @@ class AwsAlbAuthProvider {
|
|
|
1825
2010
|
if (optionalCacheKey) {
|
|
1826
2011
|
return crypto__namespace.createPublicKey(optionalCacheKey);
|
|
1827
2012
|
}
|
|
1828
|
-
const keyText = await fetch__default[
|
|
2013
|
+
const keyText = await fetch__default["default"](`https://public-keys.auth.elb.${this.region}.amazonaws.com/${keyId}`).then((response) => response.text());
|
|
1829
2014
|
const keyValue = crypto__namespace.createPublicKey(keyText);
|
|
1830
|
-
this.keyCache.set(keyId, keyValue.export({format: "pem", type: "spki"}));
|
|
2015
|
+
this.keyCache.set(keyId, keyValue.export({ format: "pem", type: "spki" }));
|
|
1831
2016
|
return keyValue;
|
|
1832
2017
|
}
|
|
1833
2018
|
}
|
|
1834
2019
|
const createAwsAlbProvider = (options) => {
|
|
1835
|
-
return ({config, tokenIssuer, catalogApi, logger}) => {
|
|
2020
|
+
return ({ config, tokenIssuer, catalogApi, logger }) => {
|
|
1836
2021
|
const region = config.getString("region");
|
|
1837
2022
|
const issuer = config.getOptionalString("iss");
|
|
1838
2023
|
if ((options == null ? void 0 : options.signIn.resolver) === void 0) {
|
|
@@ -1842,7 +2027,7 @@ const createAwsAlbProvider = (options) => {
|
|
|
1842
2027
|
catalogApi,
|
|
1843
2028
|
tokenIssuer
|
|
1844
2029
|
});
|
|
1845
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile}) => ({
|
|
2030
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
1846
2031
|
profile: makeProfileInfo(fullProfile)
|
|
1847
2032
|
});
|
|
1848
2033
|
const signInResolver = options == null ? void 0 : options.signIn.resolver;
|
|
@@ -1858,182 +2043,98 @@ const createAwsAlbProvider = (options) => {
|
|
|
1858
2043
|
};
|
|
1859
2044
|
};
|
|
1860
2045
|
|
|
1861
|
-
class OidcAuthProvider {
|
|
1862
|
-
constructor(options) {
|
|
1863
|
-
this.implementation = this.setupStrategy(options);
|
|
1864
|
-
this.scope = options.scope;
|
|
1865
|
-
this.prompt = options.prompt;
|
|
1866
|
-
}
|
|
1867
|
-
async start(req) {
|
|
1868
|
-
const {strategy} = await this.implementation;
|
|
1869
|
-
const options = {
|
|
1870
|
-
accessType: "offline",
|
|
1871
|
-
scope: req.scope || this.scope || "openid profile email",
|
|
1872
|
-
state: encodeState(req.state)
|
|
1873
|
-
};
|
|
1874
|
-
const prompt = this.prompt || "none";
|
|
1875
|
-
if (prompt !== "auto") {
|
|
1876
|
-
options.prompt = prompt;
|
|
1877
|
-
}
|
|
1878
|
-
return await executeRedirectStrategy(req, strategy, options);
|
|
1879
|
-
}
|
|
1880
|
-
async handler(req) {
|
|
1881
|
-
const {strategy} = await this.implementation;
|
|
1882
|
-
const strategyResponse = await executeFrameHandlerStrategy(req, strategy);
|
|
1883
|
-
const {
|
|
1884
|
-
result: {userinfo, tokenset},
|
|
1885
|
-
privateInfo
|
|
1886
|
-
} = strategyResponse;
|
|
1887
|
-
const identityResponse = await this.populateIdentity({
|
|
1888
|
-
profile: {
|
|
1889
|
-
displayName: userinfo.name,
|
|
1890
|
-
email: userinfo.email,
|
|
1891
|
-
picture: userinfo.picture
|
|
1892
|
-
},
|
|
1893
|
-
providerInfo: {
|
|
1894
|
-
idToken: tokenset.id_token,
|
|
1895
|
-
accessToken: tokenset.access_token || "",
|
|
1896
|
-
scope: tokenset.scope || "",
|
|
1897
|
-
expiresInSeconds: tokenset.expires_in
|
|
1898
|
-
}
|
|
1899
|
-
});
|
|
1900
|
-
return {
|
|
1901
|
-
response: identityResponse,
|
|
1902
|
-
refreshToken: privateInfo.refreshToken
|
|
1903
|
-
};
|
|
1904
|
-
}
|
|
1905
|
-
async refresh(req) {
|
|
1906
|
-
const {client} = await this.implementation;
|
|
1907
|
-
const tokenset = await client.refresh(req.refreshToken);
|
|
1908
|
-
if (!tokenset.access_token) {
|
|
1909
|
-
throw new Error("Refresh failed");
|
|
1910
|
-
}
|
|
1911
|
-
const profile = await client.userinfo(tokenset.access_token);
|
|
1912
|
-
return this.populateIdentity({
|
|
1913
|
-
providerInfo: {
|
|
1914
|
-
accessToken: tokenset.access_token,
|
|
1915
|
-
refreshToken: tokenset.refresh_token,
|
|
1916
|
-
expiresInSeconds: tokenset.expires_in,
|
|
1917
|
-
idToken: tokenset.id_token,
|
|
1918
|
-
scope: tokenset.scope || ""
|
|
1919
|
-
},
|
|
1920
|
-
profile
|
|
1921
|
-
});
|
|
1922
|
-
}
|
|
1923
|
-
async setupStrategy(options) {
|
|
1924
|
-
const issuer = await openidClient.Issuer.discover(options.metadataUrl);
|
|
1925
|
-
const client = new issuer.Client({
|
|
1926
|
-
client_id: options.clientId,
|
|
1927
|
-
client_secret: options.clientSecret,
|
|
1928
|
-
redirect_uris: [options.callbackUrl],
|
|
1929
|
-
response_types: ["code"],
|
|
1930
|
-
id_token_signed_response_alg: options.tokenSignedResponseAlg || "RS256",
|
|
1931
|
-
scope: options.scope || ""
|
|
1932
|
-
});
|
|
1933
|
-
const strategy = new openidClient.Strategy({
|
|
1934
|
-
client,
|
|
1935
|
-
passReqToCallback: false
|
|
1936
|
-
}, (tokenset, userinfo, done) => {
|
|
1937
|
-
if (typeof done !== "function") {
|
|
1938
|
-
throw new Error("OIDC IdP must provide a userinfo_endpoint in the metadata response");
|
|
1939
|
-
}
|
|
1940
|
-
done(void 0, {tokenset, userinfo}, {
|
|
1941
|
-
refreshToken: tokenset.refresh_token
|
|
1942
|
-
});
|
|
1943
|
-
});
|
|
1944
|
-
strategy.error = console.error;
|
|
1945
|
-
return {strategy, client};
|
|
1946
|
-
}
|
|
1947
|
-
async populateIdentity(response) {
|
|
1948
|
-
const {profile} = response;
|
|
1949
|
-
if (!profile.email) {
|
|
1950
|
-
throw new Error("Profile does not contain an email");
|
|
1951
|
-
}
|
|
1952
|
-
const id = profile.email.split("@")[0];
|
|
1953
|
-
return {...response, backstageIdentity: {id}};
|
|
1954
|
-
}
|
|
1955
|
-
}
|
|
1956
|
-
const createOidcProvider = (_options) => {
|
|
1957
|
-
return ({providerId, globalConfig, config, tokenIssuer}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1958
|
-
const clientId = envConfig.getString("clientId");
|
|
1959
|
-
const clientSecret = envConfig.getString("clientSecret");
|
|
1960
|
-
const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1961
|
-
const metadataUrl = envConfig.getString("metadataUrl");
|
|
1962
|
-
const tokenSignedResponseAlg = envConfig.getOptionalString("tokenSignedResponseAlg");
|
|
1963
|
-
const scope = envConfig.getOptionalString("scope");
|
|
1964
|
-
const prompt = envConfig.getOptionalString("prompt");
|
|
1965
|
-
const provider = new OidcAuthProvider({
|
|
1966
|
-
clientId,
|
|
1967
|
-
clientSecret,
|
|
1968
|
-
callbackUrl,
|
|
1969
|
-
tokenSignedResponseAlg,
|
|
1970
|
-
metadataUrl,
|
|
1971
|
-
scope,
|
|
1972
|
-
prompt
|
|
1973
|
-
});
|
|
1974
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1975
|
-
disableRefresh: false,
|
|
1976
|
-
providerId,
|
|
1977
|
-
tokenIssuer
|
|
1978
|
-
});
|
|
1979
|
-
});
|
|
1980
|
-
};
|
|
1981
|
-
|
|
1982
2046
|
class SamlAuthProvider {
|
|
1983
2047
|
constructor(options) {
|
|
1984
2048
|
this.appUrl = options.appUrl;
|
|
2049
|
+
this.signInResolver = options.signInResolver;
|
|
2050
|
+
this.authHandler = options.authHandler;
|
|
1985
2051
|
this.tokenIssuer = options.tokenIssuer;
|
|
1986
|
-
this.
|
|
1987
|
-
|
|
2052
|
+
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
2053
|
+
this.logger = options.logger;
|
|
2054
|
+
this.strategy = new passportSaml.Strategy({ ...options }, (fullProfile, done) => {
|
|
2055
|
+
done(void 0, { fullProfile });
|
|
1988
2056
|
});
|
|
1989
2057
|
}
|
|
1990
2058
|
async start(req, res) {
|
|
1991
|
-
const {url} = await executeRedirectStrategy(req, this.strategy, {});
|
|
2059
|
+
const { url } = await executeRedirectStrategy(req, this.strategy, {});
|
|
1992
2060
|
res.redirect(url);
|
|
1993
2061
|
}
|
|
1994
2062
|
async frameHandler(req, res) {
|
|
1995
2063
|
try {
|
|
1996
|
-
const {result} = await executeFrameHandlerStrategy(req, this.strategy);
|
|
1997
|
-
const
|
|
1998
|
-
const
|
|
1999
|
-
|
|
2000
|
-
|
|
2064
|
+
const { result } = await executeFrameHandlerStrategy(req, this.strategy);
|
|
2065
|
+
const { profile } = await this.authHandler(result);
|
|
2066
|
+
const response = {
|
|
2067
|
+
profile,
|
|
2068
|
+
providerInfo: {}
|
|
2069
|
+
};
|
|
2070
|
+
if (this.signInResolver) {
|
|
2071
|
+
const signInResponse = await this.signInResolver({
|
|
2072
|
+
result,
|
|
2073
|
+
profile
|
|
2074
|
+
}, {
|
|
2075
|
+
tokenIssuer: this.tokenIssuer,
|
|
2076
|
+
catalogIdentityClient: this.catalogIdentityClient,
|
|
2077
|
+
logger: this.logger
|
|
2078
|
+
});
|
|
2079
|
+
response.backstageIdentity = prepareBackstageIdentityResponse(signInResponse);
|
|
2080
|
+
}
|
|
2001
2081
|
return postMessageResponse(res, this.appUrl, {
|
|
2002
2082
|
type: "authorization_response",
|
|
2003
|
-
response
|
|
2004
|
-
profile: {
|
|
2005
|
-
email: result.fullProfile.email,
|
|
2006
|
-
displayName: result.fullProfile.displayName
|
|
2007
|
-
},
|
|
2008
|
-
providerInfo: {},
|
|
2009
|
-
backstageIdentity: {id, idToken}
|
|
2010
|
-
}
|
|
2083
|
+
response
|
|
2011
2084
|
});
|
|
2012
2085
|
} catch (error) {
|
|
2013
|
-
const {name, message} = errors.isError(error) ? error : new Error("Encountered invalid error");
|
|
2086
|
+
const { name, message } = errors.isError(error) ? error : new Error("Encountered invalid error");
|
|
2014
2087
|
return postMessageResponse(res, this.appUrl, {
|
|
2015
2088
|
type: "authorization_response",
|
|
2016
|
-
error: {name, message}
|
|
2089
|
+
error: { name, message }
|
|
2017
2090
|
});
|
|
2018
2091
|
}
|
|
2019
2092
|
}
|
|
2020
2093
|
async logout(_req, res) {
|
|
2021
|
-
res.
|
|
2022
|
-
}
|
|
2023
|
-
identifyEnv() {
|
|
2024
|
-
return void 0;
|
|
2094
|
+
res.end();
|
|
2025
2095
|
}
|
|
2026
2096
|
}
|
|
2027
|
-
const
|
|
2028
|
-
|
|
2029
|
-
|
|
2097
|
+
const samlDefaultSignInResolver = async (info, ctx) => {
|
|
2098
|
+
const id = info.result.fullProfile.nameID;
|
|
2099
|
+
const token = await ctx.tokenIssuer.issueToken({
|
|
2100
|
+
claims: { sub: id }
|
|
2101
|
+
});
|
|
2102
|
+
return { id, token };
|
|
2103
|
+
};
|
|
2104
|
+
const createSamlProvider = (options) => {
|
|
2105
|
+
return ({
|
|
2106
|
+
providerId,
|
|
2107
|
+
globalConfig,
|
|
2108
|
+
config,
|
|
2109
|
+
tokenIssuer,
|
|
2110
|
+
catalogApi,
|
|
2111
|
+
logger
|
|
2112
|
+
}) => {
|
|
2113
|
+
var _a, _b;
|
|
2114
|
+
const catalogIdentityClient = new CatalogIdentityClient({
|
|
2115
|
+
catalogApi,
|
|
2116
|
+
tokenIssuer
|
|
2117
|
+
});
|
|
2118
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
2119
|
+
profile: {
|
|
2120
|
+
email: fullProfile.email,
|
|
2121
|
+
displayName: fullProfile.displayName
|
|
2122
|
+
}
|
|
2123
|
+
});
|
|
2124
|
+
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : samlDefaultSignInResolver;
|
|
2125
|
+
const signInResolver = (info) => signInResolverFn(info, {
|
|
2126
|
+
catalogIdentityClient,
|
|
2127
|
+
tokenIssuer,
|
|
2128
|
+
logger
|
|
2129
|
+
});
|
|
2130
|
+
return new SamlAuthProvider({
|
|
2030
2131
|
callbackUrl: `${globalConfig.baseUrl}/${providerId}/handler/frame`,
|
|
2031
2132
|
entryPoint: config.getString("entryPoint"),
|
|
2032
2133
|
logoutUrl: config.getOptionalString("logoutUrl"),
|
|
2033
2134
|
audience: config.getOptionalString("audience"),
|
|
2034
2135
|
issuer: config.getString("issuer"),
|
|
2035
2136
|
cert: config.getString("cert"),
|
|
2036
|
-
|
|
2137
|
+
privateKey: config.getOptionalString("privateKey"),
|
|
2037
2138
|
authnContext: config.getOptionalStringArray("authnContext"),
|
|
2038
2139
|
identifierFormat: config.getOptionalString("identifierFormat"),
|
|
2039
2140
|
decryptionPvk: config.getOptionalString("decryptionPvk"),
|
|
@@ -2041,13 +2142,16 @@ const createSamlProvider = (_options) => {
|
|
|
2041
2142
|
digestAlgorithm: config.getOptionalString("digestAlgorithm"),
|
|
2042
2143
|
acceptedClockSkewMs: config.getOptionalNumber("acceptedClockSkewMs"),
|
|
2043
2144
|
tokenIssuer,
|
|
2044
|
-
appUrl: globalConfig.appUrl
|
|
2045
|
-
|
|
2046
|
-
|
|
2145
|
+
appUrl: globalConfig.appUrl,
|
|
2146
|
+
authHandler,
|
|
2147
|
+
signInResolver,
|
|
2148
|
+
logger,
|
|
2149
|
+
catalogIdentityClient
|
|
2150
|
+
});
|
|
2047
2151
|
};
|
|
2048
2152
|
};
|
|
2049
2153
|
|
|
2050
|
-
class Auth0Strategy extends OAuth2Strategy__default[
|
|
2154
|
+
class Auth0Strategy extends OAuth2Strategy__default["default"] {
|
|
2051
2155
|
constructor(options, verify) {
|
|
2052
2156
|
const optionsWithURLs = {
|
|
2053
2157
|
...options,
|
|
@@ -2088,7 +2192,7 @@ class Auth0AuthProvider {
|
|
|
2088
2192
|
});
|
|
2089
2193
|
}
|
|
2090
2194
|
async handler(req) {
|
|
2091
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
2195
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
2092
2196
|
const profile = makeProfileInfo(result.fullProfile, result.params.id_token);
|
|
2093
2197
|
return {
|
|
2094
2198
|
response: await this.populateIdentity({
|
|
@@ -2104,7 +2208,7 @@ class Auth0AuthProvider {
|
|
|
2104
2208
|
};
|
|
2105
2209
|
}
|
|
2106
2210
|
async refresh(req) {
|
|
2107
|
-
const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
2211
|
+
const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
2108
2212
|
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
|
|
2109
2213
|
const profile = makeProfileInfo(fullProfile, params.id_token);
|
|
2110
2214
|
return this.populateIdentity({
|
|
@@ -2118,16 +2222,16 @@ class Auth0AuthProvider {
|
|
|
2118
2222
|
});
|
|
2119
2223
|
}
|
|
2120
2224
|
async populateIdentity(response) {
|
|
2121
|
-
const {profile} = response;
|
|
2225
|
+
const { profile } = response;
|
|
2122
2226
|
if (!profile.email) {
|
|
2123
2227
|
throw new Error("Profile does not contain an email");
|
|
2124
2228
|
}
|
|
2125
2229
|
const id = profile.email.split("@")[0];
|
|
2126
|
-
return {...response, backstageIdentity: {id}};
|
|
2230
|
+
return { ...response, backstageIdentity: { id, token: "" } };
|
|
2127
2231
|
}
|
|
2128
2232
|
}
|
|
2129
2233
|
const createAuth0Provider = (_options) => {
|
|
2130
|
-
return ({providerId, globalConfig, config, tokenIssuer}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
2234
|
+
return ({ providerId, globalConfig, config, tokenIssuer }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
2131
2235
|
const clientId = envConfig.getString("clientId");
|
|
2132
2236
|
const clientSecret = envConfig.getString("clientSecret");
|
|
2133
2237
|
const domain = envConfig.getString("domain");
|
|
@@ -2174,7 +2278,7 @@ class OneLoginProvider {
|
|
|
2174
2278
|
});
|
|
2175
2279
|
}
|
|
2176
2280
|
async handler(req) {
|
|
2177
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
2281
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
2178
2282
|
const profile = makeProfileInfo(result.fullProfile, result.params.id_token);
|
|
2179
2283
|
return {
|
|
2180
2284
|
response: await this.populateIdentity({
|
|
@@ -2190,7 +2294,7 @@ class OneLoginProvider {
|
|
|
2190
2294
|
};
|
|
2191
2295
|
}
|
|
2192
2296
|
async refresh(req) {
|
|
2193
|
-
const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
2297
|
+
const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
2194
2298
|
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
|
|
2195
2299
|
const profile = makeProfileInfo(fullProfile, params.id_token);
|
|
2196
2300
|
return this.populateIdentity({
|
|
@@ -2204,16 +2308,16 @@ class OneLoginProvider {
|
|
|
2204
2308
|
});
|
|
2205
2309
|
}
|
|
2206
2310
|
async populateIdentity(response) {
|
|
2207
|
-
const {profile} = response;
|
|
2311
|
+
const { profile } = response;
|
|
2208
2312
|
if (!profile.email) {
|
|
2209
2313
|
throw new Error("OIDC profile contained no email");
|
|
2210
2314
|
}
|
|
2211
2315
|
const id = profile.email.split("@")[0];
|
|
2212
|
-
return {...response, backstageIdentity: {id}};
|
|
2316
|
+
return { ...response, backstageIdentity: { id, token: "" } };
|
|
2213
2317
|
}
|
|
2214
2318
|
}
|
|
2215
2319
|
const createOneLoginProvider = (_options) => {
|
|
2216
|
-
return ({providerId, globalConfig, config, tokenIssuer}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
2320
|
+
return ({ providerId, globalConfig, config, tokenIssuer }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
2217
2321
|
const clientId = envConfig.getString("clientId");
|
|
2218
2322
|
const clientSecret = envConfig.getString("clientSecret");
|
|
2219
2323
|
const issuer = envConfig.getString("issuer");
|
|
@@ -2249,8 +2353,8 @@ const factories = {
|
|
|
2249
2353
|
};
|
|
2250
2354
|
|
|
2251
2355
|
function createOidcRouter(options) {
|
|
2252
|
-
const {baseUrl, tokenIssuer} = options;
|
|
2253
|
-
const router = Router__default[
|
|
2356
|
+
const { baseUrl, tokenIssuer } = options;
|
|
2357
|
+
const router = Router__default["default"]();
|
|
2254
2358
|
const config = {
|
|
2255
2359
|
issuer: baseUrl,
|
|
2256
2360
|
token_endpoint: `${baseUrl}/v1/token`,
|
|
@@ -2268,8 +2372,8 @@ function createOidcRouter(options) {
|
|
|
2268
2372
|
res.json(config);
|
|
2269
2373
|
});
|
|
2270
2374
|
router.get("/.well-known/jwks.json", async (_req, res) => {
|
|
2271
|
-
const {keys} = await tokenIssuer.listPublicKeys();
|
|
2272
|
-
res.json({keys});
|
|
2375
|
+
const { keys } = await tokenIssuer.listPublicKeys();
|
|
2376
|
+
res.json({ keys });
|
|
2273
2377
|
});
|
|
2274
2378
|
router.get("/v1/token", (_req, res) => {
|
|
2275
2379
|
res.status(501).send("Not Implemented");
|
|
@@ -2289,21 +2393,30 @@ class IdentityClient {
|
|
|
2289
2393
|
this.keyStoreUpdated = 0;
|
|
2290
2394
|
}
|
|
2291
2395
|
async authenticate(token) {
|
|
2396
|
+
var _a;
|
|
2292
2397
|
if (!token) {
|
|
2293
|
-
throw new
|
|
2398
|
+
throw new errors.AuthenticationError("No token specified");
|
|
2294
2399
|
}
|
|
2295
2400
|
const key = await this.getKey(token);
|
|
2296
2401
|
if (!key) {
|
|
2297
|
-
throw new
|
|
2402
|
+
throw new errors.AuthenticationError("No signing key matching token found");
|
|
2298
2403
|
}
|
|
2299
2404
|
const decoded = jose.JWT.IdToken.verify(token, key, {
|
|
2300
2405
|
algorithms: ["ES256"],
|
|
2301
2406
|
audience: "backstage",
|
|
2302
2407
|
issuer: this.issuer
|
|
2303
2408
|
});
|
|
2409
|
+
if (!decoded.sub) {
|
|
2410
|
+
throw new errors.AuthenticationError("No user sub found in token");
|
|
2411
|
+
}
|
|
2304
2412
|
const user = {
|
|
2305
2413
|
id: decoded.sub,
|
|
2306
|
-
|
|
2414
|
+
token,
|
|
2415
|
+
identity: {
|
|
2416
|
+
type: "user",
|
|
2417
|
+
userEntityRef: decoded.sub,
|
|
2418
|
+
ownershipEntityRefs: (_a = decoded.ent) != null ? _a : []
|
|
2419
|
+
}
|
|
2307
2420
|
};
|
|
2308
2421
|
return user;
|
|
2309
2422
|
}
|
|
@@ -2315,19 +2428,19 @@ class IdentityClient {
|
|
|
2315
2428
|
return matches == null ? void 0 : matches[1];
|
|
2316
2429
|
}
|
|
2317
2430
|
async getKey(rawJwtToken) {
|
|
2318
|
-
const {header, payload} = jose.JWT.decode(rawJwtToken, {
|
|
2431
|
+
const { header, payload } = jose.JWT.decode(rawJwtToken, {
|
|
2319
2432
|
complete: true
|
|
2320
2433
|
});
|
|
2321
|
-
const keyStoreHasKey = !!this.keyStore.get({kid: header.kid});
|
|
2434
|
+
const keyStoreHasKey = !!this.keyStore.get({ kid: header.kid });
|
|
2322
2435
|
const issuedAfterLastRefresh = (payload == null ? void 0 : payload.iat) && payload.iat > this.keyStoreUpdated - CLOCK_MARGIN_S;
|
|
2323
2436
|
if (!keyStoreHasKey && issuedAfterLastRefresh) {
|
|
2324
2437
|
await this.refreshKeyStore();
|
|
2325
2438
|
}
|
|
2326
|
-
return this.keyStore.get({kid: header.kid});
|
|
2439
|
+
return this.keyStore.get({ kid: header.kid });
|
|
2327
2440
|
}
|
|
2328
2441
|
async listPublicKeys() {
|
|
2329
2442
|
const url = `${await this.discovery.getBaseUrl("auth")}/.well-known/jwks.json`;
|
|
2330
|
-
const response = await fetch__default[
|
|
2443
|
+
const response = await fetch__default["default"](url);
|
|
2331
2444
|
if (!response.ok) {
|
|
2332
2445
|
const payload = await response.text();
|
|
2333
2446
|
const message = `Request failed with ${response.status} ${response.statusText}, ${payload}`;
|
|
@@ -2363,13 +2476,13 @@ class TokenFactory {
|
|
|
2363
2476
|
const iat = Math.floor(Date.now() / MS_IN_S);
|
|
2364
2477
|
const exp = iat + this.keyDurationSeconds;
|
|
2365
2478
|
this.logger.info(`Issuing token for ${sub}, with entities ${ent != null ? ent : []}`);
|
|
2366
|
-
return jose.JWS.sign({iss, sub, aud, iat, exp, ent}, key, {
|
|
2479
|
+
return jose.JWS.sign({ iss, sub, aud, iat, exp, ent }, key, {
|
|
2367
2480
|
alg: key.alg,
|
|
2368
2481
|
kid: key.kid
|
|
2369
2482
|
});
|
|
2370
2483
|
}
|
|
2371
2484
|
async listPublicKeys() {
|
|
2372
|
-
const {items: keys} = await this.keyStore.listKeys();
|
|
2485
|
+
const { items: keys } = await this.keyStore.listKeys();
|
|
2373
2486
|
const validKeys = [];
|
|
2374
2487
|
const expiredKeys = [];
|
|
2375
2488
|
for (const key of keys) {
|
|
@@ -2383,13 +2496,13 @@ class TokenFactory {
|
|
|
2383
2496
|
}
|
|
2384
2497
|
}
|
|
2385
2498
|
if (expiredKeys.length > 0) {
|
|
2386
|
-
const kids = expiredKeys.map(({key}) => key.kid);
|
|
2499
|
+
const kids = expiredKeys.map(({ key }) => key.kid);
|
|
2387
2500
|
this.logger.info(`Removing expired signing keys, '${kids.join("', '")}'`);
|
|
2388
2501
|
this.keyStore.removeKeys(kids).catch((error) => {
|
|
2389
2502
|
this.logger.error(`Failed to remove expired keys, ${error}`);
|
|
2390
2503
|
});
|
|
2391
2504
|
}
|
|
2392
|
-
return {keys: validKeys.map(({key}) => key)};
|
|
2505
|
+
return { keys: validKeys.map(({ key }) => key) };
|
|
2393
2506
|
}
|
|
2394
2507
|
async getKey() {
|
|
2395
2508
|
if (this.privateKeyPromise) {
|
|
@@ -2427,7 +2540,7 @@ class TokenFactory {
|
|
|
2427
2540
|
const migrationsDir = backendCommon.resolvePackagePath("@backstage/plugin-auth-backend", "migrations");
|
|
2428
2541
|
const TABLE = "signing_keys";
|
|
2429
2542
|
const parseDate = (date) => {
|
|
2430
|
-
const parsedDate = typeof date === "string" ? luxon.DateTime.fromSQL(date, {zone: "UTC"}) : luxon.DateTime.fromJSDate(date);
|
|
2543
|
+
const parsedDate = typeof date === "string" ? luxon.DateTime.fromSQL(date, { zone: "UTC" }) : luxon.DateTime.fromJSDate(date);
|
|
2431
2544
|
if (!parsedDate.isValid) {
|
|
2432
2545
|
throw new Error(`Failed to parse date, reason: ${parsedDate.invalidReason}, explanation: ${parsedDate.invalidExplanation}`);
|
|
2433
2546
|
}
|
|
@@ -2435,7 +2548,7 @@ const parseDate = (date) => {
|
|
|
2435
2548
|
};
|
|
2436
2549
|
class DatabaseKeyStore {
|
|
2437
2550
|
static async create(options) {
|
|
2438
|
-
const {database} = options;
|
|
2551
|
+
const { database } = options;
|
|
2439
2552
|
await database.migrate.latest({
|
|
2440
2553
|
directory: migrationsDir
|
|
2441
2554
|
});
|
|
@@ -2466,7 +2579,7 @@ class DatabaseKeyStore {
|
|
|
2466
2579
|
|
|
2467
2580
|
class MemoryKeyStore {
|
|
2468
2581
|
constructor() {
|
|
2469
|
-
this.keys = new Map();
|
|
2582
|
+
this.keys = /* @__PURE__ */ new Map();
|
|
2470
2583
|
}
|
|
2471
2584
|
async addKey(key) {
|
|
2472
2585
|
this.keys.set(key.kid, {
|
|
@@ -2481,7 +2594,7 @@ class MemoryKeyStore {
|
|
|
2481
2594
|
}
|
|
2482
2595
|
async listKeys() {
|
|
2483
2596
|
return {
|
|
2484
|
-
items: Array.from(this.keys).map(([, {createdAt, key: keyStr}]) => ({
|
|
2597
|
+
items: Array.from(this.keys).map(([, { createdAt, key: keyStr }]) => ({
|
|
2485
2598
|
createdAt,
|
|
2486
2599
|
key: JSON.parse(keyStr)
|
|
2487
2600
|
}))
|
|
@@ -2498,7 +2611,7 @@ class FirestoreKeyStore {
|
|
|
2498
2611
|
this.timeout = timeout;
|
|
2499
2612
|
}
|
|
2500
2613
|
static async create(settings) {
|
|
2501
|
-
const {path, timeout, ...firestoreSettings} = settings != null ? settings : {};
|
|
2614
|
+
const { path, timeout, ...firestoreSettings } = settings != null ? settings : {};
|
|
2502
2615
|
const database = new firestore.Firestore(firestoreSettings);
|
|
2503
2616
|
return new FirestoreKeyStore(database, path != null ? path : DEFAULT_DOCUMENT_PATH, timeout != null ? timeout : DEFAULT_TIMEOUT_MS);
|
|
2504
2617
|
}
|
|
@@ -2546,7 +2659,7 @@ class FirestoreKeyStore {
|
|
|
2546
2659
|
class KeyStores {
|
|
2547
2660
|
static async fromConfig(config, options) {
|
|
2548
2661
|
var _a;
|
|
2549
|
-
const {logger, database} = options != null ? options : {};
|
|
2662
|
+
const { logger, database } = options != null ? options : {};
|
|
2550
2663
|
const ks = config.getOptionalConfig("auth.keyStore");
|
|
2551
2664
|
const provider = (_a = ks == null ? void 0 : ks.getOptionalString("provider")) != null ? _a : "database";
|
|
2552
2665
|
logger == null ? void 0 : logger.info(`Configuring "${provider}" as KeyStore provider`);
|
|
@@ -2579,36 +2692,31 @@ class KeyStores {
|
|
|
2579
2692
|
}
|
|
2580
2693
|
}
|
|
2581
2694
|
|
|
2582
|
-
async function createRouter({
|
|
2583
|
-
logger,
|
|
2584
|
-
|
|
2585
|
-
discovery,
|
|
2586
|
-
database,
|
|
2587
|
-
providerFactories
|
|
2588
|
-
}) {
|
|
2589
|
-
const router = Router__default['default']();
|
|
2695
|
+
async function createRouter(options) {
|
|
2696
|
+
const { logger, config, discovery, database, providerFactories } = options;
|
|
2697
|
+
const router = Router__default["default"]();
|
|
2590
2698
|
const appUrl = config.getString("app.baseUrl");
|
|
2591
2699
|
const authUrl = await discovery.getExternalBaseUrl("auth");
|
|
2592
|
-
const keyStore = await KeyStores.fromConfig(config, {logger, database});
|
|
2700
|
+
const keyStore = await KeyStores.fromConfig(config, { logger, database });
|
|
2593
2701
|
const keyDurationSeconds = 3600;
|
|
2594
2702
|
const tokenIssuer = new TokenFactory({
|
|
2595
2703
|
issuer: authUrl,
|
|
2596
2704
|
keyStore,
|
|
2597
2705
|
keyDurationSeconds,
|
|
2598
|
-
logger: logger.child({component: "token-factory"})
|
|
2706
|
+
logger: logger.child({ component: "token-factory" })
|
|
2599
2707
|
});
|
|
2600
|
-
const catalogApi = new catalogClient.CatalogClient({discoveryApi: discovery});
|
|
2708
|
+
const catalogApi = new catalogClient.CatalogClient({ discoveryApi: discovery });
|
|
2601
2709
|
const secret = config.getOptionalString("auth.session.secret");
|
|
2602
2710
|
if (secret) {
|
|
2603
|
-
router.use(cookieParser__default[
|
|
2604
|
-
router.use(session__default[
|
|
2605
|
-
router.use(passport__default[
|
|
2606
|
-
router.use(passport__default[
|
|
2711
|
+
router.use(cookieParser__default["default"](secret));
|
|
2712
|
+
router.use(session__default["default"]({ secret, saveUninitialized: false, resave: false }));
|
|
2713
|
+
router.use(passport__default["default"].initialize());
|
|
2714
|
+
router.use(passport__default["default"].session());
|
|
2607
2715
|
} else {
|
|
2608
|
-
router.use(cookieParser__default[
|
|
2716
|
+
router.use(cookieParser__default["default"]());
|
|
2609
2717
|
}
|
|
2610
|
-
router.use(express__default[
|
|
2611
|
-
router.use(express__default[
|
|
2718
|
+
router.use(express__default["default"].urlencoded({ extended: false }));
|
|
2719
|
+
router.use(express__default["default"].json());
|
|
2612
2720
|
const allProviderFactories = {
|
|
2613
2721
|
...factories,
|
|
2614
2722
|
...providerFactories
|
|
@@ -2622,14 +2730,14 @@ async function createRouter({
|
|
|
2622
2730
|
try {
|
|
2623
2731
|
const provider = providerFactory({
|
|
2624
2732
|
providerId,
|
|
2625
|
-
globalConfig: {baseUrl: authUrl, appUrl, isOriginAllowed},
|
|
2733
|
+
globalConfig: { baseUrl: authUrl, appUrl, isOriginAllowed },
|
|
2626
2734
|
config: providersConfig.getConfig(providerId),
|
|
2627
2735
|
logger,
|
|
2628
2736
|
tokenIssuer,
|
|
2629
2737
|
discovery,
|
|
2630
2738
|
catalogApi
|
|
2631
2739
|
});
|
|
2632
|
-
const r = Router__default[
|
|
2740
|
+
const r = Router__default["default"]();
|
|
2633
2741
|
r.get("/start", provider.start.bind(provider));
|
|
2634
2742
|
r.get("/handler/frame", provider.frameHandler.bind(provider));
|
|
2635
2743
|
r.post("/handler/frame", provider.frameHandler.bind(provider));
|
|
@@ -2661,7 +2769,7 @@ async function createRouter({
|
|
|
2661
2769
|
baseUrl: authUrl
|
|
2662
2770
|
}));
|
|
2663
2771
|
router.use("/:provider/", (req) => {
|
|
2664
|
-
const {provider} = req.params;
|
|
2772
|
+
const { provider } = req.params;
|
|
2665
2773
|
throw new errors.NotFoundError(`Unknown auth provider '${provider}'`);
|
|
2666
2774
|
});
|
|
2667
2775
|
return router;
|
|
@@ -2669,9 +2777,9 @@ async function createRouter({
|
|
|
2669
2777
|
function createOriginFilter(config) {
|
|
2670
2778
|
var _a;
|
|
2671
2779
|
const appUrl = config.getString("app.baseUrl");
|
|
2672
|
-
const {origin: appOrigin} = new URL(appUrl);
|
|
2780
|
+
const { origin: appOrigin } = new URL(appUrl);
|
|
2673
2781
|
const allowedOrigins = config.getOptionalStringArray("auth.experimentalExtraAllowedOrigins");
|
|
2674
|
-
const allowedOriginPatterns = (_a = allowedOrigins == null ? void 0 : allowedOrigins.map((pattern) => new minimatch.Minimatch(pattern, {nocase: true, noglobstar: true}))) != null ? _a : [];
|
|
2782
|
+
const allowedOriginPatterns = (_a = allowedOrigins == null ? void 0 : allowedOrigins.map((pattern) => new minimatch.Minimatch(pattern, { nocase: true, noglobstar: true }))) != null ? _a : [];
|
|
2675
2783
|
return (origin) => {
|
|
2676
2784
|
if (origin === appOrigin) {
|
|
2677
2785
|
return true;
|
|
@@ -2694,9 +2802,11 @@ exports.createGitlabProvider = createGitlabProvider;
|
|
|
2694
2802
|
exports.createGoogleProvider = createGoogleProvider;
|
|
2695
2803
|
exports.createMicrosoftProvider = createMicrosoftProvider;
|
|
2696
2804
|
exports.createOAuth2Provider = createOAuth2Provider;
|
|
2805
|
+
exports.createOidcProvider = createOidcProvider;
|
|
2697
2806
|
exports.createOktaProvider = createOktaProvider;
|
|
2698
2807
|
exports.createOriginFilter = createOriginFilter;
|
|
2699
2808
|
exports.createRouter = createRouter;
|
|
2809
|
+
exports.createSamlProvider = createSamlProvider;
|
|
2700
2810
|
exports.defaultAuthProviderFactories = factories;
|
|
2701
2811
|
exports.encodeState = encodeState;
|
|
2702
2812
|
exports.ensuresXRequestedWith = ensuresXRequestedWith;
|
|
@@ -2705,6 +2815,7 @@ exports.googleEmailSignInResolver = googleEmailSignInResolver;
|
|
|
2705
2815
|
exports.microsoftEmailSignInResolver = microsoftEmailSignInResolver;
|
|
2706
2816
|
exports.oktaEmailSignInResolver = oktaEmailSignInResolver;
|
|
2707
2817
|
exports.postMessageResponse = postMessageResponse;
|
|
2818
|
+
exports.prepareBackstageIdentityResponse = prepareBackstageIdentityResponse;
|
|
2708
2819
|
exports.readState = readState;
|
|
2709
2820
|
exports.verifyNonce = verifyNonce;
|
|
2710
2821
|
//# sourceMappingURL=index.cjs.js.map
|