@open-core/identity 1.0.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 (46) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +682 -0
  3. package/dist/entities/account.entity.d.ts +34 -0
  4. package/dist/entities/account.entity.js +2 -0
  5. package/dist/entities/role.entity.d.ts +35 -0
  6. package/dist/entities/role.entity.js +2 -0
  7. package/dist/events/identity.events.d.ts +24 -0
  8. package/dist/events/identity.events.js +2 -0
  9. package/dist/index.d.ts +70 -0
  10. package/dist/index.js +100 -0
  11. package/dist/repositories/account.repository.d.ts +60 -0
  12. package/dist/repositories/account.repository.js +185 -0
  13. package/dist/repositories/role.repository.d.ts +50 -0
  14. package/dist/repositories/role.repository.js +79 -0
  15. package/dist/services/account.service.d.ts +78 -0
  16. package/dist/services/account.service.js +207 -0
  17. package/dist/services/auth/api-auth.provider.d.ts +30 -0
  18. package/dist/services/auth/api-auth.provider.js +134 -0
  19. package/dist/services/auth/credentials-auth.provider.d.ts +27 -0
  20. package/dist/services/auth/credentials-auth.provider.js +214 -0
  21. package/dist/services/auth/local-auth.provider.d.ts +28 -0
  22. package/dist/services/auth/local-auth.provider.js +135 -0
  23. package/dist/services/cache/memory-cache.service.d.ts +47 -0
  24. package/dist/services/cache/memory-cache.service.js +108 -0
  25. package/dist/services/identity-auth.provider.d.ts +18 -0
  26. package/dist/services/identity-auth.provider.js +125 -0
  27. package/dist/services/identity-principal.provider.d.ts +29 -0
  28. package/dist/services/identity-principal.provider.js +104 -0
  29. package/dist/services/principal/api-principal.provider.d.ts +27 -0
  30. package/dist/services/principal/api-principal.provider.js +141 -0
  31. package/dist/services/principal/local-principal.provider.d.ts +39 -0
  32. package/dist/services/principal/local-principal.provider.js +114 -0
  33. package/dist/services/role.service.d.ts +73 -0
  34. package/dist/services/role.service.js +145 -0
  35. package/dist/setup.d.ts +58 -0
  36. package/dist/setup.js +93 -0
  37. package/dist/types/auth.types.d.ts +48 -0
  38. package/dist/types/auth.types.js +2 -0
  39. package/dist/types/index.d.ts +36 -0
  40. package/dist/types/index.js +2 -0
  41. package/migrations/001_accounts_table.sql +16 -0
  42. package/migrations/002_roles_table.sql +21 -0
  43. package/migrations/003_alter_accounts_add_role.sql +24 -0
  44. package/migrations/004_rename_uuid_to_linked_id.sql +12 -0
  45. package/migrations/005_add_password_hash.sql +7 -0
  46. package/package.json +59 -0
