@backstage/plugin-auth-backend 0.22.4-next.0 → 0.22.4
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 +62 -0
- package/config.d.ts +0 -9
- package/dist/index.cjs.js +183 -518
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +25 -14
- package/package.json +23 -21
package/dist/index.cjs.js
CHANGED
|
@@ -15,8 +15,8 @@ var url = require('url');
|
|
|
15
15
|
var errors = require('@backstage/errors');
|
|
16
16
|
var jose = require('jose');
|
|
17
17
|
var pluginAuthBackendModuleAwsAlbProvider = require('@backstage/plugin-auth-backend-module-aws-alb-provider');
|
|
18
|
-
var
|
|
19
|
-
var
|
|
18
|
+
var pluginAuthBackendModuleBitbucketProvider = require('@backstage/plugin-auth-backend-module-bitbucket-provider');
|
|
19
|
+
var pluginAuthBackendModuleCloudflareAccessProvider = require('@backstage/plugin-auth-backend-module-cloudflare-access-provider');
|
|
20
20
|
var pluginAuthBackendModuleGcpIapProvider = require('@backstage/plugin-auth-backend-module-gcp-iap-provider');
|
|
21
21
|
var pluginAuthBackendModuleGithubProvider = require('@backstage/plugin-auth-backend-module-github-provider');
|
|
22
22
|
var pluginAuthBackendModuleGitlabProvider = require('@backstage/plugin-auth-backend-module-gitlab-provider');
|
|
@@ -29,6 +29,8 @@ var pluginAuthBackendModuleOktaProvider = require('@backstage/plugin-auth-backen
|
|
|
29
29
|
var passportOneloginOauth = require('passport-onelogin-oauth');
|
|
30
30
|
var passportSaml = require('@node-saml/passport-saml');
|
|
31
31
|
var passportOauth2 = require('passport-oauth2');
|
|
32
|
+
var fetch = require('node-fetch');
|
|
33
|
+
var pluginAuthBackendModuleAzureEasyauthProvider = require('@backstage/plugin-auth-backend-module-azure-easyauth-provider');
|
|
32
34
|
var catalogClient = require('@backstage/catalog-client');
|
|
33
35
|
var minimatch = require('minimatch');
|
|
34
36
|
var catalogModel = require('@backstage/catalog-model');
|
|
@@ -219,10 +221,10 @@ const ensuresXRequestedWith = (req) => {
|
|
|
219
221
|
|
|
220
222
|
const prepareBackstageIdentityResponse = pluginAuthNode.prepareBackstageIdentityResponse;
|
|
221
223
|
|
|
222
|
-
var __defProp$
|
|
223
|
-
var __defNormalProp$
|
|
224
|
-
var __publicField$
|
|
225
|
-
__defNormalProp$
|
|
224
|
+
var __defProp$9 = Object.defineProperty;
|
|
225
|
+
var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
226
|
+
var __publicField$9 = (obj, key, value) => {
|
|
227
|
+
__defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
226
228
|
return value;
|
|
227
229
|
};
|
|
228
230
|
const THOUSAND_DAYS_MS = 1e3 * 24 * 60 * 60 * 1e3;
|
|
@@ -231,8 +233,8 @@ class OAuthAdapter {
|
|
|
231
233
|
constructor(handlers, options) {
|
|
232
234
|
this.handlers = handlers;
|
|
233
235
|
this.options = options;
|
|
234
|
-
__publicField$
|
|
235
|
-
__publicField$
|
|
236
|
+
__publicField$9(this, "baseCookieOptions");
|
|
237
|
+
__publicField$9(this, "setNonceCookie", (res, nonce, cookieConfig) => {
|
|
236
238
|
res.cookie(`${this.options.providerId}-nonce`, nonce, {
|
|
237
239
|
maxAge: TEN_MINUTES_MS,
|
|
238
240
|
...this.baseCookieOptions,
|
|
@@ -240,34 +242,34 @@ class OAuthAdapter {
|
|
|
240
242
|
path: `${cookieConfig.path}/handler`
|
|
241
243
|
});
|
|
242
244
|
});
|
|
243
|
-
__publicField$
|
|
245
|
+
__publicField$9(this, "setGrantedScopeCookie", (res, scope, cookieConfig) => {
|
|
244
246
|
res.cookie(`${this.options.providerId}-granted-scope`, scope, {
|
|
245
247
|
maxAge: THOUSAND_DAYS_MS,
|
|
246
248
|
...this.baseCookieOptions,
|
|
247
249
|
...cookieConfig
|
|
248
250
|
});
|
|
249
251
|
});
|
|
250
|
-
__publicField$
|
|
252
|
+
__publicField$9(this, "getRefreshTokenFromCookie", (req) => {
|
|
251
253
|
return req.cookies[`${this.options.providerId}-refresh-token`];
|
|
252
254
|
});
|
|
253
|
-
__publicField$
|
|
255
|
+
__publicField$9(this, "getGrantedScopeFromCookie", (req) => {
|
|
254
256
|
return req.cookies[`${this.options.providerId}-granted-scope`];
|
|
255
257
|
});
|
|
256
|
-
__publicField$
|
|
258
|
+
__publicField$9(this, "setRefreshTokenCookie", (res, refreshToken, cookieConfig) => {
|
|
257
259
|
res.cookie(`${this.options.providerId}-refresh-token`, refreshToken, {
|
|
258
260
|
maxAge: THOUSAND_DAYS_MS,
|
|
259
261
|
...this.baseCookieOptions,
|
|
260
262
|
...cookieConfig
|
|
261
263
|
});
|
|
262
264
|
});
|
|
263
|
-
__publicField$
|
|
265
|
+
__publicField$9(this, "removeRefreshTokenCookie", (res, cookieConfig) => {
|
|
264
266
|
res.cookie(`${this.options.providerId}-refresh-token`, "", {
|
|
265
267
|
maxAge: 0,
|
|
266
268
|
...this.baseCookieOptions,
|
|
267
269
|
...cookieConfig
|
|
268
270
|
});
|
|
269
271
|
});
|
|
270
|
-
__publicField$
|
|
272
|
+
__publicField$9(this, "getCookieConfig", (origin) => {
|
|
271
273
|
return this.options.cookieConfigurer({
|
|
272
274
|
providerId: this.options.providerId,
|
|
273
275
|
baseUrl: this.options.baseUrl,
|
|
@@ -565,21 +567,21 @@ const executeFetchUserProfileStrategy = async (providerStrategy, accessToken) =>
|
|
|
565
567
|
});
|
|
566
568
|
};
|
|
567
569
|
|
|
568
|
-
var __defProp$
|
|
569
|
-
var __defNormalProp$
|
|
570
|
-
var __publicField$
|
|
571
|
-
__defNormalProp$
|
|
570
|
+
var __defProp$8 = Object.defineProperty;
|
|
571
|
+
var __defNormalProp$8 = (obj, key, value) => key in obj ? __defProp$8(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
572
|
+
var __publicField$8 = (obj, key, value) => {
|
|
573
|
+
__defNormalProp$8(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
572
574
|
return value;
|
|
573
575
|
};
|
|
574
576
|
class Auth0AuthProvider {
|
|
575
577
|
constructor(options) {
|
|
576
|
-
__publicField$
|
|
577
|
-
__publicField$
|
|
578
|
-
__publicField$
|
|
579
|
-
__publicField$
|
|
580
|
-
__publicField$
|
|
581
|
-
__publicField$
|
|
582
|
-
__publicField$
|
|
578
|
+
__publicField$8(this, "_strategy");
|
|
579
|
+
__publicField$8(this, "signInResolver");
|
|
580
|
+
__publicField$8(this, "authHandler");
|
|
581
|
+
__publicField$8(this, "resolverContext");
|
|
582
|
+
__publicField$8(this, "audience");
|
|
583
|
+
__publicField$8(this, "connection");
|
|
584
|
+
__publicField$8(this, "connectionScope");
|
|
583
585
|
/**
|
|
584
586
|
* Due to passport-auth0 forcing options.state = true,
|
|
585
587
|
* passport-oauth2 requires express-session to be installed
|
|
@@ -588,7 +590,7 @@ class Auth0AuthProvider {
|
|
|
588
590
|
* passport-oauth2, which is the StateStore implementation used when options.state = false,
|
|
589
591
|
* allowing us to avoid using express-session in order to integrate with auth0.
|
|
590
592
|
*/
|
|
591
|
-
__publicField$
|
|
593
|
+
__publicField$8(this, "store", {
|
|
592
594
|
store(_req, cb) {
|
|
593
595
|
cb(null, null);
|
|
594
596
|
},
|
|
@@ -740,370 +742,34 @@ const awsAlb = createAuthProviderIntegration({
|
|
|
740
742
|
}
|
|
741
743
|
});
|
|
742
744
|
|
|
743
|
-
var __defProp$a = Object.defineProperty;
|
|
744
|
-
var __defNormalProp$a = (obj, key, value) => key in obj ? __defProp$a(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
745
|
-
var __publicField$a = (obj, key, value) => {
|
|
746
|
-
__defNormalProp$a(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
747
|
-
return value;
|
|
748
|
-
};
|
|
749
|
-
class BitbucketAuthProvider {
|
|
750
|
-
constructor(options) {
|
|
751
|
-
__publicField$a(this, "_strategy");
|
|
752
|
-
__publicField$a(this, "signInResolver");
|
|
753
|
-
__publicField$a(this, "authHandler");
|
|
754
|
-
__publicField$a(this, "resolverContext");
|
|
755
|
-
this.signInResolver = options.signInResolver;
|
|
756
|
-
this.authHandler = options.authHandler;
|
|
757
|
-
this.resolverContext = options.resolverContext;
|
|
758
|
-
this._strategy = new passportBitbucketOauth2.Strategy(
|
|
759
|
-
{
|
|
760
|
-
clientID: options.clientId,
|
|
761
|
-
clientSecret: options.clientSecret,
|
|
762
|
-
callbackURL: options.callbackUrl,
|
|
763
|
-
passReqToCallback: false
|
|
764
|
-
},
|
|
765
|
-
(accessToken, refreshToken, params, fullProfile, done) => {
|
|
766
|
-
done(
|
|
767
|
-
void 0,
|
|
768
|
-
{
|
|
769
|
-
fullProfile,
|
|
770
|
-
params,
|
|
771
|
-
accessToken,
|
|
772
|
-
refreshToken
|
|
773
|
-
},
|
|
774
|
-
{
|
|
775
|
-
refreshToken
|
|
776
|
-
}
|
|
777
|
-
);
|
|
778
|
-
}
|
|
779
|
-
);
|
|
780
|
-
}
|
|
781
|
-
async start(req) {
|
|
782
|
-
return await executeRedirectStrategy(req, this._strategy, {
|
|
783
|
-
accessType: "offline",
|
|
784
|
-
prompt: "consent",
|
|
785
|
-
scope: req.scope,
|
|
786
|
-
state: encodeState(req.state)
|
|
787
|
-
});
|
|
788
|
-
}
|
|
789
|
-
async handler(req) {
|
|
790
|
-
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
791
|
-
return {
|
|
792
|
-
response: await this.handleResult(result),
|
|
793
|
-
refreshToken: privateInfo.refreshToken
|
|
794
|
-
};
|
|
795
|
-
}
|
|
796
|
-
async refresh(req) {
|
|
797
|
-
const { accessToken, refreshToken, params } = await executeRefreshTokenStrategy(
|
|
798
|
-
this._strategy,
|
|
799
|
-
req.refreshToken,
|
|
800
|
-
req.scope
|
|
801
|
-
);
|
|
802
|
-
const fullProfile = await executeFetchUserProfileStrategy(
|
|
803
|
-
this._strategy,
|
|
804
|
-
accessToken
|
|
805
|
-
);
|
|
806
|
-
return {
|
|
807
|
-
response: await this.handleResult({
|
|
808
|
-
fullProfile,
|
|
809
|
-
params,
|
|
810
|
-
accessToken
|
|
811
|
-
}),
|
|
812
|
-
refreshToken
|
|
813
|
-
};
|
|
814
|
-
}
|
|
815
|
-
async handleResult(result) {
|
|
816
|
-
result.fullProfile.avatarUrl = result.fullProfile._json.links.avatar.href;
|
|
817
|
-
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
818
|
-
const response = {
|
|
819
|
-
providerInfo: {
|
|
820
|
-
idToken: result.params.id_token,
|
|
821
|
-
accessToken: result.accessToken,
|
|
822
|
-
scope: result.params.scope,
|
|
823
|
-
expiresInSeconds: result.params.expires_in
|
|
824
|
-
},
|
|
825
|
-
profile
|
|
826
|
-
};
|
|
827
|
-
if (this.signInResolver) {
|
|
828
|
-
response.backstageIdentity = await this.signInResolver(
|
|
829
|
-
{
|
|
830
|
-
result,
|
|
831
|
-
profile
|
|
832
|
-
},
|
|
833
|
-
this.resolverContext
|
|
834
|
-
);
|
|
835
|
-
}
|
|
836
|
-
return response;
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
745
|
const bitbucket = createAuthProviderIntegration({
|
|
840
746
|
create(options) {
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
847
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
848
|
-
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
849
|
-
});
|
|
850
|
-
const provider = new BitbucketAuthProvider({
|
|
851
|
-
clientId,
|
|
852
|
-
clientSecret,
|
|
853
|
-
callbackUrl,
|
|
854
|
-
signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver,
|
|
855
|
-
authHandler,
|
|
856
|
-
resolverContext
|
|
857
|
-
});
|
|
858
|
-
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
859
|
-
providerId,
|
|
860
|
-
callbackUrl
|
|
861
|
-
});
|
|
747
|
+
var _a;
|
|
748
|
+
return pluginAuthNode.createOAuthProviderFactory({
|
|
749
|
+
authenticator: pluginAuthBackendModuleBitbucketProvider.bitbucketAuthenticator,
|
|
750
|
+
profileTransform: adaptLegacyOAuthHandler(options == null ? void 0 : options.authHandler),
|
|
751
|
+
signInResolver: adaptLegacyOAuthSignInResolver((_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver)
|
|
862
752
|
});
|
|
863
753
|
},
|
|
864
|
-
resolvers: {
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
usernameMatchingUserEntityAnnotation() {
|
|
869
|
-
return async (info, ctx) => {
|
|
870
|
-
const { result } = info;
|
|
871
|
-
if (!result.fullProfile.username) {
|
|
872
|
-
throw new Error("Bitbucket profile contained no Username");
|
|
873
|
-
}
|
|
874
|
-
return ctx.signInWithCatalogUser({
|
|
875
|
-
annotations: {
|
|
876
|
-
"bitbucket.org/username": result.fullProfile.username
|
|
877
|
-
}
|
|
878
|
-
});
|
|
879
|
-
};
|
|
880
|
-
},
|
|
881
|
-
/**
|
|
882
|
-
* Looks up the user by matching their user ID to the `bitbucket.org/user-id` annotation.
|
|
883
|
-
*/
|
|
884
|
-
userIdMatchingUserEntityAnnotation() {
|
|
885
|
-
return async (info, ctx) => {
|
|
886
|
-
const { result } = info;
|
|
887
|
-
if (!result.fullProfile.id) {
|
|
888
|
-
throw new Error("Bitbucket profile contained no User ID");
|
|
889
|
-
}
|
|
890
|
-
return ctx.signInWithCatalogUser({
|
|
891
|
-
annotations: {
|
|
892
|
-
"bitbucket.org/user-id": result.fullProfile.id
|
|
893
|
-
}
|
|
894
|
-
});
|
|
895
|
-
};
|
|
896
|
-
}
|
|
897
|
-
}
|
|
754
|
+
resolvers: adaptOAuthSignInResolverToLegacy({
|
|
755
|
+
userIdMatchingUserEntityAnnotation: pluginAuthBackendModuleBitbucketProvider.bitbucketSignInResolvers.userIdMatchingUserEntityAnnotation(),
|
|
756
|
+
usernameMatchingUserEntityAnnotation: pluginAuthBackendModuleBitbucketProvider.bitbucketSignInResolvers.usernameMatchingUserEntityAnnotation()
|
|
757
|
+
})
|
|
898
758
|
});
|
|
899
759
|
|
|
900
|
-
const commonByEmailLocalPartResolver = async (info, ctx) => {
|
|
901
|
-
const { profile } = info;
|
|
902
|
-
if (!profile.email) {
|
|
903
|
-
throw new Error("Login failed, user profile does not contain an email");
|
|
904
|
-
}
|
|
905
|
-
const [localPart] = profile.email.split("@");
|
|
906
|
-
return ctx.signInWithCatalogUser({
|
|
907
|
-
entityRef: { name: localPart }
|
|
908
|
-
});
|
|
909
|
-
};
|
|
910
|
-
const commonByEmailResolver = async (info, ctx) => {
|
|
911
|
-
const { profile } = info;
|
|
912
|
-
if (!profile.email) {
|
|
913
|
-
throw new Error("Login failed, user profile does not contain an email");
|
|
914
|
-
}
|
|
915
|
-
return ctx.signInWithCatalogUser({
|
|
916
|
-
filter: {
|
|
917
|
-
"spec.profile.email": profile.email
|
|
918
|
-
}
|
|
919
|
-
});
|
|
920
|
-
};
|
|
921
|
-
|
|
922
|
-
var __defProp$9 = Object.defineProperty;
|
|
923
|
-
var __defNormalProp$9 = (obj, key, value) => key in obj ? __defProp$9(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
924
|
-
var __publicField$9 = (obj, key, value) => {
|
|
925
|
-
__defNormalProp$9(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
926
|
-
return value;
|
|
927
|
-
};
|
|
928
|
-
const CF_JWT_HEADER = "cf-access-jwt-assertion";
|
|
929
|
-
const COOKIE_AUTH_NAME = "CF_Authorization";
|
|
930
|
-
const CACHE_PREFIX = "providers/cloudflare-access/profile-v1";
|
|
931
|
-
class CloudflareAccessAuthProvider {
|
|
932
|
-
constructor(options) {
|
|
933
|
-
__publicField$9(this, "teamName");
|
|
934
|
-
__publicField$9(this, "serviceTokens");
|
|
935
|
-
__publicField$9(this, "resolverContext");
|
|
936
|
-
__publicField$9(this, "authHandler");
|
|
937
|
-
__publicField$9(this, "signInResolver");
|
|
938
|
-
__publicField$9(this, "jwtKeySet");
|
|
939
|
-
__publicField$9(this, "cache");
|
|
940
|
-
this.teamName = options.teamName;
|
|
941
|
-
this.serviceTokens = options.serviceTokens;
|
|
942
|
-
this.authHandler = options.authHandler;
|
|
943
|
-
this.signInResolver = options.signInResolver;
|
|
944
|
-
this.resolverContext = options.resolverContext;
|
|
945
|
-
this.jwtKeySet = jose.createRemoteJWKSet(
|
|
946
|
-
new URL(
|
|
947
|
-
`https://${this.teamName}.cloudflareaccess.com/cdn-cgi/access/certs`
|
|
948
|
-
)
|
|
949
|
-
);
|
|
950
|
-
this.cache = options.cache;
|
|
951
|
-
}
|
|
952
|
-
frameHandler() {
|
|
953
|
-
return Promise.resolve();
|
|
954
|
-
}
|
|
955
|
-
async refresh(req, res) {
|
|
956
|
-
const result = await this.getResult(req);
|
|
957
|
-
const response = await this.handleResult(result);
|
|
958
|
-
res.json(response);
|
|
959
|
-
}
|
|
960
|
-
start() {
|
|
961
|
-
return Promise.resolve();
|
|
962
|
-
}
|
|
963
|
-
async getIdentityProfile(jwt) {
|
|
964
|
-
const headers = new fetch.Headers();
|
|
965
|
-
headers.set(CF_JWT_HEADER, jwt);
|
|
966
|
-
headers.set("cookie", `${COOKIE_AUTH_NAME}=${jwt}`);
|
|
967
|
-
try {
|
|
968
|
-
const res = await fetch__default.default(
|
|
969
|
-
`https://${this.teamName}.cloudflareaccess.com/cdn-cgi/access/get-identity`,
|
|
970
|
-
{ headers }
|
|
971
|
-
);
|
|
972
|
-
if (!res.ok) {
|
|
973
|
-
throw await errors.ResponseError.fromResponse(res);
|
|
974
|
-
}
|
|
975
|
-
const cfIdentity = await res.json();
|
|
976
|
-
return cfIdentity;
|
|
977
|
-
} catch (err) {
|
|
978
|
-
throw new errors.ForwardedError("getIdentityProfile failed", err);
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
async getResult(req) {
|
|
982
|
-
var _a, _b;
|
|
983
|
-
let jwt = req.header(CF_JWT_HEADER);
|
|
984
|
-
if (!jwt) {
|
|
985
|
-
jwt = req.cookies.CF_Authorization;
|
|
986
|
-
}
|
|
987
|
-
if (!jwt) {
|
|
988
|
-
throw new errors.AuthenticationError(
|
|
989
|
-
`Missing ${CF_JWT_HEADER} from Cloudflare Access`
|
|
990
|
-
);
|
|
991
|
-
}
|
|
992
|
-
const verifyResult = await jose.jwtVerify(jwt, this.jwtKeySet, {
|
|
993
|
-
issuer: `https://${this.teamName}.cloudflareaccess.com`
|
|
994
|
-
});
|
|
995
|
-
const isServiceToken = !verifyResult.payload.sub;
|
|
996
|
-
const subject = isServiceToken ? verifyResult.payload.common_name : verifyResult.payload.sub;
|
|
997
|
-
if (!subject) {
|
|
998
|
-
throw new errors.AuthenticationError(
|
|
999
|
-
`Missing both sub and common_name from Cloudflare Access JWT`
|
|
1000
|
-
);
|
|
1001
|
-
}
|
|
1002
|
-
const serviceToken = this.serviceTokens.find((st) => st.token === subject);
|
|
1003
|
-
if (isServiceToken && !serviceToken) {
|
|
1004
|
-
throw new errors.AuthenticationError(
|
|
1005
|
-
`${subject} is not a permitted Service Token.`
|
|
1006
|
-
);
|
|
1007
|
-
}
|
|
1008
|
-
const cacheKey = `${CACHE_PREFIX}/${subject}`;
|
|
1009
|
-
const cfAccessResultStr = await ((_a = this.cache) == null ? void 0 : _a.get(cacheKey));
|
|
1010
|
-
if (typeof cfAccessResultStr === "string") {
|
|
1011
|
-
const result = JSON.parse(cfAccessResultStr);
|
|
1012
|
-
return {
|
|
1013
|
-
...result,
|
|
1014
|
-
token: jwt
|
|
1015
|
-
};
|
|
1016
|
-
}
|
|
1017
|
-
const claims = verifyResult.payload;
|
|
1018
|
-
try {
|
|
1019
|
-
let cfIdentity;
|
|
1020
|
-
if (serviceToken) {
|
|
1021
|
-
cfIdentity = {
|
|
1022
|
-
id: subject,
|
|
1023
|
-
name: "Bot",
|
|
1024
|
-
email: serviceToken.subject,
|
|
1025
|
-
groups: []
|
|
1026
|
-
};
|
|
1027
|
-
} else {
|
|
1028
|
-
cfIdentity = await this.getIdentityProfile(jwt);
|
|
1029
|
-
}
|
|
1030
|
-
const cfAccessResult = {
|
|
1031
|
-
claims,
|
|
1032
|
-
cfIdentity,
|
|
1033
|
-
expiresInSeconds: claims.exp - claims.iat
|
|
1034
|
-
};
|
|
1035
|
-
(_b = this.cache) == null ? void 0 : _b.set(cacheKey, JSON.stringify(cfAccessResult));
|
|
1036
|
-
return {
|
|
1037
|
-
...cfAccessResult,
|
|
1038
|
-
token: jwt
|
|
1039
|
-
};
|
|
1040
|
-
} catch (err) {
|
|
1041
|
-
throw new errors.ForwardedError(
|
|
1042
|
-
"Failed to populate access identity information",
|
|
1043
|
-
err
|
|
1044
|
-
);
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
async handleResult(result) {
|
|
1048
|
-
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
1049
|
-
const backstageIdentity = await this.signInResolver(
|
|
1050
|
-
{
|
|
1051
|
-
result,
|
|
1052
|
-
profile
|
|
1053
|
-
},
|
|
1054
|
-
this.resolverContext
|
|
1055
|
-
);
|
|
1056
|
-
return {
|
|
1057
|
-
providerInfo: {
|
|
1058
|
-
expiresInSeconds: result.expiresInSeconds,
|
|
1059
|
-
claims: result.claims,
|
|
1060
|
-
cfAccessIdentityProfile: result.cfIdentity
|
|
1061
|
-
},
|
|
1062
|
-
backstageIdentity: prepareBackstageIdentityResponse(backstageIdentity),
|
|
1063
|
-
profile
|
|
1064
|
-
};
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
760
|
const cfAccess = createAuthProviderIntegration({
|
|
1068
761
|
create(options) {
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
if (!options.signIn.resolver) {
|
|
1079
|
-
throw new Error(
|
|
1080
|
-
"SignInResolver is required to use this authentication provider"
|
|
1081
|
-
);
|
|
1082
|
-
}
|
|
1083
|
-
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ claims, cfIdentity }) => {
|
|
1084
|
-
return {
|
|
1085
|
-
profile: {
|
|
1086
|
-
email: claims.email,
|
|
1087
|
-
displayName: cfIdentity.name
|
|
1088
|
-
}
|
|
1089
|
-
};
|
|
1090
|
-
};
|
|
1091
|
-
return new CloudflareAccessAuthProvider({
|
|
1092
|
-
teamName,
|
|
1093
|
-
serviceTokens,
|
|
1094
|
-
signInResolver: options == null ? void 0 : options.signIn.resolver,
|
|
1095
|
-
authHandler,
|
|
1096
|
-
resolverContext,
|
|
1097
|
-
...options.cache && { cache: options.cache }
|
|
1098
|
-
});
|
|
1099
|
-
};
|
|
762
|
+
var _a;
|
|
763
|
+
return pluginAuthNode.createProxyAuthProviderFactory({
|
|
764
|
+
authenticator: pluginAuthBackendModuleCloudflareAccessProvider.createCloudflareAccessAuthenticator({
|
|
765
|
+
cache: options.cache
|
|
766
|
+
}),
|
|
767
|
+
profileTransform: options == null ? void 0 : options.authHandler,
|
|
768
|
+
signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver,
|
|
769
|
+
signInResolverFactories: pluginAuthBackendModuleCloudflareAccessProvider.cloudflareAccessSignInResolvers
|
|
770
|
+
});
|
|
1100
771
|
},
|
|
1101
|
-
resolvers:
|
|
1102
|
-
/**
|
|
1103
|
-
* Looks up the user by matching their email to the entity email.
|
|
1104
|
-
*/
|
|
1105
|
-
emailMatchingUserEntityProfileEmail: () => commonByEmailResolver
|
|
1106
|
-
}
|
|
772
|
+
resolvers: pluginAuthBackendModuleCloudflareAccessProvider.cloudflareAccessSignInResolvers
|
|
1107
773
|
});
|
|
1108
774
|
|
|
1109
775
|
const gcpIap = createAuthProviderIntegration({
|
|
@@ -1236,6 +902,28 @@ const oauth2Proxy = createAuthProviderIntegration({
|
|
|
1236
902
|
}
|
|
1237
903
|
});
|
|
1238
904
|
|
|
905
|
+
const commonByEmailLocalPartResolver = async (info, ctx) => {
|
|
906
|
+
const { profile } = info;
|
|
907
|
+
if (!profile.email) {
|
|
908
|
+
throw new Error("Login failed, user profile does not contain an email");
|
|
909
|
+
}
|
|
910
|
+
const [localPart] = profile.email.split("@");
|
|
911
|
+
return ctx.signInWithCatalogUser({
|
|
912
|
+
entityRef: { name: localPart }
|
|
913
|
+
});
|
|
914
|
+
};
|
|
915
|
+
const commonByEmailResolver = async (info, ctx) => {
|
|
916
|
+
const { profile } = info;
|
|
917
|
+
if (!profile.email) {
|
|
918
|
+
throw new Error("Login failed, user profile does not contain an email");
|
|
919
|
+
}
|
|
920
|
+
return ctx.signInWithCatalogUser({
|
|
921
|
+
filter: {
|
|
922
|
+
"spec.profile.email": profile.email
|
|
923
|
+
}
|
|
924
|
+
});
|
|
925
|
+
};
|
|
926
|
+
|
|
1239
927
|
const oidc = createAuthProviderIntegration({
|
|
1240
928
|
create(options) {
|
|
1241
929
|
var _a;
|
|
@@ -1302,18 +990,18 @@ const okta = createAuthProviderIntegration({
|
|
|
1302
990
|
}
|
|
1303
991
|
});
|
|
1304
992
|
|
|
1305
|
-
var __defProp$
|
|
1306
|
-
var __defNormalProp$
|
|
1307
|
-
var __publicField$
|
|
1308
|
-
__defNormalProp$
|
|
993
|
+
var __defProp$7 = Object.defineProperty;
|
|
994
|
+
var __defNormalProp$7 = (obj, key, value) => key in obj ? __defProp$7(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
995
|
+
var __publicField$7 = (obj, key, value) => {
|
|
996
|
+
__defNormalProp$7(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1309
997
|
return value;
|
|
1310
998
|
};
|
|
1311
999
|
class OneLoginProvider {
|
|
1312
1000
|
constructor(options) {
|
|
1313
|
-
__publicField$
|
|
1314
|
-
__publicField$
|
|
1315
|
-
__publicField$
|
|
1316
|
-
__publicField$
|
|
1001
|
+
__publicField$7(this, "_strategy");
|
|
1002
|
+
__publicField$7(this, "signInResolver");
|
|
1003
|
+
__publicField$7(this, "authHandler");
|
|
1004
|
+
__publicField$7(this, "resolverContext");
|
|
1317
1005
|
this.signInResolver = options.signInResolver;
|
|
1318
1006
|
this.authHandler = options.authHandler;
|
|
1319
1007
|
this.resolverContext = options.resolverContext;
|
|
@@ -1427,19 +1115,19 @@ const onelogin = createAuthProviderIntegration({
|
|
|
1427
1115
|
}
|
|
1428
1116
|
});
|
|
1429
1117
|
|
|
1430
|
-
var __defProp$
|
|
1431
|
-
var __defNormalProp$
|
|
1432
|
-
var __publicField$
|
|
1433
|
-
__defNormalProp$
|
|
1118
|
+
var __defProp$6 = Object.defineProperty;
|
|
1119
|
+
var __defNormalProp$6 = (obj, key, value) => key in obj ? __defProp$6(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1120
|
+
var __publicField$6 = (obj, key, value) => {
|
|
1121
|
+
__defNormalProp$6(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1434
1122
|
return value;
|
|
1435
1123
|
};
|
|
1436
1124
|
class SamlAuthProvider {
|
|
1437
1125
|
constructor(options) {
|
|
1438
|
-
__publicField$
|
|
1439
|
-
__publicField$
|
|
1440
|
-
__publicField$
|
|
1441
|
-
__publicField$
|
|
1442
|
-
__publicField$
|
|
1126
|
+
__publicField$6(this, "strategy");
|
|
1127
|
+
__publicField$6(this, "signInResolver");
|
|
1128
|
+
__publicField$6(this, "authHandler");
|
|
1129
|
+
__publicField$6(this, "resolverContext");
|
|
1130
|
+
__publicField$6(this, "appUrl");
|
|
1443
1131
|
this.appUrl = options.appUrl;
|
|
1444
1132
|
this.signInResolver = options.signInResolver;
|
|
1445
1133
|
this.authHandler = options.authHandler;
|
|
@@ -1543,19 +1231,19 @@ const saml = createAuthProviderIntegration({
|
|
|
1543
1231
|
}
|
|
1544
1232
|
});
|
|
1545
1233
|
|
|
1546
|
-
var __defProp$
|
|
1547
|
-
var __defNormalProp$
|
|
1548
|
-
var __publicField$
|
|
1549
|
-
__defNormalProp$
|
|
1234
|
+
var __defProp$5 = Object.defineProperty;
|
|
1235
|
+
var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1236
|
+
var __publicField$5 = (obj, key, value) => {
|
|
1237
|
+
__defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1550
1238
|
return value;
|
|
1551
1239
|
};
|
|
1552
1240
|
class BitbucketServerAuthProvider {
|
|
1553
1241
|
constructor(options) {
|
|
1554
|
-
__publicField$
|
|
1555
|
-
__publicField$
|
|
1556
|
-
__publicField$
|
|
1557
|
-
__publicField$
|
|
1558
|
-
__publicField$
|
|
1242
|
+
__publicField$5(this, "signInResolver");
|
|
1243
|
+
__publicField$5(this, "authHandler");
|
|
1244
|
+
__publicField$5(this, "resolverContext");
|
|
1245
|
+
__publicField$5(this, "strategy");
|
|
1246
|
+
__publicField$5(this, "host");
|
|
1559
1247
|
this.signInResolver = options.signInResolver;
|
|
1560
1248
|
this.authHandler = options.authHandler;
|
|
1561
1249
|
this.resolverContext = options.resolverContext;
|
|
@@ -1720,112 +1408,16 @@ const bitbucketServer = createAuthProviderIntegration({
|
|
|
1720
1408
|
}
|
|
1721
1409
|
});
|
|
1722
1410
|
|
|
1723
|
-
var __defProp$5 = Object.defineProperty;
|
|
1724
|
-
var __defNormalProp$5 = (obj, key, value) => key in obj ? __defProp$5(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1725
|
-
var __publicField$5 = (obj, key, value) => {
|
|
1726
|
-
__defNormalProp$5(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1727
|
-
return value;
|
|
1728
|
-
};
|
|
1729
|
-
const ID_TOKEN_HEADER = "x-ms-token-aad-id-token";
|
|
1730
|
-
const ACCESS_TOKEN_HEADER = "x-ms-token-aad-access-token";
|
|
1731
|
-
class EasyAuthAuthProvider {
|
|
1732
|
-
constructor(options) {
|
|
1733
|
-
__publicField$5(this, "resolverContext");
|
|
1734
|
-
__publicField$5(this, "authHandler");
|
|
1735
|
-
__publicField$5(this, "signInResolver");
|
|
1736
|
-
this.authHandler = options.authHandler;
|
|
1737
|
-
this.signInResolver = options.signInResolver;
|
|
1738
|
-
this.resolverContext = options.resolverContext;
|
|
1739
|
-
}
|
|
1740
|
-
frameHandler() {
|
|
1741
|
-
return Promise.resolve(void 0);
|
|
1742
|
-
}
|
|
1743
|
-
async refresh(req, res) {
|
|
1744
|
-
const result = await this.getResult(req);
|
|
1745
|
-
const response = await this.handleResult(result);
|
|
1746
|
-
res.json(response);
|
|
1747
|
-
}
|
|
1748
|
-
start() {
|
|
1749
|
-
return Promise.resolve(void 0);
|
|
1750
|
-
}
|
|
1751
|
-
async getResult(req) {
|
|
1752
|
-
const idToken = req.header(ID_TOKEN_HEADER);
|
|
1753
|
-
const accessToken = req.header(ACCESS_TOKEN_HEADER);
|
|
1754
|
-
if (idToken === void 0) {
|
|
1755
|
-
throw new errors.AuthenticationError(`Missing ${ID_TOKEN_HEADER} header`);
|
|
1756
|
-
}
|
|
1757
|
-
return {
|
|
1758
|
-
fullProfile: this.idTokenToProfile(idToken),
|
|
1759
|
-
accessToken
|
|
1760
|
-
};
|
|
1761
|
-
}
|
|
1762
|
-
idTokenToProfile(idToken) {
|
|
1763
|
-
const claims = jose.decodeJwt(idToken);
|
|
1764
|
-
if (claims.ver !== "2.0") {
|
|
1765
|
-
throw new Error("id_token is not version 2.0 ");
|
|
1766
|
-
}
|
|
1767
|
-
return {
|
|
1768
|
-
id: claims.oid,
|
|
1769
|
-
displayName: claims.name,
|
|
1770
|
-
provider: "easyauth",
|
|
1771
|
-
emails: [{ value: claims.email }],
|
|
1772
|
-
username: claims.preferred_username
|
|
1773
|
-
};
|
|
1774
|
-
}
|
|
1775
|
-
async handleResult(result) {
|
|
1776
|
-
const { profile } = await this.authHandler(result, this.resolverContext);
|
|
1777
|
-
const backstageIdentity = await this.signInResolver(
|
|
1778
|
-
{
|
|
1779
|
-
result,
|
|
1780
|
-
profile
|
|
1781
|
-
},
|
|
1782
|
-
this.resolverContext
|
|
1783
|
-
);
|
|
1784
|
-
return {
|
|
1785
|
-
providerInfo: {
|
|
1786
|
-
accessToken: result.accessToken
|
|
1787
|
-
},
|
|
1788
|
-
backstageIdentity: prepareBackstageIdentityResponse(backstageIdentity),
|
|
1789
|
-
profile
|
|
1790
|
-
};
|
|
1791
|
-
}
|
|
1792
|
-
}
|
|
1793
1411
|
const easyAuth = createAuthProviderIntegration({
|
|
1794
1412
|
create(options) {
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
);
|
|
1802
|
-
}
|
|
1803
|
-
const authHandler = (_a = options.authHandler) != null ? _a : async ({ fullProfile }) => ({
|
|
1804
|
-
profile: makeProfileInfo(fullProfile)
|
|
1805
|
-
});
|
|
1806
|
-
return new EasyAuthAuthProvider({
|
|
1807
|
-
signInResolver: options.signIn.resolver,
|
|
1808
|
-
authHandler,
|
|
1809
|
-
resolverContext
|
|
1810
|
-
});
|
|
1811
|
-
};
|
|
1413
|
+
var _a;
|
|
1414
|
+
return pluginAuthNode.createProxyAuthProviderFactory({
|
|
1415
|
+
authenticator: pluginAuthBackendModuleAzureEasyauthProvider.azureEasyAuthAuthenticator,
|
|
1416
|
+
profileTransform: options == null ? void 0 : options.authHandler,
|
|
1417
|
+
signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver
|
|
1418
|
+
});
|
|
1812
1419
|
}
|
|
1813
1420
|
});
|
|
1814
|
-
function validateAppServiceConfiguration(env) {
|
|
1815
|
-
var _a, _b, _c;
|
|
1816
|
-
if (env.WEBSITE_SKU === void 0) {
|
|
1817
|
-
throw new Error("Backstage is not running on Azure App Services");
|
|
1818
|
-
}
|
|
1819
|
-
if (((_a = env.WEBSITE_AUTH_ENABLED) == null ? void 0 : _a.toLowerCase()) !== "true") {
|
|
1820
|
-
throw new Error("Azure App Services does not have authentication enabled");
|
|
1821
|
-
}
|
|
1822
|
-
if (((_b = env.WEBSITE_AUTH_DEFAULT_PROVIDER) == null ? void 0 : _b.toLowerCase()) !== "azureactivedirectory") {
|
|
1823
|
-
throw new Error("Authentication provider is not Entra ID");
|
|
1824
|
-
}
|
|
1825
|
-
if (((_c = process.env.WEBSITE_AUTH_TOKEN_STORE) == null ? void 0 : _c.toLowerCase()) !== "true") {
|
|
1826
|
-
throw new Error("Token Store is not enabled");
|
|
1827
|
-
}
|
|
1828
|
-
}
|
|
1829
1421
|
|
|
1830
1422
|
const providers = Object.freeze({
|
|
1831
1423
|
atlassian,
|
|
@@ -2156,7 +1748,7 @@ function createOriginFilter(config) {
|
|
|
2156
1748
|
}
|
|
2157
1749
|
|
|
2158
1750
|
function bindOidcRouter(targetRouter, options) {
|
|
2159
|
-
const { baseUrl, tokenIssuer } = options;
|
|
1751
|
+
const { baseUrl, auth, tokenIssuer } = options;
|
|
2160
1752
|
const router = Router__default.default();
|
|
2161
1753
|
targetRouter.use(router);
|
|
2162
1754
|
const config = {
|
|
@@ -2180,7 +1772,7 @@ function bindOidcRouter(targetRouter, options) {
|
|
|
2180
1772
|
],
|
|
2181
1773
|
scopes_supported: ["openid"],
|
|
2182
1774
|
token_endpoint_auth_methods_supported: [],
|
|
2183
|
-
claims_supported: ["sub"],
|
|
1775
|
+
claims_supported: ["sub", "ent"],
|
|
2184
1776
|
grant_types_supported: []
|
|
2185
1777
|
};
|
|
2186
1778
|
router.get("/.well-known/openid-configuration", (_req, res) => {
|
|
@@ -2193,8 +1785,31 @@ function bindOidcRouter(targetRouter, options) {
|
|
|
2193
1785
|
router.get("/v1/token", (_req, res) => {
|
|
2194
1786
|
res.status(501).send("Not Implemented");
|
|
2195
1787
|
});
|
|
2196
|
-
router.get("/v1/userinfo", (
|
|
2197
|
-
|
|
1788
|
+
router.get("/v1/userinfo", async (req, res) => {
|
|
1789
|
+
var _a;
|
|
1790
|
+
const matches = (_a = req.headers.authorization) == null ? void 0 : _a.match(/^Bearer[ ]+(\S+)$/i);
|
|
1791
|
+
const token = matches == null ? void 0 : matches[1];
|
|
1792
|
+
if (!token) {
|
|
1793
|
+
throw new errors.AuthenticationError("No token provided");
|
|
1794
|
+
}
|
|
1795
|
+
const credentials = await auth.authenticate(token, {
|
|
1796
|
+
allowLimitedAccess: true
|
|
1797
|
+
});
|
|
1798
|
+
if (!auth.isPrincipal(credentials, "user")) {
|
|
1799
|
+
throw new errors.InputError(
|
|
1800
|
+
"Userinfo endpoint must be called with a token that represents a user principal"
|
|
1801
|
+
);
|
|
1802
|
+
}
|
|
1803
|
+
const { sub: userEntityRef, ent: ownershipEntityRefs = [] } = jose.decodeJwt(token);
|
|
1804
|
+
if (typeof userEntityRef !== "string") {
|
|
1805
|
+
throw new Error("Invalid user token, user entity ref must be a string");
|
|
1806
|
+
}
|
|
1807
|
+
if (!Array.isArray(ownershipEntityRefs) || ownershipEntityRefs.some((ref) => typeof ref !== "string")) {
|
|
1808
|
+
throw new Error(
|
|
1809
|
+
"Invalid user token, ownership entity refs must be an array of strings"
|
|
1810
|
+
);
|
|
1811
|
+
}
|
|
1812
|
+
res.json({ sub: userEntityRef, ent: ownershipEntityRefs });
|
|
2198
1813
|
});
|
|
2199
1814
|
}
|
|
2200
1815
|
|
|
@@ -2225,8 +1840,8 @@ class TokenFactory {
|
|
|
2225
1840
|
async issueToken(params) {
|
|
2226
1841
|
const key = await this.getKey();
|
|
2227
1842
|
const iss = this.issuer;
|
|
2228
|
-
const { sub, ent, ...additionalClaims } = params.claims;
|
|
2229
|
-
const aud =
|
|
1843
|
+
const { sub, ent = [sub], ...additionalClaims } = params.claims;
|
|
1844
|
+
const aud = pluginAuthNode.tokenTypes.user.audClaim;
|
|
2230
1845
|
const iat = Math.floor(Date.now() / MS_IN_S$1);
|
|
2231
1846
|
const exp = iat + this.keyDurationSeconds;
|
|
2232
1847
|
try {
|
|
@@ -2236,12 +1851,35 @@ class TokenFactory {
|
|
|
2236
1851
|
'"sub" claim provided by the auth resolver is not a valid EntityRef.'
|
|
2237
1852
|
);
|
|
2238
1853
|
}
|
|
2239
|
-
this.logger.info(`Issuing token for ${sub}, with entities ${ent != null ? ent : []}`);
|
|
2240
1854
|
if (!key.alg) {
|
|
2241
1855
|
throw new errors.AuthenticationError("No algorithm was provided in the key");
|
|
2242
1856
|
}
|
|
2243
|
-
|
|
2244
|
-
const
|
|
1857
|
+
this.logger.info(`Issuing token for ${sub}, with entities ${ent}`);
|
|
1858
|
+
const signingKey = await jose.importJWK(key);
|
|
1859
|
+
const uip = await this.createUserIdentityClaim({
|
|
1860
|
+
header: {
|
|
1861
|
+
typ: pluginAuthNode.tokenTypes.limitedUser.typParam,
|
|
1862
|
+
alg: key.alg,
|
|
1863
|
+
kid: key.kid
|
|
1864
|
+
},
|
|
1865
|
+
payload: { sub, ent, iat, exp },
|
|
1866
|
+
key: signingKey
|
|
1867
|
+
});
|
|
1868
|
+
const claims = {
|
|
1869
|
+
...additionalClaims,
|
|
1870
|
+
iss,
|
|
1871
|
+
sub,
|
|
1872
|
+
ent,
|
|
1873
|
+
aud,
|
|
1874
|
+
iat,
|
|
1875
|
+
exp,
|
|
1876
|
+
uip
|
|
1877
|
+
};
|
|
1878
|
+
const token = await new jose.SignJWT(claims).setProtectedHeader({
|
|
1879
|
+
typ: pluginAuthNode.tokenTypes.user.typParam,
|
|
1880
|
+
alg: key.alg,
|
|
1881
|
+
kid: key.kid
|
|
1882
|
+
}).sign(signingKey);
|
|
2245
1883
|
if (token.length > MAX_TOKEN_LENGTH) {
|
|
2246
1884
|
throw new Error(
|
|
2247
1885
|
`Failed to issue a new user token. The resulting token is excessively large, with either too many ownership claims or too large custom claims. You likely have a bug either in the sign-in resolver or catalog data. The following claims were requested: '${JSON.stringify(
|
|
@@ -2308,6 +1946,26 @@ class TokenFactory {
|
|
|
2308
1946
|
}
|
|
2309
1947
|
return promise;
|
|
2310
1948
|
}
|
|
1949
|
+
// Creates a string claim that can be used as part of reconstructing a limited
|
|
1950
|
+
// user token. The output of this function is only the signature part of a
|
|
1951
|
+
// JWS.
|
|
1952
|
+
async createUserIdentityClaim(options) {
|
|
1953
|
+
const header = {
|
|
1954
|
+
typ: options.header.typ,
|
|
1955
|
+
alg: options.header.alg,
|
|
1956
|
+
...options.header.kid ? { kid: options.header.kid } : {}
|
|
1957
|
+
};
|
|
1958
|
+
const payload = {
|
|
1959
|
+
sub: options.payload.sub,
|
|
1960
|
+
ent: options.payload.ent,
|
|
1961
|
+
iat: options.payload.iat,
|
|
1962
|
+
exp: options.payload.exp
|
|
1963
|
+
};
|
|
1964
|
+
const jws = await new jose.GeneralSign(
|
|
1965
|
+
new TextEncoder().encode(JSON.stringify(payload))
|
|
1966
|
+
).addSignature(options.key).setProtectedHeader(header).done().sign();
|
|
1967
|
+
return jws.signatures[0].signature;
|
|
1968
|
+
}
|
|
2311
1969
|
}
|
|
2312
1970
|
|
|
2313
1971
|
const TABLE = "signing_keys";
|
|
@@ -2807,6 +2465,7 @@ async function createRouter(options) {
|
|
|
2807
2465
|
httpAuth
|
|
2808
2466
|
});
|
|
2809
2467
|
bindOidcRouter(router, {
|
|
2468
|
+
auth,
|
|
2810
2469
|
tokenIssuer,
|
|
2811
2470
|
baseUrl: authUrl
|
|
2812
2471
|
});
|
|
@@ -2839,6 +2498,8 @@ const authPlugin = backendPluginApi.createBackendPlugin({
|
|
|
2839
2498
|
database: backendPluginApi.coreServices.database,
|
|
2840
2499
|
discovery: backendPluginApi.coreServices.discovery,
|
|
2841
2500
|
tokenManager: backendPluginApi.coreServices.tokenManager,
|
|
2501
|
+
auth: backendPluginApi.coreServices.auth,
|
|
2502
|
+
httpAuth: backendPluginApi.coreServices.httpAuth,
|
|
2842
2503
|
catalogApi: alpha.catalogServiceRef
|
|
2843
2504
|
},
|
|
2844
2505
|
async init({
|
|
@@ -2848,6 +2509,8 @@ const authPlugin = backendPluginApi.createBackendPlugin({
|
|
|
2848
2509
|
database,
|
|
2849
2510
|
discovery,
|
|
2850
2511
|
tokenManager,
|
|
2512
|
+
auth,
|
|
2513
|
+
httpAuth,
|
|
2851
2514
|
catalogApi
|
|
2852
2515
|
}) {
|
|
2853
2516
|
const router = await createRouter({
|
|
@@ -2856,6 +2519,8 @@ const authPlugin = backendPluginApi.createBackendPlugin({
|
|
|
2856
2519
|
database,
|
|
2857
2520
|
discovery,
|
|
2858
2521
|
tokenManager,
|
|
2522
|
+
auth,
|
|
2523
|
+
httpAuth,
|
|
2859
2524
|
catalogApi,
|
|
2860
2525
|
providerFactories: Object.fromEntries(providers),
|
|
2861
2526
|
disableDefaultProviderFactories: true
|