@open-core/identity 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -2
- package/dist/contracts.d.ts +93 -0
- package/dist/contracts.js +21 -0
- package/dist/index.d.ts +86 -67
- package/dist/index.js +107 -56
- package/dist/providers/auth/api-auth.provider.d.ts +52 -0
- package/dist/providers/auth/api-auth.provider.js +82 -0
- package/dist/providers/auth/credentials-auth.provider.d.ts +63 -0
- package/dist/providers/auth/credentials-auth.provider.js +149 -0
- package/dist/providers/auth/local-auth.provider.d.ts +82 -0
- package/dist/providers/auth/local-auth.provider.js +151 -0
- package/dist/providers/identity-auth.provider.d.ts +0 -0
- package/dist/providers/identity-auth.provider.js +1 -0
- package/dist/providers/principal/api-principal.provider.d.ts +50 -0
- package/dist/providers/principal/api-principal.provider.js +84 -0
- package/dist/providers/principal/local-principal.provider.d.ts +77 -0
- package/dist/providers/principal/local-principal.provider.js +164 -0
- package/dist/services/account.service.d.ts +52 -57
- package/dist/services/account.service.js +77 -160
- package/dist/services/role.service.d.ts +33 -54
- package/dist/services/role.service.js +48 -103
- package/dist/tokens.d.ts +7 -0
- package/dist/tokens.js +7 -0
- package/dist/types.d.ts +170 -0
- package/dist/types.js +1 -0
- package/package.json +2 -3
|
@@ -1,73 +1,52 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type {
|
|
3
|
-
import { RoleRepository } from "../repositories/role.repository";
|
|
1
|
+
import { RoleStore } from "../contracts";
|
|
2
|
+
import type { IdentityOptions, IdentityRole } from "../types";
|
|
4
3
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* High-level service for managing security roles and their associated permissions.
|
|
5
|
+
*
|
|
6
|
+
* Provides a programmer-friendly API for role administration, including creation,
|
|
7
|
+
* updates, and permission retrieval. This service interacts with the configured
|
|
8
|
+
* {@link RoleStore}.
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
* @injectable
|
|
7
12
|
*/
|
|
8
13
|
export declare class RoleService {
|
|
9
|
-
private readonly
|
|
10
|
-
|
|
14
|
+
private readonly store;
|
|
15
|
+
private readonly options;
|
|
11
16
|
/**
|
|
12
|
-
*
|
|
17
|
+
* Initializes a new instance of the RoleService.
|
|
13
18
|
*
|
|
14
|
-
* @param
|
|
15
|
-
* @
|
|
19
|
+
* @param store - Persistence layer for role definitions.
|
|
20
|
+
* @param options - Identity system configuration options.
|
|
16
21
|
*/
|
|
17
|
-
|
|
22
|
+
constructor(store: RoleStore, options: IdentityOptions);
|
|
18
23
|
/**
|
|
19
|
-
*
|
|
24
|
+
* Persists a new security role definition.
|
|
20
25
|
*
|
|
21
|
-
* @param
|
|
22
|
-
* @returns
|
|
26
|
+
* @param role - The complete role definition to create.
|
|
27
|
+
* @returns A promise that resolves when the role is saved.
|
|
23
28
|
*/
|
|
24
|
-
|
|
29
|
+
create(role: IdentityRole): Promise<void>;
|
|
25
30
|
/**
|
|
26
|
-
*
|
|
31
|
+
* Updates an existing role's rank or permissions.
|
|
27
32
|
*
|
|
28
|
-
* @
|
|
33
|
+
* @param name - The unique technical name of the role to update.
|
|
34
|
+
* @param data - Partial object containing the fields to modify.
|
|
35
|
+
* @returns A promise that resolves when the update is complete.
|
|
29
36
|
*/
|
|
30
|
-
|
|
37
|
+
update(name: string, data: Partial<Omit<IdentityRole, "name">>): Promise<void>;
|
|
31
38
|
/**
|
|
32
|
-
*
|
|
39
|
+
* Permanently removes a role definition from the system.
|
|
33
40
|
*
|
|
34
|
-
* @
|
|
41
|
+
* @param name - The technical name of the role to delete.
|
|
42
|
+
* @returns A promise that resolves when the role is deleted.
|
|
35
43
|
*/
|
|
36
|
-
|
|
44
|
+
delete(name: string): Promise<void>;
|
|
37
45
|
/**
|
|
38
|
-
*
|
|
46
|
+
* Retrieves the full list of permissions granted to a specific role.
|
|
39
47
|
*
|
|
40
|
-
* @param
|
|
41
|
-
* @returns
|
|
48
|
+
* @param name - The technical name of the role.
|
|
49
|
+
* @returns A promise resolving to an array of permission strings.
|
|
42
50
|
*/
|
|
43
|
-
|
|
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>;
|
|
51
|
+
getPermissions(name: string): Promise<string[]>;
|
|
73
52
|
}
|
|
@@ -7,136 +7,81 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
8
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
9
|
};
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
|
+
};
|
|
13
|
+
import { injectable, inject } from "tsyringe";
|
|
14
|
+
import { IDENTITY_OPTIONS } from "../tokens";
|
|
15
|
+
import { RoleStore } from "../contracts";
|
|
12
16
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
17
|
+
* High-level service for managing security roles and their associated permissions.
|
|
18
|
+
*
|
|
19
|
+
* Provides a programmer-friendly API for role administration, including creation,
|
|
20
|
+
* updates, and permission retrieval. This service interacts with the configured
|
|
21
|
+
* {@link RoleStore}.
|
|
22
|
+
*
|
|
23
|
+
* @public
|
|
24
|
+
* @injectable
|
|
15
25
|
*/
|
|
16
26
|
let RoleService = class RoleService {
|
|
17
|
-
constructor(repo) {
|
|
18
|
-
this.repo = repo;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Find a role by its ID.
|
|
22
|
-
*
|
|
23
|
-
* @param id - Role ID
|
|
24
|
-
* @returns The role or null if not found
|
|
25
|
-
*/
|
|
26
|
-
async findById(id) {
|
|
27
|
-
return this.repo.findById(id);
|
|
28
|
-
}
|
|
29
27
|
/**
|
|
30
|
-
*
|
|
28
|
+
* Initializes a new instance of the RoleService.
|
|
31
29
|
*
|
|
32
|
-
* @param
|
|
33
|
-
* @
|
|
30
|
+
* @param store - Persistence layer for role definitions.
|
|
31
|
+
* @param options - Identity system configuration options.
|
|
34
32
|
*/
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
constructor(store, options) {
|
|
34
|
+
this.store = store;
|
|
35
|
+
this.options = options;
|
|
37
36
|
}
|
|
38
37
|
/**
|
|
39
|
-
*
|
|
38
|
+
* Persists a new security role definition.
|
|
40
39
|
*
|
|
41
|
-
* @
|
|
40
|
+
* @param role - The complete role definition to create.
|
|
41
|
+
* @returns A promise that resolves when the role is saved.
|
|
42
42
|
*/
|
|
43
|
-
async
|
|
44
|
-
|
|
45
|
-
return result.data;
|
|
43
|
+
async create(role) {
|
|
44
|
+
await this.store.save(role);
|
|
46
45
|
}
|
|
47
46
|
/**
|
|
48
|
-
*
|
|
47
|
+
* Updates an existing role's rank or permissions.
|
|
49
48
|
*
|
|
50
|
-
* @
|
|
49
|
+
* @param name - The unique technical name of the role to update.
|
|
50
|
+
* @param data - Partial object containing the fields to modify.
|
|
51
|
+
* @returns A promise that resolves when the update is complete.
|
|
51
52
|
*/
|
|
52
|
-
async
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Create a new role.
|
|
57
|
-
*
|
|
58
|
-
* @param input - Role creation data
|
|
59
|
-
* @returns The created role
|
|
60
|
-
*/
|
|
61
|
-
async create(input) {
|
|
62
|
-
const now = new Date();
|
|
63
|
-
const role = {
|
|
64
|
-
id: 0, // Will be set by DB
|
|
65
|
-
name: input.name,
|
|
66
|
-
displayName: input.displayName,
|
|
67
|
-
rank: input.rank,
|
|
68
|
-
permissions: input.permissions ?? [],
|
|
69
|
-
isDefault: input.isDefault ?? false,
|
|
70
|
-
createdAt: now,
|
|
71
|
-
};
|
|
72
|
-
return this.repo.save(role);
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Update an existing role.
|
|
76
|
-
*
|
|
77
|
-
* @param id - Role ID
|
|
78
|
-
* @param input - Update data
|
|
79
|
-
* @returns The updated role or null if not found
|
|
80
|
-
*/
|
|
81
|
-
async update(id, input) {
|
|
82
|
-
const existing = await this.repo.findById(id);
|
|
53
|
+
async update(name, data) {
|
|
54
|
+
const existing = await this.store.findByName(name);
|
|
83
55
|
if (!existing)
|
|
84
|
-
return
|
|
85
|
-
|
|
56
|
+
return;
|
|
57
|
+
await this.store.save({
|
|
86
58
|
...existing,
|
|
87
|
-
...
|
|
88
|
-
|
|
89
|
-
}),
|
|
90
|
-
...(input.rank !== undefined && { rank: input.rank }),
|
|
91
|
-
...(input.permissions !== undefined && {
|
|
92
|
-
permissions: input.permissions,
|
|
93
|
-
}),
|
|
94
|
-
};
|
|
95
|
-
if (input.isDefault !== undefined) {
|
|
96
|
-
await this.repo.setDefault(id, input.isDefault);
|
|
97
|
-
updated.isDefault = input.isDefault;
|
|
98
|
-
}
|
|
99
|
-
return this.repo.save(updated);
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Delete a role.
|
|
103
|
-
*
|
|
104
|
-
* @param id - Role ID
|
|
105
|
-
* @returns true if deleted, false if not found
|
|
106
|
-
*/
|
|
107
|
-
async delete(id) {
|
|
108
|
-
return this.repo.delete(id);
|
|
59
|
+
...data,
|
|
60
|
+
});
|
|
109
61
|
}
|
|
110
62
|
/**
|
|
111
|
-
*
|
|
63
|
+
* Permanently removes a role definition from the system.
|
|
112
64
|
*
|
|
113
|
-
* @param
|
|
114
|
-
* @
|
|
65
|
+
* @param name - The technical name of the role to delete.
|
|
66
|
+
* @returns A promise that resolves when the role is deleted.
|
|
115
67
|
*/
|
|
116
|
-
async
|
|
117
|
-
|
|
118
|
-
if (!role)
|
|
119
|
-
return;
|
|
120
|
-
const permissions = new Set(role.permissions);
|
|
121
|
-
permissions.add(permission);
|
|
122
|
-
await this.repo.updatePermissions(roleId, Array.from(permissions));
|
|
68
|
+
async delete(name) {
|
|
69
|
+
await this.store.delete(name);
|
|
123
70
|
}
|
|
124
71
|
/**
|
|
125
|
-
*
|
|
72
|
+
* Retrieves the full list of permissions granted to a specific role.
|
|
126
73
|
*
|
|
127
|
-
* @param
|
|
128
|
-
* @
|
|
74
|
+
* @param name - The technical name of the role.
|
|
75
|
+
* @returns A promise resolving to an array of permission strings.
|
|
129
76
|
*/
|
|
130
|
-
async
|
|
131
|
-
const role = await this.
|
|
132
|
-
|
|
133
|
-
return;
|
|
134
|
-
const filtered = role.permissions.filter((p) => p !== permission);
|
|
135
|
-
await this.repo.updatePermissions(roleId, filtered);
|
|
77
|
+
async getPermissions(name) {
|
|
78
|
+
const role = await this.store.findByName(name);
|
|
79
|
+
return role?.permissions || [];
|
|
136
80
|
}
|
|
137
81
|
};
|
|
138
82
|
RoleService = __decorate([
|
|
139
83
|
injectable(),
|
|
140
|
-
|
|
84
|
+
__param(1, inject(IDENTITY_OPTIONS)),
|
|
85
|
+
__metadata("design:paramtypes", [RoleStore, Object])
|
|
141
86
|
], RoleService);
|
|
142
87
|
export { RoleService };
|
package/dist/tokens.d.ts
ADDED
package/dist/tokens.js
ADDED
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication strategy modes.
|
|
3
|
+
*
|
|
4
|
+
* - `local`: Automatic authentication based on FiveM connection identifiers (e.g., license, discord).
|
|
5
|
+
* Ideal for traditional FiveM servers where account creation should be transparent.
|
|
6
|
+
* - `credentials`: Manual authentication using username and password.
|
|
7
|
+
* Suitable for servers with an integrated registration system.
|
|
8
|
+
* - `api`: Delegation of authentication to an external HTTP API.
|
|
9
|
+
* Useful for servers integrated with a web dashboard or external auth service.
|
|
10
|
+
*
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export type AuthMode = "local" | "credentials" | "api";
|
|
14
|
+
/**
|
|
15
|
+
* Authorization and principal resolution modes.
|
|
16
|
+
*
|
|
17
|
+
* - `roles`: Uses a static role hierarchy defined in the application code.
|
|
18
|
+
* Provides the best performance and version control for role definitions.
|
|
19
|
+
* - `db`: Fetches roles and permissions dynamically from a persistent store.
|
|
20
|
+
* - `api`: Fetches principal data from an external HTTP API on demand.
|
|
21
|
+
*
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
export type PrincipalMode = "roles" | "db" | "api";
|
|
25
|
+
/**
|
|
26
|
+
* Represents a security role within the identity system.
|
|
27
|
+
*
|
|
28
|
+
* Roles define base permissions and a rank hierarchy used by the framework's `@Guard` decorator.
|
|
29
|
+
*
|
|
30
|
+
* @public
|
|
31
|
+
*/
|
|
32
|
+
export interface IdentityRole {
|
|
33
|
+
/**
|
|
34
|
+
* Technical identifier for the role (e.g., 'admin', 'moderator', 'user').
|
|
35
|
+
*/
|
|
36
|
+
name: string;
|
|
37
|
+
/**
|
|
38
|
+
* Hierarchical weight.
|
|
39
|
+
*
|
|
40
|
+
* Used for rank-based authorization.
|
|
41
|
+
* Logic: UserRank >= RequiredRank.
|
|
42
|
+
*/
|
|
43
|
+
rank: number;
|
|
44
|
+
/**
|
|
45
|
+
* List of permission strings granted to this role by default.
|
|
46
|
+
*
|
|
47
|
+
* Supports '*' wildcard for full framework access.
|
|
48
|
+
*/
|
|
49
|
+
permissions: string[];
|
|
50
|
+
/**
|
|
51
|
+
* Human-readable label for UI display or chat prefix.
|
|
52
|
+
*/
|
|
53
|
+
displayName?: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Global configuration options for the OpenCore Identity System.
|
|
57
|
+
*
|
|
58
|
+
* @public
|
|
59
|
+
*/
|
|
60
|
+
export interface IdentityOptions {
|
|
61
|
+
/**
|
|
62
|
+
* Authentication configuration.
|
|
63
|
+
*/
|
|
64
|
+
auth: {
|
|
65
|
+
/**
|
|
66
|
+
* The strategy to use for authenticating players.
|
|
67
|
+
*/
|
|
68
|
+
mode: AuthMode;
|
|
69
|
+
/**
|
|
70
|
+
* Whether to automatically create a new account when a player connects
|
|
71
|
+
* with valid identifiers that are not yet registered.
|
|
72
|
+
*
|
|
73
|
+
* Only applicable when mode is 'local'.
|
|
74
|
+
* @defaultValue true
|
|
75
|
+
*/
|
|
76
|
+
autoCreate?: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* The primary FiveM identifier used to unique-link an account.
|
|
79
|
+
* @defaultValue 'license'
|
|
80
|
+
*/
|
|
81
|
+
primaryIdentifier?: string;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Authorization and permissions configuration.
|
|
85
|
+
*/
|
|
86
|
+
principal: {
|
|
87
|
+
/**
|
|
88
|
+
* The strategy to use for resolving roles and permissions.
|
|
89
|
+
*/
|
|
90
|
+
mode: PrincipalMode;
|
|
91
|
+
/**
|
|
92
|
+
* Static role definitions.
|
|
93
|
+
*
|
|
94
|
+
* Required when mode is 'roles'.
|
|
95
|
+
*/
|
|
96
|
+
roles?: Record<string, IdentityRole>;
|
|
97
|
+
/**
|
|
98
|
+
* The name of the role assigned to newly created accounts.
|
|
99
|
+
* @defaultValue 'user'
|
|
100
|
+
*/
|
|
101
|
+
defaultRole?: string;
|
|
102
|
+
/**
|
|
103
|
+
* Time-to-live in milliseconds for cached principal data.
|
|
104
|
+
*
|
|
105
|
+
* Since principal resolution is a high-frequency operation, caching is
|
|
106
|
+
* critical for performance.
|
|
107
|
+
* @defaultValue 300000 (5 minutes)
|
|
108
|
+
*/
|
|
109
|
+
cacheTtl?: number;
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Represents a persistent identity account.
|
|
114
|
+
*
|
|
115
|
+
* This object links a FiveM player to their persistent roles, permissions,
|
|
116
|
+
* and operational status (e.g., bans).
|
|
117
|
+
*
|
|
118
|
+
* @public
|
|
119
|
+
*/
|
|
120
|
+
export interface IdentityAccount {
|
|
121
|
+
/**
|
|
122
|
+
* Internal unique database/store ID.
|
|
123
|
+
*/
|
|
124
|
+
id: string;
|
|
125
|
+
/**
|
|
126
|
+
* External stable ID used by the framework (linkedID).
|
|
127
|
+
*
|
|
128
|
+
* Usually a UUID or an external system ID.
|
|
129
|
+
*/
|
|
130
|
+
linkedId: string;
|
|
131
|
+
/**
|
|
132
|
+
* Primary connection identifier (e.g., 'license:123...').
|
|
133
|
+
*/
|
|
134
|
+
identifier: string;
|
|
135
|
+
/**
|
|
136
|
+
* Current technical role name assigned to this account.
|
|
137
|
+
*/
|
|
138
|
+
roleName: string;
|
|
139
|
+
/**
|
|
140
|
+
* Optional technical username for credentials-based authentication.
|
|
141
|
+
*/
|
|
142
|
+
username?: string | null;
|
|
143
|
+
/**
|
|
144
|
+
* Hashed password for credentials-based authentication.
|
|
145
|
+
*
|
|
146
|
+
* @internal
|
|
147
|
+
*/
|
|
148
|
+
passwordHash?: string | null;
|
|
149
|
+
/**
|
|
150
|
+
* List of specific permission overrides for this account.
|
|
151
|
+
*
|
|
152
|
+
* - `+perm`: Explicitly grant a permission.
|
|
153
|
+
* - `-perm`: Explicitly revoke a permission (even if granted by role).
|
|
154
|
+
*/
|
|
155
|
+
customPermissions: string[];
|
|
156
|
+
/**
|
|
157
|
+
* Whether the account is currently prohibited from connecting.
|
|
158
|
+
*/
|
|
159
|
+
isBanned: boolean;
|
|
160
|
+
/**
|
|
161
|
+
* The reason provided for the current ban.
|
|
162
|
+
*/
|
|
163
|
+
banReason?: string;
|
|
164
|
+
/**
|
|
165
|
+
* Timestamp when the ban expires.
|
|
166
|
+
*
|
|
167
|
+
* If null and isBanned is true, the ban is permanent.
|
|
168
|
+
*/
|
|
169
|
+
banExpiresAt?: Date | null;
|
|
170
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-core/identity",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "Enterprise-grade identity, authentication, and authorization plugin for OpenCore Framework",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -39,14 +39,13 @@
|
|
|
39
39
|
"packageManager": "pnpm@10.13.1",
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@open-core/framework": "^0.2.4",
|
|
42
|
-
"
|
|
42
|
+
"bcryptjs": "^3.0.3",
|
|
43
43
|
"reflect-metadata": "^0.2.2",
|
|
44
44
|
"tsyringe": "^4.10.0",
|
|
45
45
|
"uuid": "^13.0.0",
|
|
46
46
|
"zod": "^4.1.13"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@types/bcrypt": "^6.0.0",
|
|
50
49
|
"@types/node": "^22.19.1",
|
|
51
50
|
"eslint": "^9.39.1",
|
|
52
51
|
"eslint-config-prettier": "^10.1.8",
|