@ballistix.digital/identity-connector 0.0.0-local

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 (71) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +631 -0
  3. package/dist/common/domain/enum/identityConnectorExceptionType.enum.d.ts +14 -0
  4. package/dist/common/domain/enum/identityConnectorExceptionType.enum.js +18 -0
  5. package/dist/common/domain/model/identity.d.ts +9 -0
  6. package/dist/common/domain/model/identity.js +2 -0
  7. package/dist/common/domain/model/identityProfile.d.ts +6 -0
  8. package/dist/common/domain/model/identityProfile.js +2 -0
  9. package/dist/index.d.ts +12 -0
  10. package/dist/index.js +23 -0
  11. package/dist/module/entra/domain/model/entraProviderOptions.d.ts +6 -0
  12. package/dist/module/entra/domain/model/entraProviderOptions.js +42 -0
  13. package/dist/module/entra/index.d.ts +2 -0
  14. package/dist/module/entra/index.js +7 -0
  15. package/dist/module/entra/service/entra.provider.d.ts +23 -0
  16. package/dist/module/entra/service/entra.provider.js +72 -0
  17. package/dist/module/identity/domain/exception/identityConnectorException.d.ts +5 -0
  18. package/dist/module/identity/domain/exception/identityConnectorException.js +48 -0
  19. package/dist/module/identity/domain/model/identityConnectorModuleOptions.d.ts +7 -0
  20. package/dist/module/identity/domain/model/identityConnectorModuleOptions.js +2 -0
  21. package/dist/module/identity/domain/model/identityProvider.d.ts +22 -0
  22. package/dist/module/identity/domain/model/identityProvider.js +17 -0
  23. package/dist/module/identity/domain/model/identityProviderOptions.d.ts +5 -0
  24. package/dist/module/identity/domain/model/identityProviderOptions.js +34 -0
  25. package/dist/module/identity/domain/model/identityProvidersToken.d.ts +1 -0
  26. package/dist/module/identity/domain/model/identityProvidersToken.js +4 -0
  27. package/dist/module/identity/domain/model/userStore.d.ts +10 -0
  28. package/dist/module/identity/domain/model/userStore.js +12 -0
  29. package/dist/module/identity/domain/validation/default.decorator.d.ts +1 -0
  30. package/dist/module/identity/domain/validation/default.decorator.js +10 -0
  31. package/dist/module/identity/domain/validation/trimmed.decorator.d.ts +2 -0
  32. package/dist/module/identity/domain/validation/trimmed.decorator.js +17 -0
  33. package/dist/module/identity/domain/validation/validateOptions.d.ts +2 -0
  34. package/dist/module/identity/domain/validation/validateOptions.js +44 -0
  35. package/dist/module/identity/identityConnector.module.d.ts +6 -0
  36. package/dist/module/identity/identityConnector.module.js +47 -0
  37. package/dist/module/identity/service/identityAuth.guard.d.ts +20 -0
  38. package/dist/module/identity/service/identityAuth.guard.js +117 -0
  39. package/dist/module/identity/service/identityManagement.d.ts +16 -0
  40. package/dist/module/identity/service/identityManagement.js +54 -0
  41. package/dist/module/identity/service/identityRuntime.d.ts +2 -0
  42. package/dist/module/identity/service/identityRuntime.js +6 -0
  43. package/dist/module/identity/service/identityRuntimeInternals.d.ts +11 -0
  44. package/dist/module/identity/service/identityRuntimeInternals.js +52 -0
  45. package/dist/module/identity/service/signIn.cache.d.ts +20 -0
  46. package/dist/module/identity/service/signIn.cache.js +102 -0
  47. package/dist/module/jwt/service/signedToken.verifier.d.ts +12 -0
  48. package/dist/module/jwt/service/signedToken.verifier.js +56 -0
  49. package/dist/module/zitadel/domain/model/zitadelManagementOptions.d.ts +4 -0
  50. package/dist/module/zitadel/domain/model/zitadelManagementOptions.js +31 -0
  51. package/dist/module/zitadel/domain/model/zitadelProviderOptions.d.ts +10 -0
  52. package/dist/module/zitadel/domain/model/zitadelProviderOptions.js +48 -0
  53. package/dist/module/zitadel/domain/model/zitadelServiceUserKey.d.ts +6 -0
  54. package/dist/module/zitadel/domain/model/zitadelServiceUserKey.js +42 -0
  55. package/dist/module/zitadel/domain/validation/isRsaPrivateKey.decorator.d.ts +2 -0
  56. package/dist/module/zitadel/domain/validation/isRsaPrivateKey.decorator.js +26 -0
  57. package/dist/module/zitadel/domain/validation/organizationIdList.decorator.d.ts +1 -0
  58. package/dist/module/zitadel/domain/validation/organizationIdList.decorator.js +19 -0
  59. package/dist/module/zitadel/index.d.ts +4 -0
  60. package/dist/module/zitadel/index.js +11 -0
  61. package/dist/module/zitadel/service/zitadel.provider.d.ts +40 -0
  62. package/dist/module/zitadel/service/zitadel.provider.js +266 -0
  63. package/dist/testing/index.d.ts +2 -0
  64. package/dist/testing/index.js +7 -0
  65. package/dist/testing/service/testIdentityProvider.mock.d.ts +42 -0
  66. package/dist/testing/service/testIdentityProvider.mock.js +118 -0
  67. package/dist/testing/service/userStore.contract.d.ts +17 -0
  68. package/dist/testing/service/userStore.contract.js +156 -0
  69. package/dist/types/index.d.ts +1 -0
  70. package/dist/types/index.js +5 -0
  71. package/package.json +139 -0
