@backstage/plugin-auth-backend 0.22.6-next.3 → 0.22.7
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 +68 -0
- package/dist/index.cjs.js +49 -16
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/migrations/20240510120825_user_info.js +49 -0
- package/package.json +23 -23
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,73 @@
|
|
|
1
1
|
# @backstage/plugin-auth-backend
|
|
2
2
|
|
|
3
|
+
## 0.22.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @backstage/backend-common@0.23.1
|
|
9
|
+
- @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.12
|
|
10
|
+
- @backstage/plugin-auth-backend-module-oidc-provider@0.2.1
|
|
11
|
+
- @backstage/plugin-auth-node@0.4.15
|
|
12
|
+
- @backstage/plugin-auth-backend-module-atlassian-provider@0.2.1
|
|
13
|
+
- @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.3
|
|
14
|
+
- @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.3
|
|
15
|
+
- @backstage/plugin-auth-backend-module-github-provider@0.1.17
|
|
16
|
+
- @backstage/plugin-auth-backend-module-gitlab-provider@0.1.17
|
|
17
|
+
- @backstage/plugin-auth-backend-module-microsoft-provider@0.1.15
|
|
18
|
+
- @backstage/plugin-auth-backend-module-oauth2-provider@0.2.1
|
|
19
|
+
- @backstage/plugin-auth-backend-module-okta-provider@0.0.13
|
|
20
|
+
- @backstage/plugin-auth-backend-module-onelogin-provider@0.1.1
|
|
21
|
+
- @backstage/backend-plugin-api@0.6.20
|
|
22
|
+
- @backstage/catalog-client@1.6.5
|
|
23
|
+
- @backstage/catalog-model@1.5.0
|
|
24
|
+
- @backstage/config@1.2.0
|
|
25
|
+
- @backstage/errors@1.2.4
|
|
26
|
+
- @backstage/types@1.1.1
|
|
27
|
+
- @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.3
|
|
28
|
+
- @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.15
|
|
29
|
+
- @backstage/plugin-auth-backend-module-google-provider@0.1.17
|
|
30
|
+
- @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.13
|
|
31
|
+
- @backstage/plugin-catalog-node@1.12.2
|
|
32
|
+
|
|
33
|
+
## 0.22.6
|
|
34
|
+
|
|
35
|
+
### Patch Changes
|
|
36
|
+
|
|
37
|
+
- 3e823d3: Limited user tokens will no longer include the `ent` field in its payload. Ownership claims will now be fetched from the user info service.
|
|
38
|
+
|
|
39
|
+
NOTE: Limited tokens issued prior to this change will no longer be valid. Users may have to clear their browser cookies in order to refresh their auth tokens.
|
|
40
|
+
|
|
41
|
+
- 8869b8e: Updated local development setup.
|
|
42
|
+
- 78a0b08: Internal refactor to handle `BackendFeature` contract change.
|
|
43
|
+
- d44a20a: Added additional plugin metadata to `package.json`.
|
|
44
|
+
- 3e1bb15: Updated to use the new `@backstage/plugin-auth-backend-module-onelogin-provider` implementation
|
|
45
|
+
- Updated dependencies
|
|
46
|
+
- @backstage/backend-common@0.23.0
|
|
47
|
+
- @backstage/plugin-auth-backend-module-onelogin-provider@0.1.0
|
|
48
|
+
- @backstage/backend-plugin-api@0.6.19
|
|
49
|
+
- @backstage/plugin-auth-node@0.4.14
|
|
50
|
+
- @backstage/plugin-auth-backend-module-cloudflare-access-provider@0.1.2
|
|
51
|
+
- @backstage/plugin-auth-backend-module-azure-easyauth-provider@0.1.2
|
|
52
|
+
- @backstage/plugin-auth-backend-module-oauth2-proxy-provider@0.1.12
|
|
53
|
+
- @backstage/plugin-auth-backend-module-atlassian-provider@0.2.0
|
|
54
|
+
- @backstage/plugin-auth-backend-module-bitbucket-provider@0.1.2
|
|
55
|
+
- @backstage/plugin-auth-backend-module-microsoft-provider@0.1.14
|
|
56
|
+
- @backstage/plugin-auth-backend-module-aws-alb-provider@0.1.11
|
|
57
|
+
- @backstage/plugin-auth-backend-module-gcp-iap-provider@0.2.14
|
|
58
|
+
- @backstage/plugin-auth-backend-module-github-provider@0.1.16
|
|
59
|
+
- @backstage/plugin-auth-backend-module-gitlab-provider@0.1.16
|
|
60
|
+
- @backstage/plugin-auth-backend-module-google-provider@0.1.16
|
|
61
|
+
- @backstage/plugin-auth-backend-module-oauth2-provider@0.2.0
|
|
62
|
+
- @backstage/plugin-auth-backend-module-oidc-provider@0.2.0
|
|
63
|
+
- @backstage/plugin-auth-backend-module-okta-provider@0.0.12
|
|
64
|
+
- @backstage/plugin-catalog-node@1.12.1
|
|
65
|
+
- @backstage/catalog-client@1.6.5
|
|
66
|
+
- @backstage/catalog-model@1.5.0
|
|
67
|
+
- @backstage/config@1.2.0
|
|
68
|
+
- @backstage/errors@1.2.4
|
|
69
|
+
- @backstage/types@1.1.1
|
|
70
|
+
|
|
3
71
|
## 0.22.6-next.3
|
|
4
72
|
|
|
5
73
|
### Patch Changes
|
package/dist/index.cjs.js
CHANGED
|
@@ -35,10 +35,10 @@ var catalogClient = require('@backstage/catalog-client');
|
|
|
35
35
|
var minimatch = require('minimatch');
|
|
36
36
|
var catalogModel = require('@backstage/catalog-model');
|
|
37
37
|
var backendCommon = require('@backstage/backend-common');
|
|
38
|
+
var lodash = require('lodash');
|
|
38
39
|
var luxon = require('luxon');
|
|
39
40
|
var uuid = require('uuid');
|
|
40
41
|
var firestore = require('@google-cloud/firestore');
|
|
41
|
-
var lodash = require('lodash');
|
|
42
42
|
var fs = require('fs');
|
|
43
43
|
var session = require('express-session');
|
|
44
44
|
var connectSessionKnex = require('connect-session-knex');
|
|
@@ -1579,7 +1579,7 @@ function createOriginFilter(config) {
|
|
|
1579
1579
|
}
|
|
1580
1580
|
|
|
1581
1581
|
function bindOidcRouter(targetRouter, options) {
|
|
1582
|
-
const { baseUrl, auth, tokenIssuer } = options;
|
|
1582
|
+
const { baseUrl, auth, tokenIssuer, userInfoDatabaseHandler } = options;
|
|
1583
1583
|
const router = Router__default.default();
|
|
1584
1584
|
targetRouter.use(router);
|
|
1585
1585
|
const config = {
|
|
@@ -1630,16 +1630,16 @@ function bindOidcRouter(targetRouter, options) {
|
|
|
1630
1630
|
"Userinfo endpoint must be called with a token that represents a user principal"
|
|
1631
1631
|
);
|
|
1632
1632
|
}
|
|
1633
|
-
const { sub: userEntityRef
|
|
1633
|
+
const { sub: userEntityRef } = jose.decodeJwt(token);
|
|
1634
1634
|
if (typeof userEntityRef !== "string") {
|
|
1635
1635
|
throw new Error("Invalid user token, user entity ref must be a string");
|
|
1636
1636
|
}
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1637
|
+
const userInfo = await userInfoDatabaseHandler.getUserInfo(userEntityRef);
|
|
1638
|
+
if (!userInfo) {
|
|
1639
|
+
res.status(404).send("User info not found");
|
|
1640
|
+
return;
|
|
1641
1641
|
}
|
|
1642
|
-
res.json(
|
|
1642
|
+
res.json(userInfo);
|
|
1643
1643
|
});
|
|
1644
1644
|
}
|
|
1645
1645
|
|
|
@@ -1651,6 +1651,7 @@ class TokenFactory {
|
|
|
1651
1651
|
keyStore;
|
|
1652
1652
|
keyDurationSeconds;
|
|
1653
1653
|
algorithm;
|
|
1654
|
+
userInfoDatabaseHandler;
|
|
1654
1655
|
keyExpiry;
|
|
1655
1656
|
privateKeyPromise;
|
|
1656
1657
|
constructor(options) {
|
|
@@ -1659,6 +1660,7 @@ class TokenFactory {
|
|
|
1659
1660
|
this.keyStore = options.keyStore;
|
|
1660
1661
|
this.keyDurationSeconds = options.keyDurationSeconds;
|
|
1661
1662
|
this.algorithm = options.algorithm ?? "ES256";
|
|
1663
|
+
this.userInfoDatabaseHandler = options.userInfoDatabaseHandler;
|
|
1662
1664
|
}
|
|
1663
1665
|
async issueToken(params) {
|
|
1664
1666
|
const key = await this.getKey();
|
|
@@ -1685,7 +1687,7 @@ class TokenFactory {
|
|
|
1685
1687
|
alg: key.alg,
|
|
1686
1688
|
kid: key.kid
|
|
1687
1689
|
},
|
|
1688
|
-
payload: { sub,
|
|
1690
|
+
payload: { sub, iat, exp },
|
|
1689
1691
|
key: signingKey
|
|
1690
1692
|
});
|
|
1691
1693
|
const claims = {
|
|
@@ -1710,6 +1712,9 @@ class TokenFactory {
|
|
|
1710
1712
|
)}'`
|
|
1711
1713
|
);
|
|
1712
1714
|
}
|
|
1715
|
+
await this.userInfoDatabaseHandler.addUserInfo({
|
|
1716
|
+
claims: lodash.omit(claims, ["aud", "iat", "iss", "uip"])
|
|
1717
|
+
});
|
|
1713
1718
|
return token;
|
|
1714
1719
|
}
|
|
1715
1720
|
// This will be called by other services that want to verify ID tokens.
|
|
@@ -1780,7 +1785,6 @@ class TokenFactory {
|
|
|
1780
1785
|
};
|
|
1781
1786
|
const payload = {
|
|
1782
1787
|
sub: options.payload.sub,
|
|
1783
|
-
ent: options.payload.ent,
|
|
1784
1788
|
iat: options.payload.iat,
|
|
1785
1789
|
exp: options.payload.exp
|
|
1786
1790
|
};
|
|
@@ -1791,7 +1795,7 @@ class TokenFactory {
|
|
|
1791
1795
|
}
|
|
1792
1796
|
}
|
|
1793
1797
|
|
|
1794
|
-
const TABLE = "signing_keys";
|
|
1798
|
+
const TABLE$1 = "signing_keys";
|
|
1795
1799
|
const parseDate = (date) => {
|
|
1796
1800
|
const parsedDate = typeof date === "string" ? luxon.DateTime.fromSQL(date, { zone: "UTC" }) : luxon.DateTime.fromJSDate(date);
|
|
1797
1801
|
if (!parsedDate.isValid) {
|
|
@@ -1806,13 +1810,13 @@ class DatabaseKeyStore {
|
|
|
1806
1810
|
this.client = client;
|
|
1807
1811
|
}
|
|
1808
1812
|
async addKey(key) {
|
|
1809
|
-
await this.client(TABLE).insert({
|
|
1813
|
+
await this.client(TABLE$1).insert({
|
|
1810
1814
|
kid: key.kid,
|
|
1811
1815
|
key: JSON.stringify(key)
|
|
1812
1816
|
});
|
|
1813
1817
|
}
|
|
1814
1818
|
async listKeys() {
|
|
1815
|
-
const rows = await this.client(TABLE).select();
|
|
1819
|
+
const rows = await this.client(TABLE$1).select();
|
|
1816
1820
|
return {
|
|
1817
1821
|
items: rows.map((row) => ({
|
|
1818
1822
|
key: JSON.parse(row.key),
|
|
@@ -1821,7 +1825,7 @@ class DatabaseKeyStore {
|
|
|
1821
1825
|
};
|
|
1822
1826
|
}
|
|
1823
1827
|
async removeKeys(kids) {
|
|
1824
|
-
await this.client(TABLE).delete().whereIn("kid", kids);
|
|
1828
|
+
await this.client(TABLE$1).delete().whereIn("kid", kids);
|
|
1825
1829
|
}
|
|
1826
1830
|
}
|
|
1827
1831
|
|
|
@@ -2058,6 +2062,30 @@ class KeyStores {
|
|
|
2058
2062
|
}
|
|
2059
2063
|
}
|
|
2060
2064
|
|
|
2065
|
+
const TABLE = "user_info";
|
|
2066
|
+
class UserInfoDatabaseHandler {
|
|
2067
|
+
constructor(client) {
|
|
2068
|
+
this.client = client;
|
|
2069
|
+
}
|
|
2070
|
+
async addUserInfo(userInfo) {
|
|
2071
|
+
await this.client(TABLE).insert({
|
|
2072
|
+
user_entity_ref: userInfo.claims.sub,
|
|
2073
|
+
user_info: JSON.stringify(userInfo),
|
|
2074
|
+
exp: luxon.DateTime.fromSeconds(userInfo.claims.exp, {
|
|
2075
|
+
zone: "utc"
|
|
2076
|
+
}).toSQL({ includeOffset: false })
|
|
2077
|
+
}).onConflict("user_entity_ref").merge();
|
|
2078
|
+
}
|
|
2079
|
+
async getUserInfo(userEntityRef) {
|
|
2080
|
+
const info = await this.client(TABLE).where({ user_entity_ref: userEntityRef }).first();
|
|
2081
|
+
if (!info) {
|
|
2082
|
+
return void 0;
|
|
2083
|
+
}
|
|
2084
|
+
const userInfo = JSON.parse(info.user_info);
|
|
2085
|
+
return userInfo;
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
|
|
2061
2089
|
const migrationsDir = backendPluginApi.resolvePackagePath(
|
|
2062
2090
|
"@backstage/plugin-auth-backend",
|
|
2063
2091
|
"migrations"
|
|
@@ -2185,6 +2213,9 @@ async function createRouter(options) {
|
|
|
2185
2213
|
logger,
|
|
2186
2214
|
database: authDb
|
|
2187
2215
|
});
|
|
2216
|
+
const userInfoDatabaseHandler = new UserInfoDatabaseHandler(
|
|
2217
|
+
await authDb.get()
|
|
2218
|
+
);
|
|
2188
2219
|
let tokenIssuer;
|
|
2189
2220
|
if (keyStore instanceof StaticKeyStore) {
|
|
2190
2221
|
tokenIssuer = new StaticTokenIssuer(
|
|
@@ -2201,7 +2232,8 @@ async function createRouter(options) {
|
|
|
2201
2232
|
keyStore,
|
|
2202
2233
|
keyDurationSeconds: backstageTokenExpiration,
|
|
2203
2234
|
logger: logger.child({ component: "token-factory" }),
|
|
2204
|
-
algorithm: tokenFactoryAlgorithm ?? config.getOptionalString("auth.identityTokenAlgorithm")
|
|
2235
|
+
algorithm: tokenFactoryAlgorithm ?? config.getOptionalString("auth.identityTokenAlgorithm"),
|
|
2236
|
+
userInfoDatabaseHandler
|
|
2205
2237
|
});
|
|
2206
2238
|
}
|
|
2207
2239
|
const secret = config.getOptionalString("auth.session.secret");
|
|
@@ -2244,7 +2276,8 @@ async function createRouter(options) {
|
|
|
2244
2276
|
bindOidcRouter(router, {
|
|
2245
2277
|
auth,
|
|
2246
2278
|
tokenIssuer,
|
|
2247
|
-
baseUrl: authUrl
|
|
2279
|
+
baseUrl: authUrl,
|
|
2280
|
+
userInfoDatabaseHandler
|
|
2248
2281
|
});
|
|
2249
2282
|
router.use("/:provider/", (req) => {
|
|
2250
2283
|
const { provider } = req.params;
|