@forklaunch/implementation-iam-base 0.2.3 → 0.3.1
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/lib/schemas/index.d.mts +474 -0
- package/lib/schemas/index.d.ts +474 -5
- package/lib/schemas/index.js +339 -4
- package/lib/schemas/index.mjs +369 -0
- package/lib/services/index.d.mts +203 -0
- package/lib/services/index.d.ts +203 -5
- package/lib/services/index.js +666 -4
- package/lib/services/index.mjs +652 -0
- package/package.json +13 -10
- package/lib/__test__/schemaEquality.test.d.ts +0 -2
- package/lib/__test__/schemaEquality.test.d.ts.map +0 -1
- package/lib/__test__/schemaEquality.test.js +0 -283
- package/lib/jest.config.d.ts +0 -4
- package/lib/jest.config.d.ts.map +0 -1
- package/lib/jest.config.js +0 -19
- package/lib/schemas/index.d.ts.map +0 -1
- package/lib/schemas/organization.schema.d.ts +0 -423
- package/lib/schemas/organization.schema.d.ts.map +0 -1
- package/lib/schemas/organization.schema.js +0 -7
- package/lib/schemas/permission.schema.d.ts +0 -104
- package/lib/schemas/permission.schema.d.ts.map +0 -1
- package/lib/schemas/permission.schema.js +0 -7
- package/lib/schemas/role.schema.d.ts +0 -163
- package/lib/schemas/role.schema.d.ts.map +0 -1
- package/lib/schemas/role.schema.js +0 -7
- package/lib/schemas/typebox/organization.schema.d.ts +0 -382
- package/lib/schemas/typebox/organization.schema.d.ts.map +0 -1
- package/lib/schemas/typebox/organization.schema.js +0 -44
- package/lib/schemas/typebox/permission.schema.d.ts +0 -123
- package/lib/schemas/typebox/permission.schema.d.ts.map +0 -1
- package/lib/schemas/typebox/permission.schema.js +0 -32
- package/lib/schemas/typebox/role.schema.d.ts +0 -183
- package/lib/schemas/typebox/role.schema.d.ts.map +0 -1
- package/lib/schemas/typebox/role.schema.js +0 -33
- package/lib/schemas/typebox/user.schema.d.ts +0 -315
- package/lib/schemas/typebox/user.schema.d.ts.map +0 -1
- package/lib/schemas/typebox/user.schema.js +0 -49
- package/lib/schemas/user.schema.d.ts +0 -298
- package/lib/schemas/user.schema.d.ts.map +0 -1
- package/lib/schemas/user.schema.js +0 -7
- package/lib/schemas/zod/organization.schema.d.ts +0 -418
- package/lib/schemas/zod/organization.schema.d.ts.map +0 -1
- package/lib/schemas/zod/organization.schema.js +0 -44
- package/lib/schemas/zod/permission.schema.d.ts +0 -71
- package/lib/schemas/zod/permission.schema.d.ts.map +0 -1
- package/lib/schemas/zod/permission.schema.js +0 -32
- package/lib/schemas/zod/role.schema.d.ts +0 -129
- package/lib/schemas/zod/role.schema.d.ts.map +0 -1
- package/lib/schemas/zod/role.schema.js +0 -33
- package/lib/schemas/zod/user.schema.d.ts +0 -249
- package/lib/schemas/zod/user.schema.d.ts.map +0 -1
- package/lib/schemas/zod/user.schema.js +0 -49
- package/lib/services/index.d.ts.map +0 -1
- package/lib/services/organization.service.d.ts +0 -123
- package/lib/services/organization.service.d.ts.map +0 -1
- package/lib/services/organization.service.js +0 -88
- package/lib/services/permission.service.d.ts +0 -149
- package/lib/services/permission.service.d.ts.map +0 -1
- package/lib/services/permission.service.js +0 -264
- package/lib/services/role.service.d.ts +0 -123
- package/lib/services/role.service.d.ts.map +0 -1
- package/lib/services/role.service.js +0 -139
- package/lib/services/user.service.d.ts +0 -134
- package/lib/services/user.service.d.ts.map +0 -1
- package/lib/services/user.service.js +0 -185
- package/lib/tsconfig.tsbuildinfo +0 -1
- package/lib/vitest.config.d.ts +0 -3
- package/lib/vitest.config.d.ts.map +0 -1
- package/lib/vitest.config.js +0 -7
|
@@ -0,0 +1,652 @@
|
|
|
1
|
+
// services/organization.service.ts
|
|
2
|
+
import {
|
|
3
|
+
evaluateTelemetryOptions
|
|
4
|
+
} from "@forklaunch/core/http";
|
|
5
|
+
import {
|
|
6
|
+
transformIntoInternalDtoMapper
|
|
7
|
+
} from "@forklaunch/core/mappers";
|
|
8
|
+
var BaseOrganizationService = class {
|
|
9
|
+
constructor(em, openTelemetryCollector, schemaValidator, mappers, options) {
|
|
10
|
+
this.em = em;
|
|
11
|
+
this.openTelemetryCollector = openTelemetryCollector;
|
|
12
|
+
this.schemaValidator = schemaValidator;
|
|
13
|
+
this.mappers = mappers;
|
|
14
|
+
this.#mappers = transformIntoInternalDtoMapper(mappers, schemaValidator);
|
|
15
|
+
this.evaluatedTelemetryOptions = options?.telemetry ? evaluateTelemetryOptions(options.telemetry).enabled : {
|
|
16
|
+
logging: false,
|
|
17
|
+
metrics: false,
|
|
18
|
+
tracing: false
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
#mappers;
|
|
22
|
+
evaluatedTelemetryOptions;
|
|
23
|
+
async createOrganization(organizationDto, em) {
|
|
24
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
25
|
+
this.openTelemetryCollector.info(
|
|
26
|
+
"Creating organization",
|
|
27
|
+
organizationDto
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
const organization = await this.#mappers.CreateOrganizationDtoMapper.deserializeDtoToEntity(
|
|
31
|
+
organizationDto,
|
|
32
|
+
em ?? this.em
|
|
33
|
+
);
|
|
34
|
+
if (em) {
|
|
35
|
+
await em.persist(organization);
|
|
36
|
+
} else {
|
|
37
|
+
await this.em.persistAndFlush(organization);
|
|
38
|
+
}
|
|
39
|
+
return this.#mappers.OrganizationDtoMapper.serializeEntityToDto(
|
|
40
|
+
organization
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
async getOrganization(idDto, em) {
|
|
44
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
45
|
+
this.openTelemetryCollector.info("Getting organization", idDto);
|
|
46
|
+
}
|
|
47
|
+
const organization = await (em ?? this.em).findOneOrFail(
|
|
48
|
+
"Organization",
|
|
49
|
+
idDto
|
|
50
|
+
);
|
|
51
|
+
return this.#mappers.OrganizationDtoMapper.serializeEntityToDto(
|
|
52
|
+
organization
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
async updateOrganization(organizationDto, em) {
|
|
56
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
57
|
+
this.openTelemetryCollector.info(
|
|
58
|
+
"Updating organization",
|
|
59
|
+
organizationDto
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
const updatedOrganization = await this.#mappers.UpdateOrganizationDtoMapper.deserializeDtoToEntity(
|
|
63
|
+
organizationDto,
|
|
64
|
+
em ?? this.em
|
|
65
|
+
);
|
|
66
|
+
if (em) {
|
|
67
|
+
await em.persist(updatedOrganization);
|
|
68
|
+
} else {
|
|
69
|
+
await this.em.persistAndFlush(updatedOrganization);
|
|
70
|
+
}
|
|
71
|
+
return this.#mappers.OrganizationDtoMapper.serializeEntityToDto(
|
|
72
|
+
updatedOrganization
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
async deleteOrganization(idDto, em) {
|
|
76
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
77
|
+
this.openTelemetryCollector.info("Deleting organization", idDto);
|
|
78
|
+
}
|
|
79
|
+
if (em) {
|
|
80
|
+
await em.nativeDelete("Organization", idDto);
|
|
81
|
+
} else {
|
|
82
|
+
await this.em.nativeDelete("Organization", idDto);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// services/permission.service.ts
|
|
88
|
+
import {
|
|
89
|
+
evaluateTelemetryOptions as evaluateTelemetryOptions2
|
|
90
|
+
} from "@forklaunch/core/http";
|
|
91
|
+
import {
|
|
92
|
+
transformIntoInternalDtoMapper as transformIntoInternalDtoMapper2
|
|
93
|
+
} from "@forklaunch/core/mappers";
|
|
94
|
+
var BasePermissionService = class {
|
|
95
|
+
constructor(em, roleServiceFactory, openTelemetryCollector, schemaValidator, mappers, options) {
|
|
96
|
+
this.em = em;
|
|
97
|
+
this.roleServiceFactory = roleServiceFactory;
|
|
98
|
+
this.openTelemetryCollector = openTelemetryCollector;
|
|
99
|
+
this.schemaValidator = schemaValidator;
|
|
100
|
+
this.mappers = mappers;
|
|
101
|
+
this.#mappers = transformIntoInternalDtoMapper2(mappers, schemaValidator);
|
|
102
|
+
this.evaluatedTelemetryOptions = options?.telemetry ? evaluateTelemetryOptions2(options.telemetry).enabled : {
|
|
103
|
+
logging: false,
|
|
104
|
+
metrics: false,
|
|
105
|
+
tracing: false
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
#mappers;
|
|
109
|
+
evaluatedTelemetryOptions;
|
|
110
|
+
// start: global helper functions
|
|
111
|
+
async updateRolesWithPermissions(roles, permissions) {
|
|
112
|
+
return Promise.all(
|
|
113
|
+
roles.map(async (role) => {
|
|
114
|
+
permissions.forEach((permission) => role.permissions.add(permission));
|
|
115
|
+
return role;
|
|
116
|
+
})
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
async removePermissionsFromRoles(roles, permissions) {
|
|
120
|
+
return Promise.all(
|
|
121
|
+
roles.map(async (role) => {
|
|
122
|
+
permissions.forEach(
|
|
123
|
+
(permission) => role.permissions.remove(permission)
|
|
124
|
+
);
|
|
125
|
+
return role;
|
|
126
|
+
})
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
async getBatchRoles(roleIds, em) {
|
|
130
|
+
return roleIds ? await Promise.all(
|
|
131
|
+
(await this.roleServiceFactory().getBatchRoles(roleIds, em)).map(
|
|
132
|
+
async (role) => {
|
|
133
|
+
return (em ?? this.em).merge(
|
|
134
|
+
await this.#mappers.RoleEntityMapper.deserializeDtoToEntity(
|
|
135
|
+
role,
|
|
136
|
+
em ?? this.em
|
|
137
|
+
)
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
)
|
|
141
|
+
) : [];
|
|
142
|
+
}
|
|
143
|
+
// end: global helper functions
|
|
144
|
+
// start: createPermission helper functions
|
|
145
|
+
async createPermissionDto({
|
|
146
|
+
permission,
|
|
147
|
+
addToRoles
|
|
148
|
+
}) {
|
|
149
|
+
let roles = [];
|
|
150
|
+
if (addToRoles) {
|
|
151
|
+
roles = await this.updateRolesWithPermissions(addToRoles, [permission]);
|
|
152
|
+
}
|
|
153
|
+
return { permission, roles };
|
|
154
|
+
}
|
|
155
|
+
async extractCreatePermissionDtoToEntityData(permissionDto, em) {
|
|
156
|
+
return {
|
|
157
|
+
permission: (em ?? this.em).merge(
|
|
158
|
+
await this.#mappers.CreatePermissionDtoMapper.deserializeDtoToEntity(
|
|
159
|
+
permissionDto,
|
|
160
|
+
em ?? this.em
|
|
161
|
+
)
|
|
162
|
+
),
|
|
163
|
+
addToRoles: permissionDto.addToRolesIds ? await this.getBatchRoles({ ids: permissionDto.addToRolesIds }, em) : []
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
// end: createPermission helper functions
|
|
167
|
+
async createPermission(createPermissionDto, em) {
|
|
168
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
169
|
+
this.openTelemetryCollector.info(
|
|
170
|
+
"Creating permission",
|
|
171
|
+
createPermissionDto
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
const { permission, roles } = await this.createPermissionDto(
|
|
175
|
+
await this.extractCreatePermissionDtoToEntityData(createPermissionDto, em)
|
|
176
|
+
);
|
|
177
|
+
if (em) {
|
|
178
|
+
await em.persist([permission, ...roles]);
|
|
179
|
+
} else {
|
|
180
|
+
await this.em.persistAndFlush([permission, ...roles]);
|
|
181
|
+
}
|
|
182
|
+
return this.#mappers.PermissionDtoMapper.serializeEntityToDto(permission);
|
|
183
|
+
}
|
|
184
|
+
async createBatchPermissions(permissionDtos, em) {
|
|
185
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
186
|
+
this.openTelemetryCollector.info(
|
|
187
|
+
"Creating batch permissions",
|
|
188
|
+
permissionDtos
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
const rolesCache = {};
|
|
192
|
+
const permissions = [];
|
|
193
|
+
permissionDtos.map(async (createPermissionDto) => {
|
|
194
|
+
const { permission, roles } = await this.createPermissionDto(
|
|
195
|
+
await this.extractCreatePermissionDtoToEntityData(
|
|
196
|
+
createPermissionDto,
|
|
197
|
+
em
|
|
198
|
+
)
|
|
199
|
+
);
|
|
200
|
+
roles.forEach((role) => {
|
|
201
|
+
if (rolesCache[role.id] && role.permissions !== rolesCache[role.id].permissions) {
|
|
202
|
+
role.permissions.getItems().forEach((permission2) => {
|
|
203
|
+
if (!rolesCache[role.id].permissions.contains(permission2)) {
|
|
204
|
+
rolesCache[role.id].permissions.add(permission2);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
} else {
|
|
208
|
+
rolesCache[role.id] = role;
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
permissions.push(permission);
|
|
212
|
+
});
|
|
213
|
+
const entities = [...permissions, ...Object.values(rolesCache)];
|
|
214
|
+
if (em) {
|
|
215
|
+
await em.persist(entities);
|
|
216
|
+
} else {
|
|
217
|
+
await this.em.persistAndFlush(entities);
|
|
218
|
+
}
|
|
219
|
+
return Promise.all(
|
|
220
|
+
permissions.map(
|
|
221
|
+
async (permission) => this.#mappers.PermissionDtoMapper.serializeEntityToDto(permission)
|
|
222
|
+
)
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
async getPermission(idDto, em) {
|
|
226
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
227
|
+
this.openTelemetryCollector.info("Getting permission", idDto);
|
|
228
|
+
}
|
|
229
|
+
const permission = await (em ?? this.em).findOneOrFail("Permission", idDto);
|
|
230
|
+
return this.#mappers.PermissionDtoMapper.serializeEntityToDto(
|
|
231
|
+
permission
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
async getBatchPermissions(idsDto, em) {
|
|
235
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
236
|
+
this.openTelemetryCollector.info("Getting batch permissions", idsDto);
|
|
237
|
+
}
|
|
238
|
+
return Promise.all(
|
|
239
|
+
(await (em ?? this.em).find("Permission", idsDto)).map(
|
|
240
|
+
(permission) => this.#mappers.PermissionDtoMapper.serializeEntityToDto(
|
|
241
|
+
permission
|
|
242
|
+
)
|
|
243
|
+
)
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
// start: updatePermission helper functions
|
|
247
|
+
updatePermissionDto = async (permissionDto, em) => {
|
|
248
|
+
const permission = await this.#mappers.UpdatePermissionDtoMapper.deserializeDtoToEntity(
|
|
249
|
+
permissionDto,
|
|
250
|
+
em ?? this.em
|
|
251
|
+
);
|
|
252
|
+
const addToRoles = permissionDto.addToRolesIds ? await this.getBatchRoles({ ids: permissionDto.addToRolesIds }, em) : [];
|
|
253
|
+
const removeFromRoles = permissionDto.removeFromRolesIds ? await this.getBatchRoles({ ids: permissionDto.removeFromRolesIds }, em) : [];
|
|
254
|
+
let roles = [];
|
|
255
|
+
roles = roles.concat(
|
|
256
|
+
await this.updateRolesWithPermissions(addToRoles, [permission])
|
|
257
|
+
);
|
|
258
|
+
roles = roles.concat(
|
|
259
|
+
await this.removePermissionsFromRoles(removeFromRoles, [permission])
|
|
260
|
+
);
|
|
261
|
+
return {
|
|
262
|
+
permission,
|
|
263
|
+
roles
|
|
264
|
+
};
|
|
265
|
+
};
|
|
266
|
+
// end: updatePermission helper functions
|
|
267
|
+
async updatePermission(permissionDto, em) {
|
|
268
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
269
|
+
this.openTelemetryCollector.info("Updating permission", permissionDto);
|
|
270
|
+
}
|
|
271
|
+
const { permission, roles } = await this.updatePermissionDto(permissionDto);
|
|
272
|
+
const entities = await (em ?? this.em).upsertMany([permission, ...roles]);
|
|
273
|
+
if (em) {
|
|
274
|
+
await em.persist(entities);
|
|
275
|
+
} else {
|
|
276
|
+
await this.em.persistAndFlush(entities);
|
|
277
|
+
}
|
|
278
|
+
return this.#mappers.PermissionDtoMapper.serializeEntityToDto(permission);
|
|
279
|
+
}
|
|
280
|
+
async updateBatchPermissions(permissionDtos, em) {
|
|
281
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
282
|
+
this.openTelemetryCollector.info(
|
|
283
|
+
"Updating batch permissions",
|
|
284
|
+
permissionDtos
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
const rolesCache = {};
|
|
288
|
+
const permissions = [];
|
|
289
|
+
await (em ?? this.em).transactional(async (em2) => {
|
|
290
|
+
permissionDtos.map(async (updatePermissionDto) => {
|
|
291
|
+
const { permission, roles } = await this.updatePermissionDto(updatePermissionDto);
|
|
292
|
+
roles.forEach((role) => {
|
|
293
|
+
if (rolesCache[role.id] && role.permissions !== rolesCache[role.id].permissions) {
|
|
294
|
+
role.permissions.getItems().forEach((permission2) => {
|
|
295
|
+
if (!rolesCache[role.id].permissions.contains(permission2)) {
|
|
296
|
+
rolesCache[role.id].permissions.add(permission2);
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
} else {
|
|
300
|
+
rolesCache[role.id] = role;
|
|
301
|
+
}
|
|
302
|
+
});
|
|
303
|
+
permissions.push(permission);
|
|
304
|
+
});
|
|
305
|
+
const entities = [...permissions, ...Object.values(rolesCache)];
|
|
306
|
+
if (em2) {
|
|
307
|
+
await em2.persist(entities);
|
|
308
|
+
} else {
|
|
309
|
+
await this.em.persistAndFlush(entities);
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
return Promise.all(
|
|
313
|
+
permissions.map(
|
|
314
|
+
(permission) => this.#mappers.PermissionDtoMapper.serializeEntityToDto(permission)
|
|
315
|
+
)
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
async deletePermission(idDto, em) {
|
|
319
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
320
|
+
this.openTelemetryCollector.info("Deleting permission", idDto);
|
|
321
|
+
}
|
|
322
|
+
await (em ?? this.em).nativeDelete("Permission", idDto);
|
|
323
|
+
}
|
|
324
|
+
async deleteBatchPermissions(idsDto, em) {
|
|
325
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
326
|
+
this.openTelemetryCollector.info("Deleting batch permissions", idsDto);
|
|
327
|
+
}
|
|
328
|
+
await (em ?? this.em).nativeDelete("Permission", {
|
|
329
|
+
id: { $in: idsDto.ids }
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
// services/role.service.ts
|
|
335
|
+
import {
|
|
336
|
+
evaluateTelemetryOptions as evaluateTelemetryOptions3
|
|
337
|
+
} from "@forklaunch/core/http";
|
|
338
|
+
import {
|
|
339
|
+
transformIntoInternalDtoMapper as transformIntoInternalDtoMapper3
|
|
340
|
+
} from "@forklaunch/core/mappers";
|
|
341
|
+
var BaseRoleService = class {
|
|
342
|
+
constructor(em, openTelemetryCollector, schemaValidator, mappers, options) {
|
|
343
|
+
this.em = em;
|
|
344
|
+
this.openTelemetryCollector = openTelemetryCollector;
|
|
345
|
+
this.schemaValidator = schemaValidator;
|
|
346
|
+
this.mappers = mappers;
|
|
347
|
+
this.#mappers = transformIntoInternalDtoMapper3(mappers, schemaValidator);
|
|
348
|
+
this.evaluatedTelemetryOptions = options?.telemetry ? evaluateTelemetryOptions3(options.telemetry).enabled : {
|
|
349
|
+
logging: false,
|
|
350
|
+
metrics: false,
|
|
351
|
+
tracing: false
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
#mappers;
|
|
355
|
+
evaluatedTelemetryOptions;
|
|
356
|
+
async createRole(roleDto, em) {
|
|
357
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
358
|
+
this.openTelemetryCollector.info("Creating role", roleDto);
|
|
359
|
+
}
|
|
360
|
+
const role = await this.#mappers.CreateRoleDtoMapper.deserializeDtoToEntity(
|
|
361
|
+
roleDto,
|
|
362
|
+
em ?? this.em
|
|
363
|
+
);
|
|
364
|
+
if (em) {
|
|
365
|
+
await em.persist(role);
|
|
366
|
+
} else {
|
|
367
|
+
await this.em.persistAndFlush(role);
|
|
368
|
+
}
|
|
369
|
+
return this.#mappers.RoleDtoMapper.serializeEntityToDto(role);
|
|
370
|
+
}
|
|
371
|
+
async createBatchRoles(roleDtos, em) {
|
|
372
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
373
|
+
this.openTelemetryCollector.info("Creating batch roles", roleDtos);
|
|
374
|
+
}
|
|
375
|
+
const roles = await Promise.all(
|
|
376
|
+
roleDtos.map(
|
|
377
|
+
async (roleDto) => this.#mappers.CreateRoleDtoMapper.deserializeDtoToEntity(
|
|
378
|
+
roleDto,
|
|
379
|
+
em ?? this.em
|
|
380
|
+
)
|
|
381
|
+
)
|
|
382
|
+
);
|
|
383
|
+
if (em) {
|
|
384
|
+
await em.persist(roles);
|
|
385
|
+
} else {
|
|
386
|
+
await this.em.persistAndFlush(roles);
|
|
387
|
+
}
|
|
388
|
+
return Promise.all(
|
|
389
|
+
roles.map(
|
|
390
|
+
(role) => this.#mappers.RoleDtoMapper.serializeEntityToDto(role)
|
|
391
|
+
)
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
async getRole({ id }, em) {
|
|
395
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
396
|
+
this.openTelemetryCollector.info("Getting role", { id });
|
|
397
|
+
}
|
|
398
|
+
const role = await (em ?? this.em).findOneOrFail("Role", id, {
|
|
399
|
+
populate: ["id", "*"]
|
|
400
|
+
});
|
|
401
|
+
return this.#mappers.RoleDtoMapper.serializeEntityToDto(
|
|
402
|
+
role
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
async getBatchRoles({ ids }, em) {
|
|
406
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
407
|
+
this.openTelemetryCollector.info("Getting batch roles", { ids });
|
|
408
|
+
}
|
|
409
|
+
return Promise.all(
|
|
410
|
+
(await (em ?? this.em).find(
|
|
411
|
+
"Role",
|
|
412
|
+
{
|
|
413
|
+
id: { $in: ids }
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
populate: ["id", "*"]
|
|
417
|
+
}
|
|
418
|
+
)).map(
|
|
419
|
+
(role) => this.#mappers.RoleDtoMapper.serializeEntityToDto(
|
|
420
|
+
role
|
|
421
|
+
)
|
|
422
|
+
)
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
async updateRole(roleDto, em) {
|
|
426
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
427
|
+
this.openTelemetryCollector.info("Updating role", roleDto);
|
|
428
|
+
}
|
|
429
|
+
const role = await this.#mappers.UpdateRoleDtoMapper.deserializeDtoToEntity(
|
|
430
|
+
roleDto,
|
|
431
|
+
em ?? this.em
|
|
432
|
+
);
|
|
433
|
+
if (em) {
|
|
434
|
+
await em.persist(role);
|
|
435
|
+
} else {
|
|
436
|
+
await this.em.persistAndFlush(role);
|
|
437
|
+
}
|
|
438
|
+
return this.#mappers.RoleDtoMapper.serializeEntityToDto(role);
|
|
439
|
+
}
|
|
440
|
+
async updateBatchRoles(roleDtos, em) {
|
|
441
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
442
|
+
this.openTelemetryCollector.info("Updating batch roles", roleDtos);
|
|
443
|
+
}
|
|
444
|
+
const roles = await Promise.all(
|
|
445
|
+
roleDtos.map(
|
|
446
|
+
async (roleDto) => this.#mappers.UpdateRoleDtoMapper.deserializeDtoToEntity(
|
|
447
|
+
roleDto,
|
|
448
|
+
em ?? this.em
|
|
449
|
+
)
|
|
450
|
+
)
|
|
451
|
+
);
|
|
452
|
+
if (em) {
|
|
453
|
+
await em.persist(roles);
|
|
454
|
+
} else {
|
|
455
|
+
await this.em.persistAndFlush(roles);
|
|
456
|
+
}
|
|
457
|
+
return Promise.all(
|
|
458
|
+
roles.map(
|
|
459
|
+
(role) => this.#mappers.RoleDtoMapper.serializeEntityToDto(
|
|
460
|
+
role
|
|
461
|
+
)
|
|
462
|
+
)
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
async deleteRole(idDto, em) {
|
|
466
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
467
|
+
this.openTelemetryCollector.info("Deleting role", idDto);
|
|
468
|
+
}
|
|
469
|
+
await (em ?? this.em).nativeDelete("Role", idDto);
|
|
470
|
+
}
|
|
471
|
+
async deleteBatchRoles(idsDto, em) {
|
|
472
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
473
|
+
this.openTelemetryCollector.info("Deleting batch roles", idsDto);
|
|
474
|
+
}
|
|
475
|
+
await (em ?? this.em).nativeDelete("Role", { id: { $in: idsDto.ids } });
|
|
476
|
+
}
|
|
477
|
+
};
|
|
478
|
+
|
|
479
|
+
// services/user.service.ts
|
|
480
|
+
import {
|
|
481
|
+
evaluateTelemetryOptions as evaluateTelemetryOptions4
|
|
482
|
+
} from "@forklaunch/core/http";
|
|
483
|
+
import {
|
|
484
|
+
transformIntoInternalDtoMapper as transformIntoInternalDtoMapper4
|
|
485
|
+
} from "@forklaunch/core/mappers";
|
|
486
|
+
var BaseUserService = class {
|
|
487
|
+
constructor(em, passwordEncryptionPublicKeyPath, roleServiceFactory, organizationServiceFactory, openTelemetryCollector, schemaValidator, mappers, options) {
|
|
488
|
+
this.em = em;
|
|
489
|
+
this.passwordEncryptionPublicKeyPath = passwordEncryptionPublicKeyPath;
|
|
490
|
+
this.roleServiceFactory = roleServiceFactory;
|
|
491
|
+
this.organizationServiceFactory = organizationServiceFactory;
|
|
492
|
+
this.openTelemetryCollector = openTelemetryCollector;
|
|
493
|
+
this.schemaValidator = schemaValidator;
|
|
494
|
+
this.mappers = mappers;
|
|
495
|
+
this.options = options;
|
|
496
|
+
this.#mappers = transformIntoInternalDtoMapper4(mappers, schemaValidator);
|
|
497
|
+
this.evaluatedTelemetryOptions = options?.telemetry ? evaluateTelemetryOptions4(options.telemetry).enabled : {
|
|
498
|
+
logging: false,
|
|
499
|
+
metrics: false,
|
|
500
|
+
tracing: false
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
#mappers;
|
|
504
|
+
evaluatedTelemetryOptions;
|
|
505
|
+
async createUser(userDto, em) {
|
|
506
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
507
|
+
this.openTelemetryCollector.info("Creating user", userDto);
|
|
508
|
+
}
|
|
509
|
+
const user = await this.#mappers.CreateUserDtoMapper.deserializeDtoToEntity(
|
|
510
|
+
userDto,
|
|
511
|
+
em ?? this.em
|
|
512
|
+
);
|
|
513
|
+
if (em) {
|
|
514
|
+
await em.persist(user);
|
|
515
|
+
} else {
|
|
516
|
+
await this.em.persistAndFlush(user);
|
|
517
|
+
}
|
|
518
|
+
return this.#mappers.UserDtoMapper.serializeEntityToDto(user);
|
|
519
|
+
}
|
|
520
|
+
async createBatchUsers(userDtos, em) {
|
|
521
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
522
|
+
this.openTelemetryCollector.info("Creating batch users", userDtos);
|
|
523
|
+
}
|
|
524
|
+
const users = await Promise.all(
|
|
525
|
+
userDtos.map(
|
|
526
|
+
async (createUserDto) => this.#mappers.CreateUserDtoMapper.deserializeDtoToEntity(
|
|
527
|
+
createUserDto,
|
|
528
|
+
em ?? this.em
|
|
529
|
+
)
|
|
530
|
+
)
|
|
531
|
+
);
|
|
532
|
+
if (em) {
|
|
533
|
+
await em.persist(users);
|
|
534
|
+
} else {
|
|
535
|
+
await this.em.persistAndFlush(users);
|
|
536
|
+
}
|
|
537
|
+
return Promise.all(
|
|
538
|
+
users.map(
|
|
539
|
+
(user) => this.#mappers.UserDtoMapper.serializeEntityToDto(user)
|
|
540
|
+
)
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
async getUser(idDto, em) {
|
|
544
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
545
|
+
this.openTelemetryCollector.info("Getting user", idDto);
|
|
546
|
+
}
|
|
547
|
+
const user = await (em ?? this.em).findOneOrFail("User", idDto, {
|
|
548
|
+
populate: ["id", "*"]
|
|
549
|
+
});
|
|
550
|
+
return this.#mappers.UserDtoMapper.serializeEntityToDto(
|
|
551
|
+
user
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
async getBatchUsers(idsDto, em) {
|
|
555
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
556
|
+
this.openTelemetryCollector.info("Getting batch users", idsDto);
|
|
557
|
+
}
|
|
558
|
+
return Promise.all(
|
|
559
|
+
(await (em ?? this.em).find("User", idsDto, {
|
|
560
|
+
populate: ["id", "*"]
|
|
561
|
+
})).map(
|
|
562
|
+
(user) => this.#mappers.UserDtoMapper.serializeEntityToDto(
|
|
563
|
+
user
|
|
564
|
+
)
|
|
565
|
+
)
|
|
566
|
+
);
|
|
567
|
+
}
|
|
568
|
+
async updateUser(userDto, em) {
|
|
569
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
570
|
+
this.openTelemetryCollector.info("Updating user", userDto);
|
|
571
|
+
}
|
|
572
|
+
const user = await this.#mappers.UpdateUserDtoMapper.deserializeDtoToEntity(
|
|
573
|
+
userDto,
|
|
574
|
+
em ?? this.em
|
|
575
|
+
);
|
|
576
|
+
if (em) {
|
|
577
|
+
await em.persist(user);
|
|
578
|
+
} else {
|
|
579
|
+
await this.em.persistAndFlush(user);
|
|
580
|
+
}
|
|
581
|
+
return this.#mappers.UserDtoMapper.serializeEntityToDto(user);
|
|
582
|
+
}
|
|
583
|
+
async updateBatchUsers(userDtos, em) {
|
|
584
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
585
|
+
this.openTelemetryCollector.info("Updating batch users", userDtos);
|
|
586
|
+
}
|
|
587
|
+
const users = await Promise.all(
|
|
588
|
+
userDtos.map(
|
|
589
|
+
async (updateUserDto) => this.#mappers.UpdateUserDtoMapper.deserializeDtoToEntity(
|
|
590
|
+
updateUserDto,
|
|
591
|
+
em ?? this.em
|
|
592
|
+
)
|
|
593
|
+
)
|
|
594
|
+
);
|
|
595
|
+
if (em) {
|
|
596
|
+
await em.persist(users);
|
|
597
|
+
} else {
|
|
598
|
+
await this.em.persistAndFlush(users);
|
|
599
|
+
}
|
|
600
|
+
return Promise.all(
|
|
601
|
+
users.map(
|
|
602
|
+
(user) => this.#mappers.UserDtoMapper.serializeEntityToDto(user)
|
|
603
|
+
)
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
async deleteUser(idDto, em) {
|
|
607
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
608
|
+
this.openTelemetryCollector.info("Deleting user", idDto);
|
|
609
|
+
}
|
|
610
|
+
await (em ?? this.em).nativeDelete("User", idDto);
|
|
611
|
+
}
|
|
612
|
+
async deleteBatchUsers(idsDto, em) {
|
|
613
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
614
|
+
this.openTelemetryCollector.info("Deleting batch users", idsDto);
|
|
615
|
+
}
|
|
616
|
+
await (em ?? this.em).nativeDelete("User", idsDto);
|
|
617
|
+
}
|
|
618
|
+
async verifyHasRole(idDto, roleId) {
|
|
619
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
620
|
+
this.openTelemetryCollector.info("Verifying user has role", {
|
|
621
|
+
idDto,
|
|
622
|
+
roleId
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
const user = await this.getUser(idDto);
|
|
626
|
+
if (user.roles.filter((role) => {
|
|
627
|
+
return roleId == role.id;
|
|
628
|
+
}).length === 0) {
|
|
629
|
+
throw new Error(`User ${idDto.id} does not have role ${roleId}`);
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
async verifyHasPermission(idDto, permissionId) {
|
|
633
|
+
if (this.evaluatedTelemetryOptions.logging) {
|
|
634
|
+
this.openTelemetryCollector.info("Verifying user has permission", {
|
|
635
|
+
idDto,
|
|
636
|
+
permissionId
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
const user = await this.getUser(idDto);
|
|
640
|
+
if (user.roles.map((role) => role.permissions.map((permission) => permission.id)).flat().filter((id) => id == permissionId).length === 0) {
|
|
641
|
+
throw new Error(
|
|
642
|
+
`User ${idDto.id} does not have permission ${permissionId}`
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
};
|
|
647
|
+
export {
|
|
648
|
+
BaseOrganizationService,
|
|
649
|
+
BasePermissionService,
|
|
650
|
+
BaseRoleService,
|
|
651
|
+
BaseUserService
|
|
652
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forklaunch/implementation-iam-base",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Billing basic implementation for forklaunch",
|
|
5
5
|
"homepage": "https://github.com/forklaunch/forklaunch-js#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -15,13 +15,15 @@
|
|
|
15
15
|
"exports": {
|
|
16
16
|
"./schemas": {
|
|
17
17
|
"types": "./lib/schemas/index.d.ts",
|
|
18
|
-
"import": "./lib/schemas/index.
|
|
19
|
-
"require": "./lib/schemas/index.js"
|
|
18
|
+
"import": "./lib/schemas/index.mjs",
|
|
19
|
+
"require": "./lib/schemas/index.js",
|
|
20
|
+
"default": "./lib/schemas/index.js"
|
|
20
21
|
},
|
|
21
22
|
"./services": {
|
|
22
23
|
"types": "./lib/services/index.d.ts",
|
|
23
|
-
"import": "./lib/services/index.
|
|
24
|
-
"require": "./lib/services/index.js"
|
|
24
|
+
"import": "./lib/services/index.mjs",
|
|
25
|
+
"require": "./lib/services/index.js",
|
|
26
|
+
"default": "./lib/services/index.js"
|
|
25
27
|
}
|
|
26
28
|
},
|
|
27
29
|
"files": [
|
|
@@ -29,21 +31,22 @@
|
|
|
29
31
|
],
|
|
30
32
|
"dependencies": {
|
|
31
33
|
"@forklaunch/common": "^0.3.11",
|
|
32
|
-
"@forklaunch/core": "^0.9.
|
|
33
|
-
"@forklaunch/validator": "^0.6.
|
|
34
|
+
"@forklaunch/core": "^0.9.15",
|
|
35
|
+
"@forklaunch/validator": "^0.6.13",
|
|
34
36
|
"@mikro-orm/core": "^6.4.16",
|
|
35
37
|
"@sinclair/typebox": "^0.34.33",
|
|
36
38
|
"ajv": "^8.17.1",
|
|
37
|
-
"zod": "^3.25.
|
|
38
|
-
"@forklaunch/interfaces-iam": "0.
|
|
39
|
+
"zod": "^3.25.63",
|
|
40
|
+
"@forklaunch/interfaces-iam": "0.3.1"
|
|
39
41
|
},
|
|
40
42
|
"devDependencies": {
|
|
43
|
+
"@typescript/native-preview": "7.0.0-dev.20250611.1",
|
|
41
44
|
"depcheck": "^1.4.7",
|
|
42
45
|
"prettier": "^3.5.3",
|
|
43
46
|
"typedoc": "^0.28.5"
|
|
44
47
|
},
|
|
45
48
|
"scripts": {
|
|
46
|
-
"build": "tsc && if [ -f eject-package.bash ]; then pnpm package:eject; fi",
|
|
49
|
+
"build": "tsc --noEmit && tsup schemas/index.ts services/index.ts --format cjs,esm --no-splitting --dts --tsconfig tsconfig.json --out-dir lib --clean && if [ -f eject-package.bash ]; then pnpm package:eject; fi",
|
|
47
50
|
"clean": "rm -rf lib pnpm.lock.yaml node_modules",
|
|
48
51
|
"docs": "typedoc --out docs *",
|
|
49
52
|
"format": "prettier --ignore-path=.prettierignore --config .prettierrc '**/*.{ts,tsx,json}' --write",
|