@@ -0,0 +1,9 @@
1
+ export interface Identity {
2
+ provider: string;
3
+ id: string;
4
+ email: string | null;
5
+ emailVerified: boolean;
6
+ givenName: string | null;
7
+ familyName: string | null;
8
+ roles: string[];
9
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ export interface IdentityProfile {
2
+ identityId: string | null;
3
+ email: string;
4
+ givenName: string;
5
+ familyName: string;
6
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,12 @@
1
+ export { IdentityConnectorExceptionTypeEnum } from './common/domain/enum/identityConnectorExceptionType.enum';
2
+ export { identityConnectorException, IdentityConnectorException, identityConnectorExceptionTypeOf, } from './module/identity/domain/exception/identityConnectorException';
3
+ export { Identity } from './common/domain/model/identity';
4
+ export { IdentityProfile } from './common/domain/model/identityProfile';
5
+ export { IdentityProviderOptions } from './module/identity/domain/model/identityProviderOptions';
6
+ export { IdentityConnectorModuleOptions } from './module/identity/domain/model/identityConnectorModuleOptions';
7
+ export { IdentityProvider, ManagementOptionsOf, ProviderIdentity, } from './module/identity/domain/model/identityProvider';
8
+ export { UserStore } from './module/identity/domain/model/userStore';
9
+ export { DEFAULT_SIGN_IN_CACHE_SECONDS, IdentityConnectorModule } from './module/identity/identityConnector.module';
10
+ export { IdentityAuthGuard } from './module/identity/service/identityAuth.guard';
11
+ export { IdentityManagement } from './module/identity/service/identityManagement';
12
+ export { IdentityRuntime } from './module/identity/service/identityRuntime';
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IdentityRuntime = exports.IdentityManagement = exports.IdentityAuthGuard = exports.IdentityConnectorModule = exports.DEFAULT_SIGN_IN_CACHE_SECONDS = exports.UserStore = exports.IdentityProvider = exports.IdentityProviderOptions = exports.identityConnectorExceptionTypeOf = exports.identityConnectorException = exports.IdentityConnectorExceptionTypeEnum = void 0;
4
+ var identityConnectorExceptionType_enum_1 = require("./common/domain/enum/identityConnectorExceptionType.enum");
5
+ Object.defineProperty(exports, "IdentityConnectorExceptionTypeEnum", { enumerable: true, get: function () { return identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum; } });
6
+ var identityConnectorException_1 = require("./module/identity/domain/exception/identityConnectorException");
7
+ Object.defineProperty(exports, "identityConnectorException", { enumerable: true, get: function () { return identityConnectorException_1.identityConnectorException; } });
8
+ Object.defineProperty(exports, "identityConnectorExceptionTypeOf", { enumerable: true, get: function () { return identityConnectorException_1.identityConnectorExceptionTypeOf; } });
9
+ var identityProviderOptions_1 = require("./module/identity/domain/model/identityProviderOptions");
10
+ Object.defineProperty(exports, "IdentityProviderOptions", { enumerable: true, get: function () { return identityProviderOptions_1.IdentityProviderOptions; } });
11
+ var identityProvider_1 = require("./module/identity/domain/model/identityProvider");
12
+ Object.defineProperty(exports, "IdentityProvider", { enumerable: true, get: function () { return identityProvider_1.IdentityProvider; } });
13
+ var userStore_1 = require("./module/identity/domain/model/userStore");
14
+ Object.defineProperty(exports, "UserStore", { enumerable: true, get: function () { return userStore_1.UserStore; } });
15
+ var identityConnector_module_1 = require("./module/identity/identityConnector.module");
16
+ Object.defineProperty(exports, "DEFAULT_SIGN_IN_CACHE_SECONDS", { enumerable: true, get: function () { return identityConnector_module_1.DEFAULT_SIGN_IN_CACHE_SECONDS; } });
17
+ Object.defineProperty(exports, "IdentityConnectorModule", { enumerable: true, get: function () { return identityConnector_module_1.IdentityConnectorModule; } });
18
+ var identityAuth_guard_1 = require("./module/identity/service/identityAuth.guard");
19
+ Object.defineProperty(exports, "IdentityAuthGuard", { enumerable: true, get: function () { return identityAuth_guard_1.IdentityAuthGuard; } });
20
+ var identityManagement_1 = require("./module/identity/service/identityManagement");
21
+ Object.defineProperty(exports, "IdentityManagement", { enumerable: true, get: function () { return identityManagement_1.IdentityManagement; } });
22
+ var identityRuntime_1 = require("./module/identity/service/identityRuntime");
23
+ Object.defineProperty(exports, "IdentityRuntime", { enumerable: true, get: function () { return identityRuntime_1.IdentityRuntime; } });
@@ -0,0 +1,6 @@
1
+ import { IdentityProviderOptions } from '../../../identity/domain/model/identityProviderOptions';
2
+ export declare class EntraProviderOptions extends IdentityProviderOptions {
3
+ tenantId: string;
4
+ audience: string | string[];
5
+ acceptIdTokens?: boolean;
6
+ }
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.EntraProviderOptions = void 0;
13
+ const class_transformer_1 = require("class-transformer");
14
+ const class_validator_1 = require("class-validator");
15
+ const identityProviderOptions_1 = require("../../../identity/domain/model/identityProviderOptions");
16
+ const default_decorator_1 = require("../../../identity/domain/validation/default.decorator");
17
+ const trimmed_decorator_1 = require("../../../identity/domain/validation/trimmed.decorator");
18
+ class EntraProviderOptions extends identityProviderOptions_1.IdentityProviderOptions {
19
+ }
20
+ exports.EntraProviderOptions = EntraProviderOptions;
21
+ __decorate([
22
+ (0, class_transformer_1.Transform)(({ value }) => (typeof value === 'string' ? value.trim().toLowerCase() : value)),
23
+ (0, class_validator_1.IsString)(),
24
+ (0, class_validator_1.IsNotEmpty)(),
25
+ (0, class_validator_1.Matches)(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/, {
26
+ message: '$property must be the GUID of one tenant, not "$value"; a multi-tenant value names no single issuer',
27
+ }),
28
+ __metadata("design:type", String)
29
+ ], EntraProviderOptions.prototype, "tenantId", void 0);
30
+ __decorate([
31
+ (0, trimmed_decorator_1.TrimmedList)(true),
32
+ (0, class_validator_1.IsArray)({ message: '$property must be a non-empty string, or a list of them' }),
33
+ (0, class_validator_1.ArrayNotEmpty)({ message: '$property must name at least one audience' }),
34
+ (0, class_validator_1.IsString)({ each: true }),
35
+ (0, class_validator_1.IsNotEmpty)({ each: true }),
36
+ __metadata("design:type", Object)
37
+ ], EntraProviderOptions.prototype, "audience", void 0);
38
+ __decorate([
39
+ (0, default_decorator_1.Default)(false),
40
+ (0, class_validator_1.IsBoolean)(),
41
+ __metadata("design:type", Boolean)
42
+ ], EntraProviderOptions.prototype, "acceptIdTokens", void 0);
@@ -0,0 +1,2 @@
1
+ export { EntraProviderOptions } from './domain/model/entraProviderOptions';
2
+ export { EntraProvider } from './service/entra.provider';
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EntraProvider = exports.EntraProviderOptions = void 0;
4
+ var entraProviderOptions_1 = require("./domain/model/entraProviderOptions");
5
+ Object.defineProperty(exports, "EntraProviderOptions", { enumerable: true, get: function () { return entraProviderOptions_1.EntraProviderOptions; } });
6
+ var entra_provider_1 = require("./service/entra.provider");
7
+ Object.defineProperty(exports, "EntraProvider", { enumerable: true, get: function () { return entra_provider_1.EntraProvider; } });
@@ -0,0 +1,23 @@
1
+ import { IdentityProfile } from '../../../common/domain/model/identityProfile';
2
+ import { IdentityProvider, ProviderIdentity } from '../../identity/domain/model/identityProvider';
3
+ import { EntraProviderOptions } from '../domain/model/entraProviderOptions';
4
+ export declare class EntraProvider extends IdentityProvider {
5
+ readonly issuers: [string, ...string[]];
6
+ private readonly tenantId;
7
+ private readonly audience;
8
+ private readonly acceptIdTokens;
9
+ private readonly verifier;
10
+ constructor(options: EntraProviderOptions);
11
+ private get loginUrl();
12
+ private get v1IssuerUrl();
13
+ authenticate(accessToken: string): Promise<ProviderIdentity>;
14
+ readProfile(accessToken: string, identity: ProviderIdentity): Promise<ProviderIdentity>;
15
+ findByEmail(email: string, managementOptions: unknown): Promise<string | null>;
16
+ create(profile: IdentityProfile, managementOptions: unknown): Promise<string>;
17
+ createAccountSetupLink(identityId: string, managementOptions: unknown, options?: {
18
+ returnUrl?: string;
19
+ }): Promise<string>;
20
+ isFederated(email: string, managementOptions: unknown): Promise<boolean>;
21
+ private static isIdToken;
22
+ private static rolesOf;
23
+ }
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EntraProvider = void 0;
4
+ const identityConnectorExceptionType_enum_1 = require("../../../common/domain/enum/identityConnectorExceptionType.enum");
5
+ const identityConnectorException_1 = require("../../identity/domain/exception/identityConnectorException");
6
+ const identityProvider_1 = require("../../identity/domain/model/identityProvider");
7
+ const validateOptions_1 = require("../../identity/domain/validation/validateOptions");
8
+ const signedToken_verifier_1 = require("../../jwt/service/signedToken.verifier");
9
+ const entraProviderOptions_1 = require("../domain/model/entraProviderOptions");
10
+ class EntraProvider extends identityProvider_1.IdentityProvider {
11
+ constructor(options) {
12
+ const checked = (0, validateOptions_1.validateOptions)(entraProviderOptions_1.EntraProviderOptions, options, `Entra provider "${options?.name}"`);
13
+ super(checked);
14
+ this.tenantId = checked.tenantId;
15
+ this.audience = checked.audience;
16
+ this.acceptIdTokens = checked.acceptIdTokens;
17
+ this.issuers = [`${this.loginUrl}/${this.tenantId}/v2.0`, `${this.v1IssuerUrl}/${this.tenantId}/`];
18
+ this.verifier = new signedToken_verifier_1.SignedTokenVerifier({
19
+ keysUrl: `${this.loginUrl}/${this.tenantId}/discovery/v2.0/keys`,
20
+ issuers: this.issuers,
21
+ audience: this.audience,
22
+ });
23
+ }
24
+ get loginUrl() {
25
+ return 'https://login.microsoftonline.com';
26
+ }
27
+ get v1IssuerUrl() {
28
+ return 'https://sts.windows.net';
29
+ }
30
+ async authenticate(accessToken) {
31
+ const claims = await this.verifier.verify(accessToken);
32
+ if (typeof claims.oid !== 'string' || claims.oid === '') {
33
+ throw (0, identityConnectorException_1.identityConnectorException)(identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.INVALID_TOKEN);
34
+ }
35
+ const hasScopes = typeof claims.scp === 'string' && claims.scp.trim() !== '';
36
+ if (!hasScopes && !(this.acceptIdTokens && EntraProvider.isIdToken(claims))) {
37
+ throw (0, identityConnectorException_1.identityConnectorException)(identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.INVALID_TOKEN);
38
+ }
39
+ return {
40
+ id: claims.oid,
41
+ email: typeof claims.email === 'string' ? claims.email : null,
42
+ emailVerified: false,
43
+ givenName: typeof claims.given_name === 'string' ? claims.given_name : null,
44
+ familyName: typeof claims.family_name === 'string' ? claims.family_name : null,
45
+ roles: EntraProvider.rolesOf(claims),
46
+ };
47
+ }
48
+ async readProfile(accessToken, identity) {
49
+ return identity;
50
+ }
51
+ async findByEmail(email, managementOptions) {
52
+ throw (0, identityConnectorException_1.identityConnectorException)(identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.NOT_CONFIGURED);
53
+ }
54
+ async create(profile, managementOptions) {
55
+ throw (0, identityConnectorException_1.identityConnectorException)(identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.NOT_CONFIGURED);
56
+ }
57
+ async createAccountSetupLink(identityId, managementOptions, options) {
58
+ throw (0, identityConnectorException_1.identityConnectorException)(identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.NOT_SUPPORTED);
59
+ }
60
+ async isFederated(email, managementOptions) {
61
+ throw (0, identityConnectorException_1.identityConnectorException)(identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.NOT_SUPPORTED);
62
+ }
63
+ static isIdToken(claims) {
64
+ const namesClient = ['azp', 'appid'].some((claim) => claims[claim] !== undefined) || claims.idtyp === 'app';
65
+ const namesPerson = ['name', 'preferred_username', 'unique_name'].some((claim) => typeof claims[claim] === 'string' && claims[claim].trim() !== '');
66
+ return !namesClient && namesPerson;
67
+ }
68
+ static rolesOf(claims) {
69
+ return Array.isArray(claims.roles) ? claims.roles.filter((role) => typeof role === 'string') : [];
70
+ }
71
+ }
72
+ exports.EntraProvider = EntraProvider;
@@ -0,0 +1,5 @@
1
+ import { BaseException, GenericErrorDetailDto, PreconditionFailedDetailDto } from '@ballistix.digital/exception-types';
2
+ import { IdentityConnectorExceptionTypeEnum } from '../../../../common/domain/enum/identityConnectorExceptionType.enum';
3
+ export type IdentityConnectorException = BaseException<GenericErrorDetailDto | PreconditionFailedDetailDto>;
4
+ export declare function identityConnectorException(type: IdentityConnectorExceptionTypeEnum): IdentityConnectorException;
5
+ export declare function identityConnectorExceptionTypeOf(error: unknown): IdentityConnectorExceptionTypeEnum | undefined;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.identityConnectorException = identityConnectorException;
4
+ exports.identityConnectorExceptionTypeOf = identityConnectorExceptionTypeOf;
5
+ const exception_types_1 = require("@ballistix.digital/exception-types");
6
+ const identityConnectorExceptionType_enum_1 = require("../../../../common/domain/enum/identityConnectorExceptionType.enum");
7
+ const { ACCESS_DENIED, GENERIC_ERROR, PRECONDITION_FAILED, UNAUTHENTICATED } = exception_types_1.ExceptionCodeEnum;
8
+ const ENVELOPE_BY_TYPE = {
9
+ [identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.NO_TOKEN]: { code: UNAUTHENTICATED, status: 401 },
10
+ [identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.UNKNOWN_ISSUER]: { code: UNAUTHENTICATED, status: 401 },
11
+ [identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.PROVIDER_NOT_ACCEPTED]: { code: UNAUTHENTICATED, status: 401 },
12
+ [identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.INVALID_TOKEN]: { code: UNAUTHENTICATED, status: 401 },
13
+ [identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.PROVIDER_UNREACHABLE]: { code: GENERIC_ERROR, status: 503 },
14
+ [identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.USER_NOT_LINKED]: { code: ACCESS_DENIED, status: 403 },
15
+ [identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.USER_NOT_PROVISIONED]: { code: PRECONDITION_FAILED, status: 409 },
16
+ [identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.IDENTITY_ALREADY_LINKED]: { code: PRECONDITION_FAILED, status: 409 },
17
+ [identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.LINK_REFUSED]: { code: PRECONDITION_FAILED, status: 409 },
18
+ [identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.NO_EMAIL]: { code: PRECONDITION_FAILED, status: 409 },
19
+ [identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.NOT_SUPPORTED]: { code: GENERIC_ERROR, status: 501 },
20
+ [identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum.NOT_CONFIGURED]: { code: GENERIC_ERROR, status: 503 },
21
+ };
22
+ const TYPES = new Set(Object.values(identityConnectorExceptionType_enum_1.IdentityConnectorExceptionTypeEnum));
23
+ function identityConnectorException(type) {
24
+ const { code, status } = ENVELOPE_BY_TYPE[type];
25
+ if (code === PRECONDITION_FAILED) {
26
+ return new exception_types_1.PreconditionFailedException(type);
27
+ }
28
+ if (code === ACCESS_DENIED) {
29
+ return new exception_types_1.AccessDeniedException(type);
30
+ }
31
+ if (code === UNAUTHENTICATED) {
32
+ return new exception_types_1.UnauthenticatedException(type);
33
+ }
34
+ return new exception_types_1.GenericErrorException(type, status);
35
+ }
36
+ function identityConnectorExceptionTypeOf(error) {
37
+ if (!(error instanceof exception_types_1.BaseException)) {
38
+ return undefined;
39
+ }
40
+ const detail = error.errors?.[0];
41
+ const candidate = error.code === PRECONDITION_FAILED ? detail?.condition : detail?.message;
42
+ if (typeof candidate !== 'string' || !TYPES.has(candidate)) {
43
+ return undefined;
44
+ }
45
+ const type = candidate;
46
+ const expected = identityConnectorException(type);
47
+ return error.code === expected.code && error.status === expected.status ? type : undefined;
48
+ }
@@ -0,0 +1,7 @@
1
+ import { ModuleMetadata, Type } from '@nestjs/common';
2
+ import { IdentityProvider } from './identityProvider';
3
+ export interface IdentityConnectorModuleOptions {
4
+ identityProviders: Type<IdentityProvider>[];
5
+ imports?: ModuleMetadata['imports'];
6
+ signInCacheSeconds?: number;
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,22 @@
1
+ import { Type } from '@nestjs/common';
2
+ import { Identity } from '../../../../common/domain/model/identity';
3
+ import { IdentityProfile } from '../../../../common/domain/model/identityProfile';
4
+ import { IdentityProviderOptions } from './identityProviderOptions';
5
+ export type ProviderIdentity = Omit<Identity, 'provider'>;
6
+ export declare abstract class IdentityProvider<TManagementOptions = unknown> {
7
+ readonly name: string;
8
+ abstract readonly issuers: string[];
9
+ readonly linkByEmail: boolean;
10
+ readonly createOnSignIn: boolean;
11
+ constructor(options: IdentityProviderOptions);
12
+ abstract authenticate(accessToken: string): Promise<ProviderIdentity>;
13
+ abstract readProfile(accessToken: string, identity: ProviderIdentity): Promise<ProviderIdentity>;
14
+ get managementOptionsType(): Type<TManagementOptions> | undefined;
15
+ abstract findByEmail(email: string, managementOptions: TManagementOptions): Promise<string | null>;
16
+ abstract create(profile: IdentityProfile, managementOptions: TManagementOptions): Promise<string>;
17
+ abstract createAccountSetupLink(identityId: string, managementOptions: TManagementOptions, options?: {
18
+ returnUrl?: string;
19
+ }): Promise<string>;
20
+ abstract isFederated(email: string, managementOptions: TManagementOptions): Promise<boolean>;
21
+ }
22
+ export type ManagementOptionsOf<TProvider> = TProvider extends IdentityProvider<infer T> ? T : never;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IdentityProvider = void 0;
4
+ const validateOptions_1 = require("../validation/validateOptions");
5
+ const identityProviderOptions_1 = require("./identityProviderOptions");
6
+ class IdentityProvider {
7
+ constructor(options) {
8
+ const checked = (0, validateOptions_1.validateOptions)(identityProviderOptions_1.IdentityProviderOptions, options, `Identity provider "${options?.name}"`);
9
+ this.name = checked.name;
10
+ this.linkByEmail = checked.linkByEmail;
11
+ this.createOnSignIn = checked.createOnSignIn;
12
+ }
13
+ get managementOptionsType() {
14
+ return undefined;
15
+ }
16
+ }
17
+ exports.IdentityProvider = IdentityProvider;
@@ -0,0 +1,5 @@
1
+ export declare class IdentityProviderOptions {
2
+ name: string;
3
+ linkByEmail?: boolean;
4
+ createOnSignIn?: boolean;
5
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.IdentityProviderOptions = void 0;
13
+ const class_validator_1 = require("class-validator");
14
+ const default_decorator_1 = require("../validation/default.decorator");
15
+ const trimmed_decorator_1 = require("../validation/trimmed.decorator");
16
+ class IdentityProviderOptions {
17
+ }
18
+ exports.IdentityProviderOptions = IdentityProviderOptions;
19
+ __decorate([
20
+ (0, trimmed_decorator_1.Trimmed)(),
21
+ (0, class_validator_1.IsString)(),
22
+ (0, class_validator_1.IsNotEmpty)(),
23
+ __metadata("design:type", String)
24
+ ], IdentityProviderOptions.prototype, "name", void 0);
25
+ __decorate([
26
+ (0, default_decorator_1.Default)(false),
27
+ (0, class_validator_1.IsBoolean)(),
28
+ __metadata("design:type", Boolean)
29
+ ], IdentityProviderOptions.prototype, "linkByEmail", void 0);
30
+ __decorate([
31
+ (0, default_decorator_1.Default)(false),
32
+ (0, class_validator_1.IsBoolean)(),
33
+ __metadata("design:type", Boolean)
34
+ ], IdentityProviderOptions.prototype, "createOnSignIn", void 0);
@@ -0,0 +1 @@
1
+ export declare const IDENTITY_PROVIDERS: unique symbol;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IDENTITY_PROVIDERS = void 0;
4
+ exports.IDENTITY_PROVIDERS = Symbol('IDENTITY_PROVIDERS');
@@ -0,0 +1,10 @@
1
+ import { Identity } from '../../../../common/domain/model/identity';
2
+ import { IdentityProfile } from '../../../../common/domain/model/identityProfile';
3
+ export declare abstract class UserStore<TUser> {
4
+ abstract findByIdentityId(identityId: string, provider: string, transaction?: unknown): Promise<TUser | null>;
5
+ linkByEmail(identity: Identity): Promise<TUser | null>;
6
+ create(identity: Identity): Promise<TUser | null>;
7
+ abstract sync(user: TUser, identity: Identity): Promise<TUser>;
8
+ abstract toProfile(user: TUser, provider: string): IdentityProfile;
9
+ abstract link(user: TUser, identityId: string, provider: string, transaction?: unknown): Promise<boolean>;
10
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UserStore = void 0;
4
+ class UserStore {
5
+ async linkByEmail(identity) {
6
+ return null;
7
+ }
8
+ async create(identity) {
9
+ return null;
10
+ }
11
+ }
12
+ exports.UserStore = UserStore;
@@ -0,0 +1 @@
1
+ export declare function Default(fallback: unknown): PropertyDecorator;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Default = Default;
4
+ const class_transformer_1 = require("class-transformer");
5
+ function Default(fallback) {
6
+ return (target, property) => {
7
+ (0, class_transformer_1.Expose)()(target, property);
8
+ (0, class_transformer_1.Transform)(({ value }) => value ?? fallback)(target, property);
9
+ };
10
+ }
@@ -0,0 +1,2 @@
1
+ export declare function Trimmed(): PropertyDecorator;
2
+ export declare function TrimmedList(acceptOne?: boolean): PropertyDecorator;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Trimmed = Trimmed;
4
+ exports.TrimmedList = TrimmedList;
5
+ const class_transformer_1 = require("class-transformer");
6
+ function Trimmed() {
7
+ return (0, class_transformer_1.Transform)(({ value }) => (typeof value === 'string' ? value.trim() : value));
8
+ }
9
+ function TrimmedList(acceptOne = false) {
10
+ return (0, class_transformer_1.Transform)(({ value }) => {
11
+ const list = acceptOne && typeof value === 'string' ? [value] : value;
12
+ if (!Array.isArray(list) || list.some((entry) => typeof entry !== 'string')) {
13
+ return list;
14
+ }
15
+ return [...new Set(list.map((entry) => entry.trim()))];
16
+ });
17
+ }
@@ -0,0 +1,2 @@
1
+ import { Type } from '@nestjs/common';
2
+ export declare function validateOptions<T extends object>(type: Type<T>, options: unknown, label: string, what?: string): T;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateOptions = validateOptions;
4
+ const class_transformer_1 = require("class-transformer");
5
+ const class_validator_1 = require("class-validator");
6
+ function validateOptions(type, options, label, what = 'options') {
7
+ const given = (options !== null && typeof options === 'object' && !Array.isArray(options) ? options : {});
8
+ const declared = declaredOptionsOf(type);
9
+ const read = Object.fromEntries(declared.filter((option) => option in given).map((option) => [option, given[option]]));
10
+ const checked = (0, class_transformer_1.plainToInstance)(type, read);
11
+ const errors = (0, class_validator_1.validateSync)(checked, {
12
+ forbidUnknownValues: false,
13
+ validationError: { target: false, value: false },
14
+ });
15
+ if (errors.length > 0) {
16
+ throw new Error(`${label} has invalid ${what}: ${messagesOf(errors).join('; ')}.`, { cause: errors });
17
+ }
18
+ for (const [option, value] of Object.entries(given)) {
19
+ if (!declared.includes(option)) {
20
+ Object.defineProperty(checked, option, { value, enumerable: true, writable: true, configurable: true });
21
+ }
22
+ }
23
+ return checked;
24
+ }
25
+ function declaredOptionsOf(type) {
26
+ const rules = (0, class_validator_1.getMetadataStorage)().getTargetValidationMetadatas(type, '', false, false);
27
+ return [...new Set(rules.map((rule) => rule.propertyName))];
28
+ }
29
+ function messagesOf(errors, parent) {
30
+ return errors.flatMap((error) => {
31
+ const path = parent ? `${parent}.${error.property}` : error.property;
32
+ const message = Object.values(error.constraints ?? {}).at(-1);
33
+ const own = message === undefined
34
+ ? []
35
+ : [
36
+ message.startsWith(`${error.property} `)
37
+ ? `${path}${message.slice(error.property.length)}`
38
+ : parent
39
+ ? `${path}: ${message}`
40
+ : message,
41
+ ];
42
+ return [...own, ...messagesOf(error.children ?? [], path)];
43
+ });
44
+ }
@@ -0,0 +1,6 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import { IdentityConnectorModuleOptions } from './domain/model/identityConnectorModuleOptions';
3
+ export declare const DEFAULT_SIGN_IN_CACHE_SECONDS = 60;
4
+ export declare class IdentityConnectorModule {
5
+ static forRoot(options: IdentityConnectorModuleOptions): DynamicModule;
6
+ }
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var IdentityConnectorModule_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.IdentityConnectorModule = exports.DEFAULT_SIGN_IN_CACHE_SECONDS = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ const identityProvidersToken_1 = require("./domain/model/identityProvidersToken");
13
+ const identityRuntime_1 = require("./service/identityRuntime");
14
+ const identityRuntimeInternals_1 = require("./service/identityRuntimeInternals");
15
+ const signIn_cache_1 = require("./service/signIn.cache");
16
+ exports.DEFAULT_SIGN_IN_CACHE_SECONDS = 60;
17
+ let IdentityConnectorModule = IdentityConnectorModule_1 = class IdentityConnectorModule {
18
+ static forRoot(options) {
19
+ const { identityProviders } = options;
20
+ const signInCacheSeconds = options.signInCacheSeconds ?? exports.DEFAULT_SIGN_IN_CACHE_SECONDS;
21
+ signIn_cache_1.SignInCache.assertLifetime(signInCacheSeconds);
22
+ const listedTwice = identityProviders.find((type, index) => identityProviders.indexOf(type) !== index);
23
+ if (listedTwice) {
24
+ throw new Error(`IdentityConnectorModule.forRoot() lists ${listedTwice.name} twice in identityProviders.`);
25
+ }
26
+ return {
27
+ module: IdentityConnectorModule_1,
28
+ imports: options.imports ?? [],
29
+ providers: [
30
+ ...identityProviders,
31
+ {
32
+ provide: identityProvidersToken_1.IDENTITY_PROVIDERS,
33
+ useFactory: (...providers) => providers,
34
+ inject: identityProviders,
35
+ },
36
+ { provide: signIn_cache_1.SignInCache, useFactory: () => new signIn_cache_1.SignInCache(signInCacheSeconds) },
37
+ { provide: identityRuntime_1.IdentityRuntime, useClass: identityRuntimeInternals_1.IdentityRuntimeInternals },
38
+ ],
39
+ exports: [identityRuntime_1.IdentityRuntime, ...identityProviders],
40
+ };
41
+ }
42
+ };
43
+ exports.IdentityConnectorModule = IdentityConnectorModule;
44
+ exports.IdentityConnectorModule = IdentityConnectorModule = IdentityConnectorModule_1 = __decorate([
45
+ (0, common_1.Global)(),
46
+ (0, common_1.Module)({})
47
+ ], IdentityConnectorModule);
@@ -0,0 +1,20 @@
1
+ import { CanActivate, ExecutionContext, OnModuleInit } from '@nestjs/common';
2
+ import { IdentityProvider } from '../domain/model/identityProvider';
3
+ import { UserStore } from '../domain/model/userStore';
4
+ import { IdentityRuntime } from './identityRuntime';
5
+ export declare abstract class IdentityAuthGuard<TUser> implements CanActivate, OnModuleInit {
6
+ private readonly store;
7
+ private readonly runtime;
8
+ private readonly providers;
9
+ constructor(runtime: IdentityRuntime, store: UserStore<TUser>, providers: [IdentityProvider, ...IdentityProvider[]]);
10
+ onModuleInit(): void;
11
+ canActivate(context: ExecutionContext): Promise<boolean>;
12
+ private signIn;
13
+ private providerOf;
14
+ private static readBearerToken;
15
+ private static readUnverifiedIssuer;
16
+ private assertStoreAllows;
17
+ private resolveUser;
18
+ private authenticate;
19
+ private signInFirstTime;
20
+ }