@backstage/plugin-auth-backend 0.4.5 → 0.4.9
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 +58 -0
- package/README.md +6 -6
- package/config.d.ts +1 -0
- package/dist/index.cjs.js +34 -31
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +116 -96
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,63 @@
|
|
|
1
1
|
# @backstage/plugin-auth-backend
|
|
2
2
|
|
|
3
|
+
## 0.4.9
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 9312572360: Switched to using the standardized JSON error responses for all provider endpoints.
|
|
8
|
+
- bab752e2b3: Change default port of backend from 7000 to 7007.
|
|
9
|
+
|
|
10
|
+
This is due to the AirPlay Receiver process occupying port 7000 and preventing local Backstage instances on MacOS to start.
|
|
11
|
+
|
|
12
|
+
You can change the port back to 7000 or any other value by providing an `app-config.yaml` with the following values:
|
|
13
|
+
|
|
14
|
+
```
|
|
15
|
+
backend:
|
|
16
|
+
listen: 0.0.0.0:7123
|
|
17
|
+
baseUrl: http://localhost:7123
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
More information can be found here: https://backstage.io/docs/conf/writing
|
|
21
|
+
|
|
22
|
+
- Updated dependencies
|
|
23
|
+
- @backstage/errors@0.1.5
|
|
24
|
+
- @backstage/backend-common@0.9.11
|
|
25
|
+
- @backstage/test-utils@0.1.23
|
|
26
|
+
|
|
27
|
+
## 0.4.8
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- 892c1d9202: Update OAuthAdapter to create identity.token from identity.idToken if it does not exist, and prevent overwrites to identity.toke. Update login page commonProvider to prefer .token over .idToken
|
|
32
|
+
- Updated dependencies
|
|
33
|
+
- @backstage/catalog-client@0.5.2
|
|
34
|
+
- @backstage/catalog-model@0.9.7
|
|
35
|
+
- @backstage/backend-common@0.9.10
|
|
36
|
+
- @backstage/test-utils@0.1.22
|
|
37
|
+
|
|
38
|
+
## 0.4.7
|
|
39
|
+
|
|
40
|
+
### Patch Changes
|
|
41
|
+
|
|
42
|
+
- 5ee31f860b: Only use settings that have a value when creating a new FirestoreKeyStore instance
|
|
43
|
+
- 3e0e2f09d5: Added forwarding of the `audience` option for the SAML provider, making it possible to enable `audience` verification.
|
|
44
|
+
- Updated dependencies
|
|
45
|
+
- @backstage/backend-common@0.9.9
|
|
46
|
+
- @backstage/test-utils@0.1.21
|
|
47
|
+
- @backstage/catalog-client@0.5.1
|
|
48
|
+
|
|
49
|
+
## 0.4.6
|
|
50
|
+
|
|
51
|
+
### Patch Changes
|
|
52
|
+
|
|
53
|
+
- 3b767f19c9: Allow OAuth state to be encoded by a stateEncoder.
|
|
54
|
+
- Updated dependencies
|
|
55
|
+
- @backstage/test-utils@0.1.20
|
|
56
|
+
- @backstage/config@0.1.11
|
|
57
|
+
- @backstage/errors@0.1.4
|
|
58
|
+
- @backstage/backend-common@0.9.8
|
|
59
|
+
- @backstage/catalog-model@0.9.6
|
|
60
|
+
|
|
3
61
|
## 0.4.5
|
|
4
62
|
|
|
5
63
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ Follow this link, [Create new OAuth App](https://github.com/settings/application
|
|
|
34
34
|
1. Set Application Name to `backstage-dev` or something along those lines.
|
|
35
35
|
1. You can set the Homepage URL to whatever you want to.
|
|
36
36
|
1. The Authorization Callback URL should match the redirect URI set in Backstage.
|
|
37
|
-
1. Set this to `http://localhost:
|
|
37
|
+
1. Set this to `http://localhost:7007/api/auth/github` for local development.
|
|
38
38
|
1. Set this to `http://{APP_FQDN}:{APP_BACKEND_PORT}/api/auth/github` for non-local deployments.
|
|
39
39
|
|
|
40
40
|
```bash
|
|
@@ -58,7 +58,7 @@ Follow this link, [Add new application](https://gitlab.com/-/profile/application
|
|
|
58
58
|
|
|
59
59
|
1. Set Application Name to `backstage-dev` or something along those lines.
|
|
60
60
|
1. The Authorization Callback URL should match the redirect URI set in Backstage.
|
|
61
|
-
1. Set this to `http://localhost:
|
|
61
|
+
1. Set this to `http://localhost:7007/api/auth/gitlab/handler/frame` for local development.
|
|
62
62
|
1. Set this to `http://{APP_FQDN}:{APP_BACKEND_PORT}/api/auth/gitlab/handler/frame` for non-local deployments.
|
|
63
63
|
1. Select the following scopes from the list:
|
|
64
64
|
- [x] `read_user` Grants read-only access to the authenticated user's profile through the /user API endpoint, which includes username, public email, and full name. Also grants access to read-only API endpoints under /users.
|
|
@@ -91,9 +91,9 @@ export AUTH_GITLAB_CLIENT_SECRET=x
|
|
|
91
91
|
|
|
92
92
|
Add a new Okta application using the following URI conventions:
|
|
93
93
|
|
|
94
|
-
Login redirect URI's: `http://localhost:
|
|
95
|
-
Logout redirect URI's: `http://localhost:
|
|
96
|
-
Initiate login URI's: `http://localhost:
|
|
94
|
+
Login redirect URI's: `http://localhost:7007/api/auth/okta/handler/frame`
|
|
95
|
+
Logout redirect URI's: `http://localhost:7007/api/auth/okta/logout`
|
|
96
|
+
Initiate login URI's: `http://localhost:7007/api/auth/okta/start`
|
|
97
97
|
|
|
98
98
|
Then configure the following environment variables to be used in the `app-config.yaml` file:
|
|
99
99
|
|
|
@@ -122,7 +122,7 @@ Click [here](https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMe
|
|
|
122
122
|
- Give the app a name. e.g. `backstage-dev`
|
|
123
123
|
- Select `Accounts in this organizational directory only` under supported account types.
|
|
124
124
|
- Enter the callback URL for your backstage backend instance:
|
|
125
|
-
- For local development, this is likely `http://localhost:
|
|
125
|
+
- For local development, this is likely `http://localhost:7007/api/auth/microsoft/handler/frame`
|
|
126
126
|
- For non-local deployments, this will be `https://{APP_FQDN}:{APP_BACKEND_PORT}/auth/microsoft/handler/frame`
|
|
127
127
|
- Click `Register`.
|
|
128
128
|
|
package/config.d.ts
CHANGED
package/dist/index.cjs.js
CHANGED
|
@@ -30,6 +30,7 @@ var uuid = require('uuid');
|
|
|
30
30
|
var luxon = require('luxon');
|
|
31
31
|
var backendCommon = require('@backstage/backend-common');
|
|
32
32
|
var firestore = require('@google-cloud/firestore');
|
|
33
|
+
var lodash = require('lodash');
|
|
33
34
|
var session = require('express-session');
|
|
34
35
|
var passport = require('passport');
|
|
35
36
|
var minimatch = require('minimatch');
|
|
@@ -226,22 +227,22 @@ class OAuthEnvironmentHandler {
|
|
|
226
227
|
return new OAuthEnvironmentHandler(handlers);
|
|
227
228
|
}
|
|
228
229
|
async start(req, res) {
|
|
229
|
-
const provider = this.getProviderForEnv(req
|
|
230
|
-
await
|
|
230
|
+
const provider = this.getProviderForEnv(req);
|
|
231
|
+
await provider.start(req, res);
|
|
231
232
|
}
|
|
232
233
|
async frameHandler(req, res) {
|
|
233
|
-
const provider = this.getProviderForEnv(req
|
|
234
|
-
await
|
|
234
|
+
const provider = this.getProviderForEnv(req);
|
|
235
|
+
await provider.frameHandler(req, res);
|
|
235
236
|
}
|
|
236
237
|
async refresh(req, res) {
|
|
237
238
|
var _a;
|
|
238
|
-
const provider = this.getProviderForEnv(req
|
|
239
|
-
await ((_a = provider
|
|
239
|
+
const provider = this.getProviderForEnv(req);
|
|
240
|
+
await ((_a = provider.refresh) == null ? void 0 : _a.call(provider, req, res));
|
|
240
241
|
}
|
|
241
242
|
async logout(req, res) {
|
|
242
243
|
var _a;
|
|
243
|
-
const provider = this.getProviderForEnv(req
|
|
244
|
-
await ((_a = provider
|
|
244
|
+
const provider = this.getProviderForEnv(req);
|
|
245
|
+
await ((_a = provider.logout) == null ? void 0 : _a.call(provider, req, res));
|
|
245
246
|
}
|
|
246
247
|
getRequestFromEnv(req) {
|
|
247
248
|
var _a, _b;
|
|
@@ -256,19 +257,16 @@ class OAuthEnvironmentHandler {
|
|
|
256
257
|
const env = readState(stateParams).env;
|
|
257
258
|
return env;
|
|
258
259
|
}
|
|
259
|
-
getProviderForEnv(req
|
|
260
|
+
getProviderForEnv(req) {
|
|
260
261
|
const env = this.getRequestFromEnv(req);
|
|
261
262
|
if (!env) {
|
|
262
263
|
throw new errors.InputError(`Must specify 'env' query to select environment`);
|
|
263
264
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
<br>
|
|
268
|
-
For this flow to work you need to supply a valid configuration for the "${env}" environment of provider.`);
|
|
269
|
-
return void 0;
|
|
265
|
+
const handler = this.handlers.get(env);
|
|
266
|
+
if (!handler) {
|
|
267
|
+
throw new errors.NotFoundError(`No configuration available for the '${env}' environment of this provider.`);
|
|
270
268
|
}
|
|
271
|
-
return
|
|
269
|
+
return handler;
|
|
272
270
|
}
|
|
273
271
|
}
|
|
274
272
|
|
|
@@ -427,26 +425,23 @@ class OAuthAdapter {
|
|
|
427
425
|
}
|
|
428
426
|
async logout(req, res) {
|
|
429
427
|
if (!ensuresXRequestedWith(req)) {
|
|
430
|
-
|
|
431
|
-
return;
|
|
428
|
+
throw new errors.AuthenticationError("Invalid X-Requested-With header");
|
|
432
429
|
}
|
|
433
430
|
this.removeRefreshTokenCookie(res);
|
|
434
|
-
res.status(200).
|
|
431
|
+
res.status(200).end();
|
|
435
432
|
}
|
|
436
433
|
async refresh(req, res) {
|
|
437
434
|
var _a, _b;
|
|
438
435
|
if (!ensuresXRequestedWith(req)) {
|
|
439
|
-
|
|
440
|
-
return;
|
|
436
|
+
throw new errors.AuthenticationError("Invalid X-Requested-With header");
|
|
441
437
|
}
|
|
442
438
|
if (!this.handlers.refresh || this.options.disableRefresh) {
|
|
443
|
-
|
|
444
|
-
return;
|
|
439
|
+
throw new errors.InputError(`Refresh token is not supported for provider ${this.options.providerId}`);
|
|
445
440
|
}
|
|
446
441
|
try {
|
|
447
442
|
const refreshToken = req.cookies[`${this.options.providerId}-refresh-token`];
|
|
448
443
|
if (!refreshToken) {
|
|
449
|
-
throw new
|
|
444
|
+
throw new errors.InputError("Missing session cookie");
|
|
450
445
|
}
|
|
451
446
|
const scope = (_b = (_a = req.query.scope) == null ? void 0 : _a.toString()) != null ? _b : "";
|
|
452
447
|
const forwardReq = Object.assign(req, {scope, refreshToken});
|
|
@@ -457,17 +452,19 @@ class OAuthAdapter {
|
|
|
457
452
|
}
|
|
458
453
|
res.status(200).json(response);
|
|
459
454
|
} catch (error) {
|
|
460
|
-
|
|
455
|
+
throw new errors.AuthenticationError("Refresh failed", error);
|
|
461
456
|
}
|
|
462
457
|
}
|
|
463
458
|
async populateIdentity(identity) {
|
|
464
459
|
if (!identity) {
|
|
465
460
|
return;
|
|
466
461
|
}
|
|
467
|
-
if (!identity.idToken) {
|
|
468
|
-
identity.
|
|
462
|
+
if (!(identity.token || identity.idToken)) {
|
|
463
|
+
identity.token = await this.options.tokenIssuer.issueToken({
|
|
469
464
|
claims: {sub: identity.id}
|
|
470
465
|
});
|
|
466
|
+
} else if (!identity.token && identity.idToken) {
|
|
467
|
+
identity.token = identity.idToken;
|
|
471
468
|
}
|
|
472
469
|
}
|
|
473
470
|
}
|
|
@@ -550,6 +547,7 @@ class GithubAuthProvider {
|
|
|
550
547
|
constructor(options) {
|
|
551
548
|
this.signInResolver = options.signInResolver;
|
|
552
549
|
this.authHandler = options.authHandler;
|
|
550
|
+
this.stateEncoder = options.stateEncoder;
|
|
553
551
|
this.tokenIssuer = options.tokenIssuer;
|
|
554
552
|
this.catalogIdentityClient = options.catalogIdentityClient;
|
|
555
553
|
this.logger = options.logger;
|
|
@@ -567,7 +565,7 @@ class GithubAuthProvider {
|
|
|
567
565
|
async start(req) {
|
|
568
566
|
return await executeRedirectStrategy(req, this._strategy, {
|
|
569
567
|
scope: req.scope,
|
|
570
|
-
state:
|
|
568
|
+
state: (await this.stateEncoder(req)).encodedState
|
|
571
569
|
});
|
|
572
570
|
}
|
|
573
571
|
async handler(req) {
|
|
@@ -633,7 +631,7 @@ const createGithubProvider = (options) => {
|
|
|
633
631
|
catalogApi,
|
|
634
632
|
logger
|
|
635
633
|
}) => OAuthEnvironmentHandler.mapConfig(config, (envConfig) => {
|
|
636
|
-
var _a, _b;
|
|
634
|
+
var _a, _b, _c;
|
|
637
635
|
const clientId = envConfig.getString("clientId");
|
|
638
636
|
const clientSecret = envConfig.getString("clientSecret");
|
|
639
637
|
const enterpriseInstanceUrl = envConfig.getOptionalString("enterpriseInstanceUrl");
|
|
@@ -655,6 +653,9 @@ const createGithubProvider = (options) => {
|
|
|
655
653
|
tokenIssuer,
|
|
656
654
|
logger
|
|
657
655
|
});
|
|
656
|
+
const stateEncoder = (_c = options == null ? void 0 : options.stateEncoder) != null ? _c : async (req) => {
|
|
657
|
+
return {encodedState: encodeState(req.state)};
|
|
658
|
+
};
|
|
658
659
|
const provider = new GithubAuthProvider({
|
|
659
660
|
clientId,
|
|
660
661
|
clientSecret,
|
|
@@ -666,6 +667,7 @@ const createGithubProvider = (options) => {
|
|
|
666
667
|
authHandler,
|
|
667
668
|
tokenIssuer,
|
|
668
669
|
catalogIdentityClient,
|
|
670
|
+
stateEncoder,
|
|
669
671
|
logger
|
|
670
672
|
});
|
|
671
673
|
return OAuthAdapter.fromConfig(globalConfig, provider, {
|
|
@@ -2028,6 +2030,7 @@ const createSamlProvider = (_options) => {
|
|
|
2028
2030
|
callbackUrl: `${globalConfig.baseUrl}/${providerId}/handler/frame`,
|
|
2029
2031
|
entryPoint: config.getString("entryPoint"),
|
|
2030
2032
|
logoutUrl: config.getOptionalString("logoutUrl"),
|
|
2033
|
+
audience: config.getOptionalString("audience"),
|
|
2031
2034
|
issuer: config.getString("issuer"),
|
|
2032
2035
|
cert: config.getString("cert"),
|
|
2033
2036
|
privateCert: config.getOptionalString("privateKey"),
|
|
@@ -2560,7 +2563,7 @@ class KeyStores {
|
|
|
2560
2563
|
}
|
|
2561
2564
|
if (provider === "firestore") {
|
|
2562
2565
|
const settings = ks == null ? void 0 : ks.getConfig(provider);
|
|
2563
|
-
const keyStore = await FirestoreKeyStore.create({
|
|
2566
|
+
const keyStore = await FirestoreKeyStore.create(lodash.pickBy({
|
|
2564
2567
|
projectId: settings == null ? void 0 : settings.getOptionalString("projectId"),
|
|
2565
2568
|
keyFilename: settings == null ? void 0 : settings.getOptionalString("keyFilename"),
|
|
2566
2569
|
host: settings == null ? void 0 : settings.getOptionalString("host"),
|
|
@@ -2568,7 +2571,7 @@ class KeyStores {
|
|
|
2568
2571
|
ssl: settings == null ? void 0 : settings.getOptionalBoolean("ssl"),
|
|
2569
2572
|
path: settings == null ? void 0 : settings.getOptionalString("path"),
|
|
2570
2573
|
timeout: settings == null ? void 0 : settings.getOptionalNumber("timeout")
|
|
2571
|
-
});
|
|
2574
|
+
}, (value) => value !== void 0));
|
|
2572
2575
|
await FirestoreKeyStore.verifyConnection(keyStore, logger);
|
|
2573
2576
|
return keyStore;
|
|
2574
2577
|
}
|