@backstage/plugin-auth-backend 0.3.24 → 0.4.3
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 +59 -0
- package/config.d.ts +1 -1
- package/dist/index.cjs.js +156 -10
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +44 -1
- package/package.json +12 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,64 @@
|
|
|
1
1
|
# @backstage/plugin-auth-backend
|
|
2
2
|
|
|
3
|
+
## 0.4.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4c3eea7788: Bitbucket Cloud authentication - based on the existing GitHub authentication + changes around BB apis and updated scope.
|
|
8
|
+
|
|
9
|
+
- BitbucketAuth added to core-app-api.
|
|
10
|
+
- Bitbucket provider added to plugin-auth-backend.
|
|
11
|
+
- Cosmetic entry for Bitbucket connection in user-settings Authentication Providers tab.
|
|
12
|
+
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
- @backstage/test-utils@0.1.18
|
|
15
|
+
- @backstage/catalog-model@0.9.4
|
|
16
|
+
- @backstage/backend-common@0.9.6
|
|
17
|
+
- @backstage/catalog-client@0.5.0
|
|
18
|
+
|
|
19
|
+
## 0.4.2
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- 88622e6422: Allow users to override callback url of GitHub provider
|
|
24
|
+
- c46396ebb0: Update OAuth refresh handler to pass updated refresh token to ensure cookie is updated with new value.
|
|
25
|
+
- Updated dependencies
|
|
26
|
+
- @backstage/backend-common@0.9.5
|
|
27
|
+
|
|
28
|
+
## 0.4.1
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- Updated dependencies
|
|
33
|
+
- @backstage/catalog-client@0.4.0
|
|
34
|
+
- @backstage/catalog-model@0.9.3
|
|
35
|
+
- @backstage/backend-common@0.9.4
|
|
36
|
+
- @backstage/config@0.1.10
|
|
37
|
+
|
|
38
|
+
## 0.4.0
|
|
39
|
+
|
|
40
|
+
### Minor Changes
|
|
41
|
+
|
|
42
|
+
- 19f45179a5: Bump `passport-saml` to version 3. This is a breaking change, in that it [now requires](https://github.com/node-saml/passport-saml/pull/548) the `auth.saml.cert` parameter to be set. If you are not using SAML auth, you can ignore this.
|
|
43
|
+
|
|
44
|
+
To update your settings, add something similar to the following to your app-config:
|
|
45
|
+
|
|
46
|
+
```yaml
|
|
47
|
+
auth:
|
|
48
|
+
saml:
|
|
49
|
+
# ... other settings ...
|
|
50
|
+
cert: 'MIICizCCAfQCCQCY8tKaMc0BMjANBgkqh ... W=='
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
For more information, see the [library README](https://github.com/node-saml/passport-saml#security-and-signatures).
|
|
54
|
+
|
|
55
|
+
### Patch Changes
|
|
56
|
+
|
|
57
|
+
- 560d6810f0: Fix a bug preventing an access token to be refreshed a second time with the GitLab provider.
|
|
58
|
+
- de5717872d: Use a more informative error message if the configured OIDC identity provider does not provide a `userinfo_endpoint` in its metadata.
|
|
59
|
+
- Updated dependencies
|
|
60
|
+
- @backstage/backend-common@0.9.3
|
|
61
|
+
|
|
3
62
|
## 0.3.24
|
|
4
63
|
|
|
5
64
|
### Patch Changes
|
package/config.d.ts
CHANGED
package/dist/index.cjs.js
CHANGED
|
@@ -18,6 +18,7 @@ var passportMicrosoft = require('passport-microsoft');
|
|
|
18
18
|
var got = require('got');
|
|
19
19
|
var OAuth2Strategy = require('passport-oauth2');
|
|
20
20
|
var passportOktaOauth = require('passport-okta-oauth');
|
|
21
|
+
var passportBitbucketOauth2 = require('passport-bitbucket-oauth2');
|
|
21
22
|
var openidClient = require('openid-client');
|
|
22
23
|
var passportSaml = require('passport-saml');
|
|
23
24
|
var passportOneloginOauth = require('passport-onelogin-oauth');
|
|
@@ -285,7 +286,7 @@ const postMessageResponse = (res, appOrigin, response) => {
|
|
|
285
286
|
(window.opener || window.parent).postMessage(JSON.parse(authResponse), origin);
|
|
286
287
|
setTimeout(() => {
|
|
287
288
|
window.close();
|
|
288
|
-
}, 100); // same as the interval of the core-api lib/loginPopup.ts (to address race conditions)
|
|
289
|
+
}, 100); // same as the interval of the core-app-api lib/loginPopup.ts (to address race conditions)
|
|
289
290
|
`;
|
|
290
291
|
const hash = crypto__default['default'].createHash("sha256").update(script).digest("base64");
|
|
291
292
|
res.setHeader("Content-Type", "text/html");
|
|
@@ -632,10 +633,11 @@ const createGithubProvider = (options) => {
|
|
|
632
633
|
const clientId = envConfig.getString("clientId");
|
|
633
634
|
const clientSecret = envConfig.getString("clientSecret");
|
|
634
635
|
const enterpriseInstanceUrl = envConfig.getOptionalString("enterpriseInstanceUrl");
|
|
636
|
+
const customCallbackUrl = envConfig.getOptionalString("callbackUrl");
|
|
635
637
|
const authorizationUrl = enterpriseInstanceUrl ? `${enterpriseInstanceUrl}/login/oauth/authorize` : void 0;
|
|
636
638
|
const tokenUrl = enterpriseInstanceUrl ? `${enterpriseInstanceUrl}/login/oauth/access_token` : void 0;
|
|
637
639
|
const userProfileUrl = enterpriseInstanceUrl ? `${enterpriseInstanceUrl}/api/v3/user` : void 0;
|
|
638
|
-
const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
640
|
+
const callbackUrl = customCallbackUrl || `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
639
641
|
const catalogIdentityClient = new CatalogIdentityClient({
|
|
640
642
|
catalogApi,
|
|
641
643
|
tokenIssuer
|
|
@@ -738,6 +740,7 @@ class GitlabAuthProvider {
|
|
|
738
740
|
providerInfo: {
|
|
739
741
|
idToken: result.params.id_token,
|
|
740
742
|
accessToken: result.accessToken,
|
|
743
|
+
refreshToken: result.refreshToken,
|
|
741
744
|
scope: result.params.scope,
|
|
742
745
|
expiresInSeconds: result.params.expires_in
|
|
743
746
|
},
|
|
@@ -1174,7 +1177,8 @@ class OAuth2AuthProvider {
|
|
|
1174
1177
|
idToken: result.params.id_token,
|
|
1175
1178
|
accessToken: result.accessToken,
|
|
1176
1179
|
scope: result.params.scope,
|
|
1177
|
-
expiresInSeconds: result.params.expires_in
|
|
1180
|
+
expiresInSeconds: result.params.expires_in,
|
|
1181
|
+
refreshToken: result.refreshToken
|
|
1178
1182
|
},
|
|
1179
1183
|
profile
|
|
1180
1184
|
};
|
|
@@ -1407,6 +1411,145 @@ const createOktaProvider = (_options) => {
|
|
|
1407
1411
|
});
|
|
1408
1412
|
};
|
|
1409
1413
|
|
|
1414
|
+
class BitbucketAuthProvider {
|
|
1415
|
+
constructor(options) {
|
|
1416
|
+
this.signInResolver = options.signInResolver;
|
|
1417
|
+
this.authHandler = options.authHandler;
|
|
1418
|
+
this.tokenIssuer = options.tokenIssuer;
|
|
1419
|
+
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
1420
|
+
this.logger = options.logger;
|
|
1421
|
+
this._strategy = new passportBitbucketOauth2.Strategy({
|
|
1422
|
+
clientID: options.clientId,
|
|
1423
|
+
clientSecret: options.clientSecret,
|
|
1424
|
+
callbackURL: options.callbackUrl,
|
|
1425
|
+
passReqToCallback: false
|
|
1426
|
+
}, (accessToken, refreshToken, params, fullProfile, done) => {
|
|
1427
|
+
done(void 0, {
|
|
1428
|
+
fullProfile,
|
|
1429
|
+
params,
|
|
1430
|
+
accessToken,
|
|
1431
|
+
refreshToken
|
|
1432
|
+
}, {
|
|
1433
|
+
refreshToken
|
|
1434
|
+
});
|
|
1435
|
+
});
|
|
1436
|
+
}
|
|
1437
|
+
async start(req) {
|
|
1438
|
+
return await executeRedirectStrategy(req, this._strategy, {
|
|
1439
|
+
accessType: "offline",
|
|
1440
|
+
prompt: "consent",
|
|
1441
|
+
scope: req.scope,
|
|
1442
|
+
state: encodeState(req.state)
|
|
1443
|
+
});
|
|
1444
|
+
}
|
|
1445
|
+
async handler(req) {
|
|
1446
|
+
const {result, privateInfo} = await executeFrameHandlerStrategy(req, this._strategy);
|
|
1447
|
+
return {
|
|
1448
|
+
response: await this.handleResult(result),
|
|
1449
|
+
refreshToken: privateInfo.refreshToken
|
|
1450
|
+
};
|
|
1451
|
+
}
|
|
1452
|
+
async refresh(req) {
|
|
1453
|
+
const {accessToken, params} = await executeRefreshTokenStrategy(this._strategy, req.refreshToken, req.scope);
|
|
1454
|
+
const fullProfile = await executeFetchUserProfileStrategy(this._strategy, accessToken);
|
|
1455
|
+
return this.handleResult({
|
|
1456
|
+
fullProfile,
|
|
1457
|
+
params,
|
|
1458
|
+
accessToken,
|
|
1459
|
+
refreshToken: req.refreshToken
|
|
1460
|
+
});
|
|
1461
|
+
}
|
|
1462
|
+
async handleResult(result) {
|
|
1463
|
+
result.fullProfile.avatarUrl = result.fullProfile._json.links.avatar.href;
|
|
1464
|
+
const {profile} = await this.authHandler(result);
|
|
1465
|
+
const response = {
|
|
1466
|
+
providerInfo: {
|
|
1467
|
+
idToken: result.params.id_token,
|
|
1468
|
+
accessToken: result.accessToken,
|
|
1469
|
+
scope: result.params.scope,
|
|
1470
|
+
expiresInSeconds: result.params.expires_in
|
|
1471
|
+
},
|
|
1472
|
+
profile
|
|
1473
|
+
};
|
|
1474
|
+
if (this.signInResolver) {
|
|
1475
|
+
response.backstageIdentity = await this.signInResolver({
|
|
1476
|
+
result,
|
|
1477
|
+
profile
|
|
1478
|
+
}, {
|
|
1479
|
+
tokenIssuer: this.tokenIssuer,
|
|
1480
|
+
catalogIdentityClient: this.catalogIdentityClient,
|
|
1481
|
+
logger: this.logger
|
|
1482
|
+
});
|
|
1483
|
+
}
|
|
1484
|
+
return response;
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
const bitbucketUsernameSignInResolver = async (info, ctx) => {
|
|
1488
|
+
const {result} = info;
|
|
1489
|
+
if (!result.fullProfile.username) {
|
|
1490
|
+
throw new Error("Bitbucket profile contained no Username");
|
|
1491
|
+
}
|
|
1492
|
+
const entity = await ctx.catalogIdentityClient.findUser({
|
|
1493
|
+
annotations: {
|
|
1494
|
+
"bitbucket.org/username": result.fullProfile.username
|
|
1495
|
+
}
|
|
1496
|
+
});
|
|
1497
|
+
const claims = getEntityClaims(entity);
|
|
1498
|
+
const token = await ctx.tokenIssuer.issueToken({claims});
|
|
1499
|
+
return {id: entity.metadata.name, entity, token};
|
|
1500
|
+
};
|
|
1501
|
+
const bitbucketUserIdSignInResolver = async (info, ctx) => {
|
|
1502
|
+
const {result} = info;
|
|
1503
|
+
if (!result.fullProfile.id) {
|
|
1504
|
+
throw new Error("Bitbucket profile contained no User ID");
|
|
1505
|
+
}
|
|
1506
|
+
const entity = await ctx.catalogIdentityClient.findUser({
|
|
1507
|
+
annotations: {
|
|
1508
|
+
"bitbucket.org/user-id": result.fullProfile.id
|
|
1509
|
+
}
|
|
1510
|
+
});
|
|
1511
|
+
const claims = getEntityClaims(entity);
|
|
1512
|
+
const token = await ctx.tokenIssuer.issueToken({claims});
|
|
1513
|
+
return {id: entity.metadata.name, entity, token};
|
|
1514
|
+
};
|
|
1515
|
+
const createBitbucketProvider = (options) => {
|
|
1516
|
+
return ({
|
|
1517
|
+
providerId,
|
|
1518
|
+
globalConfig,
|
|
1519
|
+
config,
|
|
1520
|
+
tokenIssuer,
|
|
1521
|
+
catalogApi,
|
|
1522
|
+
logger
|
|
1523
|
+
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
1524
|
+
var _a;
|
|
1525
|
+
const clientId = envConfig.getString("clientId");
|
|
1526
|
+
const clientSecret = envConfig.getString("clientSecret");
|
|
1527
|
+
const callbackUrl = `${globalConfig.baseUrl}/${providerId}/handler/frame`;
|
|
1528
|
+
const catalogIdentityClient = new CatalogIdentityClient({
|
|
1529
|
+
catalogApi,
|
|
1530
|
+
tokenIssuer
|
|
1531
|
+
});
|
|
1532
|
+
const authHandler = (options == null ? void 0 : options.authHandler) ? options.authHandler : async ({fullProfile, params}) => ({
|
|
1533
|
+
profile: makeProfileInfo(fullProfile, params.id_token)
|
|
1534
|
+
});
|
|
1535
|
+
const provider = new BitbucketAuthProvider({
|
|
1536
|
+
clientId,
|
|
1537
|
+
clientSecret,
|
|
1538
|
+
callbackUrl,
|
|
1539
|
+
signInResolver: (_a = options == null ? void 0 : options.signIn) == null ? void 0 : _a.resolver,
|
|
1540
|
+
authHandler,
|
|
1541
|
+
tokenIssuer,
|
|
1542
|
+
catalogIdentityClient,
|
|
1543
|
+
logger
|
|
1544
|
+
});
|
|
1545
|
+
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
1546
|
+
disableRefresh: false,
|
|
1547
|
+
providerId,
|
|
1548
|
+
tokenIssuer
|
|
1549
|
+
});
|
|
1550
|
+
});
|
|
1551
|
+
};
|
|
1552
|
+
|
|
1410
1553
|
class OidcAuthProvider {
|
|
1411
1554
|
constructor(options) {
|
|
1412
1555
|
this.implementation = this.setupStrategy(options);
|
|
@@ -1483,6 +1626,9 @@ class OidcAuthProvider {
|
|
|
1483
1626
|
client,
|
|
1484
1627
|
passReqToCallback: false
|
|
1485
1628
|
}, (tokenset, userinfo, done) => {
|
|
1629
|
+
if (typeof done !== "function") {
|
|
1630
|
+
throw new Error("OIDC IdP must provide a userinfo_endpoint in the metadata response");
|
|
1631
|
+
}
|
|
1486
1632
|
done(void 0, {tokenset, userinfo}, {
|
|
1487
1633
|
refreshToken: tokenset.refresh_token
|
|
1488
1634
|
});
|
|
@@ -1573,13 +1719,13 @@ class SamlAuthProvider {
|
|
|
1573
1719
|
}
|
|
1574
1720
|
}
|
|
1575
1721
|
const createSamlProvider = (_options) => {
|
|
1576
|
-
return ({providerId, globalConfig, config, tokenIssuer
|
|
1722
|
+
return ({providerId, globalConfig, config, tokenIssuer}) => {
|
|
1577
1723
|
const opts = {
|
|
1578
1724
|
callbackUrl: `${globalConfig.baseUrl}/${providerId}/handler/frame`,
|
|
1579
1725
|
entryPoint: config.getString("entryPoint"),
|
|
1580
1726
|
logoutUrl: config.getOptionalString("logoutUrl"),
|
|
1581
1727
|
issuer: config.getString("issuer"),
|
|
1582
|
-
cert: config.
|
|
1728
|
+
cert: config.getString("cert"),
|
|
1583
1729
|
privateCert: config.getOptionalString("privateKey"),
|
|
1584
1730
|
decryptionPvk: config.getOptionalString("decryptionPvk"),
|
|
1585
1731
|
signatureAlgorithm: config.getOptionalString("signatureAlgorithm"),
|
|
@@ -1588,10 +1734,6 @@ const createSamlProvider = (_options) => {
|
|
|
1588
1734
|
tokenIssuer,
|
|
1589
1735
|
appUrl: globalConfig.appUrl
|
|
1590
1736
|
};
|
|
1591
|
-
if (!opts.cert) {
|
|
1592
|
-
logger.warn('SamlAuthProvider was initialized without a cert configuration parameter. This will soon be required by the underlying passport-saml library, which may soon lead to failures to start the auth backend. Please add an "auth.saml.cert" config parameter.');
|
|
1593
|
-
delete opts.cert;
|
|
1594
|
-
}
|
|
1595
1737
|
return new SamlAuthProvider(opts);
|
|
1596
1738
|
};
|
|
1597
1739
|
};
|
|
@@ -1863,7 +2005,8 @@ const factories = {
|
|
|
1863
2005
|
oauth2: createOAuth2Provider(),
|
|
1864
2006
|
oidc: createOidcProvider(),
|
|
1865
2007
|
onelogin: createOneLoginProvider(),
|
|
1866
|
-
awsalb: createAwsAlbProvider()
|
|
2008
|
+
awsalb: createAwsAlbProvider(),
|
|
2009
|
+
bitbucket: createBitbucketProvider()
|
|
1867
2010
|
};
|
|
1868
2011
|
|
|
1869
2012
|
function createOidcRouter(options) {
|
|
@@ -2187,6 +2330,9 @@ function createOriginFilter(config) {
|
|
|
2187
2330
|
exports.IdentityClient = IdentityClient;
|
|
2188
2331
|
exports.OAuthAdapter = OAuthAdapter;
|
|
2189
2332
|
exports.OAuthEnvironmentHandler = OAuthEnvironmentHandler;
|
|
2333
|
+
exports.bitbucketUserIdSignInResolver = bitbucketUserIdSignInResolver;
|
|
2334
|
+
exports.bitbucketUsernameSignInResolver = bitbucketUsernameSignInResolver;
|
|
2335
|
+
exports.createBitbucketProvider = createBitbucketProvider;
|
|
2190
2336
|
exports.createGithubProvider = createGithubProvider;
|
|
2191
2337
|
exports.createGitlabProvider = createGitlabProvider;
|
|
2192
2338
|
exports.createGoogleProvider = createGoogleProvider;
|