@backstage/backend-test-utils 1.6.0-next.1 → 1.6.0

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.
Files changed (50) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/dist/alpha/services/ActionsRegistryServiceMock.cjs.js +26 -0
  3. package/dist/alpha/services/ActionsRegistryServiceMock.cjs.js.map +1 -0
  4. package/dist/alpha/services/ActionsServiceMock.cjs.js +15 -0
  5. package/dist/alpha/services/ActionsServiceMock.cjs.js.map +1 -0
  6. package/dist/alpha/services/MockActionsRegistry.cjs.js +83 -0
  7. package/dist/alpha/services/MockActionsRegistry.cjs.js.map +1 -0
  8. package/dist/alpha/services/simpleMock.cjs.js +28 -0
  9. package/dist/alpha/services/simpleMock.cjs.js.map +1 -0
  10. package/dist/alpha.cjs.js +18 -0
  11. package/dist/alpha.cjs.js.map +1 -0
  12. package/dist/alpha.d.ts +89 -0
  13. package/dist/backend-app-api/src/lib/DependencyGraph.cjs.js +19 -3
  14. package/dist/backend-app-api/src/lib/DependencyGraph.cjs.js.map +1 -1
  15. package/dist/index.cjs.js +6 -6
  16. package/dist/index.d.ts +106 -92
  17. package/dist/services/MockAuthService.cjs.js.map +1 -0
  18. package/dist/services/MockEventsService.cjs.js.map +1 -0
  19. package/dist/services/MockHttpAuthService.cjs.js.map +1 -0
  20. package/dist/services/MockPermissionsService.cjs.js +25 -0
  21. package/dist/services/MockPermissionsService.cjs.js.map +1 -0
  22. package/dist/services/MockRootLoggerService.cjs.js.map +1 -0
  23. package/dist/services/MockUserInfoService.cjs.js.map +1 -0
  24. package/dist/{next/services → services}/mockCredentials.cjs.js +16 -8
  25. package/dist/services/mockCredentials.cjs.js.map +1 -0
  26. package/dist/{next/services → services}/mockServices.cjs.js +32 -58
  27. package/dist/services/mockServices.cjs.js.map +1 -0
  28. package/dist/services/simpleMock.cjs.js +28 -0
  29. package/dist/services/simpleMock.cjs.js.map +1 -0
  30. package/dist/util/errorHandler.cjs.js +2 -5
  31. package/dist/util/errorHandler.cjs.js.map +1 -1
  32. package/dist/{next/wiring → wiring}/ServiceFactoryTester.cjs.js +1 -1
  33. package/dist/wiring/ServiceFactoryTester.cjs.js.map +1 -0
  34. package/dist/{next/wiring → wiring}/TestBackend.cjs.js +9 -1
  35. package/dist/wiring/TestBackend.cjs.js.map +1 -0
  36. package/package.json +23 -12
  37. package/dist/next/services/MockAuthService.cjs.js.map +0 -1
  38. package/dist/next/services/MockEventsService.cjs.js.map +0 -1
  39. package/dist/next/services/MockHttpAuthService.cjs.js.map +0 -1
  40. package/dist/next/services/MockRootLoggerService.cjs.js.map +0 -1
  41. package/dist/next/services/MockUserInfoService.cjs.js.map +0 -1
  42. package/dist/next/services/mockCredentials.cjs.js.map +0 -1
  43. package/dist/next/services/mockServices.cjs.js.map +0 -1
  44. package/dist/next/wiring/ServiceFactoryTester.cjs.js.map +0 -1
  45. package/dist/next/wiring/TestBackend.cjs.js.map +0 -1
  46. /package/dist/{next/services → services}/MockAuthService.cjs.js +0 -0
  47. /package/dist/{next/services → services}/MockEventsService.cjs.js +0 -0
  48. /package/dist/{next/services → services}/MockHttpAuthService.cjs.js +0 -0
  49. /package/dist/{next/services → services}/MockRootLoggerService.cjs.js +0 -0
  50. /package/dist/{next/services → services}/MockUserInfoService.cjs.js +0 -0
package/dist/index.d.ts CHANGED
@@ -1,11 +1,12 @@
1
1
  import Keyv from 'keyv';
2
2
  import { Knex } from 'knex';
3
3
  import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
4
- import { ServiceFactory, ServiceRef, ExtensionPoint, BackendFeature, RootConfigService, LoggerService, AuthService, DiscoveryService, BackstageCredentials, HttpAuthService, BackstageUserInfo, UserInfoService, DatabaseService, BackstageNonePrincipal, BackstageUserPrincipal, BackstagePrincipalAccessRestrictions, BackstageServicePrincipal } from '@backstage/backend-plugin-api';
5
- import { Backend } from '@backstage/backend-app-api';
6
- import { ExtendedHttpServer } from '@backstage/backend-defaults/rootHttpRouter';
4
+ import { ServiceFactory, RootConfigService, LoggerService, AuthService, DiscoveryService, BackstageCredentials, HttpAuthService, BackstageUserInfo, UserInfoService, DatabaseService, PermissionsService, BackstageNonePrincipal, BackstageUserPrincipal, BackstagePrincipalAccessRestrictions, BackstageServicePrincipal, ServiceRef, ExtensionPoint, BackendFeature } from '@backstage/backend-plugin-api';
7
5
  import { EventsService } from '@backstage/plugin-events-node';
6
+ import { AuthorizeResult } from '@backstage/plugin-permission-common';
8
7
  import { JsonObject } from '@backstage/types';
8
+ import { Backend } from '@backstage/backend-app-api';
9
+ import { ExtendedHttpServer } from '@backstage/backend-defaults/rootHttpRouter';
9
10
  import * as express from 'express';
10
11
  import * as qs from 'qs';
11
12
  import * as express_serve_static_core from 'express-serve-static-core';