@@ -0,0 +1,141 @@
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.ApiPrincipalProvider = void 0;
13
+ const tsyringe_1 = require("tsyringe");
14
+ const framework_1 = require("@open-core/framework");
15
+ const memory_cache_service_1 = require("../cache/memory-cache.service");
16
+ /**
17
+ * API-based principal provider that fetches permissions from external API.
18
+ * Does NOT require local database (uses memory cache only).
19
+ *
20
+ * Features:
21
+ * - GETs principal data from external API by linkedId
22
+ * - Caches results in RAM with configurable TTL
23
+ * - Falls back to empty permissions if API fails
24
+ * - Optionally syncs to local DB if configured
25
+ *
26
+ * Expected API endpoint: GET {principalUrl}/principals/{linkedId}
27
+ * Response: { name?: string, rank?: number, permissions: string[], meta?: {...} }
28
+ */
29
+ let ApiPrincipalProvider = class ApiPrincipalProvider {
30
+ constructor(config, http, cache) {
31
+ this.config = config;
32
+ this.http = http;
33
+ this.cache = cache;
34
+ // Load API configuration from convars
35
+ const principalUrl = this.config.get("identity_api_principal_url", "") ||
36
+ this.config.get("identity_api_auth_url", "") ||
37
+ "http://localhost:3000/api";
38
+ this.apiConfig = {
39
+ authUrl: principalUrl,
40
+ principalUrl: principalUrl,
41
+ headers: this.parseHeaders(this.config.get("identity_api_headers", "")),
42
+ timeoutMs: this.config.getNumber("identity_api_timeout", 5000),
43
+ };
44
+ this.cacheTtl = this.config.getNumber("identity_cache_ttl", 300000); // 5 min default
45
+ }
46
+ async getPrincipal(player) {
47
+ const linked = player.accountID;
48
+ if (!linked) {
49
+ throw new framework_1.Utils.AppError("UNAUTHORIZED", "Player is not authenticated (no linked account)", "server");
50
+ }
51
+ // Check cache first
52
+ const cacheKey = `principal:${linked}`;
53
+ const cached = this.cache.get(cacheKey);
54
+ if (cached) {
55
+ return cached;
56
+ }
57
+ // Fetch from API
58
+ try {
59
+ const url = `${this.apiConfig.principalUrl}/principals/${linked}`;
60
+ const response = await this.http.get(url, {
61
+ headers: this.apiConfig.headers,
62
+ timeoutMs: this.apiConfig.timeoutMs,
63
+ });
64
+ const principal = {
65
+ id: String(linked),
66
+ name: response.name,
67
+ rank: response.rank,
68
+ permissions: response.permissions ?? [],
69
+ meta: response.meta ?? {},
70
+ };
71
+ // Cache the result
72
+ this.cache.set(cacheKey, principal, this.cacheTtl);
73
+ return principal;
74
+ }
75
+ catch (error) {
76
+ // If API fails, return empty principal or throw based on config
77
+ const allowFallback = this.config.getBoolean("identity_api_allow_fallback", false);
78
+ if (allowFallback) {
79
+ return {
80
+ id: String(linked),
81
+ permissions: [],
82
+ meta: {},
83
+ };
84
+ }
85
+ throw new framework_1.Utils.AppError("UNAUTHORIZED", `Failed to fetch principal from API: ${error instanceof Error ? error.message : "Unknown error"}`, "server");
86
+ }
87
+ }
88
+ async refreshPrincipal(player) {
89
+ const linked = player.accountID;
90
+ if (linked) {
91
+ // Clear cache to force refresh
92
+ this.cache.delete(`principal:${linked}`);
93
+ }
94
+ const principal = await this.getPrincipal(player);
95
+ player.setMeta("identity:principal", principal);
96
+ }
97
+ async getPrincipalByLinkedID(linkedID) {
98
+ // Check cache first
99
+ const cacheKey = `principal:${linkedID}`;
100
+ const cached = this.cache.get(cacheKey);
101
+ if (cached) {
102
+ return cached;
103
+ }
104
+ // Fetch from API
105
+ try {
106
+ const url = `${this.apiConfig.principalUrl}/principals/${linkedID}`;
107
+ const response = await this.http.get(url, {
108
+ headers: this.apiConfig.headers,
109
+ timeoutMs: this.apiConfig.timeoutMs,
110
+ });
111
+ const principal = {
112
+ id: linkedID,
113
+ name: response.name,
114
+ rank: response.rank,
115
+ permissions: response.permissions ?? [],
116
+ meta: response.meta ?? {},
117
+ };
118
+ // Cache the result
119
+ this.cache.set(cacheKey, principal, this.cacheTtl);
120
+ return principal;
121
+ }
122
+ catch {
123
+ return null;
124
+ }
125
+ }
126
+ parseHeaders(headersString) {
127
+ if (!headersString)
128
+ return {};
129
+ try {
130
+ return JSON.parse(headersString);
131
+ }
132
+ catch {
133
+ return {};
134
+ }
135
+ }
136
+ };
137
+ exports.ApiPrincipalProvider = ApiPrincipalProvider;
138
+ exports.ApiPrincipalProvider = ApiPrincipalProvider = __decorate([
139
+ (0, tsyringe_1.injectable)(),
140
+ __metadata("design:paramtypes", [framework_1.Server.ConfigService, framework_1.Server.HttpService, memory_cache_service_1.MemoryCacheService])
141
+ ], ApiPrincipalProvider);
@@ -0,0 +1,39 @@
1
+ import { Server } from "@open-core/framework";
2
+ import { AccountService } from "../account.service";
3
+ import { AccountRepository } from "../../repositories/account.repository";
4
+ /**
5
+ * Local principal provider that reads roles and permissions from local database.
6
+ * This is the default/traditional principal provider for FiveM servers.
7
+ *
8
+ * Features:
9
+ * - Reads from local database (accounts + roles tables)
10
+ * - Combines role permissions with custom account permissions
11
+ * - Supports permission negation (e.g., "-admin.ban")
12
+ * - Caches in player metadata
13
+ */
14
+ export declare class LocalPrincipalProvider implements Server.PrincipalProviderContract {
15
+ private readonly accounts;
16
+ private readonly repo;
17
+ constructor(accounts: AccountService, repo: AccountRepository);
18
+ getPrincipal(player: Server.Player): Promise<Server.Principal | null>;
19
+ refreshPrincipal(player: Server.Player): Promise<void>;
20
+ getPrincipalByLinkedID(linkedID: string): Promise<Server.Principal | null>;
21
+ /**
22
+ * Builds a Principal from account and role.
23
+ * Combines role permissions with account custom permissions.
24
+ *
25
+ * @param account - Account entity
26
+ * @param role - Role entity (or null if no role assigned)
27
+ * @returns Principal with combined permissions
28
+ */
29
+ private toPrincipal;
30
+ /**
31
+ * Combine role permissions with account custom permissions.
32
+ * Custom permissions starting with '-' negate the base permission.
33
+ *
34
+ * @param role - Role with base permissions
35
+ * @param customPerms - Account custom permissions
36
+ * @returns Combined permissions array
37
+ */
38
+ private combinePermissions;
39
+ }
@@ -0,0 +1,114 @@
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.LocalPrincipalProvider = void 0;
13
+ const tsyringe_1 = require("tsyringe");
14
+ const framework_1 = require("@open-core/framework");
15
+ const account_service_1 = require("../account.service");
16
+ const account_repository_1 = require("../../repositories/account.repository");
17
+ /**
18
+ * Local principal provider that reads roles and permissions from local database.
19
+ * This is the default/traditional principal provider for FiveM servers.
20
+ *
21
+ * Features:
22
+ * - Reads from local database (accounts + roles tables)
23
+ * - Combines role permissions with custom account permissions
24
+ * - Supports permission negation (e.g., "-admin.ban")
25
+ * - Caches in player metadata
26
+ */
27
+ let LocalPrincipalProvider = class LocalPrincipalProvider {
28
+ constructor(accounts, repo) {
29
+ this.accounts = accounts;
30
+ this.repo = repo;
31
+ }
32
+ async getPrincipal(player) {
33
+ const linked = player.accountID;
34
+ if (!linked) {
35
+ throw new framework_1.Utils.AppError("UNAUTHORIZED", "Player is not authenticated (no linked account)", "server");
36
+ }
37
+ const result = await this.repo.findByLinkedIdWithRole(String(linked));
38
+ if (!result) {
39
+ throw new framework_1.Utils.AppError("UNAUTHORIZED", "Linked account not found", "server");
40
+ }
41
+ const { account, role } = result;
42
+ if (this.accounts.isBanExpired(account)) {
43
+ await this.accounts.unban(account.id);
44
+ account.banned = false;
45
+ }
46
+ if (account.banned) {
47
+ throw new framework_1.Utils.AppError("PERMISSION_DENIED", "Account is banned", "server", {
48
+ banReason: account.banReason,
49
+ banExpires: account.banExpires,
50
+ });
51
+ }
52
+ return this.toPrincipal(account, role);
53
+ }
54
+ async refreshPrincipal(player) {
55
+ const principal = await this.getPrincipal(player);
56
+ player.setMeta("identity:principal", principal);
57
+ }
58
+ async getPrincipalByLinkedID(linkedID) {
59
+ const result = await this.repo.findByLinkedIdWithRole(linkedID);
60
+ if (!result || result.account.banned)
61
+ return null;
62
+ return this.toPrincipal(result.account, result.role);
63
+ }
64
+ /**
65
+ * Builds a Principal from account and role.
66
+ * Combines role permissions with account custom permissions.
67
+ *
68
+ * @param account - Account entity
69
+ * @param role - Role entity (or null if no role assigned)
70
+ * @returns Principal with combined permissions
71
+ */
72
+ toPrincipal(account, role) {
73
+ const effectivePermissions = this.combinePermissions(role, account.customPermissions);
74
+ return {
75
+ id: account.linkedId ?? String(account.id),
76
+ name: role?.displayName ?? undefined,
77
+ rank: role?.rank ?? undefined,
78
+ permissions: effectivePermissions,
79
+ meta: {
80
+ accountId: account.id,
81
+ roleId: role?.id,
82
+ roleName: role?.name,
83
+ },
84
+ };
85
+ }
86
+ /**
87
+ * Combine role permissions with account custom permissions.
88
+ * Custom permissions starting with '-' negate the base permission.
89
+ *
90
+ * @param role - Role with base permissions
91
+ * @param customPerms - Account custom permissions
92
+ * @returns Combined permissions array
93
+ */
94
+ combinePermissions(role, customPerms) {
95
+ const base = new Set(role?.permissions ?? []);
96
+ for (const perm of customPerms) {
97
+ if (perm.startsWith("-")) {
98
+ // Negation: remove the base permission
99
+ base.delete(perm.slice(1));
100
+ }
101
+ else {
102
+ // Addition: add custom permission
103
+ base.add(perm);
104
+ }
105
+ }
106
+ return Array.from(base);
107
+ }
108
+ };
109
+ exports.LocalPrincipalProvider = LocalPrincipalProvider;
110
+ exports.LocalPrincipalProvider = LocalPrincipalProvider = __decorate([
111
+ (0, tsyringe_1.injectable)(),
112
+ __metadata("design:paramtypes", [account_service_1.AccountService,
113
+ account_repository_1.AccountRepository])
114
+ ], LocalPrincipalProvider);
@@ -0,0 +1,73 @@
1
+ import type { Role } from "../entities/role.entity";
2
+ import type { CreateRoleInput, UpdateRoleInput } from "../types";
3
+ import { RoleRepository } from "../repositories/role.repository";
4
+ /**
5
+ * Service for managing roles and their permissions.
6
+ * Handles CRUD operations and permission management for roles.
7
+ */
8
+ export declare class RoleService {
9
+ private readonly repo;
10
+ constructor(repo: RoleRepository);
11
+ /**
12
+ * Find a role by its ID.
13
+ *
14
+ * @param id - Role ID
15
+ * @returns The role or null if not found
16
+ */
17
+ findById(id: number): Promise<Role | null>;
18
+ /**
19
+ * Find a role by its internal name.
20
+ *
21
+ * @param name - Role name (e.g., 'admin', 'user')
22
+ * @returns The role or null if not found
23
+ */
24
+ findByName(name: string): Promise<Role | null>;
25
+ /**
26
+ * Get all roles.
27
+ *
28
+ * @returns Array of all roles
29
+ */
30
+ getAll(): Promise<Role[]>;
31
+ /**
32
+ * Get the default role for new accounts.
33
+ *
34
+ * @returns The default role or null if none is configured
35
+ */
36
+ getDefaultRole(): Promise<Role | null>;
37
+ /**
38
+ * Create a new role.
39
+ *
40
+ * @param input - Role creation data
41
+ * @returns The created role
42
+ */
43
+ create(input: CreateRoleInput): Promise<Role>;
44
+ /**
45
+ * Update an existing role.
46
+ *
47
+ * @param id - Role ID
48
+ * @param input - Update data
49
+ * @returns The updated role or null if not found
50
+ */
51
+ update(id: number, input: UpdateRoleInput): Promise<Role | null>;
52
+ /**
53
+ * Delete a role.
54
+ *
55
+ * @param id - Role ID
56
+ * @returns true if deleted, false if not found
57
+ */
58
+ delete(id: number): Promise<boolean>;
59
+ /**
60
+ * Add a permission to a role.
61
+ *
62
+ * @param roleId - Role ID
63
+ * @param permission - Permission string to add
64
+ */
65
+ addPermission(roleId: number, permission: string): Promise<void>;
66
+ /**
67
+ * Remove a permission from a role.
68
+ *
69
+ * @param roleId - Role ID
70
+ * @param permission - Permission string to remove
71
+ */
72
+ removePermission(roleId: number, permission: string): Promise<void>;
73
+ }
@@ -0,0 +1,145 @@
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.RoleService = void 0;
13
+ const tsyringe_1 = require("tsyringe");
14
+ const role_repository_1 = require("../repositories/role.repository");
15
+ /**
16
+ * Service for managing roles and their permissions.
17
+ * Handles CRUD operations and permission management for roles.
18
+ */
19
+ let RoleService = class RoleService {
20
+ constructor(repo) {
21
+ this.repo = repo;
22
+ }
23
+ /**
24
+ * Find a role by its ID.
25
+ *
26
+ * @param id - Role ID
27
+ * @returns The role or null if not found
28
+ */
29
+ async findById(id) {
30
+ return this.repo.findById(id);
31
+ }
32
+ /**
33
+ * Find a role by its internal name.
34
+ *
35
+ * @param name - Role name (e.g., 'admin', 'user')
36
+ * @returns The role or null if not found
37
+ */
38
+ async findByName(name) {
39
+ return this.repo.findByName(name);
40
+ }
41
+ /**
42
+ * Get all roles.
43
+ *
44
+ * @returns Array of all roles
45
+ */
46
+ async getAll() {
47
+ const result = await this.repo.findMany();
48
+ return result.data;
49
+ }
50
+ /**
51
+ * Get the default role for new accounts.
52
+ *
53
+ * @returns The default role or null if none is configured
54
+ */
55
+ async getDefaultRole() {
56
+ return this.repo.getDefaultRole();
57
+ }
58
+ /**
59
+ * Create a new role.
60
+ *
61
+ * @param input - Role creation data
62
+ * @returns The created role
63
+ */
64
+ async create(input) {
65
+ const now = new Date();
66
+ const role = {
67
+ id: 0, // Will be set by DB
68
+ name: input.name,
69
+ displayName: input.displayName,
70
+ rank: input.rank,
71
+ permissions: input.permissions ?? [],
72
+ isDefault: input.isDefault ?? false,
73
+ createdAt: now,
74
+ };
75
+ return this.repo.save(role);
76
+ }
77
+ /**
78
+ * Update an existing role.
79
+ *
80
+ * @param id - Role ID
81
+ * @param input - Update data
82
+ * @returns The updated role or null if not found
83
+ */
84
+ async update(id, input) {
85
+ const existing = await this.repo.findById(id);
86
+ if (!existing)
87
+ return null;
88
+ const updated = {
89
+ ...existing,
90
+ ...(input.displayName !== undefined && {
91
+ displayName: input.displayName,
92
+ }),
93
+ ...(input.rank !== undefined && { rank: input.rank }),
94
+ ...(input.permissions !== undefined && {
95
+ permissions: input.permissions,
96
+ }),
97
+ };
98
+ if (input.isDefault !== undefined) {
99
+ await this.repo.setDefault(id, input.isDefault);
100
+ updated.isDefault = input.isDefault;
101
+ }
102
+ return this.repo.save(updated);
103
+ }
104
+ /**
105
+ * Delete a role.
106
+ *
107
+ * @param id - Role ID
108
+ * @returns true if deleted, false if not found
109
+ */
110
+ async delete(id) {
111
+ return this.repo.delete(id);
112
+ }
113
+ /**
114
+ * Add a permission to a role.
115
+ *
116
+ * @param roleId - Role ID
117
+ * @param permission - Permission string to add
118
+ */
119
+ async addPermission(roleId, permission) {
120
+ const role = await this.repo.findById(roleId);
121
+ if (!role)
122
+ return;
123
+ const permissions = new Set(role.permissions);
124
+ permissions.add(permission);
125
+ await this.repo.updatePermissions(roleId, Array.from(permissions));
126
+ }
127
+ /**
128
+ * Remove a permission from a role.
129
+ *
130
+ * @param roleId - Role ID
131
+ * @param permission - Permission string to remove
132
+ */
133
+ async removePermission(roleId, permission) {
134
+ const role = await this.repo.findById(roleId);
135
+ if (!role)
136
+ return;
137
+ const filtered = role.permissions.filter((p) => p !== permission);
138
+ await this.repo.updatePermissions(roleId, filtered);
139
+ }
140
+ };
141
+ exports.RoleService = RoleService;
142
+ exports.RoleService = RoleService = __decorate([
143
+ (0, tsyringe_1.injectable)(),
144
+ __metadata("design:paramtypes", [role_repository_1.RoleRepository])
145
+ ], RoleService);
@@ -0,0 +1,58 @@
1
+ import type { DependencyContainer } from "tsyringe";
2
+ /**
3
+ * Configuration options for Identity module setup
4
+ */
5
+ export interface IdentitySetupOptions {
6
+ /**
7
+ * Authentication provider strategy
8
+ * - 'local': Auto-create accounts by FiveM identifiers (default)
9
+ * - 'credentials': Username/password authentication
10
+ * - 'api': External API authentication
11
+ */
12
+ authProvider?: "local" | "credentials" | "api";
13
+ /**
14
+ * Principal provider strategy
15
+ * - 'local': Read roles/permissions from local DB (default)
16
+ * - 'api': Fetch roles/permissions from external API
17
+ */
18
+ principalProvider?: "local" | "api";
19
+ /**
20
+ * Whether to use local database for accounts/roles
21
+ * - true: Use DB (default for 'local' strategies)
22
+ * - false: Skip DB registration (only cache, for 'api' strategies)
23
+ */
24
+ useDatabase?: boolean;
25
+ }
26
+ /**
27
+ * Register all Identity module singletons with the DI container.
28
+ *
29
+ * This function should be called once during server bootstrap to set up
30
+ * the authentication and authorization providers.
31
+ *
32
+ * @param container - The tsyringe DependencyContainer instance
33
+ * @param options - Configuration options for authentication and principal strategies
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * import { container } from "tsyringe";
38
+ * import { Identity } from "@open-core/identity";
39
+ *
40
+ * // Default setup (local auth + local principals + DB)
41
+ * Identity.setup(container);
42
+ *
43
+ * // API-based setup (no DB required)
44
+ * Identity.setup(container, {
45
+ * authProvider: 'api',
46
+ * principalProvider: 'api',
47
+ * useDatabase: false
48
+ * });
49
+ *
50
+ * // Credentials setup (DB required)
51
+ * Identity.setup(container, {
52
+ * authProvider: 'credentials',
53
+ * principalProvider: 'local',
54
+ * useDatabase: true
55
+ * });
56
+ * ```
57
+ */
58
+ export declare function setupIdentity(container: DependencyContainer, options?: IdentitySetupOptions): void;
package/dist/setup.js ADDED
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setupIdentity = setupIdentity;
4
+ const account_repository_1 = require("./repositories/account.repository");
5
+ const role_repository_1 = require("./repositories/role.repository");
6
+ const account_service_1 = require("./services/account.service");
7
+ const role_service_1 = require("./services/role.service");
8
+ const memory_cache_service_1 = require("./services/cache/memory-cache.service");
9
+ const local_auth_provider_1 = require("./services/auth/local-auth.provider");
10
+ const credentials_auth_provider_1 = require("./services/auth/credentials-auth.provider");
11
+ const api_auth_provider_1 = require("./services/auth/api-auth.provider");
12
+ const local_principal_provider_1 = require("./services/principal/local-principal.provider");
13
+ const api_principal_provider_1 = require("./services/principal/api-principal.provider");
14
+ const identity_auth_provider_1 = require("./services/identity-auth.provider");
15
+ const identity_principal_provider_1 = require("./services/identity-principal.provider");
16
+ /**
17
+ * Register all Identity module singletons with the DI container.
18
+ *
19
+ * This function should be called once during server bootstrap to set up
20
+ * the authentication and authorization providers.
21
+ *
22
+ * @param container - The tsyringe DependencyContainer instance
23
+ * @param options - Configuration options for authentication and principal strategies
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * import { container } from "tsyringe";
28
+ * import { Identity } from "@open-core/identity";
29
+ *
30
+ * // Default setup (local auth + local principals + DB)
31
+ * Identity.setup(container);
32
+ *
33
+ * // API-based setup (no DB required)
34
+ * Identity.setup(container, {
35
+ * authProvider: 'api',
36
+ * principalProvider: 'api',
37
+ * useDatabase: false
38
+ * });
39
+ *
40
+ * // Credentials setup (DB required)
41
+ * Identity.setup(container, {
42
+ * authProvider: 'credentials',
43
+ * principalProvider: 'local',
44
+ * useDatabase: true
45
+ * });
46
+ * ```
47
+ */
48
+ function setupIdentity(container, options = {}) {
49
+ const { authProvider = "local", principalProvider = "local", useDatabase = authProvider !== "api" && principalProvider !== "api", } = options;
50
+ // Always register cache service (needed for API providers)
51
+ container.registerSingleton(memory_cache_service_1.MemoryCacheService);
52
+ // Register database-dependent services only if needed
53
+ if (useDatabase) {
54
+ container.registerSingleton(account_repository_1.AccountRepository);
55
+ container.registerSingleton(role_repository_1.RoleRepository);
56
+ container.registerSingleton(account_service_1.AccountService);
57
+ container.registerSingleton(role_service_1.RoleService);
58
+ }
59
+ // Register Auth Provider based on strategy
60
+ switch (authProvider) {
61
+ case "credentials":
62
+ container.registerSingleton("AuthProviderContract", credentials_auth_provider_1.CredentialsAuthProvider);
63
+ // Also register as IdentityAuthProvider for backward compatibility
64
+ // Note: CredentialsAuthProvider is not compatible with IdentityAuthProvider interface
65
+ // Users should use the new provider directly
66
+ break;
67
+ case "api":
68
+ container.registerSingleton("AuthProviderContract", api_auth_provider_1.ApiAuthProvider);
69
+ // Note: ApiAuthProvider is not compatible with IdentityAuthProvider interface
70
+ // Users should use the new provider directly
71
+ break;
72
+ case "local":
73
+ default:
74
+ container.registerSingleton("AuthProviderContract", local_auth_provider_1.LocalAuthProvider);
75
+ // Register LocalAuthProvider as the legacy IdentityAuthProvider for compatibility
76
+ container.registerSingleton(identity_auth_provider_1.IdentityAuthProvider, local_auth_provider_1.LocalAuthProvider);
77
+ break;
78
+ }
79
+ // Register Principal Provider based on strategy
80
+ switch (principalProvider) {
81
+ case "api":
82
+ container.registerSingleton("PrincipalProviderContract", api_principal_provider_1.ApiPrincipalProvider);
83
+ // Note: ApiPrincipalProvider is not compatible with IdentityPrincipalProvider interface
84
+ // Users should use the new provider directly
85
+ break;
86
+ case "local":
87
+ default:
88
+ container.registerSingleton("PrincipalProviderContract", local_principal_provider_1.LocalPrincipalProvider);
89
+ // Register LocalPrincipalProvider as the legacy IdentityPrincipalProvider for compatibility
90
+ container.registerSingleton(identity_principal_provider_1.IdentityPrincipalProvider, local_principal_provider_1.LocalPrincipalProvider);
91
+ break;
92
+ }
93
+ }