@loomcore/api 0.2.4 → 0.2.6

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 (39) hide show
  1. package/dist/__tests__/common-test.utils.d.ts +12 -12
  2. package/dist/__tests__/common-test.utils.js +94 -101
  3. package/dist/__tests__/postgres.test-database.d.ts +2 -2
  4. package/dist/__tests__/postgres.test-database.js +16 -15
  5. package/dist/__tests__/test-objects.d.ts +1 -6
  6. package/dist/__tests__/test-objects.js +34 -73
  7. package/dist/config/base-api-config.d.ts +2 -2
  8. package/dist/config/base-api-config.js +17 -10
  9. package/dist/controllers/auth.controller.d.ts +3 -5
  10. package/dist/controllers/auth.controller.js +22 -26
  11. package/dist/controllers/index.d.ts +10 -11
  12. package/dist/controllers/index.js +10 -11
  13. package/dist/databases/mongo-db/migrations/mongo-initial-schema.d.ts +2 -2
  14. package/dist/databases/mongo-db/migrations/mongo-initial-schema.js +185 -128
  15. package/dist/services/auth.service.d.ts +8 -9
  16. package/dist/services/auth.service.js +66 -82
  17. package/dist/services/email.service.js +5 -5
  18. package/dist/services/jwt.service.js +2 -2
  19. package/dist/services/multi-tenant-api.service.d.ts +4 -4
  20. package/dist/services/multi-tenant-api.service.js +8 -8
  21. package/dist/services/organization.service.d.ts +4 -4
  22. package/dist/services/organization.service.js +12 -8
  23. package/dist/services/password-reset-token.service.d.ts +4 -4
  24. package/dist/services/password-reset-token.service.js +13 -9
  25. package/dist/services/tenant-query-decorator.d.ts +1 -1
  26. package/dist/services/tenant-query-decorator.js +17 -11
  27. package/dist/services/user.service.d.ts +6 -6
  28. package/dist/services/user.service.js +7 -7
  29. package/dist/services/utils/audit-for-create.util.d.ts +1 -1
  30. package/dist/services/utils/audit-for-update.util.d.ts +1 -1
  31. package/dist/services/utils/audit-for-update.util.js +0 -1
  32. package/dist/services/utils/getUserContextAuthorizations.util.d.ts +2 -2
  33. package/dist/services/utils/strip-sender-provided-system-properties.util.d.ts +1 -1
  34. package/dist/services/utils/strip-sender-provided-system-properties.util.js +5 -3
  35. package/package.json +5 -2
  36. package/dist/controllers/persons.controller.d.ts +0 -8
  37. package/dist/controllers/persons.controller.js +0 -18
  38. package/dist/services/person.service.d.ts +0 -6
  39. package/dist/services/person.service.js +0 -7
@@ -1,133 +1,94 @@
1
- export let TEST_META_ORG_ID = '69261691f936c45f85da24d0';
2
- export let TEST_META_ORG_USER_ID = '69261672f48fb7bf76e54dfb';
3
- export let TEST_META_ORG_USER_PERSON_ID = '69261672f48fb7bf76e54dfc';
1
+ export let TEST_META_ORG_ID = "69261691f936c45f85da24d0";
2
+ export let TEST_META_ORG_USER_ID = "69261672f48fb7bf76e54dfb";
4
3
  export function setTestMetaOrgId(metaOrgId) {
5
4
  TEST_META_ORG_ID = metaOrgId;
6
5
  }
7
6
  export function setTestMetaOrgUserId(userId) {
8
7
  TEST_META_ORG_USER_ID = userId;
9
8
  }
10
- export function setTestMetaOrgUserPersonId(personId) {
11
- TEST_META_ORG_USER_PERSON_ID = personId;
12
- }
13
- export const TEST_META_ORG_USER_PASSWORD = 'test-meta-org-user-password';
9
+ export const TEST_META_ORG_USER_PASSWORD = "test-meta-org-user-password";
14
10
  export function getTestMetaOrg() {
15
11
  return {
16
12
  _id: TEST_META_ORG_ID,
17
- name: 'Test Meta Organization',
18
- code: 'test-meta-org',
13
+ name: "Test Meta Organization",
14
+ code: "test-meta-org",
19
15
  status: 1,
20
16
  isMetaOrg: true,
21
17
  _created: new Date(),
22
- _createdBy: 'system',
18
+ _createdBy: "system",
23
19
  };
24
20
  }