@@ -315,91 +316,13 @@ interface CreateMockDirectoryOptions {
315
316
  */
316
317
  declare function createMockDirectory(options?: CreateMockDirectoryOptions): MockDirectory;
317
318
 
318
- /**
319
- * Options for {@link ServiceFactoryTester}.
320
- * @public
321
- */
322
- interface ServiceFactoryTesterOptions {
323
- /**
324
- * Additional service factories to make available as dependencies.
325
- *
326
- * @remarks
327
- *
328
- * If a service factory is provided for a service that already has a default
329
- * implementation, the provided factory will override the default.
330
- */
331
- dependencies?: Array<ServiceFactory>;
332
- }
333
- /**
334
- * A utility to help test service factories in isolation.
335
- *
336
- * @public
337
- */
338
- declare class ServiceFactoryTester<TService, TScope extends 'root' | 'plugin', TInstances extends 'singleton' | 'multiton' = 'singleton'> {
339
- #private;
340
- /**
341
- * Creates a new {@link ServiceFactoryTester} used to test the provided subject.
342
- *
343
- * @param subject - The service factory to test.
344
- * @param options - Additional options
345
- * @returns A new tester instance for the provided subject.
346
- */
347
- static from<TService, TScope extends 'root' | 'plugin', TInstances extends 'singleton' | 'multiton' = 'singleton'>(subject: ServiceFactory<TService, TScope, TInstances>, options?: ServiceFactoryTesterOptions): ServiceFactoryTester<TService, TScope, TInstances>;
348
- private constructor();
349
- /**
350
- * Returns the service instance for the subject.
351
- *
352
- * @remarks
353
- *
354
- * If the subject is a plugin scoped service factory a plugin ID
355
- * can be provided to instantiate the service for a specific plugin.
356
- *
357
- * By default the plugin ID 'test' is used.
358
- */
359
- getSubject(...args: 'root' extends TScope ? [] : [pluginId?: string]): Promise<TInstances extends 'multiton' ? TService[] : TService>;
360
- /**
361
- * Return the service instance for any of the provided dependencies or built-in services.
362
- *
363
- * @remarks
364
- *
365
- * A plugin ID can optionally be provided for plugin scoped services, otherwise the plugin ID 'test' is used.
366
- */
367
- getService<TGetService, TGetScope extends 'root' | 'plugin', TGetInstances extends 'singleton' | 'multiton' = 'singleton'>(service: ServiceRef<TGetService, TGetScope, TGetInstances>, ...args: 'root' extends TGetScope ? [] : [pluginId?: string]): Promise<TGetInstances extends 'multiton' ? TGetService[] : TGetService>;
368
- }
369
-
370
- /** @public */
371
- interface TestBackendOptions<TExtensionPoints extends any[]> {
372
- extensionPoints?: readonly [
373
- ...{
374
- [index in keyof TExtensionPoints]: [
375
- ExtensionPoint<TExtensionPoints[index]>,
376
- Partial<TExtensionPoints[index]>
377
- ];
378
- }
379
- ];
380
- features?: Array<BackendFeature | Promise<{
381
- default: BackendFeature;
382
- }>>;
383
- }
384
- /** @public */
385
- interface TestBackend extends Backend {
386
- /**
387
- * Provides access to the underling HTTP server for use with utilities
388
- * such as `supertest`.
389
- *
390
- * If the root http router service has been replaced, this will throw an error.
391
- */
392
- readonly server: ExtendedHttpServer;
393
- }
394
- /** @public */
395
- declare function startTestBackend<TExtensionPoints extends any[]>(options: TestBackendOptions<TExtensionPoints>): Promise<TestBackend>;
396
-
397
319
  /** @public */
398
320
  type ServiceMock<TService> = {
399
321
  factory: ServiceFactory<TService>;
400
322
  } & {
401
323
  [Key in keyof TService]: TService[Key] extends (...args: infer Args) => infer Return ? TService[Key] & jest.MockInstance<Return, Args> : TService[Key];
402
324
  };
325
+
403
326
  /**
404
327
  * Mock implementations of the core services, to be used in tests.
405
328
  *
@@ -582,9 +505,29 @@ declare namespace mockServices {
582
505
  const factory: () => ServiceFactory<LoggerService, "plugin", "singleton">;
583
506
  const mock: (partialImpl?: Partial<LoggerService> | undefined) => ServiceMock<LoggerService>;
584
507
  }
508
+ /**
509
+ * Creates a functional mock implementation of the
510
+ * {@link @backstage/backend-plugin-api#PermissionsService}.
511
+ */
512
+ function permissions(options?: {
513
+ result: AuthorizeResult.ALLOW | AuthorizeResult.DENY;
514
+ }): PermissionsService;
585
515
  namespace permissions {
586
- const factory: () => ServiceFactory<_backstage_backend_plugin_api.PermissionsService, "plugin", "singleton">;
587
- const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.PermissionsService> | undefined) => ServiceMock<_backstage_backend_plugin_api.PermissionsService>;
516
+ /**
517
+ * Creates a mock factory for the
518
+ * {@link @backstage/backend-plugin-api#coreServices.permissions}. Just
519
+ * returns the given `result` if you supply one. Otherwise, it returns the
520
+ * regular default permissions factory.
521
+ */
522
+ const factory: (options?: {
523
+ result: AuthorizeResult.ALLOW | AuthorizeResult.DENY;
524
+ }) => ServiceFactory<PermissionsService, "plugin", "singleton">;
525
+ /**
526
+ * Creates a mock of the
527
+ * {@link @backstage/backend-plugin-api#coreServices.permissions},
528
+ * optionally with some given method implementations.
529
+ */
530
+ const mock: (partialImpl?: Partial<PermissionsService> | undefined) => ServiceMock<PermissionsService>;
588
531
  }
589
532
  namespace permissionsRegistry {
590
533
  const factory: () => ServiceFactory<_backstage_backend_plugin_api.PermissionsRegistryService, "plugin", "singleton">;
@@ -602,14 +545,6 @@ declare namespace mockServices {
602
545
  const factory: () => ServiceFactory<_backstage_backend_plugin_api.UrlReaderService, "plugin", "singleton">;
603
546
  const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.UrlReaderService> | undefined) => ServiceMock<_backstage_backend_plugin_api.UrlReaderService>;
604
547
  }
