@backstage/plugin-auth-backend 0.28.0-next.0 → 0.28.0-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,27 @@
1
1
  # @backstage/plugin-auth-backend
2
2
 
3
+ ## 0.28.0-next.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 482ceed: Migrated from `assertError` to `toError` for error handling.
8
+ - Updated dependencies
9
+ - @backstage/errors@1.3.0-next.0
10
+ - @backstage/plugin-auth-node@0.7.0-next.2
11
+ - @backstage/plugin-catalog-node@2.2.0-next.2
12
+ - @backstage/backend-plugin-api@1.9.0-next.2
13
+ - @backstage/catalog-model@1.7.8-next.0
14
+ - @backstage/config@1.3.7-next.0
15
+
16
+ ## 0.28.0-next.1
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies
21
+ - @backstage/backend-plugin-api@1.9.0-next.1
22
+ - @backstage/plugin-auth-node@0.7.0-next.1
23
+ - @backstage/plugin-catalog-node@2.1.1-next.1
24
+
3
25
  ## 0.28.0-next.0
4
26
 
5
27
  ### Minor Changes
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var firestore = require('@google-cloud/firestore');
4
+ var errors = require('@backstage/errors');
4
5
 
5
6
  const DEFAULT_TIMEOUT_MS = 1e4;
6
7
  const DEFAULT_DOCUMENT_PATH = "sessions";
@@ -26,14 +27,11 @@ class FirestoreKeyStore {
26
27
  try {
27
28
  await keyStore.verify();
28
29
  } catch (error) {
30
+ const err = errors.toError(error);
29
31
  if (process.env.NODE_ENV !== "development") {
30
- throw new Error(
31
- `Failed to connect to database: ${error.message}`
32
- );
32
+ throw new Error(`Failed to connect to database: ${err.message}`);
33
33
  }
34
- logger?.warn(
35
- `Failed to connect to database: ${error.message}`
36
- );
34
+ logger?.warn(`Failed to connect to database: ${err.message}`);
37
35
  }
38
36
  }