25
- ;
26
21
  export function getTestMetaOrgUser() {
27
22
  return {
28
23
  _id: TEST_META_ORG_USER_ID,
29
24
  _orgId: getTestMetaOrg()._id,
30
- externalId: 'test-meta-org-user-external-id',
31
- personId: TEST_META_ORG_USER_PERSON_ID,
32
- email: 'test@example.com',
33
- displayName: 'Test User',
25
+ externalId: "test-meta-org-user-external-id",
26
+ email: "test@example.com",
27
+ displayName: "Test User",
34
28
  password: TEST_META_ORG_USER_PASSWORD,
35
29
  _created: new Date(),
36
- _createdBy: 'system',
37
- };
38
- }
39
- export function getTestMetaOrgUserPerson() {
40
- const person = {
41
- _id: TEST_META_ORG_USER_PERSON_ID,
42
- _orgId: getTestMetaOrg()._id,
43
- externalId: 'test-meta-org-user-person-external-id',
44
- firstName: 'Test',
45
- lastName: 'User',
46
- isAgent: false,
47
- isClient: false,
48
- isEmployee: false,
49
- _created: new Date(),
50
- _createdBy: 'system',
30
+ _createdBy: "system",
51
31
  };
52
- return person;
53
32
  }
54
33
  export function getTestMetaOrgUserContext() {
55
34
  return {
56
35
  user: getTestMetaOrgUser(),
57
36
  organization: getTestMetaOrg(),
58
- authorizations: [{
59
- _id: '6939c54e57a1c6576a40c590',
37
+ authorizations: [
38
+ {
39
+ _id: "6939c54e57a1c6576a40c590",
60
40
  _orgId: getTestMetaOrg()._id,
61
- role: 'metaorgUser',
62
- feature: 'metaorgUser',
41
+ role: "metaorgUser",
42
+ feature: "metaorgUser",
63
43
  config: {},
64
- }],
44
+ },
45
+ ],
65
46
  };
66
47
  }
67
- ;
68
- let TEST_ORG_ID = '6926167d06c0073a778a124f';
69
- let TEST_ORG_USER_ID = '6926167d06c0073a778a1250';
70
- let TEST_ORG_USER_PERSON_ID = '6926167d06c0073a778a1251';
48
+ let TEST_ORG_ID = "6926167d06c0073a778a124f";
49
+ let TEST_ORG_USER_ID = "6926167d06c0073a778a1250";
71
50
  export function setTestOrgId(orgId) {
72
51
  TEST_ORG_ID = orgId;
73
52
  }
74
53
  export function setTestOrgUserId(userId) {
75
54
  TEST_ORG_USER_ID = userId;
76
55
  }
77
- export function setTestOrgUserPersonId(personId) {
78
- TEST_ORG_USER_PERSON_ID = personId;
79
- }
80
56
  export function getTestOrg() {
81
57
  return {
82
58
  _id: TEST_ORG_ID,
83
- name: 'Test Organization',
84
- code: 'test-org',
59
+ name: "Test Organization",
60
+ code: "test-org",
85
61
  status: 1,
86
62
  isMetaOrg: false,
87
63
  _created: new Date(),
88
- _createdBy: 'system',
64
+ _createdBy: "system",
89
65
  };
90
66
  }
91
- ;
92
- export const TEST_ORG_USER_PASSWORD = 'test-org-user-password';
67
+ export const TEST_ORG_USER_PASSWORD = "test-org-user-password";
93
68
  export function getTestOrgUser() {
94
69
  return {
95
70
  _id: TEST_ORG_USER_ID,
96
71
  _orgId: getTestOrg()._id,
97
- externalId: 'test-org-user-external-id',
98
- email: 'test-org-user@example.com',
99
- personId: TEST_ORG_USER_PERSON_ID,
100
- displayName: 'Test User',
72
+ externalId: "test-org-user-external-id",
73
+ email: "test-org-user@example.com",
74
+ displayName: "Test User",
101
75
  password: TEST_ORG_USER_PASSWORD,
102
76
  _created: new Date(),
103
- _createdBy: 'system',
104
- };
105
- }
106
- export function getTestOrgUserPerson() {
107
- return {
108
- _id: TEST_ORG_USER_PERSON_ID,
109
- _orgId: getTestOrg()._id,
110
- externalId: 'test-org-user-person-external-id',
111
- firstName: 'Test',
112
- lastName: 'User',
113
- isAgent: false,
114
- isClient: false,
115
- isEmployee: false,
116
- _created: new Date(),
117
- _createdBy: 'system',
77
+ _createdBy: "system",
118
78
  };
119
79
  }
