@forklaunch/implementation-iam-base 0.6.3 → 0.7.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.
@@ -13,7 +13,7 @@ import {
13
13
  } from '@forklaunch/core/http';
14
14
  import { CreateUserDto, UpdateUserDto } from '@forklaunch/interfaces-iam/types';
15
15
  import { AnySchemaValidator } from '@forklaunch/validator';
16
- import { EntityManager } from '@mikro-orm/core';
16
+ import { EntityManager, FilterQuery } from '@mikro-orm/core';
17
17
  import { UserDtos } from '../domain/types/iamDto.types';
18
18
  import { UserEntities } from '../domain/types/iamEntities.types';
19
19
  import { UserMappers } from '../domain/types/user.mapper.types';
@@ -31,7 +31,6 @@ export class BaseUserService<
31
31
  tracing?: boolean;
32
32
  };
33
33
  public em: EntityManager;
34
- protected passwordEncryptionPublicKeyPath: string;
35
34
  protected roleServiceFactory: () => RoleService;
36
35
  protected organizationServiceFactory: () => OrganizationService<OrganizationStatus>;
37
36
  protected openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>;
@@ -40,7 +39,6 @@ export class BaseUserService<
40
39
 
41
40
  constructor(
42
41
  em: EntityManager,
43
- passwordEncryptionPublicKeyPath: string,
44
42
  roleServiceFactory: () => RoleService,
45
43
  organizationServiceFactory: () => OrganizationService<OrganizationStatus>,
46
44
  openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>,
@@ -51,7 +49,6 @@ export class BaseUserService<
51
49
  }
52
50
  ) {
53
51
  this.em = em;
54
- this.passwordEncryptionPublicKeyPath = passwordEncryptionPublicKeyPath;
55
52
  this.roleServiceFactory = roleServiceFactory;
56
53
  this.organizationServiceFactory = organizationServiceFactory;
57
54
  this.openTelemetryCollector = openTelemetryCollector;
@@ -120,9 +117,19 @@ export class BaseUserService<
120
117
  );
121
118
  }
122
119
 
