@backstage/plugin-auth-backend 0.17.3-next.0 → 0.17.3-next.2

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 CHANGED
@@ -1,5 +1,31 @@
1
1
  # @backstage/plugin-auth-backend
2
2
 
3
+ ## 0.17.3-next.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ - @backstage/backend-common@0.18.0-next.1
9
+ - @backstage/catalog-client@1.3.0-next.2
10
+ - @backstage/plugin-auth-node@0.2.9-next.1
11
+ - @backstage/catalog-model@1.1.5-next.1
12
+ - @backstage/config@1.0.6-next.0
13
+ - @backstage/errors@1.1.4
14
+ - @backstage/types@1.0.2
15
+
16
+ ## 0.17.3-next.1
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies
21
+ - @backstage/backend-common@0.18.0-next.0
22
+ - @backstage/config@1.0.6-next.0
23
+ - @backstage/catalog-client@1.3.0-next.1
24
+ - @backstage/catalog-model@1.1.5-next.1
25
+ - @backstage/errors@1.1.4
26
+ - @backstage/types@1.0.2
27
+ - @backstage/plugin-auth-node@0.2.9-next.0
28
+
3
29
  ## 0.17.3-next.0
4
30
 
5
31
  ### Patch Changes
package/dist/index.cjs.js CHANGED
@@ -464,6 +464,10 @@ class OAuthAdapter {
464
464
  throw new errors.AuthenticationError("Refresh failed", error);
465
465
  }
466
466
  }
