@backstage/plugin-auth-backend 0.4.9 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -0
- package/dist/index.cjs.js +445 -328
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +152 -20
- package/package.json +8 -8
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
|
-
var fetch = require('
|
|
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,32 @@ 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 userEntityRef = catalogModel.stringifyEntityRef(catalogModel.parseEntityRef(identity.id, {
|
|
483
|
+
defaultKind: "user",
|
|
484
|
+
defaultNamespace: catalogModel.ENTITY_DEFAULT_NAMESPACE
|
|
485
|
+
}));
|
|
486
|
+
const token = await this.options.tokenIssuer.issueToken({
|
|
487
|
+
claims: { sub: userEntityRef }
|
|
488
|
+
});
|
|
489
|
+
return prepareBackstageIdentityResponse({ ...identity, token });
|
|
469
490
|
}
|
|
470
491
|
}
|
|
471
492
|
|
|
@@ -482,9 +503,9 @@ class CatalogIdentityClient {
|
|
|
482
503
|
filter[`metadata.annotations.${key}`] = value;
|
|
483
504
|
}
|
|
484
505
|
const token = await this.tokenIssuer.issueToken({
|
|
485
|
-
claims: {sub: "backstage.io/auth-backend"}
|
|
506
|
+
claims: { sub: "backstage.io/auth-backend" }
|
|
486
507
|
});
|
|
487
|
-
const {items} = await this.catalogApi.getEntities({filter}, {token});
|
|
508
|
+
const { items } = await this.catalogApi.getEntities({ filter }, { token });
|
|
488
509
|
if (items.length !== 1) {
|
|
489
510
|
if (items.length > 1) {
|
|
490
511
|
throw new errors.ConflictError("User lookup resulted in multiple matches");
|
|
@@ -494,10 +515,8 @@ class CatalogIdentityClient {
|
|
|
494
515
|
}
|
|
495
516
|
return items[0];
|
|
496
517
|
}
|
|
497
|
-
async resolveCatalogMembership({
|
|
498
|
-
entityRefs,
|
|
499
|
-
logger
|
|
500
|
-
}) {
|
|
518
|
+
async resolveCatalogMembership(query) {
|
|
519
|
+
const { entityRefs, logger } = query;
|
|
501
520
|
const resolvedEntityRefs = entityRefs.map((ref) => {
|
|
502
521
|
try {
|
|
503
522
|
const parsedRef = catalogModel.parseEntityRef(ref.toLocaleLowerCase("en-US"), {
|
|
@@ -515,7 +534,7 @@ class CatalogIdentityClient {
|
|
|
515
534
|
"metadata.namespace": ref.namespace,
|
|
516
535
|
"metadata.name": ref.name
|
|
517
536
|
}));
|
|
518
|
-
const entities = await this.catalogApi.getEntities({filter}).then((r) => r.items);
|
|
537
|
+
const entities = await this.catalogApi.getEntities({ filter }).then((r) => r.items);
|
|
519
538
|
if (entityRefs.length !== entities.length) {
|
|
520
539
|
const foundEntityNames = entities.map(catalogModel.stringifyEntityRef);
|
|
521
540
|
const missingEntityNames = resolvedEntityRefs.map(catalogModel.stringifyEntityRef).filter((s) => !foundEntityNames.includes(s));
|
|
@@ -559,7 +578,7 @@ class GithubAuthProvider {
|
|
|
559
578
|
userProfileURL: options.userProfileUrl,
|
|
560
579
|
authorizationURL: options.authorizationUrl
|
|
561
580
|
}, (accessToken, refreshToken, params, fullProfile, done) => {
|
|
562
|
-
done(void 0, {fullProfile, params, accessToken}, {refreshToken});
|
|
581
|
+
done(void 0, { fullProfile, params, accessToken }, { refreshToken });
|
|
563
582
|
});
|
|
564
583
|
}
|
|
565
584
|
async start(req) {
|
|
@@ -569,7 +588,7 @@ class GithubAuthProvider {
|
|
|
569
588
|
});
|
|
570
589
|
}
|
|
571
590
|
async handler(req) {
|
|
572
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
591
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
573
592
|
return {
|
|
574
593
|
response: await this.handleResult(result),
|
|
575
594
|
refreshToken: privateInfo.refreshToken
|
|
@@ -590,7 +609,7 @@ class GithubAuthProvider {
|
|
|
590
609
|
});
|
|
591
610
|
}
|
|
592
611
|
async handleResult(result) {
|
|
593
|
-
const {profile} = await this.authHandler(result);
|
|
612
|
+
const { profile } = await this.authHandler(result);
|
|
594
613
|
const expiresInStr = result.params.expires_in;
|
|
595
614
|
const response = {
|
|
596
615
|
providerInfo: {
|
|
@@ -615,12 +634,12 @@ class GithubAuthProvider {
|
|
|
615
634
|
}
|
|
616
635
|
}
|
|
617
636
|
const githubDefaultSignInResolver = async (info, ctx) => {
|
|
618
|
-
const {fullProfile} = info.result;
|
|
637
|
+
const { fullProfile } = info.result;
|
|
619
638
|
const userId = fullProfile.username || fullProfile.id;
|
|
620
639
|
const token = await ctx.tokenIssuer.issueToken({
|
|
621
|
-
claims: {sub: userId, ent: [`user:default/${userId}`]}
|
|
640
|
+
claims: { sub: userId, ent: [`user:default/${userId}`] }
|
|
622
641
|
});
|
|
623
|
-
return {id: userId, token};
|
|
642
|
+
return { id: userId, token };
|
|
624
643
|
};
|
|
625
644
|
const createGithubProvider = (options) => {
|
|
626
645
|
return ({
|
|
@@ -644,7 +663,7 @@ const createGithubProvider = (options) => {
|
|
|
644
663
|
catalogApi,
|
|
645
664
|
tokenIssuer
|
|
646
665
|
});
|
|
647
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile}) => ({
|
|
666
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
648
667
|
profile: makeProfileInfo(fullProfile)
|
|
649
668
|
});
|
|
650
669
|
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : githubDefaultSignInResolver;
|
|
@@ -654,7 +673,7 @@ const createGithubProvider = (options) => {
|
|
|
654
673
|
logger
|
|
655
674
|
});
|
|
656
675
|
const stateEncoder = (_c = options == null ? void 0 : options.stateEncoder) != null ? _c : async (req) => {
|
|
657
|
-
return {encodedState: encodeState(req.state)};
|
|
676
|
+
return { encodedState: encodeState(req.state) };
|
|
658
677
|
};
|
|
659
678
|
const provider = new GithubAuthProvider({
|
|
660
679
|
clientId,
|
|
@@ -679,15 +698,15 @@ const createGithubProvider = (options) => {
|
|
|
679
698
|
};
|
|
680
699
|
|
|
681
700
|
const gitlabDefaultSignInResolver = async (info, ctx) => {
|
|
682
|
-
const {profile, result} = info;
|
|
701
|
+
const { profile, result } = info;
|
|
683
702
|
let id = result.fullProfile.id;
|
|
684
703
|
if (profile.email) {
|
|
685
704
|
id = profile.email.split("@")[0];
|
|
686
705
|
}
|
|
687
706
|
const token = await ctx.tokenIssuer.issueToken({
|
|
688
|
-
claims: {sub: id, ent: [`user:default/${id}`]}
|
|
707
|
+
claims: { sub: id, ent: [`user:default/${id}`] }
|
|
689
708
|
});
|
|
690
|
-
return {id, token};
|
|
709
|
+
return { id, token };
|
|
691
710
|
};
|
|
692
711
|
const gitlabDefaultAuthHandler = async ({
|
|
693
712
|
fullProfile,
|
|
@@ -708,7 +727,7 @@ class GitlabAuthProvider {
|
|
|
708
727
|
callbackURL: options.callbackUrl,
|
|
709
728
|
baseURL: options.baseUrl
|
|
710
729
|
}, (accessToken, refreshToken, params, fullProfile, done) => {
|
|
711
|
-
done(void 0, {fullProfile, params, accessToken}, {
|
|
730
|
+
done(void 0, { fullProfile, params, accessToken }, {
|
|
712
731
|
refreshToken
|
|
713
732
|
});
|
|
714
733
|
});
|
|
@@ -720,7 +739,7 @@ class GitlabAuthProvider {
|
|
|
720
739
|
});
|
|
721
740
|
}
|
|
722
741
|
async handler(req) {
|
|
723
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
742
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
724
743
|
return {
|
|
725
744
|
response: await this.handleResult(result),
|
|
726
745
|
refreshToken: privateInfo.refreshToken
|
|
@@ -741,7 +760,7 @@ class GitlabAuthProvider {
|
|
|
741
760
|
});
|
|
742
761
|
}
|
|
743
762
|
async handleResult(result) {
|
|
744
|
-
const {profile} = await this.authHandler(result);
|
|
763
|
+
const { profile } = await this.authHandler(result);
|
|
745
764
|
const response = {
|
|
746
765
|
providerInfo: {
|
|
747
766
|
idToken: result.params.id_token,
|
|
@@ -842,14 +861,14 @@ class GoogleAuthProvider {
|
|
|
842
861
|
});
|
|
843
862
|
}
|
|
844
863
|
async handler(req) {
|
|
845
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
864
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
846
865
|
return {
|
|
847
866
|
response: await this.handleResult(result),
|
|
848
867
|
refreshToken: privateInfo.refreshToken
|
|
849
868
|
};
|
|
850
869
|
}
|
|
851
870
|
async refresh(req) {
|
|
852
|
-
const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
871
|
+
const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
853
872
|
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
|
|
854
873
|
return this.handleResult({
|
|
855
874
|
fullProfile,
|
|
@@ -859,7 +878,7 @@ class GoogleAuthProvider {
|
|
|
859
878
|
});
|
|
860
879
|
}
|
|
861
880
|
async handleResult(result) {
|
|
862
|
-
const {profile} = await this.authHandler(result);
|
|
881
|
+
const { profile } = await this.authHandler(result);
|
|
863
882
|
const response = {
|
|
864
883
|
providerInfo: {
|
|
865
884
|
idToken: result.params.id_token,
|
|
@@ -883,7 +902,7 @@ class GoogleAuthProvider {
|
|
|
883
902
|
}
|
|
884
903
|
}
|
|
885
904
|
const googleEmailSignInResolver = async (info, ctx) => {
|
|
886
|
-
const {profile} = info;
|
|
905
|
+
const { profile } = info;
|
|
887
906
|
if (!profile.email) {
|
|
888
907
|
throw new Error("Google profile contained no email");
|
|
889
908
|
}
|
|
@@ -893,11 +912,11 @@ const googleEmailSignInResolver = async (info, ctx) => {
|
|
|
893
912
|
}
|
|
894
913
|
});
|
|
895
914
|
const claims = getEntityClaims(entity);
|
|
896
|
-
const token = await ctx.tokenIssuer.issueToken({claims});
|
|
897
|
-
return {id: entity.metadata.name, entity, token};
|
|
915
|
+
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
916
|
+
return { id: entity.metadata.name, entity, token };
|
|
898
917
|
};
|
|
899
918
|
const googleDefaultSignInResolver = async (info, ctx) => {
|
|
900
|
-
const {profile} = info;
|
|
919
|
+
const { profile } = info;
|
|
901
920
|
if (!profile.email) {
|
|
902
921
|
throw new Error("Google profile contained no email");
|
|
903
922
|
}
|
|
@@ -914,9 +933,9 @@ const googleDefaultSignInResolver = async (info, ctx) => {
|
|
|
914
933
|
userId = profile.email.split("@")[0];
|
|
915
934
|
}
|
|
916
935
|
const token = await ctx.tokenIssuer.issueToken({
|
|
917
|
-
claims: {sub: userId, ent: [`user:default/${userId}`]}
|
|
936
|
+
claims: { sub: userId, ent: [`user:default/${userId}`] }
|
|
918
937
|
});
|
|
919
|
-
return {id: userId, token};
|
|
938
|
+
return { id: userId, token };
|
|
920
939
|
};
|
|
921
940
|
const createGoogleProvider = (options) => {
|
|
922
941
|
return ({
|
|
@@ -935,7 +954,7 @@ const createGoogleProvider = (options) => {
|
|
|
935
954
|
catalogApi,
|
|
936
955
|
tokenIssuer
|
|
937
956
|
});
|
|
938
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile, params}) => ({
|
|
957
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
939
958
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
940
959
|
});
|
|
941
960
|
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : googleDefaultSignInResolver;
|
|
@@ -977,7 +996,7 @@ class MicrosoftAuthProvider {
|
|
|
977
996
|
tokenURL: options.tokenUrl,
|
|
978
997
|
passReqToCallback: false
|
|
979
998
|
}, (accessToken, refreshToken, params, fullProfile, done) => {
|
|
980
|
-
done(void 0, {fullProfile, accessToken, params}, {refreshToken});
|
|
999
|
+
done(void 0, { fullProfile, accessToken, params }, { refreshToken });
|
|
981
1000
|
});
|
|
982
1001
|
}
|
|
983
1002
|
async start(req) {
|
|
@@ -987,14 +1006,14 @@ class MicrosoftAuthProvider {
|
|
|
987
1006
|
});
|
|
988
1007
|
}
|
|
989
1008
|
async handler(req) {
|
|
990
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1009
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
991
1010
|
return {
|
|
992
1011
|
response: await this.handleResult(result),
|
|
993
1012
|
refreshToken: privateInfo.refreshToken
|
|
994
1013
|
};
|
|
995
1014
|
}
|
|
996
1015
|
async refresh(req) {
|
|
997
|
-
const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
1016
|
+
const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
998
1017
|
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
|
|
999
1018
|
return this.handleResult({
|
|
1000
1019
|
fullProfile,
|
|
@@ -1005,8 +1024,8 @@ class MicrosoftAuthProvider {
|
|
|
1005
1024
|
}
|
|
1006
1025
|
async handleResult(result) {
|
|
1007
1026
|
const photo = await this.getUserPhoto(result.accessToken);
|
|
1008
|
-
result.fullProfile.photos = photo ? [{value: photo}] : void 0;
|
|
1009
|
-
const {profile} = await this.authHandler(result);
|
|
1027
|
+
result.fullProfile.photos = photo ? [{ value: photo }] : void 0;
|
|
1028
|
+
const { profile } = await this.authHandler(result);
|
|
1010
1029
|
const response = {
|
|
1011
1030
|
providerInfo: {
|
|
1012
1031
|
idToken: result.params.id_token,
|
|
@@ -1030,7 +1049,7 @@ class MicrosoftAuthProvider {
|
|
|
1030
1049
|
}
|
|
1031
1050
|
getUserPhoto(accessToken) {
|
|
1032
1051
|
return new Promise((resolve) => {
|
|
1033
|
-
got__default[
|
|
1052
|
+
got__default["default"].get("https://graph.microsoft.com/v1.0/me/photos/48x48/$value", {
|
|
1034
1053
|
encoding: "binary",
|
|
1035
1054
|
responseType: "buffer",
|
|
1036
1055
|
headers: {
|
|
@@ -1047,7 +1066,7 @@ class MicrosoftAuthProvider {
|
|
|
1047
1066
|
}
|
|
1048
1067
|
}
|
|
1049
1068
|
const microsoftEmailSignInResolver = async (info, ctx) => {
|
|
1050
|
-
const {profile} = info;
|
|
1069
|
+
const { profile } = info;
|
|
1051
1070
|
if (!profile.email) {
|
|
1052
1071
|
throw new Error("Microsoft profile contained no email");
|
|
1053
1072
|
}
|
|
@@ -1057,19 +1076,19 @@ const microsoftEmailSignInResolver = async (info, ctx) => {
|
|
|
1057
1076
|
}
|
|
1058
1077
|
});
|
|
1059
1078
|
const claims = getEntityClaims(entity);
|
|
1060
|
-
const token = await ctx.tokenIssuer.issueToken({claims});
|
|
1061
|
-
return {id: entity.metadata.name, entity, token};
|
|
1079
|
+
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
1080
|
+
return { id: entity.metadata.name, entity, token };
|
|
1062
1081
|
};
|
|
1063
1082
|
const microsoftDefaultSignInResolver = async (info, ctx) => {
|
|
1064
|
-
const {profile} = info;
|
|
1083
|
+
const { profile } = info;
|
|
1065
1084
|
if (!profile.email) {
|
|
1066
1085
|
throw new Error("Profile contained no email");
|
|
1067
1086
|
}
|
|
1068
1087
|
const userId = profile.email.split("@")[0];
|
|
1069
1088
|
const token = await ctx.tokenIssuer.issueToken({
|
|
1070
|
-
claims: {sub: userId, ent: [`user:default/${userId}`]}
|
|
1089
|
+
claims: { sub: userId, ent: [`user:default/${userId}`] }
|
|
1071
1090
|
});
|
|
1072
|
-
return {id: userId, token};
|
|
1091
|
+
return { id: userId, token };
|
|
1073
1092
|
};
|
|
1074
1093
|
const createMicrosoftProvider = (options) => {
|
|
1075
1094
|
return ({
|
|
@@ -1091,7 +1110,7 @@ const createMicrosoftProvider = (options) => {
|
|
|
1091
1110
|
catalogApi,
|
|
1092
1111
|
tokenIssuer
|
|
1093
1112
|
});
|
|
1094
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile, params}) => ({
|
|
1113
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1095
1114
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1096
1115
|
});
|
|
1097
1116
|
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : microsoftDefaultSignInResolver;
|
|
@@ -1134,7 +1153,10 @@ class OAuth2AuthProvider {
|
|
|
1134
1153
|
authorizationURL: options.authorizationUrl,
|
|
1135
1154
|
tokenURL: options.tokenUrl,
|
|
1136
1155
|
passReqToCallback: false,
|
|
1137
|
-
scope: options.scope
|
|
1156
|
+
scope: options.scope,
|
|
1157
|
+
customHeaders: options.includeBasicAuth ? {
|
|
1158
|
+
Authorization: `Basic ${this.encodeClientCredentials(options.clientId, options.clientSecret)}`
|
|
1159
|
+
} : void 0
|
|
1138
1160
|
}, (accessToken, refreshToken, params, fullProfile, done) => {
|
|
1139
1161
|
done(void 0, {
|
|
1140
1162
|
fullProfile,
|
|
@@ -1155,7 +1177,7 @@ class OAuth2AuthProvider {
|
|
|
1155
1177
|
});
|
|
1156
1178
|
}
|
|
1157
1179
|
async handler(req) {
|
|
1158
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1180
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1159
1181
|
return {
|
|
1160
1182
|
response: await this.handleResult(result),
|
|
1161
1183
|
refreshToken: privateInfo.refreshToken
|
|
@@ -1177,7 +1199,7 @@ class OAuth2AuthProvider {
|
|
|
1177
1199
|
});
|
|
1178
1200
|
}
|
|
1179
1201
|
async handleResult(result) {
|
|
1180
|
-
const {profile} = await this.authHandler(result);
|
|
1202
|
+
const { profile } = await this.authHandler(result);
|
|
1181
1203
|
const response = {
|
|
1182
1204
|
providerInfo: {
|
|
1183
1205
|
idToken: result.params.id_token,
|
|
@@ -1200,17 +1222,20 @@ class OAuth2AuthProvider {
|
|
|
1200
1222
|
}
|
|
1201
1223
|
return response;
|
|
1202
1224
|
}
|
|
1225
|
+
encodeClientCredentials(clientID, clientSecret) {
|
|
1226
|
+
return Buffer.from(`${clientID}:${clientSecret}`).toString("base64");
|
|
1227
|
+
}
|
|
1203
1228
|
}
|
|
1204
|
-
const oAuth2DefaultSignInResolver = async (info, ctx) => {
|
|
1205
|
-
const {profile} = info;
|
|
1229
|
+
const oAuth2DefaultSignInResolver$1 = async (info, ctx) => {
|
|
1230
|
+
const { profile } = info;
|
|
1206
1231
|
if (!profile.email) {
|
|
1207
1232
|
throw new Error("Profile contained no email");
|
|
1208
1233
|
}
|
|
1209
1234
|
const userId = profile.email.split("@")[0];
|
|
1210
1235
|
const token = await ctx.tokenIssuer.issueToken({
|
|
1211
|
-
claims: {sub: userId, ent: [`user:default/${userId}`]}
|
|
1236
|
+
claims: { sub: userId, ent: [`user:default/${userId}`] }
|
|
1212
1237
|
});
|
|
1213
|
-
return {id: userId, token};
|
|
1238
|
+
return { id: userId, token };
|
|
1214
1239
|
};
|
|
1215
1240
|
const createOAuth2Provider = (options) => {
|
|
1216
1241
|
return ({
|
|
@@ -1228,15 +1253,16 @@ const createOAuth2Provider = (options) => {
|
|
|
1228
1253
|
const authorizationUrl = envConfig.getString("authorizationUrl");
|
|
1229
1254
|
const tokenUrl = envConfig.getString("tokenUrl");
|
|
1230
1255
|
const scope = envConfig.getOptionalString("scope");
|
|
1256
|
+
const includeBasicAuth = envConfig.getOptionalBoolean("includeBasicAuth");
|
|
1231
1257
|
const disableRefresh = (_a = envConfig.getOptionalBoolean("disableRefresh")) != null ? _a : false;
|
|
1232
1258
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1233
1259
|
catalogApi,
|
|
1234
1260
|
tokenIssuer
|
|
1235
1261
|
});
|
|
1236
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile, params}) => ({
|
|
1262
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1237
1263
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1238
1264
|
});
|
|
1239
|
-
const signInResolverFn = (_c = (_b = options == null ? void 0 : options.signIn) == null ? void 0 : _b.resolver) != null ? _c : oAuth2DefaultSignInResolver;
|
|
1265
|
+
const signInResolverFn = (_c = (_b = options == null ? void 0 : options.signIn) == null ? void 0 : _b.resolver) != null ? _c : oAuth2DefaultSignInResolver$1;
|
|
1240
1266
|
const signInResolver = (info) => signInResolverFn(info, {
|
|
1241
1267
|
catalogIdentityClient,
|
|
1242
1268
|
tokenIssuer,
|
|
@@ -1253,7 +1279,8 @@ const createOAuth2Provider = (options) => {
|
|
|
1253
1279
|
authorizationUrl,
|
|
1254
1280
|
tokenUrl,
|
|
1255
1281
|
scope,
|
|
1256
|
-
logger
|
|
1282
|
+
logger,
|
|
1283
|
+
includeBasicAuth
|
|
1257
1284
|
});
|
|
1258
1285
|
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1259
1286
|
disableRefresh,
|
|
@@ -1263,6 +1290,168 @@ const createOAuth2Provider = (options) => {
|
|
|
1263
1290
|
});
|
|
1264
1291
|
};
|
|
1265
1292
|
|
|
1293
|
+
class OidcAuthProvider {
|
|
1294
|
+
constructor(options) {
|
|
1295
|
+
this.implementation = this.setupStrategy(options);
|
|
1296
|
+
this.scope = options.scope;
|
|
1297
|
+
this.prompt = options.prompt;
|
|
1298
|
+
this.signInResolver = options.signInResolver;
|
|
1299
|
+
this.authHandler = options.authHandler;
|
|
1300
|
+
this.tokenIssuer = options.tokenIssuer;
|
|
1301
|
+
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
1302
|
+
this.logger = options.logger;
|
|
1303
|
+
}
|
|
1304
|
+
async start(req) {
|
|
1305
|
+
const { strategy } = await this.implementation;
|
|
1306
|
+
const options = {
|
|
1307
|
+
scope: req.scope || this.scope || "openid profile email",
|
|
1308
|
+
state: encodeState(req.state)
|
|
1309
|
+
};
|
|
1310
|
+
const prompt = this.prompt || "none";
|
|
1311
|
+
if (prompt !== "auto") {
|
|
1312
|
+
options.prompt = prompt;
|
|
1313
|
+
}
|
|
1314
|
+
return await executeRedirectStrategy(req, strategy, options);
|
|
1315
|
+
}
|
|
1316
|
+
async handler(req) {
|
|
1317
|
+
const { strategy } = await this.implementation;
|
|
1318
|
+
const strategyResponse = await executeFrameHandlerStrategy(req, strategy);
|
|
1319
|
+
const {
|
|
1320
|
+
result: { userinfo, tokenset },
|
|
1321
|
+
privateInfo
|
|
1322
|
+
} = strategyResponse;
|
|
1323
|
+
const identityResponse = await this.handleResult({ tokenset, userinfo });
|
|
1324
|
+
return {
|
|
1325
|
+
response: identityResponse,
|
|
1326
|
+
refreshToken: privateInfo.refreshToken
|
|
1327
|
+
};
|
|
1328
|
+
}
|
|
1329
|
+
async refresh(req) {
|
|
1330
|
+
const { client } = await this.implementation;
|
|
1331
|
+
const tokenset = await client.refresh(req.refreshToken);
|
|
1332
|
+
if (!tokenset.access_token) {
|
|
1333
|
+
throw new Error("Refresh failed");
|
|
1334
|
+
}
|
|
1335
|
+
const profile = await client.userinfo(tokenset.access_token);
|
|
1336
|
+
return this.handleResult({ tokenset, userinfo: profile });
|
|
1337
|
+
}
|
|
1338
|
+
async setupStrategy(options) {
|
|
1339
|
+
const issuer = await openidClient.Issuer.discover(options.metadataUrl);
|
|
1340
|
+
const client = new issuer.Client({
|
|
1341
|
+
access_type: "offline",
|
|
1342
|
+
client_id: options.clientId,
|
|
1343
|
+
client_secret: options.clientSecret,
|
|
1344
|
+
redirect_uris: [options.callbackUrl],
|
|
1345
|
+
response_types: ["code"],
|
|
1346
|
+
id_token_signed_response_alg: options.tokenSignedResponseAlg || "RS256",
|
|
1347
|
+
scope: options.scope || ""
|
|
1348
|
+
});
|
|
1349
|
+
const strategy = new openidClient.Strategy({
|
|
1350
|
+
client,
|
|
1351
|
+
passReqToCallback: false
|
|
1352
|
+
}, (tokenset, userinfo, done) => {
|
|
1353
|
+
if (typeof done !== "function") {
|
|
1354
|
+
throw new Error("OIDC IdP must provide a userinfo_endpoint in the metadata response");
|
|
1355
|
+
}
|
|
1356
|
+
done(void 0, { tokenset, userinfo }, {
|
|
1357
|
+
refreshToken: tokenset.refresh_token
|
|
1358
|
+
});
|
|
1359
|
+
});
|
|
1360
|
+
strategy.error = console.error;
|
|
1361
|
+
return { strategy, client };
|
|
1362
|
+
}
|
|
1363
|
+
async handleResult(result) {
|
|
1364
|
+
const { profile } = await this.authHandler(result);
|
|
1365
|
+
const response = {
|
|
1366
|
+
providerInfo: {
|
|
1367
|
+
idToken: result.tokenset.id_token,
|
|
1368
|
+
accessToken: result.tokenset.access_token,
|
|
1369
|
+
refreshToken: result.tokenset.refresh_token,
|
|
1370
|
+
scope: result.tokenset.scope,
|
|
1371
|
+
expiresInSeconds: result.tokenset.expires_in
|
|
1372
|
+
},
|
|
1373
|
+
profile
|
|
1374
|
+
};
|
|
1375
|
+
if (this.signInResolver) {
|
|
1376
|
+
response.backstageIdentity = await this.signInResolver({
|
|
1377
|
+
result,
|
|
1378
|
+
profile
|
|
1379
|
+
}, {
|
|
1380
|
+
tokenIssuer: this.tokenIssuer,
|
|
1381
|
+
catalogIdentityClient: this.catalogIdentityClient,
|
|
1382
|
+
logger: this.logger
|
|
1383
|
+
});
|
|
1384
|
+
}
|
|
1385
|
+
return response;
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
const oAuth2DefaultSignInResolver = async (info, ctx) => {
|
|
1389
|
+
const { profile } = info;
|
|
1390
|
+
if (!profile.email) {
|
|
1391
|
+
throw new Error("Profile contained no email");
|
|
1392
|
+
}
|
|
1393
|
+
const userId = profile.email.split("@")[0];
|
|
1394
|
+
const token = await ctx.tokenIssuer.issueToken({
|
|
1395
|
+
claims: { sub: userId, ent: [`user:default/${userId}`] }
|
|
1396
|
+
});
|
|
1397
|
+
return { id: userId, token };
|
|
1398
|
+
};
|
|
1399
|
+
const createOidcProvider = (options) => {
|
|
1400
|
+
return ({
|
|
1401
|
+
providerId,
|
|
1402
|
+
globalConfig,
|
|
1403
|
+
config,
|
|
1404
|
+
tokenIssuer,
|
|
1405
|
+
catalogApi,
|
|
1406
|
+
logger
|
|
1407
|
+
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1408
|
+
var _a, _b;
|
|
1409
|
+
const clientId = envConfig.getString("clientId");
|
|
1410
|
+
const clientSecret = envConfig.getString("clientSecret");
|
|
1411
|
+
const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1412
|
+
const metadataUrl = envConfig.getString("metadataUrl");
|
|
1413
|
+
const tokenSignedResponseAlg = envConfig.getOptionalString("tokenSignedResponseAlg");
|
|
1414
|
+
const scope = envConfig.getOptionalString("scope");
|
|
1415
|
+
const prompt = envConfig.getOptionalString("prompt");
|
|
1416
|
+
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1417
|
+
catalogApi,
|
|
1418
|
+
tokenIssuer
|
|
1419
|
+
});
|
|
1420
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ userinfo }) => ({
|
|
1421
|
+
profile: {
|
|
1422
|
+
displayName: userinfo.name,
|
|
1423
|
+
email: userinfo.email,
|
|
1424
|
+
picture: userinfo.picture
|
|
1425
|
+
}
|
|
1426
|
+
});
|
|
1427
|
+
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : oAuth2DefaultSignInResolver;
|
|
1428
|
+
const signInResolver = (info) => signInResolverFn(info, {
|
|
1429
|
+
catalogIdentityClient,
|
|
1430
|
+
tokenIssuer,
|
|
1431
|
+
logger
|
|
1432
|
+
});
|
|
1433
|
+
const provider = new OidcAuthProvider({
|
|
1434
|
+
clientId,
|
|
1435
|
+
clientSecret,
|
|
1436
|
+
callbackUrl,
|
|
1437
|
+
tokenSignedResponseAlg,
|
|
1438
|
+
metadataUrl,
|
|
1439
|
+
scope,
|
|
1440
|
+
prompt,
|
|
1441
|
+
signInResolver,
|
|
1442
|
+
authHandler,
|
|
1443
|
+
logger,
|
|
1444
|
+
tokenIssuer,
|
|
1445
|
+
catalogIdentityClient
|
|
1446
|
+
});
|
|
1447
|
+
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1448
|
+
disableRefresh: false,
|
|
1449
|
+
providerId,
|
|
1450
|
+
tokenIssuer
|
|
1451
|
+
});
|
|
1452
|
+
});
|
|
1453
|
+
};
|
|
1454
|
+
|
|
1266
1455
|
class OktaAuthProvider {
|
|
1267
1456
|
constructor(options) {
|
|
1268
1457
|
this._store = {
|
|
@@ -1306,14 +1495,14 @@ class OktaAuthProvider {
|
|
|
1306
1495
|
});
|
|
1307
1496
|
}
|
|
1308
1497
|
async handler(req) {
|
|
1309
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1498
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1310
1499
|
return {
|
|
1311
1500
|
response: await this.handleResult(result),
|
|
1312
1501
|
refreshToken: privateInfo.refreshToken
|
|
1313
1502
|
};
|
|
1314
1503
|
}
|
|
1315
1504
|
async refresh(req) {
|
|
1316
|
-
const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
1505
|
+
const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
1317
1506
|
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
|
|
1318
1507
|
return this.handleResult({
|
|
1319
1508
|
fullProfile,
|
|
@@ -1323,7 +1512,7 @@ class OktaAuthProvider {
|
|
|
1323
1512
|
});
|
|
1324
1513
|
}
|
|
1325
1514
|
async handleResult(result) {
|
|
1326
|
-
const {profile} = await this._authHandler(result);
|
|
1515
|
+
const { profile } = await this._authHandler(result);
|
|
1327
1516
|
const response = {
|
|
1328
1517
|
providerInfo: {
|
|
1329
1518
|
idToken: result.params.id_token,
|
|
@@ -1347,7 +1536,7 @@ class OktaAuthProvider {
|
|
|
1347
1536
|
}
|
|
1348
1537
|
}
|
|
1349
1538
|
const oktaEmailSignInResolver = async (info, ctx) => {
|
|
1350
|
-
const {profile} = info;
|
|
1539
|
+
const { profile } = info;
|
|
1351
1540
|
if (!profile.email) {
|
|
1352
1541
|
throw new Error("Okta profile contained no email");
|
|
1353
1542
|
}
|
|
@@ -1357,19 +1546,19 @@ const oktaEmailSignInResolver = async (info, ctx) => {
|
|
|
1357
1546
|
}
|
|
1358
1547
|
});
|
|
1359
1548
|
const claims = getEntityClaims(entity);
|
|
1360
|
-
const token = await ctx.tokenIssuer.issueToken({claims});
|
|
1361
|
-
return {id: entity.metadata.name, entity, token};
|
|
1549
|
+
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
1550
|
+
return { id: entity.metadata.name, entity, token };
|
|
1362
1551
|
};
|
|
1363
1552
|
const oktaDefaultSignInResolver = async (info, ctx) => {
|
|
1364
|
-
const {profile} = info;
|
|
1553
|
+
const { profile } = info;
|
|
1365
1554
|
if (!profile.email) {
|
|
1366
1555
|
throw new Error("Okta profile contained no email");
|
|
1367
1556
|
}
|
|
1368
1557
|
const userId = profile.email.split("@")[0];
|
|
1369
1558
|
const token = await ctx.tokenIssuer.issueToken({
|
|
1370
|
-
claims: {sub: userId, ent: [`user:default/${userId}`]}
|
|
1559
|
+
claims: { sub: userId, ent: [`user:default/${userId}`] }
|
|
1371
1560
|
});
|
|
1372
|
-
return {id: userId, token};
|
|
1561
|
+
return { id: userId, token };
|
|
1373
1562
|
};
|
|
1374
1563
|
const createOktaProvider = (_options) => {
|
|
1375
1564
|
return ({
|
|
@@ -1392,7 +1581,7 @@ const createOktaProvider = (_options) => {
|
|
|
1392
1581
|
catalogApi,
|
|
1393
1582
|
tokenIssuer
|
|
1394
1583
|
});
|
|
1395
|
-
const authHandler = (_options == null ? void 0 : _options.authHandler) ? _options.authHandler : async ({fullProfile, params}) => ({
|
|
1584
|
+
const authHandler = (_options == null ? void 0 : _options.authHandler) ? _options.authHandler : async ({ fullProfile, params }) => ({
|
|
1396
1585
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1397
1586
|
});
|
|
1398
1587
|
const signInResolverFn = (_b = (_a = _options == null ? void 0 : _options.signIn) == null ? void 0 : _a.resolver) != null ? _b : oktaDefaultSignInResolver;
|
|
@@ -1452,14 +1641,14 @@ class BitbucketAuthProvider {
|
|
|
1452
1641
|
});
|
|
1453
1642
|
}
|
|
1454
1643
|
async handler(req) {
|
|
1455
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1644
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1456
1645
|
return {
|
|
1457
1646
|
response: await this.handleResult(result),
|
|
1458
1647
|
refreshToken: privateInfo.refreshToken
|
|
1459
1648
|
};
|
|
1460
1649
|
}
|
|
1461
1650
|
async refresh(req) {
|
|
1462
|
-
const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
1651
|
+
const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
1463
1652
|
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
|
|
1464
1653
|
return this.handleResult({
|
|
1465
1654
|
fullProfile,
|
|
@@ -1470,7 +1659,7 @@ class BitbucketAuthProvider {
|
|
|
1470
1659
|
}
|
|
1471
1660
|
async handleResult(result) {
|
|
1472
1661
|
result.fullProfile.avatarUrl = result.fullProfile._json.links.avatar.href;
|
|
1473
|
-
const {profile} = await this.authHandler(result);
|
|
1662
|
+
const { profile } = await this.authHandler(result);
|
|
1474
1663
|
const response = {
|
|
1475
1664
|
providerInfo: {
|
|
1476
1665
|
idToken: result.params.id_token,
|
|
@@ -1494,7 +1683,7 @@ class BitbucketAuthProvider {
|
|
|
1494
1683
|
}
|
|
1495
1684
|
}
|
|
1496
1685
|
const bitbucketUsernameSignInResolver = async (info, ctx) => {
|
|
1497
|
-
const {result} = info;
|
|
1686
|
+
const { result } = info;
|
|
1498
1687
|
if (!result.fullProfile.username) {
|
|
1499
1688
|
throw new Error("Bitbucket profile contained no Username");
|
|
1500
1689
|
}
|
|
@@ -1504,11 +1693,11 @@ const bitbucketUsernameSignInResolver = async (info, ctx) => {
|
|
|
1504
1693
|
}
|
|
1505
1694
|
});
|
|
1506
1695
|
const claims = getEntityClaims(entity);
|
|
1507
|
-
const token = await ctx.tokenIssuer.issueToken({claims});
|
|
1508
|
-
return {id: entity.metadata.name, entity, token};
|
|
1696
|
+
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
1697
|
+
return { id: entity.metadata.name, entity, token };
|
|
1509
1698
|
};
|
|
1510
1699
|
const bitbucketUserIdSignInResolver = async (info, ctx) => {
|
|
1511
|
-
const {result} = info;
|
|
1700
|
+
const { result } = info;
|
|
1512
1701
|
if (!result.fullProfile.id) {
|
|
1513
1702
|
throw new Error("Bitbucket profile contained no User ID");
|
|
1514
1703
|
}
|
|
@@ -1518,8 +1707,8 @@ const bitbucketUserIdSignInResolver = async (info, ctx) => {
|
|
|
1518
1707
|
}
|
|
1519
1708
|
});
|
|
1520
1709
|
const claims = getEntityClaims(entity);
|
|
1521
|
-
const token = await ctx.tokenIssuer.issueToken({claims});
|
|
1522
|
-
return {id: entity.metadata.name, entity, token};
|
|
1710
|
+
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
1711
|
+
return { id: entity.metadata.name, entity, token };
|
|
1523
1712
|
};
|
|
1524
1713
|
const createBitbucketProvider = (options) => {
|
|
1525
1714
|
return ({
|
|
@@ -1538,7 +1727,7 @@ const createBitbucketProvider = (options) => {
|
|
|
1538
1727
|
catalogApi,
|
|
1539
1728
|
tokenIssuer
|
|
1540
1729
|
});
|
|
1541
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile, params}) => ({
|
|
1730
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1542
1731
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1543
1732
|
});
|
|
1544
1733
|
const provider = new BitbucketAuthProvider({
|
|
@@ -1560,7 +1749,7 @@ const createBitbucketProvider = (options) => {
|
|
|
1560
1749
|
};
|
|
1561
1750
|
|
|
1562
1751
|
const defaultScopes = ["offline_access", "read:me"];
|
|
1563
|
-
class AtlassianStrategy extends OAuth2Strategy__default[
|
|
1752
|
+
class AtlassianStrategy extends OAuth2Strategy__default["default"] {
|
|
1564
1753
|
constructor(options, verify) {
|
|
1565
1754
|
if (!options.scope) {
|
|
1566
1755
|
throw new TypeError("Atlassian requires a scope option");
|
|
@@ -1570,7 +1759,7 @@ class AtlassianStrategy extends OAuth2Strategy__default['default'] {
|
|
|
1570
1759
|
...options,
|
|
1571
1760
|
authorizationURL: `https://auth.atlassian.com/authorize`,
|
|
1572
1761
|
tokenURL: `https://auth.atlassian.com/oauth/token`,
|
|
1573
|
-
scope: Array.from(new Set([...defaultScopes, ...scopes]))
|
|
1762
|
+
scope: Array.from(/* @__PURE__ */ new Set([...defaultScopes, ...scopes]))
|
|
1574
1763
|
};
|
|
1575
1764
|
super(optionsWithURLs, verify);
|
|
1576
1765
|
this.profileURL = "https://api.atlassian.com/me";
|
|
@@ -1607,8 +1796,8 @@ class AtlassianStrategy extends OAuth2Strategy__default['default'] {
|
|
|
1607
1796
|
provider: "atlassian",
|
|
1608
1797
|
username: resp.nickname,
|
|
1609
1798
|
displayName: resp.name,
|
|
1610
|
-
emails: [{value: resp.email}],
|
|
1611
|
-
photos: [{value: resp.picture}]
|
|
1799
|
+
emails: [{ value: resp.email }],
|
|
1800
|
+
photos: [{ value: resp.picture }]
|
|
1612
1801
|
};
|
|
1613
1802
|
}
|
|
1614
1803
|
}
|
|
@@ -1647,14 +1836,14 @@ class AtlassianAuthProvider {
|
|
|
1647
1836
|
}
|
|
1648
1837
|
async handler(req) {
|
|
1649
1838
|
var _a;
|
|
1650
|
-
const {result} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1839
|
+
const { result } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1651
1840
|
return {
|
|
1652
1841
|
response: await this.handleResult(result),
|
|
1653
1842
|
refreshToken: (_a = result.refreshToken) != null ? _a : ""
|
|
1654
1843
|
};
|
|
1655
1844
|
}
|
|
1656
1845
|
async handleResult(result) {
|
|
1657
|
-
const {profile} = await this.authHandler(result);
|
|
1846
|
+
const { profile } = await this.authHandler(result);
|
|
1658
1847
|
const response = {
|
|
1659
1848
|
providerInfo: {
|
|
1660
1849
|
idToken: result.params.id_token,
|
|
@@ -1745,7 +1934,7 @@ class AwsAlbAuthProvider {
|
|
|
1745
1934
|
this.tokenIssuer = options.tokenIssuer;
|
|
1746
1935
|
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
1747
1936
|
this.logger = options.logger;
|
|
1748
|
-
this.keyCache = new NodeCache__default[
|
|
1937
|
+
this.keyCache = new NodeCache__default["default"]({ stdTTL: 3600 });
|
|
1749
1938
|
}
|
|
1750
1939
|
frameHandler() {
|
|
1751
1940
|
return Promise.resolve(void 0);
|
|
@@ -1789,8 +1978,8 @@ class AwsAlbAuthProvider {
|
|
|
1789
1978
|
familyName: claims.family_name,
|
|
1790
1979
|
givenName: claims.given_name
|
|
1791
1980
|
},
|
|
1792
|
-
emails: [{value: claims.email.toLowerCase()}],
|
|
1793
|
-
photos: [{value: claims.picture}]
|
|
1981
|
+
emails: [{ value: claims.email.toLowerCase() }],
|
|
1982
|
+
photos: [{ value: claims.picture }]
|
|
1794
1983
|
};
|
|
1795
1984
|
return {
|
|
1796
1985
|
fullProfile,
|
|
@@ -1802,7 +1991,7 @@ class AwsAlbAuthProvider {
|
|
|
1802
1991
|
}
|
|
1803
1992
|
}
|
|
1804
1993
|
async handleResult(result) {
|
|
1805
|
-
const {profile} = await this.authHandler(result);
|
|
1994
|
+
const { profile } = await this.authHandler(result);
|
|
1806
1995
|
const backstageIdentity = await this.signInResolver({
|
|
1807
1996
|
result,
|
|
1808
1997
|
profile
|
|
@@ -1816,7 +2005,7 @@ class AwsAlbAuthProvider {
|
|
|
1816
2005
|
accessToken: result.accessToken,
|
|
1817
2006
|
expiresInSeconds: result.expiresInSeconds
|
|
1818
2007
|
},
|
|
1819
|
-
backstageIdentity,
|
|
2008
|
+
backstageIdentity: prepareBackstageIdentityResponse(backstageIdentity),
|
|
1820
2009
|
profile
|
|
1821
2010
|
};
|
|
1822
2011
|
}
|
|
@@ -1825,14 +2014,14 @@ class AwsAlbAuthProvider {
|
|
|
1825
2014
|
if (optionalCacheKey) {
|
|
1826
2015
|
return crypto__namespace.createPublicKey(optionalCacheKey);
|
|
1827
2016
|
}
|
|
1828
|
-
const keyText = await fetch__default[
|
|
2017
|
+
const keyText = await fetch__default["default"](`https://public-keys.auth.elb.${this.region}.amazonaws.com/${keyId}`).then((response) => response.text());
|
|
1829
2018
|
const keyValue = crypto__namespace.createPublicKey(keyText);
|
|
1830
|
-
this.keyCache.set(keyId, keyValue.export({format: "pem", type: "spki"}));
|
|
2019
|
+
this.keyCache.set(keyId, keyValue.export({ format: "pem", type: "spki" }));
|
|
1831
2020
|
return keyValue;
|
|
1832
2021
|
}
|
|
1833
2022
|
}
|
|
1834
2023
|
const createAwsAlbProvider = (options) => {
|
|
1835
|
-
return ({config, tokenIssuer, catalogApi, logger}) => {
|
|
2024
|
+
return ({ config, tokenIssuer, catalogApi, logger }) => {
|
|
1836
2025
|
const region = config.getString("region");
|
|
1837
2026
|
const issuer = config.getOptionalString("iss");
|
|
1838
2027
|
if ((options == null ? void 0 : options.signIn.resolver) === void 0) {
|
|
@@ -1842,7 +2031,7 @@ const createAwsAlbProvider = (options) => {
|
|
|
1842
2031
|
catalogApi,
|
|
1843
2032
|
tokenIssuer
|
|
1844
2033
|
});
|
|
1845
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile}) => ({
|
|
2034
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
1846
2035
|
profile: makeProfileInfo(fullProfile)
|
|
1847
2036
|
});
|
|
1848
2037
|
const signInResolver = options == null ? void 0 : options.signIn.resolver;
|
|
@@ -1858,182 +2047,98 @@ const createAwsAlbProvider = (options) => {
|
|
|
1858
2047
|
};
|
|
1859
2048
|
};
|
|
1860
2049
|
|
|
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
2050
|
class SamlAuthProvider {
|
|
1983
2051
|
constructor(options) {
|
|
1984
2052
|
this.appUrl = options.appUrl;
|
|
2053
|
+
this.signInResolver = options.signInResolver;
|
|
2054
|
+
this.authHandler = options.authHandler;
|
|
1985
2055
|
this.tokenIssuer = options.tokenIssuer;
|
|
1986
|
-
this.
|
|
1987
|
-
|
|
2056
|
+
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
2057
|
+
this.logger = options.logger;
|
|
2058
|
+
this.strategy = new passportSaml.Strategy({ ...options }, (fullProfile, done) => {
|
|
2059
|
+
done(void 0, { fullProfile });
|
|
1988
2060
|
});
|
|
1989
2061
|
}
|
|
1990
2062
|
async start(req, res) {
|
|
1991
|
-
const {url} = await executeRedirectStrategy(req, this.strategy, {});
|
|
2063
|
+
const { url } = await executeRedirectStrategy(req, this.strategy, {});
|
|
1992
2064
|
res.redirect(url);
|
|
1993
2065
|
}
|
|
1994
2066
|
async frameHandler(req, res) {
|
|
1995
2067
|
try {
|
|
1996
|
-
const {result} = await executeFrameHandlerStrategy(req, this.strategy);
|
|
1997
|
-
const
|
|
1998
|
-
const
|
|
1999
|
-
|
|
2000
|
-
|
|
2068
|
+
const { result } = await executeFrameHandlerStrategy(req, this.strategy);
|
|
2069
|
+
const { profile } = await this.authHandler(result);
|
|
2070
|
+
const response = {
|
|
2071
|
+
profile,
|
|
2072
|
+
providerInfo: {}
|
|
2073
|
+
};
|
|
2074
|
+
if (this.signInResolver) {
|
|
2075
|
+
const signInResponse = await this.signInResolver({
|
|
2076
|
+
result,
|
|
2077
|
+
profile
|
|
2078
|
+
}, {
|
|
2079
|
+
tokenIssuer: this.tokenIssuer,
|
|
2080
|
+
catalogIdentityClient: this.catalogIdentityClient,
|
|
2081
|
+
logger: this.logger
|
|
2082
|
+
});
|
|
2083
|
+
response.backstageIdentity = prepareBackstageIdentityResponse(signInResponse);
|
|
2084
|
+
}
|
|
2001
2085
|
return postMessageResponse(res, this.appUrl, {
|
|
2002
2086
|
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
|
-
}
|
|
2087
|
+
response
|
|
2011
2088
|
});
|
|
2012
2089
|
} catch (error) {
|
|
2013
|
-
const {name, message} = errors.isError(error) ? error : new Error("Encountered invalid error");
|
|
2090
|
+
const { name, message } = errors.isError(error) ? error : new Error("Encountered invalid error");
|
|
2014
2091
|
return postMessageResponse(res, this.appUrl, {
|
|
2015
2092
|
type: "authorization_response",
|
|
2016
|
-
error: {name, message}
|
|
2093
|
+
error: { name, message }
|
|
2017
2094
|
});
|
|
2018
2095
|
}
|
|
2019
2096
|
}
|
|
2020
2097
|
async logout(_req, res) {
|
|
2021
|
-
res.
|
|
2022
|
-
}
|
|
2023
|
-
identifyEnv() {
|
|
2024
|
-
return void 0;
|
|
2098
|
+
res.end();
|
|
2025
2099
|
}
|
|
2026
2100
|
}
|
|
2027
|
-
const
|
|
2028
|
-
|
|
2029
|
-
|
|
2101
|
+
const samlDefaultSignInResolver = async (info, ctx) => {
|
|
2102
|
+
const id = info.result.fullProfile.nameID;
|
|
2103
|
+
const token = await ctx.tokenIssuer.issueToken({
|
|
2104
|
+
claims: { sub: id }
|
|
2105
|
+
});
|
|
2106
|
+
return { id, token };
|
|
2107
|
+
};
|
|
2108
|
+
const createSamlProvider = (options) => {
|
|
2109
|
+
return ({
|
|
2110
|
+
providerId,
|
|
2111
|
+
globalConfig,
|
|
2112
|
+
config,
|
|
2113
|
+
tokenIssuer,
|
|
2114
|
+
catalogApi,
|
|
2115
|
+
logger
|
|
2116
|
+
}) => {
|
|
2117
|
+
var _a, _b;
|
|
2118
|
+
const catalogIdentityClient = new CatalogIdentityClient({
|
|
2119
|
+
catalogApi,
|
|
2120
|
+
tokenIssuer
|
|
2121
|
+
});
|
|
2122
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
2123
|
+
profile: {
|
|
2124
|
+
email: fullProfile.email,
|
|
2125
|
+
displayName: fullProfile.displayName
|
|
2126
|
+
}
|
|
2127
|
+
});
|
|
2128
|
+
const signInResolverFn = (_b = (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver) != null ? _b : samlDefaultSignInResolver;
|
|
2129
|
+
const signInResolver = (info) => signInResolverFn(info, {
|
|
2130
|
+
catalogIdentityClient,
|
|
2131
|
+
tokenIssuer,
|
|
2132
|
+
logger
|
|
2133
|
+
});
|
|
2134
|
+
return new SamlAuthProvider({
|
|
2030
2135
|
callbackUrl: `${globalConfig.baseUrl}/${providerId}/handler/frame`,
|
|
2031
2136
|
entryPoint: config.getString("entryPoint"),
|
|
2032
2137
|
logoutUrl: config.getOptionalString("logoutUrl"),
|
|
2033
2138
|
audience: config.getOptionalString("audience"),
|
|
2034
2139
|
issuer: config.getString("issuer"),
|
|
2035
2140
|
cert: config.getString("cert"),
|
|
2036
|
-
|
|
2141
|
+
privateKey: config.getOptionalString("privateKey"),
|
|
2037
2142
|
authnContext: config.getOptionalStringArray("authnContext"),
|
|
2038
2143
|
identifierFormat: config.getOptionalString("identifierFormat"),
|
|
2039
2144
|
decryptionPvk: config.getOptionalString("decryptionPvk"),
|
|
@@ -2041,13 +2146,16 @@ const createSamlProvider = (_options) => {
|
|
|
2041
2146
|
digestAlgorithm: config.getOptionalString("digestAlgorithm"),
|
|
2042
2147
|
acceptedClockSkewMs: config.getOptionalNumber("acceptedClockSkewMs"),
|
|
2043
2148
|
tokenIssuer,
|
|
2044
|
-
appUrl: globalConfig.appUrl
|
|
2045
|
-
|
|
2046
|
-
|
|
2149
|
+
appUrl: globalConfig.appUrl,
|
|
2150
|
+
authHandler,
|
|
2151
|
+
signInResolver,
|
|
2152
|
+
logger,
|
|
2153
|
+
catalogIdentityClient
|
|
2154
|
+
});
|
|
2047
2155
|
};
|
|
2048
2156
|
};
|
|
2049
2157
|
|
|
2050
|
-
class Auth0Strategy extends OAuth2Strategy__default[
|
|
2158
|
+
class Auth0Strategy extends OAuth2Strategy__default["default"] {
|
|
2051
2159
|
constructor(options, verify) {
|
|
2052
2160
|
const optionsWithURLs = {
|
|
2053
2161
|
...options,
|
|
@@ -2088,7 +2196,7 @@ class Auth0AuthProvider {
|
|
|
2088
2196
|
});
|
|
2089
2197
|
}
|
|
2090
2198
|
async handler(req) {
|
|
2091
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
2199
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
2092
2200
|
const profile = makeProfileInfo(result.fullProfile, result.params.id_token);
|
|
2093
2201
|
return {
|
|
2094
2202
|
response: await this.populateIdentity({
|
|
@@ -2104,7 +2212,7 @@ class Auth0AuthProvider {
|
|
|
2104
2212
|
};
|
|
2105
2213
|
}
|
|
2106
2214
|
async refresh(req) {
|
|
2107
|
-
const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
2215
|
+
const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
2108
2216
|
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
|
|
2109
2217
|
const profile = makeProfileInfo(fullProfile, params.id_token);
|
|
2110
2218
|
return this.populateIdentity({
|
|
@@ -2118,16 +2226,16 @@ class Auth0AuthProvider {
|
|
|
2118
2226
|
});
|
|
2119
2227
|
}
|
|
2120
2228
|
async populateIdentity(response) {
|
|
2121
|
-
const {profile} = response;
|
|
2229
|
+
const { profile } = response;
|
|
2122
2230
|
if (!profile.email) {
|
|
2123
2231
|
throw new Error("Profile does not contain an email");
|
|
2124
2232
|
}
|
|
2125
2233
|
const id = profile.email.split("@")[0];
|
|
2126
|
-
return {...response, backstageIdentity: {id}};
|
|
2234
|
+
return { ...response, backstageIdentity: { id, token: "" } };
|
|
2127
2235
|
}
|
|
2128
2236
|
}
|
|
2129
2237
|
const createAuth0Provider = (_options) => {
|
|
2130
|
-
return ({providerId, globalConfig, config, tokenIssuer}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
2238
|
+
return ({ providerId, globalConfig, config, tokenIssuer }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
2131
2239
|
const clientId = envConfig.getString("clientId");
|
|
2132
2240
|
const clientSecret = envConfig.getString("clientSecret");
|
|
2133
2241
|
const domain = envConfig.getString("domain");
|
|
@@ -2174,7 +2282,7 @@ class OneLoginProvider {
|
|
|
2174
2282
|
});
|
|
2175
2283
|
}
|
|
2176
2284
|
async handler(req) {
|
|
2177
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
2285
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
2178
2286
|
const profile = makeProfileInfo(result.fullProfile, result.params.id_token);
|
|
2179
2287
|
return {
|
|
2180
2288
|
response: await this.populateIdentity({
|
|
@@ -2190,7 +2298,7 @@ class OneLoginProvider {
|
|
|
2190
2298
|
};
|
|
2191
2299
|
}
|
|
2192
2300
|
async refresh(req) {
|
|
2193
|
-
const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
2301
|
+
const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
2194
2302
|
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
|
|
2195
2303
|
const profile = makeProfileInfo(fullProfile, params.id_token);
|
|
2196
2304
|
return this.populateIdentity({
|
|
@@ -2204,16 +2312,16 @@ class OneLoginProvider {
|
|
|
2204
2312
|
});
|
|
2205
2313
|
}
|
|
2206
2314
|
async populateIdentity(response) {
|
|
2207
|
-
const {profile} = response;
|
|
2315
|
+
const { profile } = response;
|
|
2208
2316
|
if (!profile.email) {
|
|
2209
2317
|
throw new Error("OIDC profile contained no email");
|
|
2210
2318
|
}
|
|
2211
2319
|
const id = profile.email.split("@")[0];
|
|
2212
|
-
return {...response, backstageIdentity: {id}};
|
|
2320
|
+
return { ...response, backstageIdentity: { id, token: "" } };
|
|
2213
2321
|
}
|
|
2214
2322
|
}
|
|
2215
2323
|
const createOneLoginProvider = (_options) => {
|
|
2216
|
-
return ({providerId, globalConfig, config, tokenIssuer}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
2324
|
+
return ({ providerId, globalConfig, config, tokenIssuer }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
2217
2325
|
const clientId = envConfig.getString("clientId");
|
|
2218
2326
|
const clientSecret = envConfig.getString("clientSecret");
|
|
2219
2327
|
const issuer = envConfig.getString("issuer");
|
|
@@ -2249,8 +2357,8 @@ const factories = {
|
|
|
2249
2357
|
};
|
|
2250
2358
|
|
|
2251
2359
|
function createOidcRouter(options) {
|
|
2252
|
-
const {baseUrl, tokenIssuer} = options;
|
|
2253
|
-
const router = Router__default[
|
|
2360
|
+
const { baseUrl, tokenIssuer } = options;
|
|
2361
|
+
const router = Router__default["default"]();
|
|
2254
2362
|
const config = {
|
|
2255
2363
|
issuer: baseUrl,
|
|
2256
2364
|
token_endpoint: `${baseUrl}/v1/token`,
|
|
@@ -2268,8 +2376,8 @@ function createOidcRouter(options) {
|
|
|
2268
2376
|
res.json(config);
|
|
2269
2377
|
});
|
|
2270
2378
|
router.get("/.well-known/jwks.json", async (_req, res) => {
|
|
2271
|
-
const {keys} = await tokenIssuer.listPublicKeys();
|
|
2272
|
-
res.json({keys});
|
|
2379
|
+
const { keys } = await tokenIssuer.listPublicKeys();
|
|
2380
|
+
res.json({ keys });
|
|
2273
2381
|
});
|
|
2274
2382
|
router.get("/v1/token", (_req, res) => {
|
|
2275
2383
|
res.status(501).send("Not Implemented");
|
|
@@ -2289,21 +2397,30 @@ class IdentityClient {
|
|
|
2289
2397
|
this.keyStoreUpdated = 0;
|
|
2290
2398
|
}
|
|
2291
2399
|
async authenticate(token) {
|
|
2400
|
+
var _a;
|
|
2292
2401
|
if (!token) {
|
|
2293
|
-
throw new
|
|
2402
|
+
throw new errors.AuthenticationError("No token specified");
|
|
2294
2403
|
}
|
|
2295
2404
|
const key = await this.getKey(token);
|
|
2296
2405
|
if (!key) {
|
|
2297
|
-
throw new
|
|
2406
|
+
throw new errors.AuthenticationError("No signing key matching token found");
|
|
2298
2407
|
}
|
|
2299
2408
|
const decoded = jose.JWT.IdToken.verify(token, key, {
|
|
2300
2409
|
algorithms: ["ES256"],
|
|
2301
2410
|
audience: "backstage",
|
|
2302
2411
|
issuer: this.issuer
|
|
2303
2412
|
});
|
|
2413
|
+
if (!decoded.sub) {
|
|
2414
|
+
throw new errors.AuthenticationError("No user sub found in token");
|
|
2415
|
+
}
|
|
2304
2416
|
const user = {
|
|
2305
2417
|
id: decoded.sub,
|
|
2306
|
-
|
|
2418
|
+
token,
|
|
2419
|
+
identity: {
|
|
2420
|
+
type: "user",
|
|
2421
|
+
userEntityRef: decoded.sub,
|
|
2422
|
+
ownershipEntityRefs: (_a = decoded.ent) != null ? _a : []
|
|
2423
|
+
}
|
|
2307
2424
|
};
|
|
2308
2425
|
return user;
|
|
2309
2426
|
}
|
|
@@ -2315,19 +2432,19 @@ class IdentityClient {
|
|
|
2315
2432
|
return matches == null ? void 0 : matches[1];
|
|
2316
2433
|
}
|
|
2317
2434
|
async getKey(rawJwtToken) {
|
|
2318
|
-
const {header, payload} = jose.JWT.decode(rawJwtToken, {
|
|
2435
|
+
const { header, payload } = jose.JWT.decode(rawJwtToken, {
|
|
2319
2436
|
complete: true
|
|
2320
2437
|
});
|
|
2321
|
-
const keyStoreHasKey = !!this.keyStore.get({kid: header.kid});
|
|
2438
|
+
const keyStoreHasKey = !!this.keyStore.get({ kid: header.kid });
|
|
2322
2439
|
const issuedAfterLastRefresh = (payload == null ? void 0 : payload.iat) && payload.iat > this.keyStoreUpdated - CLOCK_MARGIN_S;
|
|
2323
2440
|
if (!keyStoreHasKey && issuedAfterLastRefresh) {
|
|
2324
2441
|
await this.refreshKeyStore();
|
|
2325
2442
|
}
|
|
2326
|
-
return this.keyStore.get({kid: header.kid});
|
|
2443
|
+
return this.keyStore.get({ kid: header.kid });
|
|
2327
2444
|
}
|
|
2328
2445
|
async listPublicKeys() {
|
|
2329
2446
|
const url = `${await this.discovery.getBaseUrl("auth")}/.well-known/jwks.json`;
|
|
2330
|
-
const response = await fetch__default[
|
|
2447
|
+
const response = await fetch__default["default"](url);
|
|
2331
2448
|
if (!response.ok) {
|
|
2332
2449
|
const payload = await response.text();
|
|
2333
2450
|
const message = `Request failed with ${response.status} ${response.statusText}, ${payload}`;
|
|
@@ -2363,13 +2480,13 @@ class TokenFactory {
|
|
|
2363
2480
|
const iat = Math.floor(Date.now() / MS_IN_S);
|
|
2364
2481
|
const exp = iat + this.keyDurationSeconds;
|
|
2365
2482
|
this.logger.info(`Issuing token for ${sub}, with entities ${ent != null ? ent : []}`);
|
|
2366
|
-
return jose.JWS.sign({iss, sub, aud, iat, exp, ent}, key, {
|
|
2483
|
+
return jose.JWS.sign({ iss, sub, aud, iat, exp, ent }, key, {
|
|
2367
2484
|
alg: key.alg,
|
|
2368
2485
|
kid: key.kid
|
|
2369
2486
|
});
|
|
2370
2487
|
}
|
|
2371
2488
|
async listPublicKeys() {
|
|
2372
|
-
const {items: keys} = await this.keyStore.listKeys();
|
|
2489
|
+
const { items: keys } = await this.keyStore.listKeys();
|
|
2373
2490
|
const validKeys = [];
|
|
2374
2491
|
const expiredKeys = [];
|
|
2375
2492
|
for (const key of keys) {
|
|
@@ -2383,13 +2500,13 @@ class TokenFactory {
|
|
|
2383
2500
|
}
|
|
2384
2501
|
}
|
|
2385
2502
|
if (expiredKeys.length > 0) {
|
|
2386
|
-
const kids = expiredKeys.map(({key}) => key.kid);
|
|
2503
|
+
const kids = expiredKeys.map(({ key }) => key.kid);
|
|
2387
2504
|
this.logger.info(`Removing expired signing keys, '${kids.join("', '")}'`);
|
|
2388
2505
|
this.keyStore.removeKeys(kids).catch((error) => {
|
|
2389
2506
|
this.logger.error(`Failed to remove expired keys, ${error}`);
|
|
2390
2507
|
});
|
|
2391
2508
|
}
|
|
2392
|
-
return {keys: validKeys.map(({key}) => key)};
|
|
2509
|
+
return { keys: validKeys.map(({ key }) => key) };
|
|
2393
2510
|
}
|
|
2394
2511
|
async getKey() {
|
|
2395
2512
|
if (this.privateKeyPromise) {
|
|
@@ -2427,7 +2544,7 @@ class TokenFactory {
|
|
|
2427
2544
|
const migrationsDir = backendCommon.resolvePackagePath("@backstage/plugin-auth-backend", "migrations");
|
|
2428
2545
|
const TABLE = "signing_keys";
|
|
2429
2546
|
const parseDate = (date) => {
|
|
2430
|
-
const parsedDate = typeof date === "string" ? luxon.DateTime.fromSQL(date, {zone: "UTC"}) : luxon.DateTime.fromJSDate(date);
|
|
2547
|
+
const parsedDate = typeof date === "string" ? luxon.DateTime.fromSQL(date, { zone: "UTC" }) : luxon.DateTime.fromJSDate(date);
|
|
2431
2548
|
if (!parsedDate.isValid) {
|
|
2432
2549
|
throw new Error(`Failed to parse date, reason: ${parsedDate.invalidReason}, explanation: ${parsedDate.invalidExplanation}`);
|
|
2433
2550
|
}
|
|
@@ -2435,7 +2552,7 @@ const parseDate = (date) => {
|
|
|
2435
2552
|
};
|
|
2436
2553
|
class DatabaseKeyStore {
|
|
2437
2554
|
static async create(options) {
|
|
2438
|
-
const {database} = options;
|
|
2555
|
+
const { database } = options;
|
|
2439
2556
|
await database.migrate.latest({
|
|
2440
2557
|
directory: migrationsDir
|
|
2441
2558
|
});
|
|
@@ -2466,7 +2583,7 @@ class DatabaseKeyStore {
|
|
|
2466
2583
|
|
|
2467
2584
|
class MemoryKeyStore {
|
|
2468
2585
|
constructor() {
|
|
2469
|
-
this.keys = new Map();
|
|
2586
|
+
this.keys = /* @__PURE__ */ new Map();
|
|
2470
2587
|
}
|
|
2471
2588
|
async addKey(key) {
|
|
2472
2589
|
this.keys.set(key.kid, {
|
|
@@ -2481,7 +2598,7 @@ class MemoryKeyStore {
|
|
|
2481
2598
|
}
|
|
2482
2599
|
async listKeys() {
|
|
2483
2600
|
return {
|
|
2484
|
-
items: Array.from(this.keys).map(([, {createdAt, key: keyStr}]) => ({
|
|
2601
|
+
items: Array.from(this.keys).map(([, { createdAt, key: keyStr }]) => ({
|
|
2485
2602
|
createdAt,
|
|
2486
2603
|
key: JSON.parse(keyStr)
|
|
2487
2604
|
}))
|
|
@@ -2498,7 +2615,7 @@ class FirestoreKeyStore {
|
|
|
2498
2615
|
this.timeout = timeout;
|
|
2499
2616
|
}
|
|
2500
2617
|
static async create(settings) {
|
|
2501
|
-
const {path, timeout, ...firestoreSettings} = settings != null ? settings : {};
|
|
2618
|
+
const { path, timeout, ...firestoreSettings } = settings != null ? settings : {};
|
|
2502
2619
|
const database = new firestore.Firestore(firestoreSettings);
|
|
2503
2620
|
return new FirestoreKeyStore(database, path != null ? path : DEFAULT_DOCUMENT_PATH, timeout != null ? timeout : DEFAULT_TIMEOUT_MS);
|
|
2504
2621
|
}
|
|
@@ -2546,7 +2663,7 @@ class FirestoreKeyStore {
|
|
|
2546
2663
|
class KeyStores {
|
|
2547
2664
|
static async fromConfig(config, options) {
|
|
2548
2665
|
var _a;
|
|
2549
|
-
const {logger, database} = options != null ? options : {};
|
|
2666
|
+
const { logger, database } = options != null ? options : {};
|
|
2550
2667
|
const ks = config.getOptionalConfig("auth.keyStore");
|
|
2551
2668
|
const provider = (_a = ks == null ? void 0 : ks.getOptionalString("provider")) != null ? _a : "database";
|
|
2552
2669
|
logger == null ? void 0 : logger.info(`Configuring "${provider}" as KeyStore provider`);
|
|
@@ -2579,36 +2696,31 @@ class KeyStores {
|
|
|
2579
2696
|
}
|
|
2580
2697
|
}
|
|
2581
2698
|
|
|
2582
|
-
async function createRouter({
|
|
2583
|
-
logger,
|
|
2584
|
-
|
|
2585
|
-
discovery,
|
|
2586
|
-
database,
|
|
2587
|
-
providerFactories
|
|
2588
|
-
}) {
|
|
2589
|
-
const router = Router__default['default']();
|
|
2699
|
+
async function createRouter(options) {
|
|
2700
|
+
const { logger, config, discovery, database, providerFactories } = options;
|
|
2701
|
+
const router = Router__default["default"]();
|
|
2590
2702
|
const appUrl = config.getString("app.baseUrl");
|
|
2591
2703
|
const authUrl = await discovery.getExternalBaseUrl("auth");
|
|
2592
|
-
const keyStore = await KeyStores.fromConfig(config, {logger, database});
|
|
2704
|
+
const keyStore = await KeyStores.fromConfig(config, { logger, database });
|
|
2593
2705
|
const keyDurationSeconds = 3600;
|
|
2594
2706
|
const tokenIssuer = new TokenFactory({
|
|
2595
2707
|
issuer: authUrl,
|
|
2596
2708
|
keyStore,
|
|
2597
2709
|
keyDurationSeconds,
|
|
2598
|
-
logger: logger.child({component: "token-factory"})
|
|
2710
|
+
logger: logger.child({ component: "token-factory" })
|
|
2599
2711
|
});
|
|
2600
|
-
const catalogApi = new catalogClient.CatalogClient({discoveryApi: discovery});
|
|
2712
|
+
const catalogApi = new catalogClient.CatalogClient({ discoveryApi: discovery });
|
|
2601
2713
|
const secret = config.getOptionalString("auth.session.secret");
|
|
2602
2714
|
if (secret) {
|
|
2603
|
-
router.use(cookieParser__default[
|
|
2604
|
-
router.use(session__default[
|
|
2605
|
-
router.use(passport__default[
|
|
2606
|
-
router.use(passport__default[
|
|
2715
|
+
router.use(cookieParser__default["default"](secret));
|
|
2716
|
+
router.use(session__default["default"]({ secret, saveUninitialized: false, resave: false }));
|
|
2717
|
+
router.use(passport__default["default"].initialize());
|
|
2718
|
+
router.use(passport__default["default"].session());
|
|
2607
2719
|
} else {
|
|
2608
|
-
router.use(cookieParser__default[
|
|
2720
|
+
router.use(cookieParser__default["default"]());
|
|
2609
2721
|
}
|
|
2610
|
-
router.use(express__default[
|
|
2611
|
-
router.use(express__default[
|
|
2722
|
+
router.use(express__default["default"].urlencoded({ extended: false }));
|
|
2723
|
+
router.use(express__default["default"].json());
|
|
2612
2724
|
const allProviderFactories = {
|
|
2613
2725
|
...factories,
|
|
2614
2726
|
...providerFactories
|
|
@@ -2622,14 +2734,14 @@ async function createRouter({
|
|
|
2622
2734
|
try {
|
|
2623
2735
|
const provider = providerFactory({
|
|
2624
2736
|
providerId,
|
|
2625
|
-
globalConfig: {baseUrl: authUrl, appUrl, isOriginAllowed},
|
|
2737
|
+
globalConfig: { baseUrl: authUrl, appUrl, isOriginAllowed },
|
|
2626
2738
|
config: providersConfig.getConfig(providerId),
|
|
2627
2739
|
logger,
|
|
2628
2740
|
tokenIssuer,
|
|
2629
2741
|
discovery,
|
|
2630
2742
|
catalogApi
|
|
2631
2743
|
});
|
|
2632
|
-
const r = Router__default[
|
|
2744
|
+
const r = Router__default["default"]();
|
|
2633
2745
|
r.get("/start", provider.start.bind(provider));
|
|
2634
2746
|
r.get("/handler/frame", provider.frameHandler.bind(provider));
|
|
2635
2747
|
r.post("/handler/frame", provider.frameHandler.bind(provider));
|
|
@@ -2661,7 +2773,7 @@ async function createRouter({
|
|
|
2661
2773
|
baseUrl: authUrl
|
|
2662
2774
|
}));
|
|
2663
2775
|
router.use("/:provider/", (req) => {
|
|
2664
|
-
const {provider} = req.params;
|
|
2776
|
+
const { provider } = req.params;
|
|
2665
2777
|
throw new errors.NotFoundError(`Unknown auth provider '${provider}'`);
|
|
2666
2778
|
});
|
|
2667
2779
|
return router;
|
|
@@ -2669,9 +2781,9 @@ async function createRouter({
|
|
|
2669
2781
|
function createOriginFilter(config) {
|
|
2670
2782
|
var _a;
|
|
2671
2783
|
const appUrl = config.getString("app.baseUrl");
|
|
2672
|
-
const {origin: appOrigin} = new URL(appUrl);
|
|
2784
|
+
const { origin: appOrigin } = new URL(appUrl);
|
|
2673
2785
|
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 : [];
|
|
2786
|
+
const allowedOriginPatterns = (_a = allowedOrigins == null ? void 0 : allowedOrigins.map((pattern) => new minimatch.Minimatch(pattern, { nocase: true, noglobstar: true }))) != null ? _a : [];
|
|
2675
2787
|
return (origin) => {
|
|
2676
2788
|
if (origin === appOrigin) {
|
|
2677
2789
|
return true;
|
|
@@ -2680,6 +2792,7 @@ function createOriginFilter(config) {
|
|
|
2680
2792
|
};
|
|
2681
2793
|
}
|
|
2682
2794
|
|
|
2795
|
+
exports.CatalogIdentityClient = CatalogIdentityClient;
|
|
2683
2796
|
exports.IdentityClient = IdentityClient;
|
|
2684
2797
|
exports.OAuthAdapter = OAuthAdapter;
|
|
2685
2798
|
exports.OAuthEnvironmentHandler = OAuthEnvironmentHandler;
|
|
@@ -2693,16 +2806,20 @@ exports.createGitlabProvider = createGitlabProvider;
|
|
|
2693
2806
|
exports.createGoogleProvider = createGoogleProvider;
|
|
2694
2807
|
exports.createMicrosoftProvider = createMicrosoftProvider;
|
|
2695
2808
|
exports.createOAuth2Provider = createOAuth2Provider;
|
|
2809
|
+
exports.createOidcProvider = createOidcProvider;
|
|
2696
2810
|
exports.createOktaProvider = createOktaProvider;
|
|
2697
2811
|
exports.createOriginFilter = createOriginFilter;
|
|
2698
2812
|
exports.createRouter = createRouter;
|
|
2813
|
+
exports.createSamlProvider = createSamlProvider;
|
|
2699
2814
|
exports.defaultAuthProviderFactories = factories;
|
|
2700
2815
|
exports.encodeState = encodeState;
|
|
2701
2816
|
exports.ensuresXRequestedWith = ensuresXRequestedWith;
|
|
2817
|
+
exports.getEntityClaims = getEntityClaims;
|
|
2702
2818
|
exports.googleEmailSignInResolver = googleEmailSignInResolver;
|
|
2703
2819
|
exports.microsoftEmailSignInResolver = microsoftEmailSignInResolver;
|
|
2704
2820
|
exports.oktaEmailSignInResolver = oktaEmailSignInResolver;
|
|
2705
2821
|
exports.postMessageResponse = postMessageResponse;
|
|
2822
|
+
exports.prepareBackstageIdentityResponse = prepareBackstageIdentityResponse;
|
|
2706
2823
|
exports.readState = readState;
|
|
2707
2824
|
exports.verifyNonce = verifyNonce;
|
|
2708
2825
|
//# sourceMappingURL=index.cjs.js.map
|