120
80
  export function getTestOrgUserContext() {
121
81
  return {
122
82
  user: getTestOrgUser(),
123
83
  organization: getTestOrg(),
124
- authorizations: [{
125
- _id: '6939c54e57a1c6576a40c591',
84
+ authorizations: [
85
+ {
86
+ _id: "6939c54e57a1c6576a40c591",
126
87
  _orgId: getTestOrg()._id,
127
- role: 'testOrgUser',
128
- feature: 'testOrgUser',
88
+ role: "testOrgUser",
89
+ feature: "testOrgUser",
129
90
  config: {},
130
- }],
91
+ },
92
+ ],
131
93
  };
132
94
  }
133
- ;
@@ -1,5 +1,5 @@
1
- import { IBaseApiConfig } from '../models/index.js';
2
- import { IDatabase } from '../databases/models/index.js';
1
+ import { IDatabase } from "../databases/models/index.js";
2
+ import { IBaseApiConfig } from "../models/index.js";
3
3
  export declare let config: IBaseApiConfig;
4
4
  export declare function setBaseApiConfig(theConfig: IBaseApiConfig): void;
5
5
  export declare function initSystemUserContext(database: IDatabase): Promise<void>;
@@ -1,9 +1,16 @@
1
- import { EmptyUserContext, initializeSystemUserContext } from '@loomcore/common/models';
1
+ import { EmptyUserContext, initializeSystemUserContext, } from "@loomcore/common/models";
2
2
  export let config;
3
3
  let isConfigSet = false;
4
4
  let isSystemUserContextSet = false;
5
5
  const BASE_API_CONFIG_KEYS = [
6
- 'app', 'auth', 'database', 'debug', 'email', 'env', 'network', 'thirdPartyClients'
6
+ "app",
7
+ "auth",
8
+ "database",
9
+ "debug",
10
+ "email",
11
+ "env",
12
+ "network",
13
+ "thirdPartyClients",
7
14
  ];