123
- async getUser(
120
+ async getOrganizationIdByUserId(
124
121
  idDto: IdDto,
125
122
  em?: EntityManager
123
+ ): Promise<string> {
124
+ const user = await (em ?? this.em).findOneOrFail('User', idDto, {
125
+ populate: ['id', 'organization']
126
+ });
127
+ return user.organization?.id;
128
+ }
129
+
130
+ async getUser(
131
+ idDto: IdDto & FilterQuery<MapperEntities['UserMapper']>,
132
+ em?: EntityManager
126
133
  ): Promise<MapperDomains['UserMapper']> {
127
134
  if (this.evaluatedTelemetryOptions.logging) {
128
135
  this.openTelemetryCollector.info('Getting user', idDto);
@@ -222,40 +229,29 @@ export class BaseUserService<
222
229
  await (em ?? this.em).nativeDelete('User', idsDto);
223
230
  }
224
231
 
225
- async verifyHasRole(idDto: IdDto, roleId: string): Promise<void> {
232
+ async surfaceRoles(
233
+ idDto: IdDto & FilterQuery<MapperEntities['UserMapper']>,
234
+ em?: EntityManager
235
+ ): Promise<MapperDomains['UserMapper']['roles']> {
226
236
  if (this.evaluatedTelemetryOptions.logging) {
227
- this.openTelemetryCollector.info('Verifying user has role', {
228
- idDto,
229
- roleId
237
+ this.openTelemetryCollector.info('Surfacing user roles', {
238
+ idDto
230
239
  });
231
240
  }
232
- const user = await this.getUser(idDto);
233
- if (
234
- user.roles.filter((role) => {
235
- return roleId == role.id;
236
- }).length === 0
237
- ) {
238
- throw new Error(`User ${idDto.id} does not have role ${roleId}`);
239
- }
241
+ const user = await this.getUser(idDto, em);
242
+ return user.roles;
240
243
  }
241
244
 
242
- async verifyHasPermission(idDto: IdDto, permissionId: string): Promise<void> {
245
+ async surfacePermissions(
246
+ idDto: IdDto & FilterQuery<MapperEntities['UserMapper']>,
247
+ em?: EntityManager
248
+ ): Promise<MapperDomains['UserMapper']['roles'][0]['permissions']> {
243
249
  if (this.evaluatedTelemetryOptions.logging) {
244
- this.openTelemetryCollector.info('Verifying user has permission', {
245
- idDto,
246
- permissionId
250
+ this.openTelemetryCollector.info('Surfacing user permissions', {
251
+ idDto
247
252
  });
248
253
  }
249
- const user = await this.getUser(idDto);
250
- if (
251
- user.roles
252
- .map((role) => role.permissions.map((permission) => permission.id))
253
- .flat()
254
- .filter((id) => id == permissionId).length === 0
255
- ) {
256
- throw new Error(
257
- `User ${idDto.id} does not have permission ${permissionId}`
258
- );
259
- }
254
+ const user = await this.getUser(idDto, em);
255
+ return user.roles.map((role) => role.permissions).flat();
260
256
  }
261
257
  }
@@ -3,7 +3,7 @@ import { OpenTelemetryCollector, MetricsDefinition, TelemetryOptions } from '@fo
3
3
  import { OrganizationService, PermissionService, RoleService, UserService } from '@forklaunch/interfaces-iam/interfaces';
4
4
  import { CreateOrganizationDto, UpdateOrganizationDto, CreatePermissionDto, UpdatePermissionDto, CreateRoleDto, RoleDto, UpdateRoleDto, CreateUserDto, UpdateUserDto } from '@forklaunch/interfaces-iam/types';
5
5
  import { AnySchemaValidator } from '@forklaunch/validator';
6
- import { EntityManager } from '@mikro-orm/core';
6
+ import { EntityManager, FilterQuery } from '@mikro-orm/core';
7
7
  import { OrganizationEntities, OrganizationDtos, OrganizationMappers, PermissionEntities, PermissionDtos, PermissionMappers, RoleEntities, RoleDtos, RoleMappers, UserEntities, UserDtos, UserMappers } from '../domain/types/index.mjs';
8
8
  import '@forklaunch/core/services';
9
9
 
@@ -70,25 +70,25 @@ declare class BaseRoleService<SchemaValidator extends AnySchemaValidator, Mapper
70
70
  declare class BaseUserService<SchemaValidator extends AnySchemaValidator, OrganizationStatus = unknown, MapperEntities extends UserEntities = UserEntities, MapperDomains extends UserDtos = UserDtos> implements UserService {
71
71
  private evaluatedTelemetryOptions;
72
72
  em: EntityManager;
73
- protected passwordEncryptionPublicKeyPath: string;
74
73
  protected roleServiceFactory: () => RoleService;
75
74
  protected organizationServiceFactory: () => OrganizationService<OrganizationStatus>;
76
75
  protected openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>;
77
76
  protected schemaValidator: SchemaValidator;
78
77
  protected mappers: UserMappers<MapperEntities, MapperDomains>;
79
- constructor(em: EntityManager, passwordEncryptionPublicKeyPath: string, roleServiceFactory: () => RoleService, organizationServiceFactory: () => OrganizationService<OrganizationStatus>, openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>, schemaValidator: SchemaValidator, mappers: UserMappers<MapperEntities, MapperDomains>, options?: {
78
+ constructor(em: EntityManager, roleServiceFactory: () => RoleService, organizationServiceFactory: () => OrganizationService<OrganizationStatus>, openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>, schemaValidator: SchemaValidator, mappers: UserMappers<MapperEntities, MapperDomains>, options?: {
80
79
  telemetry?: TelemetryOptions;
81
80
  });
82
81
  createUser(userDto: CreateUserDto, em?: EntityManager, ...args: unknown[]): Promise<MapperDomains['UserMapper']>;
83
82
  createBatchUsers(userDtos: CreateUserDto[], em?: EntityManager, ...args: unknown[]): Promise<MapperDomains['UserMapper'][]>;
84
- getUser(idDto: IdDto, em?: EntityManager): Promise<MapperDomains['UserMapper']>;
83
+ getOrganizationIdByUserId(idDto: IdDto, em?: EntityManager): Promise<string>;
84
+ getUser(idDto: IdDto & FilterQuery<MapperEntities['UserMapper']>, em?: EntityManager): Promise<MapperDomains['UserMapper']>;
85
85
  getBatchUsers(idsDto: IdsDto, em?: EntityManager): Promise<MapperDomains['UserMapper'][]>;
86
86
  updateUser(userDto: UpdateUserDto, em?: EntityManager, ...args: unknown[]): Promise<MapperDomains['UserMapper']>;
87
87
  updateBatchUsers(userDtos: UpdateUserDto[], em?: EntityManager, ...args: unknown[]): Promise<MapperDomains['UserMapper'][]>;
88
88
  deleteUser(idDto: IdDto, em?: EntityManager): Promise<void>;
89
89
  deleteBatchUsers(idsDto: IdsDto, em?: EntityManager): Promise<void>;
90
- verifyHasRole(idDto: IdDto, roleId: string): Promise<void>;
91
- verifyHasPermission(idDto: IdDto, permissionId: string): Promise<void>;
90
+ surfaceRoles(idDto: IdDto & FilterQuery<MapperEntities['UserMapper']>, em?: EntityManager): Promise<MapperDomains['UserMapper']['roles']>;
91
+ surfacePermissions(idDto: IdDto & FilterQuery<MapperEntities['UserMapper']>, em?: EntityManager): Promise<MapperDomains['UserMapper']['roles'][0]['permissions']>;
92
92
  }
93
93
 
94
94
  export { BaseOrganizationService, BasePermissionService, BaseRoleService, BaseUserService };
@@ -3,7 +3,7 @@ import { OpenTelemetryCollector, MetricsDefinition, TelemetryOptions } from '@fo
3
3
  import { OrganizationService, PermissionService, RoleService, UserService } from '@forklaunch/interfaces-iam/interfaces';
4
4
  import { CreateOrganizationDto, UpdateOrganizationDto, CreatePermissionDto, UpdatePermissionDto, CreateRoleDto, RoleDto, UpdateRoleDto, CreateUserDto, UpdateUserDto } from '@forklaunch/interfaces-iam/types';
5
5
  import { AnySchemaValidator } from '@forklaunch/validator';
6
- import { EntityManager } from '@mikro-orm/core';
6
+ import { EntityManager, FilterQuery } from '@mikro-orm/core';
7
7
  import { OrganizationEntities, OrganizationDtos, OrganizationMappers, PermissionEntities, PermissionDtos, PermissionMappers, RoleEntities, RoleDtos, RoleMappers, UserEntities, UserDtos, UserMappers } from '../domain/types/index.js';
8
8
  import '@forklaunch/core/services';
9
9
 
@@ -70,25 +70,25 @@ declare class BaseRoleService<SchemaValidator extends AnySchemaValidator, Mapper
70
70
  declare class BaseUserService<SchemaValidator extends AnySchemaValidator, OrganizationStatus = unknown, MapperEntities extends UserEntities = UserEntities, MapperDomains extends UserDtos = UserDtos> implements UserService {
71
71
  private evaluatedTelemetryOptions;
72
72
  em: EntityManager;
73
- protected passwordEncryptionPublicKeyPath: string;
74
73
  protected roleServiceFactory: () => RoleService;
75
74
  protected organizationServiceFactory: () => OrganizationService<OrganizationStatus>;
76
75
  protected openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>;
77
76
  protected schemaValidator: SchemaValidator;
78
77
  protected mappers: UserMappers<MapperEntities, MapperDomains>;
79
- constructor(em: EntityManager, passwordEncryptionPublicKeyPath: string, roleServiceFactory: () => RoleService, organizationServiceFactory: () => OrganizationService<OrganizationStatus>, openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>, schemaValidator: SchemaValidator, mappers: UserMappers<MapperEntities, MapperDomains>, options?: {
78
+ constructor(em: EntityManager, roleServiceFactory: () => RoleService, organizationServiceFactory: () => OrganizationService<OrganizationStatus>, openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>, schemaValidator: SchemaValidator, mappers: UserMappers<MapperEntities, MapperDomains>, options?: {
80
79
  telemetry?: TelemetryOptions;
81
80
  });
82
81
  createUser(userDto: CreateUserDto, em?: EntityManager, ...args: unknown[]): Promise<MapperDomains['UserMapper']>;
83
82
  createBatchUsers(userDtos: CreateUserDto[], em?: EntityManager, ...args: unknown[]): Promise<MapperDomains['UserMapper'][]>;
84
- getUser(idDto: IdDto, em?: EntityManager): Promise<MapperDomains['UserMapper']>;
83
+ getOrganizationIdByUserId(idDto: IdDto, em?: EntityManager): Promise<string>;
84
+ getUser(idDto: IdDto & FilterQuery<MapperEntities['UserMapper']>, em?: EntityManager): Promise<MapperDomains['UserMapper']>;
85
85
  getBatchUsers(idsDto: IdsDto, em?: EntityManager): Promise<MapperDomains['UserMapper'][]>;
86
86
  updateUser(userDto: UpdateUserDto, em?: EntityManager, ...args: unknown[]): Promise<MapperDomains['UserMapper']>;
87
87
  updateBatchUsers(userDtos: UpdateUserDto[], em?: EntityManager, ...args: unknown[]): Promise<MapperDomains['UserMapper'][]>;
88
88
  deleteUser(idDto: IdDto, em?: EntityManager): Promise<void>;
89
89
  deleteBatchUsers(idsDto: IdsDto, em?: EntityManager): Promise<void>;
90
- verifyHasRole(idDto: IdDto, roleId: string): Promise<void>;
91
- verifyHasPermission(idDto: IdDto, permissionId: string): Promise<void>;
90
+ surfaceRoles(idDto: IdDto & FilterQuery<MapperEntities['UserMapper']>, em?: EntityManager): Promise<MapperDomains['UserMapper']['roles']>;
91
+ surfacePermissions(idDto: IdDto & FilterQuery<MapperEntities['UserMapper']>, em?: EntityManager): Promise<MapperDomains['UserMapper']['roles'][0]['permissions']>;
92
92
  }
93
93
 
94
94
  export { BaseOrganizationService, BasePermissionService, BaseRoleService, BaseUserService };
@@ -512,15 +512,13 @@ var import_http4 = require("@forklaunch/core/http");
512
512
  var BaseUserService = class {
513
513
  evaluatedTelemetryOptions;
514
514
  em;
515
- passwordEncryptionPublicKeyPath;
516
515
  roleServiceFactory;
517
516
  organizationServiceFactory;
518
517
  openTelemetryCollector;
519
518
  schemaValidator;
520
519
  mappers;
521
- constructor(em, passwordEncryptionPublicKeyPath, roleServiceFactory, organizationServiceFactory, openTelemetryCollector, schemaValidator, mappers, options) {
520
+ constructor(em, roleServiceFactory, organizationServiceFactory, openTelemetryCollector, schemaValidator, mappers, options) {
522
521
  this.em = em;
523
- this.passwordEncryptionPublicKeyPath = passwordEncryptionPublicKeyPath;
524
522
  this.roleServiceFactory = roleServiceFactory;
525
523
  this.organizationServiceFactory = organizationServiceFactory;
526
524
  this.openTelemetryCollector = openTelemetryCollector;
@@ -570,6 +568,12 @@ var BaseUserService = class {
570
568
  users.map((user) => this.mappers.UserMapper.toDto(user))
571
569
  );
572
570
  }
571
+ async getOrganizationIdByUserId(idDto, em) {
572
+ const user = await (em ?? this.em).findOneOrFail("User", idDto, {
573
+ populate: ["id", "organization"]
574
+ });
575
+ return user.organization?.id;
576
+ }
573
577
  async getUser(idDto, em) {
574
578
  if (this.evaluatedTelemetryOptions.logging) {
575
579
  this.openTelemetryCollector.info("Getting user", idDto);
@@ -641,33 +645,23 @@ var BaseUserService = class {
641
645
  }
642
646
  await (em ?? this.em).nativeDelete("User", idsDto);
643
647
  }
644
- async verifyHasRole(idDto, roleId) {
648
+ async surfaceRoles(idDto, em) {
645
649
  if (this.evaluatedTelemetryOptions.logging) {
646
- this.openTelemetryCollector.info("Verifying user has role", {
647
- idDto,
648
- roleId
650
+ this.openTelemetryCollector.info("Surfacing user roles", {
651
+ idDto
649
652
  });
650
653
  }
651
- const user = await this.getUser(idDto);
652
- if (user.roles.filter((role) => {
653
- return roleId == role.id;
654
- }).length === 0) {
655
- throw new Error(`User ${idDto.id} does not have role ${roleId}`);
656
- }
654
+ const user = await this.getUser(idDto, em);
655
+ return user.roles;
657
656
  }
658
- async verifyHasPermission(idDto, permissionId) {
657
+ async surfacePermissions(idDto, em) {
659
658
  if (this.evaluatedTelemetryOptions.logging) {
660
- this.openTelemetryCollector.info("Verifying user has permission", {
661
- idDto,
662
- permissionId
659
+ this.openTelemetryCollector.info("Surfacing user permissions", {
660
+ idDto
663
661
  });
664
662
  }
665
- const user = await this.getUser(idDto);
666
- if (user.roles.map((role) => role.permissions.map((permission) => permission.id)).flat().filter((id) => id == permissionId).length === 0) {
667
- throw new Error(
668
- `User ${idDto.id} does not have permission ${permissionId}`
669
- );
670
- }
663
+ const user = await this.getUser(idDto, em);
664
+ return user.roles.map((role) => role.permissions).flat();
671
665
  }
672
666
  };
673
667
  // Annotate the CommonJS export names for ESM import in node:
@@ -491,15 +491,13 @@ import {
491
491
  var BaseUserService = class {
492
492
  evaluatedTelemetryOptions;
493
493
  em;
494
- passwordEncryptionPublicKeyPath;
495
494
  roleServiceFactory;
496
495
  organizationServiceFactory;
497
496
  openTelemetryCollector;
498
497
  schemaValidator;
499
498
  mappers;
500
- constructor(em, passwordEncryptionPublicKeyPath, roleServiceFactory, organizationServiceFactory, openTelemetryCollector, schemaValidator, mappers, options) {
499
+ constructor(em, roleServiceFactory, organizationServiceFactory, openTelemetryCollector, schemaValidator, mappers, options) {
501
500
  this.em = em;
502
- this.passwordEncryptionPublicKeyPath = passwordEncryptionPublicKeyPath;
503
501
  this.roleServiceFactory = roleServiceFactory;
504
502
  this.organizationServiceFactory = organizationServiceFactory;
505
503
  this.openTelemetryCollector = openTelemetryCollector;
@@ -549,6 +547,12 @@ var BaseUserService = class {
549
547
  users.map((user) => this.mappers.UserMapper.toDto(user))
550
548
  );
551
549
  }
550
+ async getOrganizationIdByUserId(idDto, em) {
551
+ const user = await (em ?? this.em).findOneOrFail("User", idDto, {
552
+ populate: ["id", "organization"]
553
+ });
554
+ return user.organization?.id;
555
+ }
552
556
  async getUser(idDto, em) {
553
557
  if (this.evaluatedTelemetryOptions.logging) {
554
558
  this.openTelemetryCollector.info("Getting user", idDto);
@@ -620,33 +624,23 @@ var BaseUserService = class {
620
624
  }
621
625
  await (em ?? this.em).nativeDelete("User", idsDto);
622
626
  }
623
- async verifyHasRole(idDto, roleId) {
627
+ async surfaceRoles(idDto, em) {
624
628
  if (this.evaluatedTelemetryOptions.logging) {
625
- this.openTelemetryCollector.info("Verifying user has role", {
626
- idDto,
627
- roleId
629
+ this.openTelemetryCollector.info("Surfacing user roles", {
630
+ idDto
628
631
  });
629
632
  }
630
- const user = await this.getUser(idDto);
631
- if (user.roles.filter((role) => {
632
- return roleId == role.id;
633
- }).length === 0) {
634
- throw new Error(`User ${idDto.id} does not have role ${roleId}`);
635
- }
633
+ const user = await this.getUser(idDto, em);
634
+ return user.roles;
636
635
  }
637
- async verifyHasPermission(idDto, permissionId) {
636
+ async surfacePermissions(idDto, em) {
638
637
  if (this.evaluatedTelemetryOptions.logging) {
639
- this.openTelemetryCollector.info("Verifying user has permission", {
640
- idDto,
641
- permissionId
638
+ this.openTelemetryCollector.info("Surfacing user permissions", {
639
+ idDto
642
640
  });
643
641
  }
644
- const user = await this.getUser(idDto);
645
- if (user.roles.map((role) => role.permissions.map((permission) => permission.id)).flat().filter((id) => id == permissionId).length === 0) {
646
- throw new Error(
647
- `User ${idDto.id} does not have permission ${permissionId}`
648
- );
649
- }
642
+ const user = await this.getUser(idDto, em);
643
+ return user.roles.map((role) => role.permissions).flat();
650
644
  }
651
645
  };
652
646
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forklaunch/implementation-iam-base",
3
- "version": "0.6.3",
3
+ "version": "0.7.0",
4
4
  "description": "Billing basic implementation for forklaunch",
5
5
  "homepage": "https://github.com/forklaunch/forklaunch-js#readme",
6
6
  "bugs": {
@@ -36,21 +36,21 @@
36
36
  "lib/**"
37
37
  ],
38
38
  "dependencies": {
39
- "@forklaunch/common": "^0.6.5",
40
- "@forklaunch/core": "^0.14.7",
41
- "@forklaunch/internal": "^0.3.5",
42
- "@forklaunch/validator": "^0.10.5",
43
- "@mikro-orm/core": "^6.5.2",
39
+ "@forklaunch/common": "^0.6.12",
40
+ "@forklaunch/core": "^0.15.1",
41
+ "@forklaunch/internal": "^0.3.12",
42
+ "@forklaunch/validator": "^0.10.12",
43
+ "@mikro-orm/core": "^6.5.5",
44
44
  "@sinclair/typebox": "^0.34.41",
45
45
  "ajv": "^8.17.1",
46
- "zod": "^4.1.5",
47
- "@forklaunch/interfaces-iam": "0.6.3"
46
+ "zod": "^4.1.11",
47
+ "@forklaunch/interfaces-iam": "0.7.0"
48
48
  },
49
49
  "devDependencies": {
50
- "@typescript/native-preview": "7.0.0-dev.20250910.1",
50
+ "@typescript/native-preview": "7.0.0-dev.20250922.1",
51
51
  "depcheck": "^1.4.7",
52
52
  "prettier": "^3.6.2",
53
- "typedoc": "^0.28.12"
53
+ "typedoc": "^0.28.13"
54
54
  },
55
55
  "scripts": {
56
56
  "build": "tsc --noEmit && tsup domain/schemas/index.ts services/index.ts domain/types/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",