@backstage/plugin-auth-backend 0.7.0 → 0.9.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 +90 -0
- package/dist/index.cjs.js +178 -99
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +42 -37
- package/package.json +6 -6
package/dist/index.cjs.js
CHANGED
|
@@ -149,6 +149,16 @@ const verifyNonce = (req, providerId) => {
|
|
|
149
149
|
throw new Error("Invalid nonce");
|
|
150
150
|
}
|
|
151
151
|
};
|
|
152
|
+
const getCookieConfig = (authUrl, providerId) => {
|
|
153
|
+
const { hostname: cookieDomain, pathname, protocol } = authUrl;
|
|
154
|
+
const secure = protocol === "https:";
|
|
155
|
+
const cookiePath = pathname.endsWith(`${providerId}/handler/frame`) ? pathname.slice(0, -"/handler/frame".length) : `${pathname}/${providerId}`;
|
|
156
|
+
return {
|
|
157
|
+
cookieDomain,
|
|
158
|
+
cookiePath,
|
|
159
|
+
secure
|
|
160
|
+
};
|
|
161
|
+
};
|
|
152
162
|
|
|
153
163
|
class OAuthEnvironmentHandler {
|
|
154
164
|
constructor(handlers) {
|
|
@@ -271,56 +281,48 @@ class OAuthAdapter {
|
|
|
271
281
|
this.setNonceCookie = (res, nonce) => {
|
|
272
282
|
res.cookie(`${this.options.providerId}-nonce`, nonce, {
|
|
273
283
|
maxAge: TEN_MINUTES_MS,
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
domain: this.options.cookieDomain,
|
|
277
|
-
path: `${this.options.cookiePath}/handler`,
|
|
278
|
-
httpOnly: true
|
|
284
|
+
...this.baseCookieOptions,
|
|
285
|
+
path: `${this.options.cookiePath}/handler`
|
|
279
286
|
});
|
|
280
287
|
};
|
|
281
|
-
this.
|
|
282
|
-
res.cookie(`${this.options.providerId}-scope`, scope, {
|
|
283
|
-
maxAge:
|
|
284
|
-
|
|
285
|
-
sameSite: "lax",
|
|
286
|
-
domain: this.options.cookieDomain,
|
|
287
|
-
path: `${this.options.cookiePath}/handler`,
|
|
288
|
-
httpOnly: true
|
|
288
|
+
this.setGrantedScopeCookie = (res, scope) => {
|
|
289
|
+
res.cookie(`${this.options.providerId}-granted-scope`, scope, {
|
|
290
|
+
maxAge: THOUSAND_DAYS_MS,
|
|
291
|
+
...this.baseCookieOptions
|
|
289
292
|
});
|
|
290
293
|
};
|
|
291
|
-
this.
|
|
292
|
-
return req.cookies[`${providerId}-scope`];
|
|
294
|
+
this.getGrantedScopeFromCookie = (req) => {
|
|
295
|
+
return req.cookies[`${this.options.providerId}-granted-scope`];
|
|
293
296
|
};
|
|
294
297
|
this.setRefreshTokenCookie = (res, refreshToken) => {
|
|
295
298
|
res.cookie(`${this.options.providerId}-refresh-token`, refreshToken, {
|
|
296
299
|
maxAge: THOUSAND_DAYS_MS,
|
|
297
|
-
|
|
298
|
-
sameSite: "lax",
|
|
299
|
-
domain: this.options.cookieDomain,
|
|
300
|
-
path: this.options.cookiePath,
|
|
301
|
-
httpOnly: true
|
|
300
|
+
...this.baseCookieOptions
|
|
302
301
|
});
|
|
303
302
|
};
|
|
304
303
|
this.removeRefreshTokenCookie = (res) => {
|
|
305
304
|
res.cookie(`${this.options.providerId}-refresh-token`, "", {
|
|
306
305
|
maxAge: 0,
|
|
307
|
-
|
|
308
|
-
sameSite: "lax",
|
|
309
|
-
domain: this.options.cookieDomain,
|
|
310
|
-
path: this.options.cookiePath,
|
|
311
|
-
httpOnly: true
|
|
306
|
+
...this.baseCookieOptions
|
|
312
307
|
});
|
|
313
308
|
};
|
|
309
|
+
this.baseCookieOptions = {
|
|
310
|
+
httpOnly: true,
|
|
311
|
+
sameSite: "lax",
|
|
312
|
+
secure: this.options.secure,
|
|
313
|
+
path: this.options.cookiePath,
|
|
314
|
+
domain: this.options.cookieDomain
|
|
315
|
+
};
|
|
314
316
|
}
|
|
315
317
|
static fromConfig(config, handlers, options) {
|
|
318
|
+
var _a;
|
|
316
319
|
const { origin: appOrigin } = new url.URL(config.appUrl);
|
|
317
|
-
const
|
|
318
|
-
const
|
|
319
|
-
const cookiePath = `${url$1.pathname}/${options.providerId}`;
|
|
320
|
+
const authUrl = new url.URL((_a = options.callbackUrl) != null ? _a : config.baseUrl);
|
|
321
|
+
const { cookieDomain, cookiePath, secure } = getCookieConfig(authUrl, options.providerId);
|
|
320
322
|
return new OAuthAdapter(handlers, {
|
|
321
323
|
...options,
|
|
322
324
|
appOrigin,
|
|
323
|
-
cookieDomain
|
|
325
|
+
cookieDomain,
|
|
324
326
|
cookiePath,
|
|
325
327
|
secure,
|
|
326
328
|
isOriginAllowed: config.isOriginAllowed
|
|
@@ -334,12 +336,12 @@ class OAuthAdapter {
|
|
|
334
336
|
if (!env) {
|
|
335
337
|
throw new errors.InputError("No env provided in request query parameters");
|
|
336
338
|
}
|
|
337
|
-
if (this.options.persistScopes) {
|
|
338
|
-
this.setScopesCookie(res, scope);
|
|
339
|
-
}
|
|
340
339
|
const nonce = crypto__default["default"].randomBytes(16).toString("base64");
|
|
341
340
|
this.setNonceCookie(res, nonce);
|
|
342
341
|
const state = { nonce, env, origin };
|
|
342
|
+
if (this.options.persistScopes) {
|
|
343
|
+
state.scope = scope;
|
|
344
|
+
}
|
|
343
345
|
const forwardReq = Object.assign(req, { scope, state });
|
|
344
346
|
const { url, status } = await this.handlers.start(forwardReq);
|
|
345
347
|
res.statusCode = status || 302;
|
|
@@ -364,9 +366,9 @@ class OAuthAdapter {
|
|
|
364
366
|
}
|
|
365
367
|
verifyNonce(req, this.options.providerId);
|
|
366
368
|
const { response, refreshToken } = await this.handlers.handler(req);
|
|
367
|
-
if (this.options.persistScopes) {
|
|
368
|
-
|
|
369
|
-
response.providerInfo.scope =
|
|
369
|
+
if (this.options.persistScopes && state.scope) {
|
|
370
|
+
this.setGrantedScopeCookie(res, state.scope);
|
|
371
|
+
response.providerInfo.scope = state.scope;
|
|
370
372
|
}
|
|
371
373
|
if (refreshToken && !this.options.disableRefresh) {
|
|
372
374
|
this.setRefreshTokenCookie(res, refreshToken);
|
|
@@ -404,7 +406,10 @@ class OAuthAdapter {
|
|
|
404
406
|
if (!refreshToken) {
|
|
405
407
|
throw new errors.InputError("Missing session cookie");
|
|
406
408
|
}
|
|
407
|
-
|
|
409
|
+
let scope = (_b = (_a = req.query.scope) == null ? void 0 : _a.toString()) != null ? _b : "";
|
|
410
|
+
if (this.options.persistScopes) {
|
|
411
|
+
scope = this.getGrantedScopeFromCookie(req);
|
|
412
|
+
}
|
|
408
413
|
const forwardReq = Object.assign(req, { scope, refreshToken });
|
|
409
414
|
const { response, refreshToken: newRefreshToken } = await this.handlers.refresh(forwardReq);
|
|
410
415
|
const backstageIdentity = await this.populateIdentity(response.backstageIdentity);
|
|
@@ -550,7 +555,7 @@ const executeFetchUserProfileStrategy = async (providerStrategy, accessToken) =>
|
|
|
550
555
|
class CatalogIdentityClient {
|
|
551
556
|
constructor(options) {
|
|
552
557
|
this.catalogApi = options.catalogApi;
|
|
553
|
-
this.
|
|
558
|
+
this.tokenManager = options.tokenManager;
|
|
554
559
|
}
|
|
555
560
|
async findUser(query) {
|
|
556
561
|
const filter = {
|
|
@@ -559,9 +564,7 @@ class CatalogIdentityClient {
|
|
|
559
564
|
for (const [key, value] of Object.entries(query.annotations)) {
|
|
560
565
|
filter[`metadata.annotations.${key}`] = value;
|
|
561
566
|
}
|
|
562
|
-
const token = await this.
|
|
563
|
-
claims: { sub: "backstage.io/auth-backend" }
|
|
564
|
-
});
|
|
567
|
+
const { token } = await this.tokenManager.getToken();
|
|
565
568
|
const { items } = await this.catalogApi.getEntities({ filter }, { token });
|
|
566
569
|
if (items.length !== 1) {
|
|
567
570
|
if (items.length > 1) {
|
|
@@ -591,7 +594,8 @@ class CatalogIdentityClient {
|
|
|
591
594
|
"metadata.namespace": ref.namespace,
|
|
592
595
|
"metadata.name": ref.name
|
|
593
596
|
}));
|
|
594
|
-
const
|
|
597
|
+
const { token } = await this.tokenManager.getToken();
|
|
598
|
+
const entities = await this.catalogApi.getEntities({ filter }, { token }).then((r) => r.items);
|
|
595
599
|
if (entityRefs.length !== entities.length) {
|
|
596
600
|
const foundEntityNames = entities.map(catalogModel.stringifyEntityRef);
|
|
597
601
|
const missingEntityNames = resolvedEntityRefs.map(catalogModel.stringifyEntityRef).filter((s) => !foundEntityNames.includes(s));
|
|
@@ -701,6 +705,7 @@ const createAtlassianProvider = (options) => {
|
|
|
701
705
|
globalConfig,
|
|
702
706
|
config,
|
|
703
707
|
tokenIssuer,
|
|
708
|
+
tokenManager,
|
|
704
709
|
catalogApi,
|
|
705
710
|
logger
|
|
706
711
|
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
@@ -708,10 +713,11 @@ const createAtlassianProvider = (options) => {
|
|
|
708
713
|
const clientId = envConfig.getString("clientId");
|
|
709
714
|
const clientSecret = envConfig.getString("clientSecret");
|
|
710
715
|
const scopes = envConfig.getString("scopes");
|
|
711
|
-
const
|
|
716
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
717
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
712
718
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
713
719
|
catalogApi,
|
|
714
|
-
|
|
720
|
+
tokenManager
|
|
715
721
|
});
|
|
716
722
|
const authHandler = (_a = options == null ? void 0 : options.authHandler) != null ? _a : atlassianDefaultAuthHandler;
|
|
717
723
|
const provider = new AtlassianAuthProvider({
|
|
@@ -728,7 +734,8 @@ const createAtlassianProvider = (options) => {
|
|
|
728
734
|
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
729
735
|
disableRefresh: true,
|
|
730
736
|
providerId,
|
|
731
|
-
tokenIssuer
|
|
737
|
+
tokenIssuer,
|
|
738
|
+
callbackUrl
|
|
732
739
|
});
|
|
733
740
|
});
|
|
734
741
|
};
|
|
@@ -836,6 +843,7 @@ const createAuth0Provider = (options) => {
|
|
|
836
843
|
globalConfig,
|
|
837
844
|
config,
|
|
838
845
|
tokenIssuer,
|
|
846
|
+
tokenManager,
|
|
839
847
|
catalogApi,
|
|
840
848
|
logger
|
|
841
849
|
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
@@ -843,10 +851,11 @@ const createAuth0Provider = (options) => {
|
|
|
843
851
|
const clientId = envConfig.getString("clientId");
|
|
844
852
|
const clientSecret = envConfig.getString("clientSecret");
|
|
845
853
|
const domain = envConfig.getString("domain");
|
|
846
|
-
const
|
|
854
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
855
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
847
856
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
848
857
|
catalogApi,
|
|
849
|
-
|
|
858
|
+
tokenManager
|
|
850
859
|
});
|
|
851
860
|
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
852
861
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
@@ -866,7 +875,8 @@ const createAuth0Provider = (options) => {
|
|
|
866
875
|
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
867
876
|
disableRefresh: true,
|
|
868
877
|
providerId,
|
|
869
|
-
tokenIssuer
|
|
878
|
+
tokenIssuer,
|
|
879
|
+
callbackUrl
|
|
870
880
|
});
|
|
871
881
|
});
|
|
872
882
|
};
|
|
@@ -974,7 +984,7 @@ class AwsAlbAuthProvider {
|
|
|
974
984
|
}
|
|
975
985
|
}
|
|
976
986
|
const createAwsAlbProvider = (options) => {
|
|
977
|
-
return ({ config, tokenIssuer, catalogApi, logger }) => {
|
|
987
|
+
return ({ config, tokenIssuer, catalogApi, logger, tokenManager }) => {
|
|
978
988
|
const region = config.getString("region");
|
|
979
989
|
const issuer = config.getOptionalString("iss");
|
|
980
990
|
if ((options == null ? void 0 : options.signIn.resolver) === void 0) {
|
|
@@ -982,7 +992,7 @@ const createAwsAlbProvider = (options) => {
|
|
|
982
992
|
}
|
|
983
993
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
984
994
|
catalogApi,
|
|
985
|
-
|
|
995
|
+
tokenManager
|
|
986
996
|
});
|
|
987
997
|
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
988
998
|
profile: makeProfileInfo(fullProfile)
|
|
@@ -1110,16 +1120,18 @@ const createBitbucketProvider = (options) => {
|
|
|
1110
1120
|
globalConfig,
|
|
1111
1121
|
config,
|
|
1112
1122
|
tokenIssuer,
|
|
1123
|
+
tokenManager,
|
|
1113
1124
|
catalogApi,
|
|
1114
1125
|
logger
|
|
1115
1126
|
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1116
1127
|
var _a;
|
|
1117
1128
|
const clientId = envConfig.getString("clientId");
|
|
1118
1129
|
const clientSecret = envConfig.getString("clientSecret");
|
|
1119
|
-
const
|
|
1130
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
1131
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1120
1132
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1121
1133
|
catalogApi,
|
|
1122
|
-
|
|
1134
|
+
tokenManager
|
|
1123
1135
|
});
|
|
1124
1136
|
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1125
1137
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
@@ -1137,11 +1149,14 @@ const createBitbucketProvider = (options) => {
|
|
|
1137
1149
|
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1138
1150
|
disableRefresh: false,
|
|
1139
1151
|
providerId,
|
|
1140
|
-
tokenIssuer
|
|
1152
|
+
tokenIssuer,
|
|
1153
|
+
callbackUrl
|
|
1141
1154
|
});
|
|
1142
1155
|
});
|
|
1143
1156
|
};
|
|
1144
1157
|
|
|
1158
|
+
const ACCESS_TOKEN_PREFIX = "access-token.";
|
|
1159
|
+
const BACKSTAGE_SESSION_EXPIRATION = 3600;
|
|
1145
1160
|
class GithubAuthProvider {
|
|
1146
1161
|
constructor(options) {
|
|
1147
1162
|
this.signInResolver = options.signInResolver;
|
|
@@ -1169,21 +1184,43 @@ class GithubAuthProvider {
|
|
|
1169
1184
|
}
|
|
1170
1185
|
async handler(req) {
|
|
1171
1186
|
const { result, privateInfo } = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1187
|
+
let refreshToken = privateInfo.refreshToken;
|
|
1188
|
+
if (!refreshToken && !result.params.expires_in) {
|
|
1189
|
+
refreshToken = ACCESS_TOKEN_PREFIX + result.accessToken;
|
|
1190
|
+
}
|
|
1172
1191
|
return {
|
|
1173
1192
|
response: await this.handleResult(result),
|
|
1174
|
-
refreshToken
|
|
1193
|
+
refreshToken
|
|
1175
1194
|
};
|
|
1176
1195
|
}
|
|
1177
1196
|
async refresh(req) {
|
|
1178
|
-
const {
|
|
1179
|
-
|
|
1197
|
+
const { scope, refreshToken } = req;
|
|
1198
|
+
if (refreshToken == null ? void 0 : refreshToken.startsWith(ACCESS_TOKEN_PREFIX)) {
|
|
1199
|
+
const accessToken = refreshToken.slice(ACCESS_TOKEN_PREFIX.length);
|
|
1200
|
+
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken).catch((error) => {
|
|
1201
|
+
var _a;
|
|
1202
|
+
if (((_a = error.oauthError) == null ? void 0 : _a.statusCode) === 401) {
|
|
1203
|
+
throw new Error("Invalid access token");
|
|
1204
|
+
}
|
|
1205
|
+
throw error;
|
|
1206
|
+
});
|
|
1207
|
+
return {
|
|
1208
|
+
response: await this.handleResult({
|
|
1209
|
+
fullProfile,
|
|
1210
|
+
params: { scope },
|
|
1211
|
+
accessToken
|
|
1212
|
+
}),
|
|
1213
|
+
refreshToken
|
|
1214
|
+
};
|
|
1215
|
+
}
|
|
1216
|
+
const result = await executeRefreshTokenStrategy(this._strategy, refreshToken, scope);
|
|
1180
1217
|
return {
|
|
1181
1218
|
response: await this.handleResult({
|
|
1182
|
-
fullProfile,
|
|
1183
|
-
params,
|
|
1184
|
-
accessToken
|
|
1219
|
+
fullProfile: await executeFetchUserProfileStrategy(this._strategy, result.accessToken),
|
|
1220
|
+
params: { ...result.params, scope },
|
|
1221
|
+
accessToken: result.accessToken
|
|
1185
1222
|
}),
|
|
1186
|
-
refreshToken
|
|
1223
|
+
refreshToken: result.refreshToken
|
|
1187
1224
|
};
|
|
1188
1225
|
}
|
|
1189
1226
|
async handleResult(result) {
|
|
@@ -1194,21 +1231,28 @@ class GithubAuthProvider {
|
|
|
1194
1231
|
};
|
|
1195
1232
|
const { profile } = await this.authHandler(result, context);
|
|
1196
1233
|
const expiresInStr = result.params.expires_in;
|
|
1197
|
-
|
|
1234
|
+
let expiresInSeconds = expiresInStr === void 0 ? void 0 : Number(expiresInStr);
|
|
1235
|
+
let backstageIdentity = void 0;
|
|
1236
|
+
if (this.signInResolver) {
|
|
1237
|
+
backstageIdentity = await this.signInResolver({
|
|
1238
|
+
result,
|
|
1239
|
+
profile
|
|
1240
|
+
}, context);
|
|
1241
|
+
if (expiresInSeconds) {
|
|
1242
|
+
expiresInSeconds = Math.min(expiresInSeconds, BACKSTAGE_SESSION_EXPIRATION);
|
|
1243
|
+
} else {
|
|
1244
|
+
expiresInSeconds = BACKSTAGE_SESSION_EXPIRATION;
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
return {
|
|
1248
|
+
backstageIdentity,
|
|
1198
1249
|
providerInfo: {
|
|
1199
1250
|
accessToken: result.accessToken,
|
|
1200
1251
|
scope: result.params.scope,
|
|
1201
|
-
expiresInSeconds
|
|
1252
|
+
expiresInSeconds
|
|
1202
1253
|
},
|
|
1203
1254
|
profile
|
|
1204
1255
|
};
|
|
1205
|
-
if (this.signInResolver) {
|
|
1206
|
-
response.backstageIdentity = await this.signInResolver({
|
|
1207
|
-
result,
|
|
1208
|
-
profile
|
|
1209
|
-
}, context);
|
|
1210
|
-
}
|
|
1211
|
-
return response;
|
|
1212
1256
|
}
|
|
1213
1257
|
}
|
|
1214
1258
|
const githubDefaultSignInResolver = async (info, ctx) => {
|
|
@@ -1228,6 +1272,7 @@ const createGithubProvider = (options) => {
|
|
|
1228
1272
|
globalConfig,
|
|
1229
1273
|
config,
|
|
1230
1274
|
tokenIssuer,
|
|
1275
|
+
tokenManager,
|
|
1231
1276
|
catalogApi,
|
|
1232
1277
|
logger
|
|
1233
1278
|
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
@@ -1242,7 +1287,7 @@ const createGithubProvider = (options) => {
|
|
|
1242
1287
|
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1243
1288
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1244
1289
|
catalogApi,
|
|
1245
|
-
|
|
1290
|
+
tokenManager
|
|
1246
1291
|
});
|
|
1247
1292
|
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
1248
1293
|
profile: makeProfileInfo(fullProfile)
|
|
@@ -1273,7 +1318,8 @@ const createGithubProvider = (options) => {
|
|
|
1273
1318
|
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1274
1319
|
persistScopes: true,
|
|
1275
1320
|
providerId,
|
|
1276
|
-
tokenIssuer
|
|
1321
|
+
tokenIssuer,
|
|
1322
|
+
callbackUrl
|
|
1277
1323
|
});
|
|
1278
1324
|
});
|
|
1279
1325
|
};
|
|
@@ -1369,6 +1415,7 @@ const createGitlabProvider = (options) => {
|
|
|
1369
1415
|
globalConfig,
|
|
1370
1416
|
config,
|
|
1371
1417
|
tokenIssuer,
|
|
1418
|
+
tokenManager,
|
|
1372
1419
|
catalogApi,
|
|
1373
1420
|
logger
|
|
1374
1421
|
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
@@ -1377,10 +1424,11 @@ const createGitlabProvider = (options) => {
|
|
|
1377
1424
|
const clientSecret = envConfig.getString("clientSecret");
|
|
1378
1425
|
const audience = envConfig.getOptionalString("audience");
|
|
1379
1426
|
const baseUrl = audience || "https://gitlab.com";
|
|
1380
|
-
const
|
|
1427
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
1428
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1381
1429
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1382
1430
|
catalogApi,
|
|
1383
|
-
|
|
1431
|
+
tokenManager
|
|
1384
1432
|
});
|
|
1385
1433
|
const authHandler = (_a = options == null ? void 0 : options.authHandler) != null ? _a : gitlabDefaultAuthHandler;
|
|
1386
1434
|
const signInResolverFn = (_c = (_b = options == null ? void 0 : options.signIn) == null ? void 0 : _b.resolver) != null ? _c : gitlabDefaultSignInResolver;
|
|
@@ -1403,7 +1451,8 @@ const createGitlabProvider = (options) => {
|
|
|
1403
1451
|
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1404
1452
|
disableRefresh: false,
|
|
1405
1453
|
providerId,
|
|
1406
|
-
tokenIssuer
|
|
1454
|
+
tokenIssuer,
|
|
1455
|
+
callbackUrl
|
|
1407
1456
|
});
|
|
1408
1457
|
});
|
|
1409
1458
|
};
|
|
@@ -1515,7 +1564,7 @@ const googleDefaultSignInResolver = async (info, ctx) => {
|
|
|
1515
1564
|
userId = profile.email.split("@")[0];
|
|
1516
1565
|
}
|
|
1517
1566
|
const token = await ctx.tokenIssuer.issueToken({
|
|
1518
|
-
claims: { sub: userId
|
|
1567
|
+
claims: { sub: `user:default/${userId}`, ent: [`user:default/${userId}`] }
|
|
1519
1568
|
});
|
|
1520
1569
|
return { id: userId, token };
|
|
1521
1570
|
};
|
|
@@ -1525,16 +1574,18 @@ const createGoogleProvider = (options) => {
|
|
|
1525
1574
|
globalConfig,
|
|
1526
1575
|
config,
|
|
1527
1576
|
tokenIssuer,
|
|
1577
|
+
tokenManager,
|
|
1528
1578
|
catalogApi,
|
|
1529
1579
|
logger
|
|
1530
1580
|
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1531
1581
|
var _a, _b;
|
|
1532
1582
|
const clientId = envConfig.getString("clientId");
|
|
1533
1583
|
const clientSecret = envConfig.getString("clientSecret");
|
|
1534
|
-
const
|
|
1584
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
1585
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1535
1586
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1536
1587
|
catalogApi,
|
|
1537
|
-
|
|
1588
|
+
tokenManager
|
|
1538
1589
|
});
|
|
1539
1590
|
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1540
1591
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
@@ -1558,7 +1609,8 @@ const createGoogleProvider = (options) => {
|
|
|
1558
1609
|
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1559
1610
|
disableRefresh: false,
|
|
1560
1611
|
providerId,
|
|
1561
|
-
tokenIssuer
|
|
1612
|
+
tokenIssuer,
|
|
1613
|
+
callbackUrl
|
|
1562
1614
|
});
|
|
1563
1615
|
});
|
|
1564
1616
|
};
|
|
@@ -1682,6 +1734,7 @@ const createMicrosoftProvider = (options) => {
|
|
|
1682
1734
|
globalConfig,
|
|
1683
1735
|
config,
|
|
1684
1736
|
tokenIssuer,
|
|
1737
|
+
tokenManager,
|
|
1685
1738
|
catalogApi,
|
|
1686
1739
|
logger
|
|
1687
1740
|
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
@@ -1689,12 +1742,13 @@ const createMicrosoftProvider = (options) => {
|
|
|
1689
1742
|
const clientId = envConfig.getString("clientId");
|
|
1690
1743
|
const clientSecret = envConfig.getString("clientSecret");
|
|
1691
1744
|
const tenantId = envConfig.getString("tenantId");
|
|
1692
|
-
const
|
|
1745
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
1746
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1693
1747
|
const authorizationUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/authorize`;
|
|
1694
1748
|
const tokenUrl = `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`;
|
|
1695
1749
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1696
1750
|
catalogApi,
|
|
1697
|
-
|
|
1751
|
+
tokenManager
|
|
1698
1752
|
});
|
|
1699
1753
|
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1700
1754
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
@@ -1720,7 +1774,8 @@ const createMicrosoftProvider = (options) => {
|
|
|
1720
1774
|
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1721
1775
|
disableRefresh: false,
|
|
1722
1776
|
providerId,
|
|
1723
|
-
tokenIssuer
|
|
1777
|
+
tokenIssuer,
|
|
1778
|
+
callbackUrl
|
|
1724
1779
|
});
|
|
1725
1780
|
});
|
|
1726
1781
|
};
|
|
@@ -1827,13 +1882,15 @@ const createOAuth2Provider = (options) => {
|
|
|
1827
1882
|
globalConfig,
|
|
1828
1883
|
config,
|
|
1829
1884
|
tokenIssuer,
|
|
1885
|
+
tokenManager,
|
|
1830
1886
|
catalogApi,
|
|
1831
1887
|
logger
|
|
1832
1888
|
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1833
1889
|
var _a, _b, _c;
|
|
1834
1890
|
const clientId = envConfig.getString("clientId");
|
|
1835
1891
|
const clientSecret = envConfig.getString("clientSecret");
|
|
1836
|
-
const
|
|
1892
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
1893
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1837
1894
|
const authorizationUrl = envConfig.getString("authorizationUrl");
|
|
1838
1895
|
const tokenUrl = envConfig.getString("tokenUrl");
|
|
1839
1896
|
const scope = envConfig.getOptionalString("scope");
|
|
@@ -1841,7 +1898,7 @@ const createOAuth2Provider = (options) => {
|
|
|
1841
1898
|
const disableRefresh = (_a = envConfig.getOptionalBoolean("disableRefresh")) != null ? _a : false;
|
|
1842
1899
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1843
1900
|
catalogApi,
|
|
1844
|
-
|
|
1901
|
+
tokenManager
|
|
1845
1902
|
});
|
|
1846
1903
|
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
1847
1904
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
@@ -1869,7 +1926,8 @@ const createOAuth2Provider = (options) => {
|
|
|
1869
1926
|
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1870
1927
|
disableRefresh,
|
|
1871
1928
|
providerId,
|
|
1872
|
-
tokenIssuer
|
|
1929
|
+
tokenIssuer,
|
|
1930
|
+
callbackUrl
|
|
1873
1931
|
});
|
|
1874
1932
|
});
|
|
1875
1933
|
};
|
|
@@ -2272,12 +2330,12 @@ class Oauth2ProxyAuthProvider {
|
|
|
2272
2330
|
};
|
|
2273
2331
|
}
|
|
2274
2332
|
}
|
|
2275
|
-
const createOauth2ProxyProvider = (options) => ({ catalogApi, logger, tokenIssuer }) => {
|
|
2333
|
+
const createOauth2ProxyProvider = (options) => ({ catalogApi, logger, tokenIssuer, tokenManager }) => {
|
|
2276
2334
|
const signInResolver = options.signIn.resolver;
|
|
2277
2335
|
const authHandler = options.authHandler;
|
|
2278
2336
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
2279
2337
|
catalogApi,
|
|
2280
|
-
|
|
2338
|
+
tokenManager
|
|
2281
2339
|
});
|
|
2282
2340
|
return new Oauth2ProxyAuthProvider({
|
|
2283
2341
|
logger,
|
|
@@ -2388,7 +2446,10 @@ const oAuth2DefaultSignInResolver = async (info, ctx) => {
|
|
|
2388
2446
|
}
|
|
2389
2447
|
const userId = profile.email.split("@")[0];
|
|
2390
2448
|
const token = await ctx.tokenIssuer.issueToken({
|
|
2391
|
-
claims: {
|
|
2449
|
+
claims: {
|
|
2450
|
+
sub: `user:default/${userId}`,
|
|
2451
|
+
ent: [`user:default/${userId}`]
|
|
2452
|
+
}
|
|
2392
2453
|
});
|
|
2393
2454
|
return { id: userId, token };
|
|
2394
2455
|
};
|
|
@@ -2398,20 +2459,22 @@ const createOidcProvider = (options) => {
|
|
|
2398
2459
|
globalConfig,
|
|
2399
2460
|
config,
|
|
2400
2461
|
tokenIssuer,
|
|
2462
|
+
tokenManager,
|
|
2401
2463
|
catalogApi,
|
|
2402
2464
|
logger
|
|
2403
2465
|
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
2404
2466
|
var _a, _b;
|
|
2405
2467
|
const clientId = envConfig.getString("clientId");
|
|
2406
2468
|
const clientSecret = envConfig.getString("clientSecret");
|
|
2407
|
-
const
|
|
2469
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
2470
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
2408
2471
|
const metadataUrl = envConfig.getString("metadataUrl");
|
|
2409
2472
|
const tokenSignedResponseAlg = envConfig.getOptionalString("tokenSignedResponseAlg");
|
|
2410
2473
|
const scope = envConfig.getOptionalString("scope");
|
|
2411
2474
|
const prompt = envConfig.getOptionalString("prompt");
|
|
2412
2475
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
2413
2476
|
catalogApi,
|
|
2414
|
-
|
|
2477
|
+
tokenManager
|
|
2415
2478
|
});
|
|
2416
2479
|
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ userinfo }) => ({
|
|
2417
2480
|
profile: {
|
|
@@ -2443,7 +2506,8 @@ const createOidcProvider = (options) => {
|
|
|
2443
2506
|
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
2444
2507
|
disableRefresh: false,
|
|
2445
2508
|
providerId,
|
|
2446
|
-
tokenIssuer
|
|
2509
|
+
tokenIssuer,
|
|
2510
|
+
callbackUrl
|
|
2447
2511
|
});
|
|
2448
2512
|
});
|
|
2449
2513
|
};
|
|
@@ -2565,6 +2629,7 @@ const createOktaProvider = (_options) => {
|
|
|
2565
2629
|
globalConfig,
|
|
2566
2630
|
config,
|
|
2567
2631
|
tokenIssuer,
|
|
2632
|
+
tokenManager,
|
|
2568
2633
|
catalogApi,
|
|
2569
2634
|
logger
|
|
2570
2635
|
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
@@ -2572,13 +2637,14 @@ const createOktaProvider = (_options) => {
|
|
|
2572
2637
|
const clientId = envConfig.getString("clientId");
|
|
2573
2638
|
const clientSecret = envConfig.getString("clientSecret");
|
|
2574
2639
|
const audience = envConfig.getString("audience");
|
|
2575
|
-
const
|
|
2640
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
2641
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
2576
2642
|
if (!audience.startsWith("https://")) {
|
|
2577
2643
|
throw new Error("URL for 'audience' must start with 'https://'.");
|
|
2578
2644
|
}
|
|
2579
2645
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
2580
2646
|
catalogApi,
|
|
2581
|
-
|
|
2647
|
+
tokenManager
|
|
2582
2648
|
});
|
|
2583
2649
|
const authHandler = (_options == null ? void 0 : _options.authHandler) ? _options.authHandler : async ({ fullProfile, params }) => ({
|
|
2584
2650
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
@@ -2603,7 +2669,8 @@ const createOktaProvider = (_options) => {
|
|
|
2603
2669
|
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
2604
2670
|
disableRefresh: false,
|
|
2605
2671
|
providerId,
|
|
2606
|
-
tokenIssuer
|
|
2672
|
+
tokenIssuer,
|
|
2673
|
+
callbackUrl
|
|
2607
2674
|
});
|
|
2608
2675
|
});
|
|
2609
2676
|
};
|
|
@@ -2698,6 +2765,7 @@ const createOneLoginProvider = (options) => {
|
|
|
2698
2765
|
globalConfig,
|
|
2699
2766
|
config,
|
|
2700
2767
|
tokenIssuer,
|
|
2768
|
+
tokenManager,
|
|
2701
2769
|
catalogApi,
|
|
2702
2770
|
logger
|
|
2703
2771
|
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
@@ -2705,10 +2773,11 @@ const createOneLoginProvider = (options) => {
|
|
|
2705
2773
|
const clientId = envConfig.getString("clientId");
|
|
2706
2774
|
const clientSecret = envConfig.getString("clientSecret");
|
|
2707
2775
|
const issuer = envConfig.getString("issuer");
|
|
2708
|
-
const
|
|
2776
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
2777
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
2709
2778
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
2710
2779
|
catalogApi,
|
|
2711
|
-
|
|
2780
|
+
tokenManager
|
|
2712
2781
|
});
|
|
2713
2782
|
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile, params }) => ({
|
|
2714
2783
|
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
@@ -2728,7 +2797,8 @@ const createOneLoginProvider = (options) => {
|
|
|
2728
2797
|
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
2729
2798
|
disableRefresh: false,
|
|
2730
2799
|
providerId,
|
|
2731
|
-
tokenIssuer
|
|
2800
|
+
tokenIssuer,
|
|
2801
|
+
callbackUrl
|
|
2732
2802
|
});
|
|
2733
2803
|
});
|
|
2734
2804
|
};
|
|
@@ -2798,13 +2868,14 @@ const createSamlProvider = (options) => {
|
|
|
2798
2868
|
globalConfig,
|
|
2799
2869
|
config,
|
|
2800
2870
|
tokenIssuer,
|
|
2871
|
+
tokenManager,
|
|
2801
2872
|
catalogApi,
|
|
2802
2873
|
logger
|
|
2803
2874
|
}) => {
|
|
2804
2875
|
var _a, _b;
|
|
2805
2876
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
2806
2877
|
catalogApi,
|
|
2807
|
-
|
|
2878
|
+
tokenManager
|
|
2808
2879
|
});
|
|
2809
2880
|
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({ fullProfile }) => ({
|
|
2810
2881
|
profile: {
|
|
@@ -2912,7 +2983,7 @@ class GcpIapProvider {
|
|
|
2912
2983
|
}
|
|
2913
2984
|
}
|
|
2914
2985
|
function createGcpIapProvider(options) {
|
|
2915
|
-
return ({ config, tokenIssuer, catalogApi, logger }) => {
|
|
2986
|
+
return ({ config, tokenIssuer, catalogApi, logger, tokenManager }) => {
|
|
2916
2987
|
var _a;
|
|
2917
2988
|
const audience = config.getString("audience");
|
|
2918
2989
|
const authHandler = (_a = options.authHandler) != null ? _a : defaultAuthHandler;
|
|
@@ -2920,7 +2991,7 @@ function createGcpIapProvider(options) {
|
|
|
2920
2991
|
const tokenValidator = createTokenValidator(audience);
|
|
2921
2992
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
2922
2993
|
catalogApi,
|
|
2923
|
-
|
|
2994
|
+
tokenManager
|
|
2924
2995
|
});
|
|
2925
2996
|
return new GcpIapProvider({
|
|
2926
2997
|
authHandler,
|
|
@@ -2950,7 +3021,14 @@ const factories = {
|
|
|
2950
3021
|
};
|
|
2951
3022
|
|
|
2952
3023
|
async function createRouter(options) {
|
|
2953
|
-
const {
|
|
3024
|
+
const {
|
|
3025
|
+
logger,
|
|
3026
|
+
config,
|
|
3027
|
+
discovery,
|
|
3028
|
+
database,
|
|
3029
|
+
tokenManager,
|
|
3030
|
+
providerFactories
|
|
3031
|
+
} = options;
|
|
2954
3032
|
const router = Router__default["default"]();
|
|
2955
3033
|
const appUrl = config.getString("app.baseUrl");
|
|
2956
3034
|
const authUrl = await discovery.getExternalBaseUrl("auth");
|
|
@@ -2996,6 +3074,7 @@ async function createRouter(options) {
|
|
|
2996
3074
|
globalConfig: { baseUrl: authUrl, appUrl, isOriginAllowed },
|
|
2997
3075
|
config: providersConfig.getConfig(providerId),
|
|
2998
3076
|
logger,
|
|
3077
|
+
tokenManager,
|
|
2999
3078
|
tokenIssuer,
|
|
3000
3079
|
discovery,
|
|
3001
3080
|
catalogApi
|