605
- namespace actions {
606
- const factory: () => ServiceFactory<_backstage_backend_plugin_api.ActionsService, "plugin", "singleton">;
607
- const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.ActionsService> | undefined) => ServiceMock<_backstage_backend_plugin_api.ActionsService>;
608
- }
609
- namespace actionsRegistry {
610
- const factory: () => ServiceFactory<_backstage_backend_plugin_api.ActionsRegistryService, "plugin", "singleton">;
611
- const mock: (partialImpl?: Partial<_backstage_backend_plugin_api.ActionsRegistryService> | undefined) => ServiceMock<_backstage_backend_plugin_api.ActionsRegistryService>;
612
- }
613
548
  /**
614
549
  * Creates a functional mock implementation of the
615
550
  * {@link @backstage/backend-events-node#eventsServiceRef}.
@@ -745,6 +680,85 @@ declare namespace mockCredentials {
745
680
  }
746
681
  }
747
682
 
683
+ /**
684
+ * Options for {@link ServiceFactoryTester}.
685
+ * @public
686
+ */
687
+ interface ServiceFactoryTesterOptions {
688
+ /**
689
+ * Additional service factories to make available as dependencies.
690
+ *
691
+ * @remarks
692
+ *
693
+ * If a service factory is provided for a service that already has a default
694
+ * implementation, the provided factory will override the default.
695
+ */
696
+ dependencies?: Array<ServiceFactory>;
697
+ }
698
+ /**
699
+ * A utility to help test service factories in isolation.
700
+ *
701
+ * @public
702
+ */
703
+ declare class ServiceFactoryTester<TService, TScope extends 'root' | 'plugin', TInstances extends 'singleton' | 'multiton' = 'singleton'> {
704
+ #private;
705
+ /**
706
+ * Creates a new {@link ServiceFactoryTester} used to test the provided subject.
707
+ *
708
+ * @param subject - The service factory to test.
709
+ * @param options - Additional options
710
+ * @returns A new tester instance for the provided subject.
711
+ */
712
+ static from<TService, TScope extends 'root' | 'plugin', TInstances extends 'singleton' | 'multiton' = 'singleton'>(subject: ServiceFactory<TService, TScope, TInstances>, options?: ServiceFactoryTesterOptions): ServiceFactoryTester<TService, TScope, TInstances>;
713
+ private constructor();
714
+ /**
715
+ * Returns the service instance for the subject.
716
+ *
717
+ * @remarks
718
+ *
719
+ * If the subject is a plugin scoped service factory a plugin ID
720
+ * can be provided to instantiate the service for a specific plugin.
721
+ *
722
+ * By default the plugin ID 'test' is used.
723
+ */
724
+ getSubject(...args: 'root' extends TScope ? [] : [pluginId?: string]): Promise<TInstances extends 'multiton' ? TService[] : TService>;
725
+ /**
726
+ * Return the service instance for any of the provided dependencies or built-in services.
727
+ *
728
+ * @remarks
729
+ *
730
+ * A plugin ID can optionally be provided for plugin scoped services, otherwise the plugin ID 'test' is used.
731
+ */
732
+ getService<TGetService, TGetScope extends 'root' | 'plugin', TGetInstances extends 'singleton' | 'multiton' = 'singleton'>(service: ServiceRef<TGetService, TGetScope, TGetInstances>, ...args: 'root' extends TGetScope ? [] : [pluginId?: string]): Promise<TGetInstances extends 'multiton' ? TGetService[] : TGetService>;
733
+ }
734
+
735
+ /** @public */
736
+ interface TestBackendOptions<TExtensionPoints extends any[]> {
737
+ extensionPoints?: readonly [
738
+ ...{
739
+ [index in keyof TExtensionPoints]: [
740
+ ExtensionPoint<TExtensionPoints[index]>,
741
+ Partial<TExtensionPoints[index]>
742
+ ];
743
+ }
744
+ ];
745
+ features?: Array<BackendFeature | Promise<{
746
+ default: BackendFeature;
747
+ }>>;
748
+ }
749
+ /** @public */
750
+ interface TestBackend extends Backend {
751
+ /**
752
+ * Provides access to the underling HTTP server for use with utilities
753
+ * such as `supertest`.
754
+ *
755
+ * If the root http router service has been replaced, this will throw an error.
756
+ */
757
+ readonly server: ExtendedHttpServer;
758
+ }
759
+ /** @public */
760
+ declare function startTestBackend<TExtensionPoints extends any[]>(options: TestBackendOptions<TExtensionPoints>): Promise<TestBackend>;
761
+
748
762
  /**
749
763
  * A mock for error handler middleware that can be used in router tests.
750
764
  * @public
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MockAuthService.cjs.js","sources":["../../src/services/MockAuthService.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 {\n BackstageCredentials,\n BackstageServicePrincipal,\n BackstagePrincipalTypes,\n BackstageUserPrincipal,\n BackstageNonePrincipal,\n AuthService,\n} from '@backstage/backend-plugin-api';\nimport { AuthenticationError } from '@backstage/errors';\nimport {\n mockCredentials,\n MOCK_USER_TOKEN,\n MOCK_USER_TOKEN_PREFIX,\n MOCK_INVALID_USER_TOKEN,\n MOCK_USER_LIMITED_TOKEN_PREFIX,\n MOCK_INVALID_USER_LIMITED_TOKEN,\n MOCK_SERVICE_TOKEN,\n MOCK_SERVICE_TOKEN_PREFIX,\n MOCK_INVALID_SERVICE_TOKEN,\n UserTokenPayload,\n ServiceTokenPayload,\n} from './mockCredentials';\nimport { JsonObject } from '@backstage/types';\n\n/** @internal */\nexport class MockAuthService implements AuthService {\n readonly pluginId: string;\n readonly disableDefaultAuthPolicy: boolean;\n\n constructor(options: {\n pluginId: string;\n disableDefaultAuthPolicy: boolean;\n }) {\n this.pluginId = options.pluginId;\n this.disableDefaultAuthPolicy = options.disableDefaultAuthPolicy;\n }\n\n async authenticate(\n token: string,\n options?: { allowLimitedAccess?: boolean },\n ): Promise<BackstageCredentials> {\n switch (token) {\n case MOCK_USER_TOKEN:\n return mockCredentials.user();\n case MOCK_SERVICE_TOKEN:\n return mockCredentials.service();\n case MOCK_INVALID_USER_TOKEN:\n throw new AuthenticationError('User token is invalid');\n case MOCK_INVALID_USER_LIMITED_TOKEN:\n throw new AuthenticationError('Limited user token is invalid');\n case MOCK_INVALID_SERVICE_TOKEN:\n throw new AuthenticationError('Service token is invalid');\n case '':\n throw new AuthenticationError('Token is empty');\n default:\n break;\n }\n\n if (token.startsWith(MOCK_USER_TOKEN_PREFIX)) {\n const { sub: userEntityRef, actor }: UserTokenPayload = JSON.parse(\n token.slice(MOCK_USER_TOKEN_PREFIX.length),\n );\n\n return mockCredentials.user(userEntityRef, { actor });\n }\n\n if (token.startsWith(MOCK_USER_LIMITED_TOKEN_PREFIX)) {\n if (!options?.allowLimitedAccess) {\n throw new AuthenticationError('Limited user token is not allowed');\n }\n\n const { sub: userEntityRef }: UserTokenPayload = JSON.parse(\n token.slice(MOCK_USER_LIMITED_TOKEN_PREFIX.length),\n );\n\n return mockCredentials.user(userEntityRef);\n }\n\n if (token.startsWith(MOCK_SERVICE_TOKEN_PREFIX)) {\n const { sub, target, obo }: ServiceTokenPayload = JSON.parse(\n token.slice(MOCK_SERVICE_TOKEN_PREFIX.length),\n );\n\n if (target && target !== this.pluginId) {\n throw new AuthenticationError(\n `Invalid mock token target plugin ID, got '${target}' but expected '${this.pluginId}'`,\n );\n }\n if (obo) {\n return mockCredentials.user(obo);\n }\n\n return mockCredentials.service(sub);\n }\n\n throw new AuthenticationError(`Unknown mock token '${token}'`);\n }\n\n async getNoneCredentials() {\n return mockCredentials.none();\n }\n\n async getOwnServiceCredentials(): Promise<\n BackstageCredentials<BackstageServicePrincipal>\n > {\n return mockCredentials.service(`plugin:${this.pluginId}`);\n }\n\n isPrincipal<TType extends keyof BackstagePrincipalTypes>(\n credentials: BackstageCredentials,\n type: TType,\n ): credentials is BackstageCredentials<BackstagePrincipalTypes[TType]> {\n const principal = credentials.principal as\n | BackstageUserPrincipal\n | BackstageServicePrincipal\n | BackstageNonePrincipal;\n\n if (type === 'unknown') {\n return true;\n }\n\n if (principal.type !== type) {\n return false;\n }\n\n return true;\n }\n\n async getPluginRequestToken(options: {\n onBehalfOf: BackstageCredentials;\n targetPluginId: string;\n }): Promise<{ token: string }> {\n const principal = options.onBehalfOf.principal as\n | BackstageUserPrincipal\n | BackstageServicePrincipal\n | BackstageNonePrincipal;\n\n if (principal.type === 'none' && this.disableDefaultAuthPolicy) {\n return { token: '' };\n }\n\n if (principal.type !== 'user' && principal.type !== 'service') {\n throw new AuthenticationError(\n `Refused to issue service token for credential type '${principal.type}'`,\n );\n }\n\n return {\n token: mockCredentials.service.token({\n onBehalfOf: options.onBehalfOf,\n targetPluginId: options.targetPluginId,\n }),\n };\n }\n\n async getLimitedUserToken(\n credentials: BackstageCredentials<BackstageUserPrincipal>,\n ): Promise<{ token: string; expiresAt: Date }> {\n if (credentials.principal.type !== 'user') {\n throw new AuthenticationError(\n `Refused to issue limited user token for credential type '${credentials.principal.type}'`,\n );\n }\n\n return {\n token: mockCredentials.limitedUser.token(\n credentials.principal.userEntityRef,\n ),\n expiresAt: new Date(Date.now() + 3600_000),\n };\n }\n\n listPublicServiceKeys(): Promise<{ keys: JsonObject[] }> {\n throw new Error('Not implemented');\n }\n}\n"],"names":["MOCK_USER_TOKEN","mockCredentials","MOCK_SERVICE_TOKEN","MOCK_INVALID_USER_TOKEN","AuthenticationError","MOCK_INVALID_USER_LIMITED_TOKEN","MOCK_INVALID_SERVICE_TOKEN","MOCK_USER_TOKEN_PREFIX","MOCK_USER_LIMITED_TOKEN_PREFIX","MOCK_SERVICE_TOKEN_PREFIX"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MockEventsService.cjs.js","sources":["../../src/services/MockEventsService.ts"],"sourcesContent":["/*\n * Copyright 2025 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 {\n EventParams,\n EventsService,\n EventsServiceSubscribeOptions,\n} from '@backstage/plugin-events-node';\n\nexport class MockEventsService implements EventsService {\n #subscribers: EventsServiceSubscribeOptions[];\n\n constructor() {\n this.#subscribers = [];\n }\n\n async publish(params: EventParams): Promise<void> {\n for (const subscriber of this.#subscribers) {\n if (subscriber.topics.includes(params.topic)) {\n await subscriber.onEvent(params);\n }\n }\n }\n\n async subscribe(options: EventsServiceSubscribeOptions): Promise<void> {\n this.#subscribers.push(options);\n }\n}\n"],"names":[],"mappings":";;AAsBO,MAAM,iBAA2C,CAAA;AAAA,EACtD,YAAA;AAAA,EAEA,WAAc,GAAA;AACZ,IAAA,IAAA,CAAK,eAAe,EAAC;AAAA;AACvB,EAEA,MAAM,QAAQ,MAAoC,EAAA;AAChD,IAAW,KAAA,MAAA,UAAA,IAAc,KAAK,YAAc,EAAA;AAC1C,MAAA,IAAI,UAAW,CAAA,MAAA,CAAO,QAAS,CAAA,MAAA,CAAO,KAAK,CAAG,EAAA;AAC5C,QAAM,MAAA,UAAA,CAAW,QAAQ,MAAM,CAAA;AAAA;AACjC;AACF;AACF,EAEA,MAAM,UAAU,OAAuD,EAAA;AACrE,IAAK,IAAA,CAAA,YAAA,CAAa,KAAK,OAAO,CAAA;AAAA;AAElC;;;;"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MockHttpAuthService.cjs.js","sources":["../../src/services/MockHttpAuthService.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 {\n AuthService,\n BackstageCredentials,\n BackstagePrincipalTypes,\n BackstageUserPrincipal,\n HttpAuthService,\n} from '@backstage/backend-plugin-api';\nimport { Request, Response } from 'express';\nimport { parse as parseCookie } from 'cookie';\nimport { MockAuthService } from './MockAuthService';\nimport { AuthenticationError, NotAllowedError } from '@backstage/errors';\nimport {\n MOCK_NONE_TOKEN,\n MOCK_AUTH_COOKIE,\n mockCredentials,\n} from './mockCredentials';\n\n// TODO: support mock cookie auth?\nexport class MockHttpAuthService implements HttpAuthService {\n #auth: AuthService;\n #defaultCredentials: BackstageCredentials;\n\n constructor(pluginId: string, defaultCredentials: BackstageCredentials) {\n this.#auth = new MockAuthService({\n pluginId,\n disableDefaultAuthPolicy: false,\n });\n this.#defaultCredentials = defaultCredentials;\n }\n\n async #getCredentials(req: Request, allowLimitedAccess: boolean) {\n const header = req.headers.authorization;\n const token =\n typeof header === 'string'\n ? header.match(/^Bearer[ ]+(\\S+)$/i)?.[1]\n : undefined;\n\n if (token) {\n if (token === MOCK_NONE_TOKEN) {\n return this.#auth.getNoneCredentials();\n }\n\n return await this.#auth.authenticate(token, {\n allowLimitedAccess,\n });\n }\n\n if (allowLimitedAccess) {\n const cookieHeader = req.headers.cookie;\n\n if (cookieHeader) {\n const cookies = parseCookie(cookieHeader);\n const cookie = cookies[MOCK_AUTH_COOKIE];\n\n if (cookie) {\n return await this.#auth.authenticate(cookie, {\n allowLimitedAccess: true,\n });\n }\n }\n }\n\n return this.#defaultCredentials;\n }\n\n async credentials<TAllowed extends keyof BackstagePrincipalTypes = 'unknown'>(\n req: Request,\n options?: {\n allow?: Array<TAllowed>;\n allowLimitedAccess?: boolean;\n },\n ): Promise<BackstageCredentials<BackstagePrincipalTypes[TAllowed]>> {\n const credentials = await this.#getCredentials(\n req,\n options?.allowLimitedAccess ?? false,\n );\n\n const allowedPrincipalTypes = options?.allow;\n if (!allowedPrincipalTypes) {\n return credentials as any;\n }\n\n if (this.#auth.isPrincipal(credentials, 'none')) {\n if (allowedPrincipalTypes.includes('none' as TAllowed)) {\n return credentials as any;\n }\n\n throw new AuthenticationError('Missing credentials');\n } else if (this.#auth.isPrincipal(credentials, 'user')) {\n if (allowedPrincipalTypes.includes('user' as TAllowed)) {\n return credentials as any;\n }\n\n throw new NotAllowedError(\n `This endpoint does not allow 'user' credentials`,\n );\n } else if (this.#auth.isPrincipal(credentials, 'service')) {\n if (allowedPrincipalTypes.includes('service' as TAllowed)) {\n return credentials as any;\n }\n\n throw new NotAllowedError(\n `This endpoint does not allow 'service' credentials`,\n );\n }\n\n throw new NotAllowedError(\n 'Unknown principal type, this should never happen',\n );\n }\n\n async issueUserCookie(\n res: Response,\n options?: { credentials?: BackstageCredentials<BackstageUserPrincipal> },\n ): Promise<{ expiresAt: Date }> {\n const credentials =\n options?.credentials ??\n (await this.credentials(res.req, { allow: ['user'] }));\n\n res.setHeader(\n 'Set-Cookie',\n mockCredentials.limitedUser.cookie(credentials.principal.userEntityRef),\n );\n\n return { expiresAt: new Date(Date.now() + 3600_000) };\n }\n}\n"],"names":["MockAuthService","MOCK_NONE_TOKEN","parseCookie","cookie","MOCK_AUTH_COOKIE","AuthenticationError","NotAllowedError","mockCredentials"],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ 'use strict';
2
+
3
+ var pluginPermissionCommon = require('@backstage/plugin-permission-common');
4
+
5
+ class MockPermissionsService {
6
+ #result;
7
+ constructor(options) {
8
+ this.#result = options?.result ?? pluginPermissionCommon.AuthorizeResult.ALLOW;
9
+ }
10
+ async authorize(requests) {
11
+ return requests.map((request) => ({
12
+ ...request,
13
+ result: this.#result
14
+ }));
15
+ }
16
+ async authorizeConditional(requests) {
17
+ return requests.map((request) => ({
18
+ ...request,
19
+ result: this.#result
20
+ }));
21
+ }
22
+ }
23
+
24
+ exports.MockPermissionsService = MockPermissionsService;
25
+ //# sourceMappingURL=MockPermissionsService.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MockPermissionsService.cjs.js","sources":["../../src/services/MockPermissionsService.ts"],"sourcesContent":["/*\n * Copyright 2025 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 { PermissionsService } from '@backstage/backend-plugin-api';\nimport {\n AuthorizePermissionRequest,\n AuthorizePermissionResponse,\n AuthorizeResult,\n QueryPermissionRequest,\n QueryPermissionResponse,\n} from '@backstage/plugin-permission-common';\n\nexport class MockPermissionsService implements PermissionsService {\n readonly #result: AuthorizeResult.ALLOW | AuthorizeResult.DENY;\n\n constructor(options?: {\n result: AuthorizeResult.ALLOW | AuthorizeResult.DENY;\n }) {\n this.#result = options?.result ?? AuthorizeResult.ALLOW;\n }\n\n async authorize(\n requests: AuthorizePermissionRequest[],\n ): Promise<AuthorizePermissionResponse[]> {\n return requests.map(request => ({\n ...request,\n result: this.#result,\n }));\n }\n\n async authorizeConditional(\n requests: QueryPermissionRequest[],\n ): Promise<QueryPermissionResponse[]> {\n return requests.map(request => ({\n ...request,\n result: this.#result,\n }));\n }\n}\n"],"names":["AuthorizeResult"],"mappings":";;;;AAyBO,MAAM,sBAAqD,CAAA;AAAA,EACvD,OAAA;AAAA,EAET,YAAY,OAET,EAAA;AACD,IAAK,IAAA,CAAA,OAAA,GAAU,OAAS,EAAA,MAAA,IAAUA,sCAAgB,CAAA,KAAA;AAAA;AACpD,EAEA,MAAM,UACJ,QACwC,EAAA;AACxC,IAAO,OAAA,QAAA,CAAS,IAAI,CAAY,OAAA,MAAA;AAAA,MAC9B,GAAG,OAAA;AAAA,MACH,QAAQ,IAAK,CAAA;AAAA,KACb,CAAA,CAAA;AAAA;AACJ,EAEA,MAAM,qBACJ,QACoC,EAAA;AACpC,IAAO,OAAA,QAAA,CAAS,IAAI,CAAY,OAAA,MAAA;AAAA,MAC9B,GAAG,OAAA;AAAA,MACH,QAAQ,IAAK,CAAA;AAAA,KACb,CAAA,CAAA;AAAA;AAEN;;;;"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MockRootLoggerService.cjs.js","sources":["../../src/services/MockRootLoggerService.ts"],"sourcesContent":["/*\n * Copyright 2023 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 {\n LoggerService,\n RootLoggerService,\n} from '@backstage/backend-plugin-api';\nimport { JsonObject } from '@backstage/types';\nimport type { mockServices } from './mockServices';\n\nconst levels = {\n none: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n};\n\nexport class MockRootLoggerService implements RootLoggerService {\n #level: number;\n #meta: JsonObject;\n\n static create(\n options?: mockServices.rootLogger.Options,\n ): MockRootLoggerService {\n const level = options?.level ?? 'none';\n if (!(level in levels)) {\n throw new Error(`Invalid log level '${level}'`);\n }\n return new MockRootLoggerService(levels[level], {});\n }\n\n error(message: string, meta?: JsonObject | Error | undefined): void {\n this.#log('error', message, meta);\n }\n\n warn(message: string, meta?: JsonObject | Error | undefined): void {\n this.#log('warn', message, meta);\n }\n\n info(message: string, meta?: JsonObject | Error | undefined): void {\n this.#log('info', message, meta);\n }\n\n debug(message: string, meta?: JsonObject | Error | undefined): void {\n this.#log('debug', message, meta);\n }\n\n child(meta: JsonObject): LoggerService {\n return new MockRootLoggerService(this.#level, { ...this.#meta, ...meta });\n }\n\n private constructor(level: number, meta: JsonObject) {\n this.#level = level;\n this.#meta = meta;\n }\n\n #log(\n level: 'error' | 'warn' | 'info' | 'debug',\n message: string,\n meta?: JsonObject | Error | undefined,\n ) {\n const levelValue = levels[level] ?? 0;\n if (levelValue <= this.#level) {\n const labels = Object.entries(this.#meta)\n .map(([key, value]) => `${key}=${value}`)\n .join(',');\n console[level](`${labels} ${message}`, meta);\n }\n }\n}\n"],"names":[],"mappings":";;AAuBA,MAAM,MAAS,GAAA;AAAA,EACb,IAAM,EAAA,CAAA;AAAA,EACN,KAAO,EAAA,CAAA;AAAA,EACP,IAAM,EAAA,CAAA;AAAA,EACN,IAAM,EAAA,CAAA;AAAA,EACN,KAAO,EAAA;AACT,CAAA;AAEO,MAAM,qBAAmD,CAAA;AAAA,EAC9D,MAAA;AAAA,EACA,KAAA;AAAA,EAEA,OAAO,OACL,OACuB,EAAA;AACvB,IAAM,MAAA,KAAA,GAAQ,SAAS,KAAS,IAAA,MAAA;AAChC,IAAI,IAAA,EAAE,SAAS,MAAS,CAAA,EAAA;AACtB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAsB,mBAAA,EAAA,KAAK,CAAG,CAAA,CAAA,CAAA;AAAA;AAEhD,IAAA,OAAO,IAAI,qBAAsB,CAAA,MAAA,CAAO,KAAK,CAAA,EAAG,EAAE,CAAA;AAAA;AACpD,EAEA,KAAA,CAAM,SAAiB,IAA6C,EAAA;AAClE,IAAK,IAAA,CAAA,IAAA,CAAK,OAAS,EAAA,OAAA,EAAS,IAAI,CAAA;AAAA;AAClC,EAEA,IAAA,CAAK,SAAiB,IAA6C,EAAA;AACjE,IAAK,IAAA,CAAA,IAAA,CAAK,MAAQ,EAAA,OAAA,EAAS,IAAI,CAAA;AAAA;AACjC,EAEA,IAAA,CAAK,SAAiB,IAA6C,EAAA;AACjE,IAAK,IAAA,CAAA,IAAA,CAAK,MAAQ,EAAA,OAAA,EAAS,IAAI,CAAA;AAAA;AACjC,EAEA,KAAA,CAAM,SAAiB,IAA6C,EAAA;AAClE,IAAK,IAAA,CAAA,IAAA,CAAK,OAAS,EAAA,OAAA,EAAS,IAAI,CAAA;AAAA;AAClC,EAEA,MAAM,IAAiC,EAAA;AACrC,IAAO,OAAA,IAAI,qBAAsB,CAAA,IAAA,CAAK,MAAQ,EAAA,EAAE,GAAG,IAAK,CAAA,KAAA,EAAO,GAAG,IAAA,EAAM,CAAA;AAAA;AAC1E,EAEQ,WAAA,CAAY,OAAe,IAAkB,EAAA;AACnD,IAAA,IAAA,CAAK,MAAS,GAAA,KAAA;AACd,IAAA,IAAA,CAAK,KAAQ,GAAA,IAAA;AAAA;AACf,EAEA,IAAA,CACE,KACA,EAAA,OAAA,EACA,IACA,EAAA;AACA,IAAM,MAAA,UAAA,GAAa,MAAO,CAAA,KAAK,CAAK,IAAA,CAAA;AACpC,IAAI,IAAA,UAAA,IAAc,KAAK,MAAQ,EAAA;AAC7B,MAAA,MAAM,SAAS,MAAO,CAAA,OAAA,CAAQ,KAAK,KAAK,CAAA,CACrC,IAAI,CAAC,CAAC,KAAK,KAAK,CAAA,KAAM,GAAG,GAAG,CAAA,CAAA,EAAI,KAAK,CAAE,CAAA,CAAA,CACvC,KAAK,GAAG,CAAA;AACX,MAAA,OAAA,CAAQ,KAAK,CAAE,CAAA,CAAA,EAAG,MAAM,CAAI,CAAA,EAAA,OAAO,IAAI,IAAI,CAAA;AAAA;AAC7C;AAEJ;;;;"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MockUserInfoService.cjs.js","sources":["../../src/services/MockUserInfoService.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 {\n BackstageCredentials,\n BackstageNonePrincipal,\n BackstageServicePrincipal,\n BackstageUserInfo,\n BackstageUserPrincipal,\n UserInfoService,\n} from '@backstage/backend-plugin-api';\nimport { InputError } from '@backstage/errors';\n\n/** @internal */\nexport class MockUserInfoService implements UserInfoService {\n private readonly customInfo: Partial<BackstageUserInfo>;\n\n constructor(customInfo?: Partial<BackstageUserInfo>) {\n this.customInfo = customInfo ?? {};\n }\n\n async getUserInfo(\n credentials: BackstageCredentials,\n ): Promise<BackstageUserInfo> {\n const principal = credentials.principal as\n | BackstageUserPrincipal\n | BackstageServicePrincipal\n | BackstageNonePrincipal;\n\n if (principal.type !== 'user') {\n throw new InputError(\n `User info not available for principal type '${principal.type}'`,\n );\n }\n\n return {\n userEntityRef: principal.userEntityRef,\n ownershipEntityRefs: [principal.userEntityRef],\n ...this.customInfo,\n };\n }\n}\n"],"names":["InputError"],"mappings":";;;;AA2BO,MAAM,mBAA+C,CAAA;AAAA,EACzC,UAAA;AAAA,EAEjB,YAAY,UAAyC,EAAA;AACnD,IAAK,IAAA,CAAA,UAAA,GAAa,cAAc,EAAC;AAAA;AACnC,EAEA,MAAM,YACJ,WAC4B,EAAA;AAC5B,IAAA,MAAM,YAAY,WAAY,CAAA,SAAA;AAK9B,IAAI,IAAA,SAAA,CAAU,SAAS,MAAQ,EAAA;AAC7B,MAAA,MAAM,IAAIA,iBAAA;AAAA,QACR,CAAA,4CAAA,EAA+C,UAAU,IAAI,CAAA,CAAA;AAAA,OAC/D;AAAA;AAGF,IAAO,OAAA;AAAA,MACL,eAAe,SAAU,CAAA,aAAA;AAAA,MACzB,mBAAA,EAAqB,CAAC,SAAA,CAAU,aAAa,CAAA;AAAA,MAC7C,GAAG,IAAK,CAAA;AAAA,KACV;AAAA;AAEJ;;;;"}
@@ -36,16 +36,24 @@ exports.mockCredentials = void 0;
36
36
  })(none = mockCredentials2.none || (mockCredentials2.none = {}));
