@backstage/plugin-auth-backend 0.4.10 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/dist/index.cjs.js +222 -199
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +82 -20
- package/package.json +5 -5
package/dist/index.cjs.js
CHANGED
|
@@ -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;
|
|
@@ -1135,9 +1150,9 @@ class OAuth2AuthProvider {
|
|
|
1135
1150
|
tokenURL: options.tokenUrl,
|
|
1136
1151
|
passReqToCallback: false,
|
|
1137
1152
|
scope: options.scope,
|
|
1138
|
-
customHeaders: {
|
|
1153
|
+
customHeaders: options.includeBasicAuth ? {
|
|
1139
1154
|
Authorization: `Basic ${this.encodeClientCredentials(options.clientId, options.clientSecret)}`
|
|
1140
|
-
}
|
|
1155
|
+
} : void 0
|
|
1141
1156
|
}, (accessToken, refreshToken, params, fullProfile, done) => {
|
|
1142
1157
|
done(void 0, {
|
|
1143
1158
|
fullProfile,
|
|
@@ -1158,7 +1173,7 @@ class OAuth2AuthProvider {
|
|
|
1158
1173
|
});
|
|
1159
1174
|
}
|
|
1160
1175
|
async handler(req) {
|
|
1161
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1176
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1162
1177
|
return {
|
|
1163
1178
|
response: await this.handleResult(result),
|
|
1164
1179
|
refreshToken: privateInfo.refreshToken
|
|
@@ -1180,7 +1195,7 @@ class OAuth2AuthProvider {
|
|
|
1180
1195
|
});
|
|
1181
1196
|
}
|
|
1182
1197
|
async handleResult(result) {
|
|
1183
|
-
const {profile} = await this.authHandler(result);
|
|
1198
|
+
const { profile } = await this.authHandler(result);
|
|
1184
1199
|
const response = {
|
|
1185
1200
|
providerInfo: {
|
|
1186
1201
|
idToken: result.params.id_token,
|
|
@@ -1208,15 +1223,15 @@ class OAuth2AuthProvider {
|
|
|
1208
1223
|
}
|
|
1209
1224
|
}
|
|
1210
1225
|
const oAuth2DefaultSignInResolver$1 = async (info, ctx) => {
|
|
1211
|
-
const {profile} = info;
|
|
1226
|
+
const { profile } = info;
|
|
1212
1227
|
if (!profile.email) {
|
|
1213
1228
|
throw new Error("Profile contained no email");
|
|
1214
1229
|
}
|
|
1215
1230
|
const userId = profile.email.split("@")[0];
|
|
1216
1231
|
const token = await ctx.tokenIssuer.issueToken({
|
|
1217
|
-
claims: {sub: userId, ent: [`user:default/${userId}`]}
|
|
1232
|
+
claims: { sub: userId, ent: [`user:default/${userId}`] }
|
|
1218
1233
|
});
|
|
1219
|
-
return {id: userId, token};
|
|
1234
|
+
return { id: userId, token };
|
|
1220
1235
|
};
|
|
1221
1236
|
const createOAuth2Provider = (options) => {
|
|
1222
1237
|
return ({
|
|
@@ -1234,12 +1249,13 @@ const createOAuth2Provider = (options) => {
|
|
|
1234
1249
|
const authorizationUrl = envConfig.getString("authorizationUrl");
|
|
1235
1250
|
const tokenUrl = envConfig.getString("tokenUrl");
|
|
1236
1251
|
const scope = envConfig.getOptionalString("scope");
|
|
1252
|
+
const includeBasicAuth = envConfig.getOptionalBoolean("includeBasicAuth");
|
|
1237
1253
|
const disableRefresh = (_a = envConfig.getOptionalBoolean("disableRefresh")) != null ? _a : false;
|
|
1238
1254
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1239
1255
|
catalogApi,
|
|
1240
1256
|
tokenIssuer
|
|
1241
1257
|
});
|
|
1242
|
-
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 }) => ({
|
|
1243
1259
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1244
1260
|
});
|
|
1245
1261
|
const signInResolverFn = (_c = (_b = options == null ? void 0 : options.signIn) == null ? void 0 : _b.resolver) != null ? _c : oAuth2DefaultSignInResolver$1;
|
|
@@ -1259,7 +1275,8 @@ const createOAuth2Provider = (options) => {
|
|
|
1259
1275
|
authorizationUrl,
|
|
1260
1276
|
tokenUrl,
|
|
1261
1277
|
scope,
|
|
1262
|
-
logger
|
|
1278
|
+
logger,
|
|
1279
|
+
includeBasicAuth
|
|
1263
1280
|
});
|
|
1264
1281
|
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1265
1282
|
disableRefresh,
|
|
@@ -1281,7 +1298,7 @@ class OidcAuthProvider {
|
|
|
1281
1298
|
this.logger = options.logger;
|
|
1282
1299
|
}
|
|
1283
1300
|
async start(req) {
|
|
1284
|
-
const {strategy} = await this.implementation;
|
|
1301
|
+
const { strategy } = await this.implementation;
|
|
1285
1302
|
const options = {
|
|
1286
1303
|
scope: req.scope || this.scope || "openid profile email",
|
|
1287
1304
|
state: encodeState(req.state)
|
|
@@ -1293,26 +1310,26 @@ class OidcAuthProvider {
|
|
|
1293
1310
|
return await executeRedirectStrategy(req, strategy, options);
|
|
1294
1311
|
}
|
|
1295
1312
|
async handler(req) {
|
|
1296
|
-
const {strategy} = await this.implementation;
|
|
1313
|
+
const { strategy } = await this.implementation;
|
|
1297
1314
|
const strategyResponse = await executeFrameHandlerStrategy(req, strategy);
|
|
1298
1315
|
const {
|
|
1299
|
-
result: {userinfo, tokenset},
|
|
1316
|
+
result: { userinfo, tokenset },
|
|
1300
1317
|
privateInfo
|
|
1301
1318
|
} = strategyResponse;
|
|
1302
|
-
const identityResponse = await this.handleResult({tokenset, userinfo});
|
|
1319
|
+
const identityResponse = await this.handleResult({ tokenset, userinfo });
|
|
1303
1320
|
return {
|
|
1304
1321
|
response: identityResponse,
|
|
1305
1322
|
refreshToken: privateInfo.refreshToken
|
|
1306
1323
|
};
|
|
1307
1324
|
}
|
|
1308
1325
|
async refresh(req) {
|
|
1309
|
-
const {client} = await this.implementation;
|
|
1326
|
+
const { client } = await this.implementation;
|
|
1310
1327
|
const tokenset = await client.refresh(req.refreshToken);
|
|
1311
1328
|
if (!tokenset.access_token) {
|
|
1312
1329
|
throw new Error("Refresh failed");
|
|
1313
1330
|
}
|
|
1314
1331
|
const profile = await client.userinfo(tokenset.access_token);
|
|
1315
|
-
return this.handleResult({tokenset, userinfo: profile});
|
|
1332
|
+
return this.handleResult({ tokenset, userinfo: profile });
|
|
1316
1333
|
}
|
|
1317
1334
|
async setupStrategy(options) {
|
|
1318
1335
|
const issuer = await openidClient.Issuer.discover(options.metadataUrl);
|
|
@@ -1332,15 +1349,15 @@ class OidcAuthProvider {
|
|
|
1332
1349
|
if (typeof done !== "function") {
|
|
1333
1350
|
throw new Error("OIDC IdP must provide a userinfo_endpoint in the metadata response");
|
|
1334
1351
|
}
|
|
1335
|
-
done(void 0, {tokenset, userinfo}, {
|
|
1352
|
+
done(void 0, { tokenset, userinfo }, {
|
|
1336
1353
|
refreshToken: tokenset.refresh_token
|
|
1337
1354
|
});
|
|
1338
1355
|
});
|
|
1339
1356
|
strategy.error = console.error;
|
|
1340
|
-
return {strategy, client};
|
|
1357
|
+
return { strategy, client };
|
|
1341
1358
|
}
|
|
1342
1359
|
async handleResult(result) {
|
|
1343
|
-
const {profile} = await this.authHandler(result);
|
|
1360
|
+
const { profile } = await this.authHandler(result);
|
|
1344
1361
|
const response = {
|
|
1345
1362
|
providerInfo: {
|
|
1346
1363
|
idToken: result.tokenset.id_token,
|
|
@@ -1365,15 +1382,15 @@ class OidcAuthProvider {
|
|
|
1365
1382
|
}
|
|
1366
1383
|
}
|
|
1367
1384
|
const oAuth2DefaultSignInResolver = async (info, ctx) => {
|
|
1368
|
-
const {profile} = info;
|
|
1385
|
+
const { profile } = info;
|
|
1369
1386
|
if (!profile.email) {
|
|
1370
1387
|
throw new Error("Profile contained no email");
|
|
1371
1388
|
}
|
|
1372
1389
|
const userId = profile.email.split("@")[0];
|
|
1373
1390
|
const token = await ctx.tokenIssuer.issueToken({
|
|
1374
|
-
claims: {sub: userId, ent: [`user:default/${userId}`]}
|
|
1391
|
+
claims: { sub: userId, ent: [`user:default/${userId}`] }
|
|
1375
1392
|
});
|
|
1376
|
-
return {id: userId, token};
|
|
1393
|
+
return { id: userId, token };
|
|
1377
1394
|
};
|
|
1378
1395
|
const createOidcProvider = (options) => {
|
|
1379
1396
|
return ({
|
|
@@ -1396,7 +1413,7 @@ const createOidcProvider = (options) => {
|
|
|
1396
1413
|
catalogApi,
|
|
1397
1414
|
tokenIssuer
|
|
1398
1415
|
});
|
|
1399
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({userinfo}) => ({
|
|
1416
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ userinfo }) => ({
|
|
1400
1417
|
profile: {
|
|
1401
1418
|
displayName: userinfo.name,
|
|
1402
1419
|
email: userinfo.email,
|
|
@@ -1474,14 +1491,14 @@ class OktaAuthProvider {
|
|
|
1474
1491
|
});
|
|
1475
1492
|
}
|
|
1476
1493
|
async handler(req) {
|
|
1477
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1494
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1478
1495
|
return {
|
|
1479
1496
|
response: await this.handleResult(result),
|
|
1480
1497
|
refreshToken: privateInfo.refreshToken
|
|
1481
1498
|
};
|
|
1482
1499
|
}
|
|
1483
1500
|
async refresh(req) {
|
|
1484
|
-
const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
1501
|
+
const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
1485
1502
|
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
|
|
1486
1503
|
return this.handleResult({
|
|
1487
1504
|
fullProfile,
|
|
@@ -1491,7 +1508,7 @@ class OktaAuthProvider {
|
|
|
1491
1508
|
});
|
|
1492
1509
|
}
|
|
1493
1510
|
async handleResult(result) {
|
|
1494
|
-
const {profile} = await this._authHandler(result);
|
|
1511
|
+
const { profile } = await this._authHandler(result);
|
|
1495
1512
|
const response = {
|
|
1496
1513
|
providerInfo: {
|
|
1497
1514
|
idToken: result.params.id_token,
|
|
@@ -1515,7 +1532,7 @@ class OktaAuthProvider {
|
|
|
1515
1532
|
}
|
|
1516
1533
|
}
|
|
1517
1534
|
const oktaEmailSignInResolver = async (info, ctx) => {
|
|
1518
|
-
const {profile} = info;
|
|
1535
|
+
const { profile } = info;
|
|
1519
1536
|
if (!profile.email) {
|
|
1520
1537
|
throw new Error("Okta profile contained no email");
|
|
1521
1538
|
}
|
|
@@ -1525,19 +1542,19 @@ const oktaEmailSignInResolver = async (info, ctx) => {
|
|
|
1525
1542
|
}
|
|
1526
1543
|
});
|
|
1527
1544
|
const claims = getEntityClaims(entity);
|
|
1528
|
-
const token = await ctx.tokenIssuer.issueToken({claims});
|
|
1529
|
-
return {id: entity.metadata.name, entity, token};
|
|
1545
|
+
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
1546
|
+
return { id: entity.metadata.name, entity, token };
|
|
1530
1547
|
};
|
|
1531
1548
|
const oktaDefaultSignInResolver = async (info, ctx) => {
|
|
1532
|
-
const {profile} = info;
|
|
1549
|
+
const { profile } = info;
|
|
1533
1550
|
if (!profile.email) {
|
|
1534
1551
|
throw new Error("Okta profile contained no email");
|
|
1535
1552
|
}
|
|
1536
1553
|
const userId = profile.email.split("@")[0];
|
|
1537
1554
|
const token = await ctx.tokenIssuer.issueToken({
|
|
1538
|
-
claims: {sub: userId, ent: [`user:default/${userId}`]}
|
|
1555
|
+
claims: { sub: userId, ent: [`user:default/${userId}`] }
|
|
1539
1556
|
});
|
|
1540
|
-
return {id: userId, token};
|
|
1557
|
+
return { id: userId, token };
|
|
1541
1558
|
};
|
|
1542
1559
|
const createOktaProvider = (_options) => {
|
|
1543
1560
|
return ({
|
|
@@ -1560,7 +1577,7 @@ const createOktaProvider = (_options) => {
|
|
|
1560
1577
|
catalogApi,
|
|
1561
1578
|
tokenIssuer
|
|
1562
1579
|
});
|
|
1563
|
-
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 }) => ({
|
|
1564
1581
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1565
1582
|
});
|
|
1566
1583
|
const signInResolverFn = (_b = (_a = _options == null ? void 0 : _options.signIn) == null ? void 0 : _a.resolver) != null ? _b : oktaDefaultSignInResolver;
|
|
@@ -1620,14 +1637,14 @@ class BitbucketAuthProvider {
|
|
|
1620
1637
|
});
|
|
1621
1638
|
}
|
|
1622
1639
|
async handler(req) {
|
|
1623
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1640
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1624
1641
|
return {
|
|
1625
1642
|
response: await this.handleResult(result),
|
|
1626
1643
|
refreshToken: privateInfo.refreshToken
|
|
1627
1644
|
};
|
|
1628
1645
|
}
|
|
1629
1646
|
async refresh(req) {
|
|
1630
|
-
const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
1647
|
+
const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
1631
1648
|
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
|
|
1632
1649
|
return this.handleResult({
|
|
1633
1650
|
fullProfile,
|
|
@@ -1638,7 +1655,7 @@ class BitbucketAuthProvider {
|
|
|
1638
1655
|
}
|
|
1639
1656
|
async handleResult(result) {
|
|
1640
1657
|
result.fullProfile.avatarUrl = result.fullProfile._json.links.avatar.href;
|
|
1641
|
-
const {profile} = await this.authHandler(result);
|
|
1658
|
+
const { profile } = await this.authHandler(result);
|
|
1642
1659
|
const response = {
|
|
1643
1660
|
providerInfo: {
|
|
1644
1661
|
idToken: result.params.id_token,
|
|
@@ -1662,7 +1679,7 @@ class BitbucketAuthProvider {
|
|
|
1662
1679
|
}
|
|
1663
1680
|
}
|
|
1664
1681
|
const bitbucketUsernameSignInResolver = async (info, ctx) => {
|
|
1665
|
-
const {result} = info;
|
|
1682
|
+
const { result } = info;
|
|
1666
1683
|
if (!result.fullProfile.username) {
|
|
1667
1684
|
throw new Error("Bitbucket profile contained no Username");
|
|
1668
1685
|
}
|
|
@@ -1672,11 +1689,11 @@ const bitbucketUsernameSignInResolver = async (info, ctx) => {
|
|
|
1672
1689
|
}
|
|
1673
1690
|
});
|
|
1674
1691
|
const claims = getEntityClaims(entity);
|
|
1675
|
-
const token = await ctx.tokenIssuer.issueToken({claims});
|
|
1676
|
-
return {id: entity.metadata.name, entity, token};
|
|
1692
|
+
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
1693
|
+
return { id: entity.metadata.name, entity, token };
|
|
1677
1694
|
};
|
|
1678
1695
|
const bitbucketUserIdSignInResolver = async (info, ctx) => {
|
|
1679
|
-
const {result} = info;
|
|
1696
|
+
const { result } = info;
|
|
1680
1697
|
if (!result.fullProfile.id) {
|
|
1681
1698
|
throw new Error("Bitbucket profile contained no User ID");
|
|
1682
1699
|
}
|
|
@@ -1686,8 +1703,8 @@ const bitbucketUserIdSignInResolver = async (info, ctx) => {
|
|
|
1686
1703
|
}
|
|
1687
1704
|
});
|
|
1688
1705
|
const claims = getEntityClaims(entity);
|
|
1689
|
-
const token = await ctx.tokenIssuer.issueToken({claims});
|
|
1690
|
-
return {id: entity.metadata.name, entity, token};
|
|
1706
|
+
const token = await ctx.tokenIssuer.issueToken({ claims });
|
|
1707
|
+
return { id: entity.metadata.name, entity, token };
|
|
1691
1708
|
};
|
|
1692
1709
|
const createBitbucketProvider = (options) => {
|
|
1693
1710
|
return ({
|
|
@@ -1706,7 +1723,7 @@ const createBitbucketProvider = (options) => {
|
|
|
1706
1723
|
catalogApi,
|
|
1707
1724
|
tokenIssuer
|
|
1708
1725
|
});
|
|
1709
|
-
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 }) => ({
|
|
1710
1727
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1711
1728
|
});
|
|
1712
1729
|
const provider = new BitbucketAuthProvider({
|
|
@@ -1728,7 +1745,7 @@ const createBitbucketProvider = (options) => {
|
|
|
1728
1745
|
};
|
|
1729
1746
|
|
|
1730
1747
|
const defaultScopes = ["offline_access", "read:me"];
|
|
1731
|
-
class AtlassianStrategy extends OAuth2Strategy__default[
|
|
1748
|
+
class AtlassianStrategy extends OAuth2Strategy__default["default"] {
|
|
1732
1749
|
constructor(options, verify) {
|
|
1733
1750
|
if (!options.scope) {
|
|
1734
1751
|
throw new TypeError("Atlassian requires a scope option");
|
|
@@ -1738,7 +1755,7 @@ class AtlassianStrategy extends OAuth2Strategy__default['default'] {
|
|
|
1738
1755
|
...options,
|
|
1739
1756
|
authorizationURL: `https://auth.atlassian.com/authorize`,
|
|
1740
1757
|
tokenURL: `https://auth.atlassian.com/oauth/token`,
|
|
1741
|
-
scope: Array.from(new Set([...defaultScopes, ...scopes]))
|
|
1758
|
+
scope: Array.from(/* @__PURE__ */ new Set([...defaultScopes, ...scopes]))
|
|
1742
1759
|
};
|
|
1743
1760
|
super(optionsWithURLs, verify);
|
|
1744
1761
|
this.profileURL = "https://api.atlassian.com/me";
|
|
@@ -1775,8 +1792,8 @@ class AtlassianStrategy extends OAuth2Strategy__default['default'] {
|
|
|
1775
1792
|
provider: "atlassian",
|
|
1776
1793
|
username: resp.nickname,
|
|
1777
1794
|
displayName: resp.name,
|
|
1778
|
-
emails: [{value: resp.email}],
|
|
1779
|
-
photos: [{value: resp.picture}]
|
|
1795
|
+
emails: [{ value: resp.email }],
|
|
1796
|
+
photos: [{ value: resp.picture }]
|
|
1780
1797
|
};
|
|
1781
1798
|
}
|
|
1782
1799
|
}
|
|
@@ -1815,14 +1832,14 @@ class AtlassianAuthProvider {
|
|
|
1815
1832
|
}
|
|
1816
1833
|
async handler(req) {
|
|
1817
1834
|
var _a;
|
|
1818
|
-
const {result} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1835
|
+
const { result } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1819
1836
|
return {
|
|
1820
1837
|
response: await this.handleResult(result),
|
|
1821
1838
|
refreshToken: (_a = result.refreshToken) != null ? _a : ""
|
|
1822
1839
|
};
|
|
1823
1840
|
}
|
|
1824
1841
|
async handleResult(result) {
|
|
1825
|
-
const {profile} = await this.authHandler(result);
|
|
1842
|
+
const { profile } = await this.authHandler(result);
|
|
1826
1843
|
const response = {
|
|
1827
1844
|
providerInfo: {
|
|
1828
1845
|
idToken: result.params.id_token,
|
|
@@ -1913,7 +1930,7 @@ class AwsAlbAuthProvider {
|
|
|
1913
1930
|
this.tokenIssuer = options.tokenIssuer;
|
|
1914
1931
|
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
1915
1932
|
this.logger = options.logger;
|
|
1916
|
-
this.keyCache = new NodeCache__default[
|
|
1933
|
+
this.keyCache = new NodeCache__default["default"]({ stdTTL: 3600 });
|
|
1917
1934
|
}
|
|
1918
1935
|
frameHandler() {
|
|
1919
1936
|
return Promise.resolve(void 0);
|
|
@@ -1957,8 +1974,8 @@ class AwsAlbAuthProvider {
|
|
|
1957
1974
|
familyName: claims.family_name,
|
|
1958
1975
|
givenName: claims.given_name
|
|
1959
1976
|
},
|
|
1960
|
-
emails: [{value: claims.email.toLowerCase()}],
|
|
1961
|
-
photos: [{value: claims.picture}]
|
|
1977
|
+
emails: [{ value: claims.email.toLowerCase() }],
|
|
1978
|
+
photos: [{ value: claims.picture }]
|
|
1962
1979
|
};
|
|
1963
1980
|
return {
|
|
1964
1981
|
fullProfile,
|
|
@@ -1970,7 +1987,7 @@ class AwsAlbAuthProvider {
|
|
|
1970
1987
|
}
|
|
1971
1988
|
}
|
|
1972
1989
|
async handleResult(result) {
|
|
1973
|
-
const {profile} = await this.authHandler(result);
|
|
1990
|
+
const { profile } = await this.authHandler(result);
|
|
1974
1991
|
const backstageIdentity = await this.signInResolver({
|
|
1975
1992
|
result,
|
|
1976
1993
|
profile
|
|
@@ -1984,7 +2001,7 @@ class AwsAlbAuthProvider {
|
|
|
1984
2001
|
accessToken: result.accessToken,
|
|
1985
2002
|
expiresInSeconds: result.expiresInSeconds
|
|
1986
2003
|
},
|
|
1987
|
-
backstageIdentity,
|
|
2004
|
+
backstageIdentity: prepareBackstageIdentityResponse(backstageIdentity),
|
|
1988
2005
|
profile
|
|
1989
2006
|
};
|
|
1990
2007
|
}
|
|
@@ -1993,14 +2010,14 @@ class AwsAlbAuthProvider {
|
|
|
1993
2010
|
if (optionalCacheKey) {
|
|
1994
2011
|
return crypto__namespace.createPublicKey(optionalCacheKey);
|
|
1995
2012
|
}
|
|
1996
|
-
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());
|
|
1997
2014
|
const keyValue = crypto__namespace.createPublicKey(keyText);
|
|
1998
|
-
this.keyCache.set(keyId, keyValue.export({format: "pem", type: "spki"}));
|
|
2015
|
+
this.keyCache.set(keyId, keyValue.export({ format: "pem", type: "spki" }));
|
|
1999
2016
|
return keyValue;
|
|
2000
2017
|
}
|
|
2001
2018
|
}
|
|
2002
2019
|
const createAwsAlbProvider = (options) => {
|
|
2003
|
-
return ({config, tokenIssuer, catalogApi, logger}) => {
|
|
2020
|
+
return ({ config, tokenIssuer, catalogApi, logger }) => {
|
|
2004
2021
|
const region = config.getString("region");
|
|
2005
2022
|
const issuer = config.getOptionalString("iss");
|
|
2006
2023
|
if ((options == null ? void 0 : options.signIn.resolver) === void 0) {
|
|
@@ -2010,7 +2027,7 @@ const createAwsAlbProvider = (options) => {
|
|
|
2010
2027
|
catalogApi,
|
|
2011
2028
|
tokenIssuer
|
|
2012
2029
|
});
|
|
2013
|
-
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 }) => ({
|
|
2014
2031
|
profile: makeProfileInfo(fullProfile)
|
|
2015
2032
|
});
|
|
2016
2033
|
const signInResolver = options == null ? void 0 : options.signIn.resolver;
|
|
@@ -2034,24 +2051,24 @@ class SamlAuthProvider {
|
|
|
2034
2051
|
this.tokenIssuer = options.tokenIssuer;
|
|
2035
2052
|
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
2036
2053
|
this.logger = options.logger;
|
|
2037
|
-
this.strategy = new passportSaml.Strategy({...options}, (fullProfile, done) => {
|
|
2038
|
-
done(void 0, {fullProfile});
|
|
2054
|
+
this.strategy = new passportSaml.Strategy({ ...options }, (fullProfile, done) => {
|
|
2055
|
+
done(void 0, { fullProfile });
|
|
2039
2056
|
});
|
|
2040
2057
|
}
|
|
2041
2058
|
async start(req, res) {
|
|
2042
|
-
const {url} = await executeRedirectStrategy(req, this.strategy, {});
|
|
2059
|
+
const { url } = await executeRedirectStrategy(req, this.strategy, {});
|
|
2043
2060
|
res.redirect(url);
|
|
2044
2061
|
}
|
|
2045
2062
|
async frameHandler(req, res) {
|
|
2046
2063
|
try {
|
|
2047
|
-
const {result} = await executeFrameHandlerStrategy(req, this.strategy);
|
|
2048
|
-
const {profile} = await this.authHandler(result);
|
|
2064
|
+
const { result } = await executeFrameHandlerStrategy(req, this.strategy);
|
|
2065
|
+
const { profile } = await this.authHandler(result);
|
|
2049
2066
|
const response = {
|
|
2050
2067
|
profile,
|
|
2051
2068
|
providerInfo: {}
|
|
2052
2069
|
};
|
|
2053
2070
|
if (this.signInResolver) {
|
|
2054
|
-
|
|
2071
|
+
const signInResponse = await this.signInResolver({
|
|
2055
2072
|
result,
|
|
2056
2073
|
profile
|
|
2057
2074
|
}, {
|
|
@@ -2059,16 +2076,17 @@ class SamlAuthProvider {
|
|
|
2059
2076
|
catalogIdentityClient: this.catalogIdentityClient,
|
|
2060
2077
|
logger: this.logger
|
|
2061
2078
|
});
|
|
2079
|
+
response.backstageIdentity = prepareBackstageIdentityResponse(signInResponse);
|
|
2062
2080
|
}
|
|
2063
2081
|
return postMessageResponse(res, this.appUrl, {
|
|
2064
2082
|
type: "authorization_response",
|
|
2065
2083
|
response
|
|
2066
2084
|
});
|
|
2067
2085
|
} catch (error) {
|
|
2068
|
-
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");
|
|
2069
2087
|
return postMessageResponse(res, this.appUrl, {
|
|
2070
2088
|
type: "authorization_response",
|
|
2071
|
-
error: {name, message}
|
|
2089
|
+
error: { name, message }
|
|
2072
2090
|
});
|
|
2073
2091
|
}
|
|
2074
2092
|
}
|
|
@@ -2079,9 +2097,9 @@ class SamlAuthProvider {
|
|
|
2079
2097
|
const samlDefaultSignInResolver = async (info, ctx) => {
|
|
2080
2098
|
const id = info.result.fullProfile.nameID;
|
|
2081
2099
|
const token = await ctx.tokenIssuer.issueToken({
|
|
2082
|
-
claims: {sub: id}
|
|
2100
|
+
claims: { sub: id }
|
|
2083
2101
|
});
|
|
2084
|
-
return {id, token};
|
|
2102
|
+
return { id, token };
|
|
2085
2103
|
};
|
|
2086
2104
|
const createSamlProvider = (options) => {
|
|
2087
2105
|
return ({
|
|
@@ -2097,7 +2115,7 @@ const createSamlProvider = (options) => {
|
|
|
2097
2115
|
catalogApi,
|
|
2098
2116
|
tokenIssuer
|
|
2099
2117
|
});
|
|
2100
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile}) => ({
|
|
2118
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
2101
2119
|
profile: {
|
|
2102
2120
|
email: fullProfile.email,
|
|
2103
2121
|
displayName: fullProfile.displayName
|
|
@@ -2133,7 +2151,7 @@ const createSamlProvider = (options) => {
|
|
|
2133
2151
|
};
|
|
2134
2152
|
};
|
|
2135
2153
|
|
|
2136
|
-
class Auth0Strategy extends OAuth2Strategy__default[
|
|
2154
|
+
class Auth0Strategy extends OAuth2Strategy__default["default"] {
|
|
2137
2155
|
constructor(options, verify) {
|
|
2138
2156
|
const optionsWithURLs = {
|
|
2139
2157
|
...options,
|
|
@@ -2174,7 +2192,7 @@ class Auth0AuthProvider {
|
|
|
2174
2192
|
});
|
|
2175
2193
|
}
|
|
2176
2194
|
async handler(req) {
|
|
2177
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
2195
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
2178
2196
|
const profile = makeProfileInfo(result.fullProfile, result.params.id_token);
|
|
2179
2197
|
return {
|
|
2180
2198
|
response: await this.populateIdentity({
|
|
@@ -2190,7 +2208,7 @@ class Auth0AuthProvider {
|
|
|
2190
2208
|
};
|
|
2191
2209
|
}
|
|
2192
2210
|
async refresh(req) {
|
|
2193
|
-
const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
2211
|
+
const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
2194
2212
|
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
|
|
2195
2213
|
const profile = makeProfileInfo(fullProfile, params.id_token);
|
|
2196
2214
|
return this.populateIdentity({
|
|
@@ -2204,16 +2222,16 @@ class Auth0AuthProvider {
|
|
|
2204
2222
|
});
|
|
2205
2223
|
}
|
|
2206
2224
|
async populateIdentity(response) {
|
|
2207
|
-
const {profile} = response;
|
|
2225
|
+
const { profile } = response;
|
|
2208
2226
|
if (!profile.email) {
|
|
2209
2227
|
throw new Error("Profile does not contain an email");
|
|
2210
2228
|
}
|
|
2211
2229
|
const id = profile.email.split("@")[0];
|
|
2212
|
-
return {...response, backstageIdentity: {id}};
|
|
2230
|
+
return { ...response, backstageIdentity: { id, token: "" } };
|
|
2213
2231
|
}
|
|
2214
2232
|
}
|
|
2215
2233
|
const createAuth0Provider = (_options) => {
|
|
2216
|
-
return ({providerId, globalConfig, config, tokenIssuer}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
2234
|
+
return ({ providerId, globalConfig, config, tokenIssuer }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
2217
2235
|
const clientId = envConfig.getString("clientId");
|
|
2218
2236
|
const clientSecret = envConfig.getString("clientSecret");
|
|
2219
2237
|
const domain = envConfig.getString("domain");
|
|
@@ -2260,7 +2278,7 @@ class OneLoginProvider {
|
|
|
2260
2278
|
});
|
|
2261
2279
|
}
|
|
2262
2280
|
async handler(req) {
|
|
2263
|
-
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
2281
|
+
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
2264
2282
|
const profile = makeProfileInfo(result.fullProfile, result.params.id_token);
|
|
2265
2283
|
return {
|
|
2266
2284
|
response: await this.populateIdentity({
|
|
@@ -2276,7 +2294,7 @@ class OneLoginProvider {
|
|
|
2276
2294
|
};
|
|
2277
2295
|
}
|
|
2278
2296
|
async refresh(req) {
|
|
2279
|
-
const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
2297
|
+
const { accessToken, params } = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
2280
2298
|
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
|
|
2281
2299
|
const profile = makeProfileInfo(fullProfile, params.id_token);
|
|
2282
2300
|
return this.populateIdentity({
|
|
@@ -2290,16 +2308,16 @@ class OneLoginProvider {
|
|
|
2290
2308
|
});
|
|
2291
2309
|
}
|
|
2292
2310
|
async populateIdentity(response) {
|
|
2293
|
-
const {profile} = response;
|
|
2311
|
+
const { profile } = response;
|
|
2294
2312
|
if (!profile.email) {
|
|
2295
2313
|
throw new Error("OIDC profile contained no email");
|
|
2296
2314
|
}
|
|
2297
2315
|
const id = profile.email.split("@")[0];
|
|
2298
|
-
return {...response, backstageIdentity: {id}};
|
|
2316
|
+
return { ...response, backstageIdentity: { id, token: "" } };
|
|
2299
2317
|
}
|
|
2300
2318
|
}
|
|
2301
2319
|
const createOneLoginProvider = (_options) => {
|
|
2302
|
-
return ({providerId, globalConfig, config, tokenIssuer}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
2320
|
+
return ({ providerId, globalConfig, config, tokenIssuer }) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
2303
2321
|
const clientId = envConfig.getString("clientId");
|
|
2304
2322
|
const clientSecret = envConfig.getString("clientSecret");
|
|
2305
2323
|
const issuer = envConfig.getString("issuer");
|
|
@@ -2335,8 +2353,8 @@ const factories = {
|
|
|
2335
2353
|
};
|
|
2336
2354
|
|
|
2337
2355
|
function createOidcRouter(options) {
|
|
2338
|
-
const {baseUrl, tokenIssuer} = options;
|
|
2339
|
-
const router = Router__default[
|
|
2356
|
+
const { baseUrl, tokenIssuer } = options;
|
|
2357
|
+
const router = Router__default["default"]();
|
|
2340
2358
|
const config = {
|
|
2341
2359
|
issuer: baseUrl,
|
|
2342
2360
|
token_endpoint: `${baseUrl}/v1/token`,
|
|
@@ -2354,8 +2372,8 @@ function createOidcRouter(options) {
|
|
|
2354
2372
|
res.json(config);
|
|
2355
2373
|
});
|
|
2356
2374
|
router.get("/.well-known/jwks.json", async (_req, res) => {
|
|
2357
|
-
const {keys} = await tokenIssuer.listPublicKeys();
|
|
2358
|
-
res.json({keys});
|
|
2375
|
+
const { keys } = await tokenIssuer.listPublicKeys();
|
|
2376
|
+
res.json({ keys });
|
|
2359
2377
|
});
|
|
2360
2378
|
router.get("/v1/token", (_req, res) => {
|
|
2361
2379
|
res.status(501).send("Not Implemented");
|
|
@@ -2375,21 +2393,30 @@ class IdentityClient {
|
|
|
2375
2393
|
this.keyStoreUpdated = 0;
|
|
2376
2394
|
}
|
|
2377
2395
|
async authenticate(token) {
|
|
2396
|
+
var _a;
|
|
2378
2397
|
if (!token) {
|
|
2379
|
-
throw new
|
|
2398
|
+
throw new errors.AuthenticationError("No token specified");
|
|
2380
2399
|
}
|
|
2381
2400
|
const key = await this.getKey(token);
|
|
2382
2401
|
if (!key) {
|
|
2383
|
-
throw new
|
|
2402
|
+
throw new errors.AuthenticationError("No signing key matching token found");
|
|
2384
2403
|
}
|
|
2385
2404
|
const decoded = jose.JWT.IdToken.verify(token, key, {
|
|
2386
2405
|
algorithms: ["ES256"],
|
|
2387
2406
|
audience: "backstage",
|
|
2388
2407
|
issuer: this.issuer
|
|
2389
2408
|
});
|
|
2409
|
+
if (!decoded.sub) {
|
|
2410
|
+
throw new errors.AuthenticationError("No user sub found in token");
|
|
2411
|
+
}
|
|
2390
2412
|
const user = {
|
|
2391
2413
|
id: decoded.sub,
|
|
2392
|
-
|
|
2414
|
+
token,
|
|
2415
|
+
identity: {
|
|
2416
|
+
type: "user",
|
|
2417
|
+
userEntityRef: decoded.sub,
|
|
2418
|
+
ownershipEntityRefs: (_a = decoded.ent) != null ? _a : []
|
|
2419
|
+
}
|
|
2393
2420
|
};
|
|
2394
2421
|
return user;
|
|
2395
2422
|
}
|
|
@@ -2401,19 +2428,19 @@ class IdentityClient {
|
|
|
2401
2428
|
return matches == null ? void 0 : matches[1];
|
|
2402
2429
|
}
|
|
2403
2430
|
async getKey(rawJwtToken) {
|
|
2404
|
-
const {header, payload} = jose.JWT.decode(rawJwtToken, {
|
|
2431
|
+
const { header, payload } = jose.JWT.decode(rawJwtToken, {
|
|
2405
2432
|
complete: true
|
|
2406
2433
|
});
|
|
2407
|
-
const keyStoreHasKey = !!this.keyStore.get({kid: header.kid});
|
|
2434
|
+
const keyStoreHasKey = !!this.keyStore.get({ kid: header.kid });
|
|
2408
2435
|
const issuedAfterLastRefresh = (payload == null ? void 0 : payload.iat) && payload.iat > this.keyStoreUpdated - CLOCK_MARGIN_S;
|
|
2409
2436
|
if (!keyStoreHasKey && issuedAfterLastRefresh) {
|
|
2410
2437
|
await this.refreshKeyStore();
|
|
2411
2438
|
}
|
|
2412
|
-
return this.keyStore.get({kid: header.kid});
|
|
2439
|
+
return this.keyStore.get({ kid: header.kid });
|
|
2413
2440
|
}
|
|
2414
2441
|
async listPublicKeys() {
|
|
2415
2442
|
const url = `${await this.discovery.getBaseUrl("auth")}/.well-known/jwks.json`;
|
|
2416
|
-
const response = await fetch__default[
|
|
2443
|
+
const response = await fetch__default["default"](url);
|
|
2417
2444
|
if (!response.ok) {
|
|
2418
2445
|
const payload = await response.text();
|
|
2419
2446
|
const message = `Request failed with ${response.status} ${response.statusText}, ${payload}`;
|
|
@@ -2449,13 +2476,13 @@ class TokenFactory {
|
|
|
2449
2476
|
const iat = Math.floor(Date.now() / MS_IN_S);
|
|
2450
2477
|
const exp = iat + this.keyDurationSeconds;
|
|
2451
2478
|
this.logger.info(`Issuing token for ${sub}, with entities ${ent != null ? ent : []}`);
|
|
2452
|
-
return jose.JWS.sign({iss, sub, aud, iat, exp, ent}, key, {
|
|
2479
|
+
return jose.JWS.sign({ iss, sub, aud, iat, exp, ent }, key, {
|
|
2453
2480
|
alg: key.alg,
|
|
2454
2481
|
kid: key.kid
|
|
2455
2482
|
});
|
|
2456
2483
|
}
|
|
2457
2484
|
async listPublicKeys() {
|
|
2458
|
-
const {items: keys} = await this.keyStore.listKeys();
|
|
2485
|
+
const { items: keys } = await this.keyStore.listKeys();
|
|
2459
2486
|
const validKeys = [];
|
|
2460
2487
|
const expiredKeys = [];
|
|
2461
2488
|
for (const key of keys) {
|
|
@@ -2469,13 +2496,13 @@ class TokenFactory {
|
|
|
2469
2496
|
}
|
|
2470
2497
|
}
|
|
2471
2498
|
if (expiredKeys.length > 0) {
|
|
2472
|
-
const kids = expiredKeys.map(({key}) => key.kid);
|
|
2499
|
+
const kids = expiredKeys.map(({ key }) => key.kid);
|
|
2473
2500
|
this.logger.info(`Removing expired signing keys, '${kids.join("', '")}'`);
|
|
2474
2501
|
this.keyStore.removeKeys(kids).catch((error) => {
|
|
2475
2502
|
this.logger.error(`Failed to remove expired keys, ${error}`);
|
|
2476
2503
|
});
|
|
2477
2504
|
}
|
|
2478
|
-
return {keys: validKeys.map(({key}) => key)};
|
|
2505
|
+
return { keys: validKeys.map(({ key }) => key) };
|
|
2479
2506
|
}
|
|
2480
2507
|
async getKey() {
|
|
2481
2508
|
if (this.privateKeyPromise) {
|
|
@@ -2513,7 +2540,7 @@ class TokenFactory {
|
|
|
2513
2540
|
const migrationsDir = backendCommon.resolvePackagePath("@backstage/plugin-auth-backend", "migrations");
|
|
2514
2541
|
const TABLE = "signing_keys";
|
|
2515
2542
|
const parseDate = (date) => {
|
|
2516
|
-
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);
|
|
2517
2544
|
if (!parsedDate.isValid) {
|
|
2518
2545
|
throw new Error(`Failed to parse date, reason: ${parsedDate.invalidReason}, explanation: ${parsedDate.invalidExplanation}`);
|
|
2519
2546
|
}
|
|
@@ -2521,7 +2548,7 @@ const parseDate = (date) => {
|
|
|
2521
2548
|
};
|
|
2522
2549
|
class DatabaseKeyStore {
|
|
2523
2550
|
static async create(options) {
|
|
2524
|
-
const {database} = options;
|
|
2551
|
+
const { database } = options;
|
|
2525
2552
|
await database.migrate.latest({
|
|
2526
2553
|
directory: migrationsDir
|
|
2527
2554
|
});
|
|
@@ -2552,7 +2579,7 @@ class DatabaseKeyStore {
|
|
|
2552
2579
|
|
|
2553
2580
|
class MemoryKeyStore {
|
|
2554
2581
|
constructor() {
|
|
2555
|
-
this.keys = new Map();
|
|
2582
|
+
this.keys = /* @__PURE__ */ new Map();
|
|
2556
2583
|
}
|
|
2557
2584
|
async addKey(key) {
|
|
2558
2585
|
this.keys.set(key.kid, {
|
|
@@ -2567,7 +2594,7 @@ class MemoryKeyStore {
|
|
|
2567
2594
|
}
|
|
2568
2595
|
async listKeys() {
|
|
2569
2596
|
return {
|
|
2570
|
-
items: Array.from(this.keys).map(([, {createdAt, key: keyStr}]) => ({
|
|
2597
|
+
items: Array.from(this.keys).map(([, { createdAt, key: keyStr }]) => ({
|
|
2571
2598
|
createdAt,
|
|
2572
2599
|
key: JSON.parse(keyStr)
|
|
2573
2600
|
}))
|
|
@@ -2584,7 +2611,7 @@ class FirestoreKeyStore {
|
|
|
2584
2611
|
this.timeout = timeout;
|
|
2585
2612
|
}
|
|
2586
2613
|
static async create(settings) {
|
|
2587
|
-
const {path, timeout, ...firestoreSettings} = settings != null ? settings : {};
|
|
2614
|
+
const { path, timeout, ...firestoreSettings } = settings != null ? settings : {};
|
|
2588
2615
|
const database = new firestore.Firestore(firestoreSettings);
|
|
2589
2616
|
return new FirestoreKeyStore(database, path != null ? path : DEFAULT_DOCUMENT_PATH, timeout != null ? timeout : DEFAULT_TIMEOUT_MS);
|
|
2590
2617
|
}
|
|
@@ -2632,7 +2659,7 @@ class FirestoreKeyStore {
|
|
|
2632
2659
|
class KeyStores {
|
|
2633
2660
|
static async fromConfig(config, options) {
|
|
2634
2661
|
var _a;
|
|
2635
|
-
const {logger, database} = options != null ? options : {};
|
|
2662
|
+
const { logger, database } = options != null ? options : {};
|
|
2636
2663
|
const ks = config.getOptionalConfig("auth.keyStore");
|
|
2637
2664
|
const provider = (_a = ks == null ? void 0 : ks.getOptionalString("provider")) != null ? _a : "database";
|
|
2638
2665
|
logger == null ? void 0 : logger.info(`Configuring "${provider}" as KeyStore provider`);
|
|
@@ -2665,36 +2692,31 @@ class KeyStores {
|
|
|
2665
2692
|
}
|
|
2666
2693
|
}
|
|
2667
2694
|
|
|
2668
|
-
async function createRouter({
|
|
2669
|
-
logger,
|
|
2670
|
-
|
|
2671
|
-
discovery,
|
|
2672
|
-
database,
|
|
2673
|
-
providerFactories
|
|
2674
|
-
}) {
|
|
2675
|
-
const router = Router__default['default']();
|
|
2695
|
+
async function createRouter(options) {
|
|
2696
|
+
const { logger, config, discovery, database, providerFactories } = options;
|
|
2697
|
+
const router = Router__default["default"]();
|
|
2676
2698
|
const appUrl = config.getString("app.baseUrl");
|
|
2677
2699
|
const authUrl = await discovery.getExternalBaseUrl("auth");
|
|
2678
|
-
const keyStore = await KeyStores.fromConfig(config, {logger, database});
|
|
2700
|
+
const keyStore = await KeyStores.fromConfig(config, { logger, database });
|
|
2679
2701
|
const keyDurationSeconds = 3600;
|
|
2680
2702
|
const tokenIssuer = new TokenFactory({
|
|
2681
2703
|
issuer: authUrl,
|
|
2682
2704
|
keyStore,
|
|
2683
2705
|
keyDurationSeconds,
|
|
2684
|
-
logger: logger.child({component: "token-factory"})
|
|
2706
|
+
logger: logger.child({ component: "token-factory" })
|
|
2685
2707
|
});
|
|
2686
|
-
const catalogApi = new catalogClient.CatalogClient({discoveryApi: discovery});
|
|
2708
|
+
const catalogApi = new catalogClient.CatalogClient({ discoveryApi: discovery });
|
|
2687
2709
|
const secret = config.getOptionalString("auth.session.secret");
|
|
2688
2710
|
if (secret) {
|
|
2689
|
-
router.use(cookieParser__default[
|
|
2690
|
-
router.use(session__default[
|
|
2691
|
-
router.use(passport__default[
|
|
2692
|
-
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());
|
|
2693
2715
|
} else {
|
|
2694
|
-
router.use(cookieParser__default[
|
|
2716
|
+
router.use(cookieParser__default["default"]());
|
|
2695
2717
|
}
|
|
2696
|
-
router.use(express__default[
|
|
2697
|
-
router.use(express__default[
|
|
2718
|
+
router.use(express__default["default"].urlencoded({ extended: false }));
|
|
2719
|
+
router.use(express__default["default"].json());
|
|
2698
2720
|
const allProviderFactories = {
|
|
2699
2721
|
...factories,
|
|
2700
2722
|
...providerFactories
|
|
@@ -2708,14 +2730,14 @@ async function createRouter({
|
|
|
2708
2730
|
try {
|
|
2709
2731
|
const provider = providerFactory({
|
|
2710
2732
|
providerId,
|
|
2711
|
-
globalConfig: {baseUrl: authUrl, appUrl, isOriginAllowed},
|
|
2733
|
+
globalConfig: { baseUrl: authUrl, appUrl, isOriginAllowed },
|
|
2712
2734
|
config: providersConfig.getConfig(providerId),
|
|
2713
2735
|
logger,
|
|
2714
2736
|
tokenIssuer,
|
|
2715
2737
|
discovery,
|
|
2716
2738
|
catalogApi
|
|
2717
2739
|
});
|
|
2718
|
-
const r = Router__default[
|
|
2740
|
+
const r = Router__default["default"]();
|
|
2719
2741
|
r.get("/start", provider.start.bind(provider));
|
|
2720
2742
|
r.get("/handler/frame", provider.frameHandler.bind(provider));
|
|
2721
2743
|
r.post("/handler/frame", provider.frameHandler.bind(provider));
|
|
@@ -2747,7 +2769,7 @@ async function createRouter({
|
|
|
2747
2769
|
baseUrl: authUrl
|
|
2748
2770
|
}));
|
|
2749
2771
|
router.use("/:provider/", (req) => {
|
|
2750
|
-
const {provider} = req.params;
|
|
2772
|
+
const { provider } = req.params;
|
|
2751
2773
|
throw new errors.NotFoundError(`Unknown auth provider '${provider}'`);
|
|
2752
2774
|
});
|
|
2753
2775
|
return router;
|
|
@@ -2755,9 +2777,9 @@ async function createRouter({
|
|
|
2755
2777
|
function createOriginFilter(config) {
|
|
2756
2778
|
var _a;
|
|
2757
2779
|
const appUrl = config.getString("app.baseUrl");
|
|
2758
|
-
const {origin: appOrigin} = new URL(appUrl);
|
|
2780
|
+
const { origin: appOrigin } = new URL(appUrl);
|
|
2759
2781
|
const allowedOrigins = config.getOptionalStringArray("auth.experimentalExtraAllowedOrigins");
|
|
2760
|
-
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 : [];
|
|
2761
2783
|
return (origin) => {
|
|
2762
2784
|
if (origin === appOrigin) {
|
|
2763
2785
|
return true;
|
|
@@ -2793,6 +2815,7 @@ exports.googleEmailSignInResolver = googleEmailSignInResolver;
|
|
|
2793
2815
|
exports.microsoftEmailSignInResolver = microsoftEmailSignInResolver;
|
|
2794
2816
|
exports.oktaEmailSignInResolver = oktaEmailSignInResolver;
|
|
2795
2817
|
exports.postMessageResponse = postMessageResponse;
|
|
2818
|
+
exports.prepareBackstageIdentityResponse = prepareBackstageIdentityResponse;
|
|
2796
2819
|
exports.readState = readState;
|
|
2797
2820
|
exports.verifyNonce = verifyNonce;
|
|
2798
2821
|
//# sourceMappingURL=index.cjs.js.map
|