467
+ /**
468
+ * If the response from the OAuth provider includes a Backstage identity, we
469
+ * make sure it's populated with all the information we can derive from the user ID.
470
+ */
467
471
  async populateIdentity(identity) {
468
472
  if (!identity) {
469
473
  return void 0;
@@ -743,6 +747,14 @@ class Auth0Strategy extends Auth0InternalStrategy__default["default"] {
743
747
 
744
748
  class Auth0AuthProvider {
745
749
  constructor(options) {
750
+ /**
751
+ * Due to passport-auth0 forcing options.state = true,
752
+ * passport-oauth2 requires express-session to be installed
753
+ * so that the 'state' parameter of the oauth2 flow can be stored.
754
+ * This implementation of StateStore matches the NullStore found within
755
+ * passport-oauth2, which is the StateStore implementation used when options.state = false,
756
+ * allowing us to avoid using express-session in order to integrate with auth0.
757
+ */
746
758
  this.store = {
747
759
  store(_req, cb) {
748
760
  cb(null, null);
@@ -763,6 +775,8 @@ class Auth0AuthProvider {
763
775
  clientSecret: options.clientSecret,
764
776
  callbackURL: options.callbackUrl,
765
777
  domain: options.domain,
778
+ // We need passReqToCallback set to false to get params, but there's
779
+ // no matching type signature for that, so instead behold this beauty
766
780
  passReqToCallback: false,
767
781
  store: this.store
768
782
  },
@@ -1126,6 +1140,9 @@ const bitbucket = createAuthProviderIntegration({
1126
1140
  });
1127
1141
  },
1128
1142
  resolvers: {
1143
+ /**
1144
+ * Looks up the user by matching their username to the `bitbucket.org/username` annotation.
1145
+ */
1129
1146
  usernameMatchingUserEntityAnnotation() {
1130
1147
  return async (info, ctx) => {
1131
1148
  const { result } = info;
@@ -1139,6 +1156,9 @@ const bitbucket = createAuthProviderIntegration({
1139
1156
  });
1140
1157
  };
1141
1158
  },
1159
+ /**
1160
+ * Looks up the user by matching their user ID to the `bitbucket.org/user-id` annotation.
1161
+ */
1142
1162
  userIdMatchingUserEntityAnnotation() {
1143
1163
  return async (info, ctx) => {
1144
1164
  const { result } = info;
@@ -1312,6 +1332,9 @@ const cfAccess = createAuthProviderIntegration({
1312
1332
  };
1313
1333
  },
1314
1334
  resolvers: {
1335
+ /**
1336
+ * Looks up the user by matching their email to the entity email.
1337
+ */
1315
1338
  emailMatchingUserEntityProfileEmail: () => commonByEmailResolver
1316
1339
  }
1317
1340
  });
@@ -1562,6 +1585,9 @@ const github = createAuthProviderIntegration({
1562
1585
  });
1563
1586
  },
1564
1587
  resolvers: {
1588
+ /**
1589
+ * Looks up the user by matching their GitHub username to the entity name.
1590
+ */
1565
1591
  usernameMatchingUserEntityName: () => {
1566
1592
  return async (info, ctx) => {
1567
1593
  const { fullProfile } = info.result;
@@ -1805,8 +1831,17 @@ const google = createAuthProviderIntegration({
1805
1831
  });
1806
1832
  },
1807
1833
  resolvers: {
1834
+ /**
1835
+ * Looks up the user by matching their email local part to the entity name.
1836
+ */
1808
1837
  emailLocalPartMatchingUserEntityName: () => commonByEmailLocalPartResolver,
1838
+ /**
1839
+ * Looks up the user by matching their email to the entity email.
1840
+ */
1809
1841
  emailMatchingUserEntityProfileEmail: () => commonByEmailResolver,
1842
+ /**
1843
+ * Looks up the user by matching their email to the `google.com/email` annotation.
1844
+ */
1810
1845
  emailMatchingUserEntityAnnotation() {
1811
1846
  return async (info, ctx) => {
1812
1847
  const { profile } = info;
@@ -1951,8 +1986,17 @@ const microsoft = createAuthProviderIntegration({
1951
1986
  });
1952
1987
  },
1953
1988
  resolvers: {
1989
+ /**
1990
+ * Looks up the user by matching their email local part to the entity name.
1991
+ */
1954
1992
  emailLocalPartMatchingUserEntityName: () => commonByEmailLocalPartResolver,
1993
+ /**
1994
+ * Looks up the user by matching their email to the entity email.
1995
+ */
1955
1996
  emailMatchingUserEntityProfileEmail: () => commonByEmailResolver,
1997
+ /**
1998
+ * Looks up the user by matching their email to the `microsoft.com/email` annotation.
1999
+ */
1956
2000
  emailMatchingUserEntityAnnotation() {
1957
2001
  return async (info, ctx) => {
1958
2002
  const { profile } = info;
@@ -2231,6 +2275,7 @@ class OidcAuthProvider {
2231
2275
  const issuer = await openidClient.Issuer.discover(options.metadataUrl);
2232
2276
  const client = new issuer.Client({
2233
2277
  access_type: "offline",
2278
+ // this option must be passed to provider to receive a refresh token
2234
2279
  client_id: options.clientId,
2235
2280
  client_secret: options.clientSecret,
2236
2281
  redirect_uris: [options.callbackUrl],
@@ -2261,6 +2306,8 @@ class OidcAuthProvider {
2261
2306
  strategy.error = console.error;
2262
2307
  return { strategy, client };
2263
2308
  }
2309
+ // Use this function to grab the user profile info from the token
2310
+ // Then populate the profile with it
2264
2311
  async handleResult(result) {
2265
2312
  const { profile } = await this.authHandler(result, this.resolverContext);
2266
2313
  const response = {
@@ -2327,6 +2374,14 @@ const oidc = createAuthProviderIntegration({
2327
2374
 
2328
2375
  class OktaAuthProvider {
2329
2376
  constructor(options) {
2377
+ /**
2378
+ * Due to passport-okta-oauth forcing options.state = true,
2379
+ * passport-oauth2 requires express-session to be installed
2380
+ * so that the 'state' parameter of the oauth2 flow can be stored.
2381
+ * This implementation of StateStore matches the NullStore found within
2382
+ * passport-oauth2, which is the StateStore implementation used when options.state = false,
2383
+ * allowing us to avoid using express-session in order to integrate with Okta.
2384
+ */
2330
2385
  this.store = {
2331
2386
  store(_req, cb) {
2332
2387
  cb(null, null);
@@ -2458,8 +2513,17 @@ const okta = createAuthProviderIntegration({
2458
2513
  });
2459
2514
  },
2460
2515
  resolvers: {
2516
+ /**
2517
+ * Looks up the user by matching their email local part to the entity name.
2518
+ */
2461
2519
  emailLocalPartMatchingUserEntityName: () => commonByEmailLocalPartResolver,
2520
+ /**
2521
+ * Looks up the user by matching their email to the entity email.
2522
+ */
2462
2523
  emailMatchingUserEntityProfileEmail: () => commonByEmailResolver,
2524
+ /**
2525
+ * Looks up the user by matching their email to the `okta.com/email` annotation.
2526
+ */
2463
2527
  emailMatchingUserEntityAnnotation() {
2464
2528
  return async (info, ctx) => {
2465
2529
  const { profile } = info;
@@ -2674,6 +2738,9 @@ const saml = createAuthProviderIntegration({
2674
2738
  };
2675
2739
  },
2676
2740
  resolvers: {
2741
+ /**
2742
+ * Looks up the user by matching their nameID to the entity name.
2743
+ */
2677
2744
  nameIdMatchingUserEntityName() {
2678
2745
  return async (info, ctx) => {
2679
2746
  const id = info.result.fullProfile.nameID;
@@ -2784,6 +2851,9 @@ class TokenFactory {
2784
2851
  }
2785
2852
  return new jose.SignJWT({ ...additionalClaims, iss, sub, ent, aud, iat, exp }).setProtectedHeader({ alg: key.alg, kid: key.kid }).setIssuer(iss).setAudience(aud).setSubject(sub).setIssuedAt(iat).setExpirationTime(exp).sign(await jose.importJWK(key));
2786
2853
  }
2854
+ // This will be called by other services that want to verify ID tokens.
2855
+ // It is important that it returns a list of all public keys that could
2856
+ // have been used to sign tokens that have not yet expired.
2787
2857
  async listPublicKeys() {
2788
2858
  const { items: keys } = await this.keyStore.listKeys();
2789
2859
  const validKeys = [];
@@ -2971,6 +3041,15 @@ class FirestoreKeyStore {
2971
3041
  );
2972
3042
  }
2973
3043
  }
3044
+ /**
3045
+ * Helper function to allow us to modify the timeout used when
3046
+ * performing Firestore database operations.
3047
+ *
3048
+ * The reason for this is that it seems that there's no other
3049
+ * practical solution to change the default timeout of 10mins
3050
+ * that Firestore has.
3051
+ *
3052
+ */
2974
3053
  async withTimeout(operation) {
2975
3054
  const timer = new Promise(
2976
3055
  (_, reject) => setTimeout(() => {
@@ -2979,12 +3058,21 @@ class FirestoreKeyStore {
2979
3058
  );
2980
3059
  return Promise.race([operation, timer]);
2981
3060
  }
3061
+ /**
3062
+ * Used to verify that the database is reachable.
3063
+ */
2982
3064
  async verify() {
2983
3065
  await this.withTimeout(this.database.collection(this.path).limit(1).get());
2984
3066
  }
2985
3067
  }
2986
3068
 
2987
3069
  class KeyStores {
3070
+ /**
3071
+ * Looks at the `auth.keyStore` section in the application configuration
3072
+ * and returns a KeyStore store. Defaults to `database`
3073
+ *
3074
+ * @returns a KeyStore store
3075
+ */
2988
3076
  static async fromConfig(config, options) {
2989
3077
  var _a;
2990
3078
  const { logger, database } = options != null ? options : {};
@@ -3028,6 +3116,11 @@ class CatalogIdentityClient {
3028
3116
  this.catalogApi = options.catalogApi;
3029
3117
  this.tokenManager = options.tokenManager;
3030
3118
  }
3119
+ /**
3120
+ * Looks up a single user using a query.
3121
+ *
3122
+ * Throws a NotFoundError or ConflictError if 0 or multiple users are found.
3123
+ */
3031
3124
  async findUser(query) {
3032
3125
  const filter = {
3033
3126
  kind: "user"
@@ -3046,6 +3139,13 @@ class CatalogIdentityClient {
3046
3139
  }
3047
3140
  return items[0];
3048
3141
  }
3142
+ /**
3143
+ * Resolve additional entity claims from the catalog, using the passed-in entity names. Designed
3144
+ * to be used within a `signInResolver` where additional entity claims might be provided, but
3145
+ * group membership and transient group membership lean on imported catalog relations.
3146
+ *
3147
+ * Returns a superset of the entity names that can be passed directly to `issueToken` as `ent`.
3148
+ */
3049
3149
  async resolveCatalogMembership(query) {
3050
3150
  const { entityRefs, logger } = query;
3051
3151
  const resolvedEntityRefs = entityRefs.map((ref) => {