37
37
  function user(userEntityRef = DEFAULT_MOCK_USER_ENTITY_REF, options) {
38
38
  validateUserEntityRef(userEntityRef);
39
- return {
40
- $$type: "@backstage/BackstageCredentials",
41
- principal: {
42
- type: "user",
43
- userEntityRef,
44
- ...options?.actor && {
45
- actor: { type: "service", subject: options.actor.subject }
39
+ return Object.defineProperty(
40
+ {
41
+ $$type: "@backstage/BackstageCredentials",
42
+ principal: {
43
+ type: "user",
44
+ userEntityRef,
45
+ ...options?.actor && {
46
+ actor: { type: "service", subject: options.actor.subject }
47
+ }
46
48
  }
49
+ },
50
+ "token",
51
+ {
52
+ enumerable: false,
53
+ configurable: true,
54
+ value: user.token()
47
55
  }
48
- };
56
+ );
49
57
  }
50
58
  mockCredentials2.user = user;
51
59
  ((user2) => {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mockCredentials.cjs.js","sources":["../../src/services/mockCredentials.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 {\n BackstageCredentials,\n BackstageNonePrincipal,\n BackstagePrincipalAccessRestrictions,\n BackstageServicePrincipal,\n BackstageUserPrincipal,\n} from '@backstage/backend-plugin-api';\n\nexport const DEFAULT_MOCK_USER_ENTITY_REF = 'user:default/mock';\nexport const DEFAULT_MOCK_SERVICE_SUBJECT = 'external:test-service';\n\nexport const MOCK_AUTH_COOKIE = 'backstage-auth';\n\nexport const MOCK_NONE_TOKEN = 'mock-none-token';\n\nexport const MOCK_USER_TOKEN = 'mock-user-token';\nexport const MOCK_USER_TOKEN_PREFIX = 'mock-user-token:';\nexport const MOCK_INVALID_USER_TOKEN = 'mock-invalid-user-token';\n\nexport const MOCK_USER_LIMITED_TOKEN_PREFIX = 'mock-limited-user-token:';\nexport const MOCK_INVALID_USER_LIMITED_TOKEN =\n 'mock-invalid-limited-user-token';\n\nexport const MOCK_SERVICE_TOKEN = 'mock-service-token';\nexport const MOCK_SERVICE_TOKEN_PREFIX = 'mock-service-token:';\nexport const MOCK_INVALID_SERVICE_TOKEN = 'mock-invalid-service-token';\n\nfunction validateUserEntityRef(ref: string) {\n if (!ref.match(/^.+:.+\\/.+$/)) {\n throw new TypeError(\n `Invalid user entity reference '${ref}', expected <kind>:<namespace>/<name>`,\n );\n }\n}\n\n/**\n * The payload that can be encoded into a mock user token.\n * @internal\n */\nexport type UserTokenPayload = {\n sub?: string;\n actor?: { subject: string };\n};\n\n/**\n * The payload that can be encoded into a mock service token.\n * @internal\n */\nexport type ServiceTokenPayload = {\n sub?: string; // service subject\n obo?: string; // user entity reference\n target?: string; // target plugin id\n};\n\n/**\n * @public\n */\nexport namespace mockCredentials {\n /**\n * Creates a mocked credentials object for a unauthenticated principal.\n */\n export function none(): BackstageCredentials<BackstageNonePrincipal> {\n return {\n $$type: '@backstage/BackstageCredentials',\n principal: { type: 'none' },\n };\n }\n\n /**\n * Utilities related to none credentials.\n */\n export namespace none {\n /**\n * Returns an authorization header that translates to unauthenticated\n * credentials.\n *\n * This is useful when one wants to explicitly test unauthenticated requests\n * while still using the default behavior of the mock HttpAuthService where\n * it defaults to user credentials.\n */\n export function header(): string {\n // NOTE: there is no .token() version of this because only the\n // HttpAuthService should know about and consume this token\n return `Bearer ${MOCK_NONE_TOKEN}`;\n }\n }\n\n /**\n * Creates a mocked credentials object for a user principal.\n *\n * The default user entity reference is 'user:default/mock'.\n */\n export function user(\n userEntityRef: string = DEFAULT_MOCK_USER_ENTITY_REF,\n options?: { actor?: { subject: string } },\n ): BackstageCredentials<BackstageUserPrincipal> {\n validateUserEntityRef(userEntityRef);\n return Object.defineProperty(\n {\n $$type: '@backstage/BackstageCredentials',\n principal: {\n type: 'user',\n userEntityRef,\n ...(options?.actor && {\n actor: { type: 'service', subject: options.actor.subject },\n }),\n },\n },\n 'token',\n {\n enumerable: false,\n configurable: true,\n value: user.token(),\n },\n );\n }\n\n /**\n * Utilities related to user credentials.\n */\n export namespace user {\n /**\n * Creates a mocked user token. If a payload is provided it will be encoded\n * into the token and forwarded to the credentials object when authenticated\n * by the mock auth service.\n */\n export function token(\n userEntityRef?: string,\n options?: { actor?: { subject: string } },\n ): string {\n if (userEntityRef) {\n validateUserEntityRef(userEntityRef);\n return `${MOCK_USER_TOKEN_PREFIX}${JSON.stringify({\n sub: userEntityRef,\n ...(options?.actor && {\n actor: { subject: options.actor.subject },\n }),\n } satisfies UserTokenPayload)}`;\n }\n return MOCK_USER_TOKEN;\n }\n\n /**\n * Returns an authorization header with a mocked user token. If a payload is\n * provided it will be encoded into the token and forwarded to the\n * credentials object when authenticated by the mock auth service.\n */\n export function header(userEntityRef?: string): string {\n return `Bearer ${token(userEntityRef)}`;\n }\n\n export function invalidToken(): string {\n return MOCK_INVALID_USER_TOKEN;\n }\n\n export function invalidHeader(): string {\n return `Bearer ${invalidToken()}`;\n }\n }\n\n /**\n * Creates a mocked credentials object for a user principal with limited\n * access.\n *\n * The default user entity reference is 'user:default/mock'.\n */\n export function limitedUser(\n userEntityRef: string = DEFAULT_MOCK_USER_ENTITY_REF,\n ): BackstageCredentials<BackstageUserPrincipal> {\n return user(userEntityRef);\n }\n\n /**\n * Utilities related to limited user credentials.\n */\n export namespace limitedUser {\n /**\n * Creates a mocked limited user token. If a payload is provided it will be\n * encoded into the token and forwarded to the credentials object when\n * authenticated by the mock auth service.\n */\n export function token(\n userEntityRef: string = DEFAULT_MOCK_USER_ENTITY_REF,\n ): string {\n validateUserEntityRef(userEntityRef);\n return `${MOCK_USER_LIMITED_TOKEN_PREFIX}${JSON.stringify({\n sub: userEntityRef,\n } satisfies UserTokenPayload)}`;\n }\n\n /**\n * Returns an authorization header with a mocked limited user token. If a\n * payload is provided it will be encoded into the token and forwarded to\n * the credentials object when authenticated by the mock auth service.\n */\n export function cookie(userEntityRef?: string): string {\n return `${MOCK_AUTH_COOKIE}=${token(userEntityRef)}`;\n }\n\n export function invalidToken(): string {\n return MOCK_INVALID_USER_LIMITED_TOKEN;\n }\n\n export function invalidCookie(): string {\n return `${MOCK_AUTH_COOKIE}=${invalidToken()}`;\n }\n }\n\n /**\n * Creates a mocked credentials object for a service principal.\n *\n * The default subject is 'external:test-service', and no access restrictions.\n */\n export function service(\n subject: string = DEFAULT_MOCK_SERVICE_SUBJECT,\n accessRestrictions?: BackstagePrincipalAccessRestrictions,\n ): BackstageCredentials<BackstageServicePrincipal> {\n return {\n $$type: '@backstage/BackstageCredentials',\n principal: {\n type: 'service',\n subject,\n ...(accessRestrictions ? { accessRestrictions } : {}),\n },\n };\n }\n\n /**\n * Utilities related to service credentials.\n */\n export namespace service {\n /**\n * Options for the creation of mock service tokens.\n */\n export type TokenOptions = {\n onBehalfOf: BackstageCredentials;\n targetPluginId: string;\n };\n\n /**\n * Creates a mocked service token. The provided options will be encoded into\n * the token and forwarded to the credentials object when authenticated by\n * the mock auth service.\n */\n export function token(options?: TokenOptions): string {\n if (options) {\n const { targetPluginId, onBehalfOf } = options; // for fixed ordering\n\n const oboPrincipal = onBehalfOf?.principal as\n | BackstageServicePrincipal\n | BackstageUserPrincipal\n | BackstageNonePrincipal;\n const obo =\n oboPrincipal.type === 'user' ? oboPrincipal.userEntityRef : undefined;\n const subject =\n oboPrincipal.type === 'service' ? oboPrincipal.subject : undefined;\n\n return `${MOCK_SERVICE_TOKEN_PREFIX}${JSON.stringify({\n sub: subject,\n obo,\n target: targetPluginId,\n } satisfies ServiceTokenPayload)}`;\n }\n return MOCK_SERVICE_TOKEN;\n }\n\n /**\n * Returns an authorization header with a mocked service token. The provided\n * options will be encoded into the token and forwarded to the credentials\n * object when authenticated by the mock auth service.\n */\n export function header(options?: TokenOptions): string {\n return `Bearer ${token(options)}`;\n }\n\n export function invalidToken(): string {\n return MOCK_INVALID_SERVICE_TOKEN;\n }\n\n export function invalidHeader(): string {\n return `Bearer ${invalidToken()}`;\n }\n }\n}\n"],"names":["mockCredentials","none","user","limitedUser","service"],"mappings":"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"}
@@ -23,8 +23,8 @@ var MockRootLoggerService = require('./MockRootLoggerService.cjs.js');
23
23
  var MockUserInfoService = require('./MockUserInfoService.cjs.js');
24
24
  var mockCredentials = require('./mockCredentials.cjs.js');
25
25
  var MockEventsService = require('./MockEventsService.cjs.js');
26
- var actions = require('@backstage/backend-defaults/actions');
27
- var actionsRegistry = require('@backstage/backend-defaults/actionsRegistry');
26
+ var MockPermissionsService = require('./MockPermissionsService.cjs.js');
27
+ var simpleMock = require('./simpleMock.cjs.js');
28
28
 
29
29
  function createLoggerMock() {
30
30
  return {
@@ -48,27 +48,6 @@ function simpleFactoryWithOptions(ref, factory) {
48
48
  factoryWithOptions(...[void 0])
49
49
  );
50
50
  }
51
- function simpleMock(ref, mockFactory) {
52
- return (partialImpl) => {
53
- const mock = mockFactory();
54
- if (partialImpl) {
55
- for (const [key, impl] of Object.entries(partialImpl)) {
56
- if (typeof impl === "function") {
57
- mock[key].mockImplementation(impl);
58
- } else {
59
- mock[key] = impl;
60
- }
61
- }
62
- }
63
- return Object.assign(mock, {
64
- factory: backendPluginApi.createServiceFactory({
65
- service: ref,
66
- deps: {},
67
- factory: () => mock
68
- })
69
- });
70
- };
71
- }
72
51
  exports.mockServices = void 0;
73
52
  ((mockServices2) => {
74
53
  function rootConfig(options) {
@@ -80,7 +59,7 @@ exports.mockServices = void 0;
80
59
  backendPluginApi.coreServices.rootConfig,
81
60
  rootConfig2
82
61
  );
83
- rootConfig2.mock = simpleMock(backendPluginApi.coreServices.rootConfig, () => ({
62
+ rootConfig2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.rootConfig, () => ({
84
63
  get: jest.fn(),
85
64
  getBoolean: jest.fn(),
86
65
  getConfig: jest.fn(),
@@ -108,7 +87,7 @@ exports.mockServices = void 0;
108
87
  backendPluginApi.coreServices.rootLogger,
109
88
  rootLogger2
110
89
  );
111
- rootLogger2.mock = simpleMock(backendPluginApi.coreServices.rootLogger, () => ({
90
+ rootLogger2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.rootLogger, () => ({
112
91
  child: jest.fn(),
113
92
  debug: jest.fn(),
114
93
  error: jest.fn(),
@@ -118,7 +97,7 @@ exports.mockServices = void 0;
118
97
  })(rootLogger = mockServices2.rootLogger || (mockServices2.rootLogger = {}));
119
98
  ((auditor2) => {
120
99
  auditor2.factory = () => auditor.auditorServiceFactory;
121
- auditor2.mock = simpleMock(backendPluginApi.coreServices.auditor, () => ({
100
+ auditor2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.auditor, () => ({
122
101
  createEvent: jest.fn(async (_) => {
123
102
  return {
124
103
  success: jest.fn(),
@@ -153,7 +132,7 @@ exports.mockServices = void 0;
153
132
  });
154
133
  }
155
134
  });
156
- auth2.mock = simpleMock(backendPluginApi.coreServices.auth, () => ({
135
+ auth2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.auth, () => ({
157
136
  authenticate: jest.fn(),
158
137
  getNoneCredentials: jest.fn(),
159
138
  getOwnServiceCredentials: jest.fn(),
@@ -181,7 +160,7 @@ exports.mockServices = void 0;
181
160
  deps: {},
182
161
  factory: () => discovery2()
183
162
  });
184
- discovery2.mock = simpleMock(backendPluginApi.coreServices.discovery, () => ({
163
+ discovery2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.discovery, () => ({
185
164
  getBaseUrl: jest.fn(),
186
165
  getExternalBaseUrl: jest.fn()
187
166
  }));
@@ -202,7 +181,7 @@ exports.mockServices = void 0;
202
181
  options?.defaultCredentials ?? mockCredentials.mockCredentials.user()
203
182
  )
204
183
  });
205
- httpAuth2.mock = simpleMock(backendPluginApi.coreServices.httpAuth, () => ({
184
+ httpAuth2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.httpAuth, () => ({
206
185
  credentials: jest.fn(),
207
186
  issueUserCookie: jest.fn()
208
187
  }));
@@ -219,13 +198,13 @@ exports.mockServices = void 0;
219
198
  return new MockUserInfoService.MockUserInfoService();
220
199
  }
221
200
  });
222
- userInfo2.mock = simpleMock(backendPluginApi.coreServices.userInfo, () => ({
201
+ userInfo2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.userInfo, () => ({
223
202
  getUserInfo: jest.fn()
224
203
  }));
225
204
  })(userInfo = mockServices2.userInfo || (mockServices2.userInfo = {}));
226
205
  ((cache2) => {
227
206
  cache2.factory = () => cache.cacheServiceFactory;
228
- cache2.mock = simpleMock(backendPluginApi.coreServices.cache, () => ({
207
+ cache2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.cache, () => ({
229
208
  delete: jest.fn(),
230
209
  get: jest.fn(),
231
210
  set: jest.fn(),
@@ -245,54 +224,62 @@ exports.mockServices = void 0;
245
224
  deps: {},
246
225
  factory: () => database2(options)
247
226
  }) : database.databaseServiceFactory;
248
- database2.mock = simpleMock(backendPluginApi.coreServices.database, () => ({
227
+ database2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.database, () => ({
249
228
  getClient: jest.fn()
250
229
  }));
251
230
  })(database$1 = mockServices2.database || (mockServices2.database = {}));
252
231
  ((rootHealth2) => {
253
232
  rootHealth2.factory = () => rootHealth.rootHealthServiceFactory;
254
- rootHealth2.mock = simpleMock(backendPluginApi.coreServices.rootHealth, () => ({
233
+ rootHealth2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.rootHealth, () => ({
255
234
  getLiveness: jest.fn(),
256
235
  getReadiness: jest.fn()
257
236
  }));
258
237
  })(mockServices2.rootHealth || (mockServices2.rootHealth = {}));
259
238
  ((httpRouter2) => {
260
239
  httpRouter2.factory = () => httpRouter.httpRouterServiceFactory;
261
- httpRouter2.mock = simpleMock(backendPluginApi.coreServices.httpRouter, () => ({
240
+ httpRouter2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.httpRouter, () => ({
262
241
  use: jest.fn(),
263
242
  addAuthPolicy: jest.fn()
264
243
  }));
265
244
  })(mockServices2.httpRouter || (mockServices2.httpRouter = {}));
266
245
  ((rootHttpRouter2) => {
267
246
  rootHttpRouter2.factory = () => rootHttpRouter.rootHttpRouterServiceFactory();
268
- rootHttpRouter2.mock = simpleMock(backendPluginApi.coreServices.rootHttpRouter, () => ({
247
+ rootHttpRouter2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.rootHttpRouter, () => ({
269
248
  use: jest.fn()
270
249
  }));
271
250
  })(mockServices2.rootHttpRouter || (mockServices2.rootHttpRouter = {}));
272
251
  ((lifecycle2) => {
273
252
  lifecycle2.factory = () => lifecycle.lifecycleServiceFactory;
274
- lifecycle2.mock = simpleMock(backendPluginApi.coreServices.lifecycle, () => ({
253
+ lifecycle2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.lifecycle, () => ({
275
254
  addShutdownHook: jest.fn(),
276
255
  addStartupHook: jest.fn()
277
256
  }));
278
257
  })(mockServices2.lifecycle || (mockServices2.lifecycle = {}));
279
258
  ((logger2) => {
280
259
  logger2.factory = () => logger.loggerServiceFactory;
281
- logger2.mock = simpleMock(
260
+ logger2.mock = simpleMock.simpleMock(
282
261
  backendPluginApi.coreServices.logger,
283
262
  () => createLoggerMock()
284
263
  );
285
264
  })(mockServices2.logger || (mockServices2.logger = {}));
265
+ function permissions$1(options) {
266
+ return new MockPermissionsService.MockPermissionsService(options);
267
+ }
268
+ mockServices2.permissions = permissions$1;
286
269
  ((permissions2) => {
287
- permissions2.factory = () => permissions.permissionsServiceFactory;
288
- permissions2.mock = simpleMock(backendPluginApi.coreServices.permissions, () => ({
270
+ permissions2.factory = (options) => options?.result ? backendPluginApi.createServiceFactory({
271
+ service: backendPluginApi.coreServices.permissions,
272
+ deps: {},
273
+ factory: () => new MockPermissionsService.MockPermissionsService(options)
274
+ }) : permissions.permissionsServiceFactory;
275
+ permissions2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.permissions, () => ({
289
276
  authorize: jest.fn(),
290
277
  authorizeConditional: jest.fn()
291
278
  }));
292
- })(mockServices2.permissions || (mockServices2.permissions = {}));
279
+ })(permissions$1 = mockServices2.permissions || (mockServices2.permissions = {}));
293
280
  ((permissionsRegistry2) => {
294
281
  permissionsRegistry2.factory = () => permissionsRegistry.permissionsRegistryServiceFactory;
295
- permissionsRegistry2.mock = simpleMock(backendPluginApi.coreServices.permissionsRegistry, () => ({
282
+ permissionsRegistry2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.permissionsRegistry, () => ({
296
283
  addPermissionRules: jest.fn(),
297
284
  addPermissions: jest.fn(),
298
285
  addResourceType: jest.fn(),
@@ -301,7 +288,7 @@ exports.mockServices = void 0;
301
288
  })(mockServices2.permissionsRegistry || (mockServices2.permissionsRegistry = {}));
302
289
  ((rootLifecycle2) => {
303
290
  rootLifecycle2.factory = () => rootLifecycle.rootLifecycleServiceFactory;
304
- rootLifecycle2.mock = simpleMock(backendPluginApi.coreServices.rootLifecycle, () => ({
291
+ rootLifecycle2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.rootLifecycle, () => ({
305
292
  addShutdownHook: jest.fn(),
306
293
  addBeforeShutdownHook: jest.fn(),
307
294
  addStartupHook: jest.fn()
@@ -309,7 +296,7 @@ exports.mockServices = void 0;
309
296
  })(mockServices2.rootLifecycle || (mockServices2.rootLifecycle = {}));
310
297
  ((scheduler2) => {
311
298
  scheduler2.factory = () => scheduler.schedulerServiceFactory;
312
- scheduler2.mock = simpleMock(backendPluginApi.coreServices.scheduler, () => ({
299
+ scheduler2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.scheduler, () => ({
313
300
  createScheduledTaskRunner: jest.fn(),
314
301
  getScheduledTasks: jest.fn(),
315
302
  scheduleTask: jest.fn(),
@@ -318,32 +305,19 @@ exports.mockServices = void 0;
318
305
  })(mockServices2.scheduler || (mockServices2.scheduler = {}));
319
306
  ((urlReader2) => {
320
307
  urlReader2.factory = () => urlReader.urlReaderServiceFactory;
321
- urlReader2.mock = simpleMock(backendPluginApi.coreServices.urlReader, () => ({
308
+ urlReader2.mock = simpleMock.simpleMock(backendPluginApi.coreServices.urlReader, () => ({
322
309
  readTree: jest.fn(),
323
310
  readUrl: jest.fn(),
324
311
  search: jest.fn()
325
312
  }));
326
313
  })(mockServices2.urlReader || (mockServices2.urlReader = {}));
327
- ((actions2) => {
328
- actions2.factory = () => actions.actionsServiceFactory;
329
- actions2.mock = simpleMock(backendPluginApi.coreServices.actions, () => ({
330
- list: jest.fn(),
331
- invoke: jest.fn()
332
- }));
333
- })(mockServices2.actions || (mockServices2.actions = {}));
334
- ((actionsRegistry2) => {
335
- actionsRegistry2.factory = () => actionsRegistry.actionsRegistryServiceFactory;
336
- actionsRegistry2.mock = simpleMock(backendPluginApi.coreServices.actionsRegistry, () => ({
337
- register: jest.fn()
338
- }));
339
- })(mockServices2.actionsRegistry || (mockServices2.actionsRegistry = {}));
340
314
  function events() {
341
315
  return new MockEventsService.MockEventsService();
342
316
  }
343
317
  mockServices2.events = events;
344
318
  ((events2) => {
345
319
  events2.factory = simpleFactoryWithOptions(pluginEventsNode.eventsServiceRef, events2);
346
- events2.mock = simpleMock(pluginEventsNode.eventsServiceRef, () => ({
320
+ events2.mock = simpleMock.simpleMock(pluginEventsNode.eventsServiceRef, () => ({
347
321
  publish: jest.fn(),
348
322
  subscribe: jest.fn()
349
323
  }));