39
37
  async addKey(key) {
@@ -1 +1 @@
1
- {"version":3,"file":"FirestoreKeyStore.cjs.js","sources":["../../src/identity/FirestoreKeyStore.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport {\n DocumentData,\n Firestore,\n QuerySnapshot,\n Settings,\n WriteResult,\n} from '@google-cloud/firestore';\n\nimport { AnyJWK, KeyStore, StoredKey } from './types';\n\nexport type FirestoreKeyStoreSettings = Settings & Options;\n\ntype Options = {\n path?: string;\n timeout?: number;\n};\n\nexport const DEFAULT_TIMEOUT_MS = 10000;\nexport const DEFAULT_DOCUMENT_PATH = 'sessions';\n\nexport class FirestoreKeyStore implements KeyStore {\n static async create(\n settings?: FirestoreKeyStoreSettings,\n ): Promise<FirestoreKeyStore> {\n const { path, timeout, ...firestoreSettings } = settings ?? {};\n const database = new Firestore(firestoreSettings);\n\n return new FirestoreKeyStore(\n database,\n path ?? DEFAULT_DOCUMENT_PATH,\n timeout ?? DEFAULT_TIMEOUT_MS,\n );\n }\n\n private readonly database: Firestore;\n private readonly path: string;\n private readonly timeout: number;\n\n private constructor(database: Firestore, path: string, timeout: number) {\n this.database = database;\n this.path = path;\n this.timeout = timeout;\n }\n\n static async verifyConnection(\n keyStore: FirestoreKeyStore,\n logger?: LoggerService,\n ): Promise<void> {\n try {\n await keyStore.verify();\n } catch (error) {\n if (process.env.NODE_ENV !== 'development') {\n throw new Error(\n `Failed to connect to database: ${(error as Error).message}`,\n );\n }\n logger?.warn(\n `Failed to connect to database: ${(error as Error).message}`,\n );\n }\n }\n\n async addKey(key: AnyJWK): Promise<void> {\n await this.withTimeout<WriteResult>(\n this.database.collection(this.path).doc(key.kid).set({\n kid: key.kid,\n key: key,\n }),\n );\n }\n\n async listKeys(): Promise<{ items: StoredKey[] }> {\n const keys = await this.withTimeout<QuerySnapshot<DocumentData>>(\n this.database.collection(this.path).get(),\n );\n\n return {\n items: keys.docs.map(doc => {\n const { key } = doc.data();\n\n return {\n createdAt: doc.createTime.toDate(),\n key: typeof key === 'string' ? JSON.parse(key) : key,\n };\n }),\n };\n }\n\n async removeKeys(kids: string[]): Promise<void> {\n // This is probably really slow, but it's done async in the background\n for (const kid of kids) {\n await this.withTimeout<WriteResult>(\n this.database.collection(this.path).doc(kid).delete(),\n );\n }\n\n /**\n * This could be achieved with batching but there's a couple of limitations with that:\n *\n * - A batched write can contain a maximum of 500 operations\n * https://firebase.google.com/docs/firestore/manage-data/transactions#batched-writes\n *\n * - The \"in\" operator can combine a maximum of 10 equality clauses\n * https://firebase.google.com/docs/firestore/query-data/queries#in_not-in_and_array-contains-any\n *\n * Example:\n *\n * const batch = this.database.batch();\n * const docs = await this.database\n * .collection(this.path)\n * .where('kid', 'in', kids)\n * .get();\n * docs.forEach(doc => {\n * batch.delete(doc.ref);\n * });\n * await batch.commit();\n *\n */\n }\n\n /**\n * Helper function to allow us to modify the timeout used when\n * performing Firestore database operations.\n *\n * The reason for this is that it seems that there's no other\n * practical solution to change the default timeout of 10mins\n * that Firestore has.\n *\n */\n private async withTimeout<T>(operation: Promise<T>): Promise<T> {\n const timer = new Promise<never>((_, reject) =>\n setTimeout(() => {\n reject(new Error(`Operation timed out after ${this.timeout}ms`));\n }, this.timeout),\n );\n return Promise.race<T>([operation, timer]);\n }\n\n /**\n * Used to verify that the database is reachable.\n */\n private async verify(): Promise<void> {\n await this.withTimeout(this.database.collection(this.path).limit(1).get());\n }\n}\n"],"names":["Firestore"],"mappings":"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"}
1
+ {"version":3,"file":"FirestoreKeyStore.cjs.js","sources":["../../src/identity/FirestoreKeyStore.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport {\n DocumentData,\n Firestore,\n QuerySnapshot,\n Settings,\n WriteResult,\n} from '@google-cloud/firestore';\n\nimport { toError } from '@backstage/errors';\nimport { AnyJWK, KeyStore, StoredKey } from './types';\n\nexport type FirestoreKeyStoreSettings = Settings & Options;\n\ntype Options = {\n path?: string;\n timeout?: number;\n};\n\nexport const DEFAULT_TIMEOUT_MS = 10000;\nexport const DEFAULT_DOCUMENT_PATH = 'sessions';\n\nexport class FirestoreKeyStore implements KeyStore {\n static async create(\n settings?: FirestoreKeyStoreSettings,\n ): Promise<FirestoreKeyStore> {\n const { path, timeout, ...firestoreSettings } = settings ?? {};\n const database = new Firestore(firestoreSettings);\n\n return new FirestoreKeyStore(\n database,\n path ?? DEFAULT_DOCUMENT_PATH,\n timeout ?? DEFAULT_TIMEOUT_MS,\n );\n }\n\n private readonly database: Firestore;\n private readonly path: string;\n private readonly timeout: number;\n\n private constructor(database: Firestore, path: string, timeout: number) {\n this.database = database;\n this.path = path;\n this.timeout = timeout;\n }\n\n static async verifyConnection(\n keyStore: FirestoreKeyStore,\n logger?: LoggerService,\n ): Promise<void> {\n try {\n await keyStore.verify();\n } catch (error) {\n const err = toError(error);\n if (process.env.NODE_ENV !== 'development') {\n throw new Error(`Failed to connect to database: ${err.message}`);\n }\n logger?.warn(`Failed to connect to database: ${err.message}`);\n }\n }\n\n async addKey(key: AnyJWK): Promise<void> {\n await this.withTimeout<WriteResult>(\n this.database.collection(this.path).doc(key.kid).set({\n kid: key.kid,\n key: key,\n }),\n );\n }\n\n async listKeys(): Promise<{ items: StoredKey[] }> {\n const keys = await this.withTimeout<QuerySnapshot<DocumentData>>(\n this.database.collection(this.path).get(),\n );\n\n return {\n items: keys.docs.map(doc => {\n const { key } = doc.data();\n\n return {\n createdAt: doc.createTime.toDate(),\n key: typeof key === 'string' ? JSON.parse(key) : key,\n };\n }),\n };\n }\n\n async removeKeys(kids: string[]): Promise<void> {\n // This is probably really slow, but it's done async in the background\n for (const kid of kids) {\n await this.withTimeout<WriteResult>(\n this.database.collection(this.path).doc(kid).delete(),\n );\n }\n\n /**\n * This could be achieved with batching but there's a couple of limitations with that:\n *\n * - A batched write can contain a maximum of 500 operations\n * https://firebase.google.com/docs/firestore/manage-data/transactions#batched-writes\n *\n * - The \"in\" operator can combine a maximum of 10 equality clauses\n * https://firebase.google.com/docs/firestore/query-data/queries#in_not-in_and_array-contains-any\n *\n * Example:\n *\n * const batch = this.database.batch();\n * const docs = await this.database\n * .collection(this.path)\n * .where('kid', 'in', kids)\n * .get();\n * docs.forEach(doc => {\n * batch.delete(doc.ref);\n * });\n * await batch.commit();\n *\n */\n }\n\n /**\n * Helper function to allow us to modify the timeout used when\n * performing Firestore database operations.\n *\n * The reason for this is that it seems that there's no other\n * practical solution to change the default timeout of 10mins\n * that Firestore has.\n *\n */\n private async withTimeout<T>(operation: Promise<T>): Promise<T> {\n const timer = new Promise<never>((_, reject) =>\n setTimeout(() => {\n reject(new Error(`Operation timed out after ${this.timeout}ms`));\n }, this.timeout),\n );\n return Promise.race<T>([operation, timer]);\n }\n\n /**\n * Used to verify that the database is reachable.\n */\n private async verify(): Promise<void> {\n await this.withTimeout(this.database.collection(this.path).limit(1).get());\n }\n}\n"],"names":["Firestore","toError"],"mappings":"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"}
@@ -62,13 +62,14 @@ function bindProviderRouters(targetRouter, options) {
62
62
  }
63
63
  targetRouter.use(`/${providerId}`, r);
64
64
  } catch (e) {
65
- errors.assertError(e);
66
65
  if (process.env.NODE_ENV !== "development") {
67
66
  throw new Error(
68
- `Failed to initialize ${providerId} auth provider, ${e.message}`
67
+ `Failed to initialize ${providerId} auth provider, ${errors.toError(e).message}`
69
68
  );
70
69
  }
71
- logger.warn(`Skipping ${providerId} auth provider, ${e.message}`);
70
+ logger.warn(
71
+ `Skipping ${providerId} auth provider, ${errors.toError(e).message}`
72
+ );
72
73
  targetRouter.use(`/${providerId}`, () => {
73
74
  throw new errors.NotFoundError(
74
75
  `Auth provider registered for '${providerId}' is misconfigured. This could mean the configs under auth.providers.${providerId} are missing or the environment variables used are not defined. Check the auth backend plugin logs when the backend starts to see more details.`
@@ -1 +1 @@
1
- {"version":3,"file":"router.cjs.js","sources":["../../src/providers/router.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AuthService, LoggerService } from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport { assertError, NotFoundError } from '@backstage/errors';\nimport {\n AuthOwnershipResolver,\n AuthProviderFactory,\n} from '@backstage/plugin-auth-node';\nimport { CatalogService } from '@backstage/plugin-catalog-node';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { Minimatch } from 'minimatch';\nimport { CatalogAuthResolverContext } from '../lib/resolvers/CatalogAuthResolverContext';\nimport { TokenIssuer } from '../identity/types';\nimport { UserInfoDatabase } from '../database/UserInfoDatabase';\n\nexport type ProviderFactories = { [s: string]: AuthProviderFactory };\n\nexport function bindProviderRouters(\n targetRouter: express.Router,\n options: {\n providers: ProviderFactories;\n appUrl: string;\n baseUrl: string;\n config: Config;\n logger: LoggerService;\n auth: AuthService;\n tokenIssuer: TokenIssuer;\n userInfo: UserInfoDatabase;\n ownershipResolver?: AuthOwnershipResolver;\n catalog: CatalogService;\n },\n) {\n const {\n providers,\n appUrl,\n baseUrl,\n config,\n logger,\n auth,\n tokenIssuer,\n catalog,\n ownershipResolver,\n userInfo,\n } = options;\n\n const providersConfig = config.getOptionalConfig('auth.providers');\n\n const isOriginAllowed = createOriginFilter(config);\n\n for (const [providerId, providerFactory] of Object.entries(providers)) {\n if (providersConfig?.has(providerId)) {\n logger.info(`Configuring auth provider: ${providerId}`);\n try {\n const provider = providerFactory({\n providerId,\n appUrl,\n baseUrl,\n isOriginAllowed,\n globalConfig: {\n baseUrl,\n appUrl,\n isOriginAllowed,\n },\n config: providersConfig.getConfig(providerId),\n logger,\n resolverContext: CatalogAuthResolverContext.create({\n logger,\n catalog,\n tokenIssuer,\n auth,\n ownershipResolver,\n userInfo,\n }),\n });\n\n const r = Router();\n\n r.get('/start', provider.start.bind(provider));\n r.get('/handler/frame', provider.frameHandler.bind(provider));\n r.post('/handler/frame', provider.frameHandler.bind(provider));\n if (provider.logout) {\n r.post('/logout', provider.logout.bind(provider));\n }\n if (provider.refresh) {\n r.get('/refresh', provider.refresh.bind(provider));\n r.post('/refresh', provider.refresh.bind(provider));\n }\n\n targetRouter.use(`/${providerId}`, r);\n } catch (e) {\n assertError(e);\n if (process.env.NODE_ENV !== 'development') {\n throw new Error(\n `Failed to initialize ${providerId} auth provider, ${e.message}`,\n );\n }\n\n logger.warn(`Skipping ${providerId} auth provider, ${e.message}`);\n\n targetRouter.use(`/${providerId}`, () => {\n // If the user added the provider under auth.providers but the clientId and clientSecret etc. were not found.\n throw new NotFoundError(\n `Auth provider registered for '${providerId}' is misconfigured. This could mean the configs under ` +\n `auth.providers.${providerId} are missing or the environment variables used are not defined. ` +\n `Check the auth backend plugin logs when the backend starts to see more details.`,\n );\n });\n }\n } else {\n targetRouter.use(`/${providerId}`, () => {\n throw new NotFoundError(\n `No auth provider registered for '${providerId}'`,\n );\n });\n }\n }\n}\n\nexport function createOriginFilter(\n config: Config,\n): (origin: string) => boolean {\n const appUrl = config.getString('app.baseUrl');\n const { origin: appOrigin } = new URL(appUrl);\n\n const allowedOrigins = config.getOptionalStringArray(\n 'auth.experimentalExtraAllowedOrigins',\n );\n\n const allowedOriginPatterns =\n allowedOrigins?.map(\n pattern => new Minimatch(pattern, { nocase: true, noglobstar: true }),\n ) ?? [];\n\n return origin => {\n if (origin === appOrigin) {\n return true;\n }\n return allowedOriginPatterns.some(pattern => pattern.match(origin));\n };\n}\n"],"names":["CatalogAuthResolverContext","Router","assertError","NotFoundError","Minimatch"],"mappings":"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"}
1
+ {"version":3,"file":"router.cjs.js","sources":["../../src/providers/router.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { AuthService, LoggerService } from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport { NotFoundError, toError } from '@backstage/errors';\nimport {\n AuthOwnershipResolver,\n AuthProviderFactory,\n} from '@backstage/plugin-auth-node';\nimport { CatalogService } from '@backstage/plugin-catalog-node';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { Minimatch } from 'minimatch';\nimport { CatalogAuthResolverContext } from '../lib/resolvers/CatalogAuthResolverContext';\nimport { TokenIssuer } from '../identity/types';\nimport { UserInfoDatabase } from '../database/UserInfoDatabase';\n\nexport type ProviderFactories = { [s: string]: AuthProviderFactory };\n\nexport function bindProviderRouters(\n targetRouter: express.Router,\n options: {\n providers: ProviderFactories;\n appUrl: string;\n baseUrl: string;\n config: Config;\n logger: LoggerService;\n auth: AuthService;\n tokenIssuer: TokenIssuer;\n userInfo: UserInfoDatabase;\n ownershipResolver?: AuthOwnershipResolver;\n catalog: CatalogService;\n },\n) {\n const {\n providers,\n appUrl,\n baseUrl,\n config,\n logger,\n auth,\n tokenIssuer,\n catalog,\n ownershipResolver,\n userInfo,\n } = options;\n\n const providersConfig = config.getOptionalConfig('auth.providers');\n\n const isOriginAllowed = createOriginFilter(config);\n\n for (const [providerId, providerFactory] of Object.entries(providers)) {\n if (providersConfig?.has(providerId)) {\n logger.info(`Configuring auth provider: ${providerId}`);\n try {\n const provider = providerFactory({\n providerId,\n appUrl,\n baseUrl,\n isOriginAllowed,\n globalConfig: {\n baseUrl,\n appUrl,\n isOriginAllowed,\n },\n config: providersConfig.getConfig(providerId),\n logger,\n resolverContext: CatalogAuthResolverContext.create({\n logger,\n catalog,\n tokenIssuer,\n auth,\n ownershipResolver,\n userInfo,\n }),\n });\n\n const r = Router();\n\n r.get('/start', provider.start.bind(provider));\n r.get('/handler/frame', provider.frameHandler.bind(provider));\n r.post('/handler/frame', provider.frameHandler.bind(provider));\n if (provider.logout) {\n r.post('/logout', provider.logout.bind(provider));\n }\n if (provider.refresh) {\n r.get('/refresh', provider.refresh.bind(provider));\n r.post('/refresh', provider.refresh.bind(provider));\n }\n\n targetRouter.use(`/${providerId}`, r);\n } catch (e) {\n if (process.env.NODE_ENV !== 'development') {\n throw new Error(\n `Failed to initialize ${providerId} auth provider, ${\n toError(e).message\n }`,\n );\n }\n\n logger.warn(\n `Skipping ${providerId} auth provider, ${toError(e).message}`,\n );\n\n targetRouter.use(`/${providerId}`, () => {\n // If the user added the provider under auth.providers but the clientId and clientSecret etc. were not found.\n throw new NotFoundError(\n `Auth provider registered for '${providerId}' is misconfigured. This could mean the configs under ` +\n `auth.providers.${providerId} are missing or the environment variables used are not defined. ` +\n `Check the auth backend plugin logs when the backend starts to see more details.`,\n );\n });\n }\n } else {\n targetRouter.use(`/${providerId}`, () => {\n throw new NotFoundError(\n `No auth provider registered for '${providerId}'`,\n );\n });\n }\n }\n}\n\nexport function createOriginFilter(\n config: Config,\n): (origin: string) => boolean {\n const appUrl = config.getString('app.baseUrl');\n const { origin: appOrigin } = new URL(appUrl);\n\n const allowedOrigins = config.getOptionalStringArray(\n 'auth.experimentalExtraAllowedOrigins',\n );\n\n const allowedOriginPatterns =\n allowedOrigins?.map(\n pattern => new Minimatch(pattern, { nocase: true, noglobstar: true }),\n ) ?? [];\n\n return origin => {\n if (origin === appOrigin) {\n return true;\n }\n return allowedOriginPatterns.some(pattern => pattern.match(origin));\n };\n}\n"],"names":["CatalogAuthResolverContext","Router","toError","NotFoundError","Minimatch"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-auth-backend",
3
- "version": "0.28.0-next.0",
3
+ "version": "0.28.0-next.2",
4
4
  "description": "A Backstage backend plugin that handles authentication",
5
5
  "backstage": {
6
6
  "role": "backend-plugin",
@@ -47,12 +47,12 @@
47
47
  "test": "backstage-cli package test"
48
48
  },
49
49
  "dependencies": {
50
- "@backstage/backend-plugin-api": "1.8.1-next.0",
51
- "@backstage/catalog-model": "1.7.7",
52
- "@backstage/config": "1.3.6",
53
- "@backstage/errors": "1.2.7",
54
- "@backstage/plugin-auth-node": "0.6.15-next.0",
55
- "@backstage/plugin-catalog-node": "2.1.1-next.0",
50
+ "@backstage/backend-plugin-api": "1.9.0-next.2",
51
+ "@backstage/catalog-model": "1.7.8-next.0",
52
+ "@backstage/config": "1.3.7-next.0",
53
+ "@backstage/errors": "1.3.0-next.0",
54
+ "@backstage/plugin-auth-node": "0.7.0-next.2",
55
+ "@backstage/plugin-catalog-node": "2.2.0-next.2",
56
56
  "@backstage/types": "1.2.2",
57
57
  "@google-cloud/firestore": "^7.0.0",
58
58
  "connect-session-knex": "^4.0.0",
@@ -73,11 +73,11 @@
73
73
  "zod-validation-error": "^5.0.0"
74
74
  },
75
75
  "devDependencies": {
76
- "@backstage/backend-defaults": "0.16.1-next.0",
77
- "@backstage/backend-test-utils": "1.11.2-next.0",
78
- "@backstage/cli": "0.36.1-next.0",
79
- "@backstage/plugin-auth-backend-module-google-provider": "0.3.14-next.0",
80
- "@backstage/plugin-auth-backend-module-guest-provider": "0.2.18-next.0",
76
+ "@backstage/backend-defaults": "0.16.1-next.2",
77
+ "@backstage/backend-test-utils": "1.11.2-next.2",
78
+ "@backstage/cli": "0.36.1-next.2",
79
+ "@backstage/plugin-auth-backend-module-google-provider": "0.3.14-next.1",
80
+ "@backstage/plugin-auth-backend-module-guest-provider": "0.2.18-next.2",
81
81
  "@types/cookie-parser": "^1.4.2",
82
82
  "@types/express": "^4.17.6",
83
83
  "@types/express-session": "^1.17.2",