8
15
  function copyOnlySpecifiedConfigProperties(obj, allowedKeys) {
9
16
  const result = {};
@@ -19,29 +26,29 @@ export function setBaseApiConfig(theConfig) {
19
26
  config = copyOnlySpecifiedConfigProperties(theConfig, BASE_API_CONFIG_KEYS);
20
27
  isConfigSet = true;
21
28
  }
22
- else if (config.env !== 'test') {
23
- console.warn('BaseApiConfig data has already been set. Ignoring subsequent calls to setBaseApiConfig.');
29
+ else if (config.env !== "test") {
30
+ console.warn("BaseApiConfig data has already been set. Ignoring subsequent calls to setBaseApiConfig.");
24
31
  }
25
32
  }
26
33
  export async function initSystemUserContext(database) {
27
34
  if (!isConfigSet) {
28
- throw new Error('BaseApiConfig has not been set. Call setBaseApiConfig first.');
35
+ throw new Error("BaseApiConfig has not been set. Call setBaseApiConfig first.");
29
36
  }
30
37
  if (!isSystemUserContextSet) {
31
- const systemEmail = config.email?.systemEmailAddress || 'system@example.com';
38
+ const systemEmail = config.email?.systemEmailAddress || "system@example.com";
32
39
  let metaOrg = undefined;
33
40
  if (config.app.isMultiTenant) {
34
- const { OrganizationService } = await import('../services/organization.service.js');
41
+ const { OrganizationService } = await import("../services/organization.service.js");
35
42
  const organizationService = new OrganizationService(database);
36
43
  metaOrg = await organizationService.getMetaOrg(EmptyUserContext);
37
44
  if (!metaOrg) {
38
- throw new Error('Meta organization not found. Please create an organization with isMetaOrg=true before starting the API.');
45
+ throw new Error("Meta organization not found. Please create an organization with isMetaOrg=true before starting the API.");
39
46
  }
40
47
  }
41
48
  initializeSystemUserContext(systemEmail, metaOrg);
42
49
  isSystemUserContextSet = true;
43
50
  }
44
- else if (config.env !== 'test') {
45
- console.warn('SystemUserContext has already been set. Ignoring subsequent calls to initSystemUserContext.');
51
+ else if (config.env !== "test") {
52
+ console.warn("SystemUserContext has already been set. Ignoring subsequent calls to initSystemUserContext.");
46
53
  }
47
54
  }
@@ -1,10 +1,8 @@
1
- import { Application, Request, Response, NextFunction } from 'express';
2
- import { AuthService } from '../services/index.js';
3
- import { IDatabase } from '../databases/models/index.js';
4
- import { PersonService } from '../services/person.service.js';
1
+ import type { Application, NextFunction, Request, Response } from "express";
2
+ import type { IDatabase } from "../databases/models/index.js";
3
+ import { AuthService } from "../services/index.js";
5
4
  export declare class AuthController {
6
5
  authService: AuthService;
7
- personService: PersonService;
8
6
  constructor(app: Application, database: IDatabase);
9
7
  mapRoutes(app: Application): void;
10
8
  login(req: Request, res: Response, next: NextFunction): Promise<void>;
@@ -1,16 +1,13 @@
1
- import { LoginResponseSpec, TokenResponseSpec, UserSpec, PublicUserSpec, passwordValidator, PublicUserContextSpec, } from '@loomcore/common/models';
2
- import { entityUtils } from '@loomcore/common/utils';
3
- import { BadRequestError, UnauthenticatedError } from '../errors/index.js';
4
- import { apiUtils } from '../utils/index.js';
5
- import { AuthService } from '../services/index.js';
6
- import { isAuthorized } from '../middleware/index.js';
7
- import { PersonService } from '../services/person.service.js';
1
+ import { LoginResponseSpec, PublicUserContextSpec, PublicUserSpec, passwordValidator, TokenResponseSpec, UserSpec, } from "@loomcore/common/models";
2
+ import { entityUtils } from "@loomcore/common/utils";
3
+ import { BadRequestError, UnauthenticatedError } from "../errors/index.js";
4
+ import { isAuthorized } from "../middleware/index.js";
5
+ import { AuthService } from "../services/index.js";
6
+ import { apiUtils } from "../utils/index.js";
8
7
  export class AuthController {
9
8
  authService;
10
- personService;
11
9
  constructor(app, database) {
12
10
  this.authService = new AuthService(database);
13
- this.personService = new PersonService(database);
14
11
  this.mapRoutes(app);
15
12
  }
16
13
  mapRoutes(app) {
@@ -24,29 +21,25 @@ export class AuthController {
24
21
  }
25
22
  async login(req, res, next) {
26
23
  const { email, password } = req.body;
27
- res.set('Content-Type', 'application/json');
24
+ res.set("Content-Type", "application/json");
28
25
  const loginResponse = await this.authService.attemptLogin(req, res, email, password);
29
26
  apiUtils.apiResponse(res, 200, { data: loginResponse }, LoginResponseSpec);
30
27
  }
31
28
  async registerUser(req, res) {
32
29
  const userContext = req.userContext;
33
30
  if (!userContext) {
34
- throw new BadRequestError('Missing required fields: userContext is required.');
31
+ throw new BadRequestError("Missing required fields: userContext is required.");
35
32
  }
36
33
  const body = req.body;
37
- let validationErrors = this.authService.validate(body.user);
38
- entityUtils.handleValidationResult(validationErrors, 'AuthController.registerUser');
39
- if (body.person) {
40
- validationErrors = this.personService.validate(body.person);
41
- entityUtils.handleValidationResult(validationErrors, 'AuthController.registerUser');
42
- }
43
- const user = await this.authService.createUser(userContext, body.user, body.person);
34
+ const validationErrors = this.authService.validate(body.user);
35
+ entityUtils.handleValidationResult(validationErrors, "AuthController.registerUser");
36
+ const user = await this.authService.createUser(userContext, body.user);
44
37
  apiUtils.apiResponse(res, 201, { data: user || undefined }, UserSpec, PublicUserSpec);
45
38
  }
46
39
  async requestTokenUsingRefreshToken(req, res, next) {
47
40
  const refreshToken = req.query.refreshToken;
48
- if (!refreshToken || typeof refreshToken !== 'string') {
49
- throw new BadRequestError('Missing required fields: refreshToken is required.');
41
+ if (!refreshToken || typeof refreshToken !== "string") {
42
+ throw new BadRequestError("Missing required fields: refreshToken is required.");
50
43
  }
51
44
  const deviceId = this.authService.getDeviceIdFromCookie(req);
52
45
  const tokens = await this.authService.requestTokenUsingRefreshToken(refreshToken, deviceId);
@@ -62,23 +55,26 @@ export class AuthController {
62
55
  apiUtils.apiResponse(res, 200, { data: userContext }, PublicUserContextSpec);
63
56
  }
64
57
  afterAuth(req, res, loginResponse) {
65
- console.log('in afterAuth');
58
+ console.log("in afterAuth");
66
59
  }
67
60
  async changePassword(req, res) {
68
61
  const userContext = req.userContext;
62
+ if (!userContext) {
63
+ throw new BadRequestError("Missing required fields: userContext is required.");
64
+ }
69
65
  const body = req.body;
70
66
  const validationErrors = entityUtils.validate(UserSpec, { password: body.password }, true, passwordValidator);
71
- entityUtils.handleValidationResult(validationErrors, 'AuthController.changePassword');
67
+ entityUtils.handleValidationResult(validationErrors, "AuthController.changePassword");
72
68
  const updateResult = await this.authService.changeLoggedInUsersPassword(userContext, body);
73
69
  apiUtils.apiResponse(res, 200, { data: updateResult });
74
70
  }
75
71
  async forgotPassword(req, res) {
76
72
  const email = req.body?.email;
77
- let referer = req.get('referer') || req.headers.referer;
73
+ let referer = req.get("referer") || req.headers.referer;
78
74
  if (!referer) {
79
- throw new BadRequestError('Missing required fields: referer is required.');
75
+ throw new BadRequestError("Missing required fields: referer is required.");
80
76
  }
81
- referer = referer.replace(/\/$/, '');
77
+ referer = referer.replace(/\/$/, "");
82
78
  const user = await this.authService.getUserByEmail(email);
83
79
  if (user) {
84
80
  await this.authService.sendResetPasswordEmail(email, referer);
@@ -88,7 +84,7 @@ export class AuthController {
88
84
  async resetPassword(req, res) {
89
85
  const { email, token, password } = req.body;
90
86
  if (!email || !token || !password) {
91
- throw new BadRequestError('Missing required fields: email, token, and password are required.');
87
+ throw new BadRequestError("Missing required fields: email, token, and password are required.");
92
88
  }
93
89
  const response = await this.authService.resetPassword(email, token, password);
94
90
  apiUtils.apiResponse(res, 200, { data: response });
@@ -1,11 +1,10 @@
1
- export * from './api.controller.js';
2
- export * from './query-api.controller.js';
3
- export * from './auth.controller.js';
4
- export * from './organizations.controller.js';
5
- export * from './users.controller.js';
6
- export * from './user-roles.controller.js';
7
- export * from './roles.controller.js';
8
- export * from './authorizations.controller.js';
9
- export * from './features.controller.js';
10
- export * from './persons.controller.js';
11
- export * from './types.js';
1
+ export * from "./api.controller.js";
2
+ export * from "./auth.controller.js";
3
+ export * from "./authorizations.controller.js";
4
+ export * from "./features.controller.js";
5
+ export * from "./organizations.controller.js";
6
+ export * from "./query-api.controller.js";
7
+ export * from "./roles.controller.js";
8
+ export * from "./types.js";
9
+ export * from "./user-roles.controller.js";
10
+ export * from "./users.controller.js";
@@ -1,11 +1,10 @@
1
- export * from './api.controller.js';
2
- export * from './query-api.controller.js';
3
- export * from './auth.controller.js';
4
- export * from './organizations.controller.js';
5
- export * from './users.controller.js';
6
- export * from './user-roles.controller.js';
7
- export * from './roles.controller.js';
8
- export * from './authorizations.controller.js';
9
- export * from './features.controller.js';
10
- export * from './persons.controller.js';
11
- export * from './types.js';
1
+ export * from "./api.controller.js";
2
+ export * from "./auth.controller.js";
3
+ export * from "./authorizations.controller.js";
4
+ export * from "./features.controller.js";
5
+ export * from "./organizations.controller.js";
6
+ export * from "./query-api.controller.js";
7
+ export * from "./roles.controller.js";
8
+ export * from "./types.js";
9
+ export * from "./user-roles.controller.js";
10
+ export * from "./users.controller.js";
@@ -1,5 +1,5 @@
1
- import { Db } from 'mongodb';
2
- import { IInitialDbMigrationConfig } from '../../../models/initial-database-config.interface.js';
1
+ import { Db } from "mongodb";
2
+ import { IInitialDbMigrationConfig } from "../../../models/initial-database-config.interface.js";
3
3
  export interface ISyntheticMigration {
4
4
  name: string;
5
5
  up: (context: {