@loomcore/api 0.2.7 → 0.2.9
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/dist/__tests__/common-test.utils.d.ts +8 -6
- package/dist/__tests__/common-test.utils.js +61 -37
- package/dist/__tests__/test-express-app.d.ts +20 -19
- package/dist/__tests__/test-express-app.js +72 -68
- package/dist/__tests__/test-objects.d.ts +5 -0
- package/dist/__tests__/test-objects.js +16 -0
- package/dist/config/base-api-config.d.ts +2 -2
- package/dist/config/base-api-config.js +2 -2
- package/dist/controllers/auth.controller.d.ts +9 -8
- package/dist/controllers/auth.controller.js +76 -29
- package/dist/controllers/authorizations.controller.d.ts +3 -3
- package/dist/controllers/authorizations.controller.js +4 -4
- package/dist/controllers/roles.controller.d.ts +1 -1
- package/dist/controllers/roles.controller.js +3 -3
- package/dist/controllers/users.controller.d.ts +5 -6
- package/dist/controllers/users.controller.js +4 -15
- package/dist/databases/postgres/commands/postgres-create.command.d.ts +2 -2
- package/dist/databases/postgres/commands/postgres-create.command.js +5 -5
- package/dist/databases/postgres/migrations/__tests__/test-migration-helper.js +2 -1
- package/dist/databases/postgres/migrations/postgres-initial-schema.js +7 -5
- package/dist/databases/postgres/postgres.database.d.ts +2 -2
- package/dist/databases/postgres/postgres.database.js +6 -8
- package/dist/middleware/index.d.ts +4 -4
- package/dist/middleware/index.js +4 -4
- package/dist/middleware/is-authorized.d.ts +2 -2
- package/dist/middleware/is-authorized.js +13 -11
- package/dist/models/app-config.interface.d.ts +1 -1
- package/dist/models/base-api-config.interface.d.ts +5 -5
- package/dist/models/initial-database-config.interface.d.ts +4 -3
- package/dist/models/refresh-token.model.d.ts +1 -1
- package/dist/models/refresh-token.model.js +3 -4
- package/dist/services/generic-api-service/generic-api-service.interface.d.ts +6 -6
- package/dist/services/generic-api-service/generic-api.service.d.ts +8 -8
- package/dist/services/generic-api-service/generic-api.service.js +16 -16
- package/dist/services/index.d.ts +11 -12
- package/dist/services/index.js +11 -12
- package/dist/services/multi-tenant-api.service.js +6 -2
- package/dist/services/password-reset-token.service.d.ts +2 -3
- package/dist/services/password-reset-token.service.js +4 -9
- package/dist/services/refresh-token.service.d.ts +6 -0
- package/dist/services/refresh-token.service.js +7 -0
- package/dist/services/user.service.js +4 -4
- package/dist/utils/auth/attempt-login.util.d.ts +3 -0
- package/dist/utils/auth/attempt-login.util.js +37 -0
- package/dist/utils/auth/change-password.util.d.ts +4 -0
- package/dist/utils/auth/change-password.util.js +14 -0
- package/dist/utils/auth/create-new-refresh-token.util.d.ts +4 -0
- package/dist/utils/auth/create-new-refresh-token.util.js +29 -0
- package/dist/utils/auth/create-new-tokens.util.d.ts +3 -0
- package/dist/utils/auth/create-new-tokens.util.js +13 -0
- package/dist/utils/auth/generate-device-id.util.d.ts +1 -0
- package/dist/utils/auth/generate-device-id.util.js +4 -0
- package/dist/utils/auth/generate-refresh-token.util.d.ts +1 -0
- package/dist/utils/auth/generate-refresh-token.util.js +4 -0
- package/dist/utils/auth/get-active-refresh-token.util.d.ts +4 -0
- package/dist/utils/auth/get-active-refresh-token.util.js +19 -0
- package/dist/utils/auth/get-and-set-device-id-cookie.util.d.ts +2 -0
- package/dist/utils/auth/get-and-set-device-id-cookie.util.js +23 -0
- package/dist/utils/auth/get-auth-config.util.d.ts +2 -0
- package/dist/utils/auth/get-auth-config.util.js +8 -0
- package/dist/utils/auth/get-device-id-from-cookie.util.d.ts +2 -0
- package/dist/utils/auth/get-device-id-from-cookie.util.js +3 -0
- package/dist/utils/auth/get-expires-on-from-days.util.d.ts +1 -0
- package/dist/utils/auth/get-expires-on-from-days.util.js +3 -0
- package/dist/utils/auth/get-expires-on-from-minutes.util.d.ts +1 -0
- package/dist/utils/auth/get-expires-on-from-minutes.util.js +3 -0
- package/dist/utils/auth/get-expires-on-from-seconds.util.d.ts +1 -0
- package/dist/utils/auth/get-expires-on-from-seconds.util.js +3 -0
- package/dist/utils/auth/index.d.ts +18 -0
- package/dist/utils/auth/index.js +18 -0
- package/dist/utils/auth/log-user-in.util.d.ts +3 -0
- package/dist/utils/auth/log-user-in.util.js +18 -0
- package/dist/utils/auth/request-token-using-refresh-token.util.d.ts +3 -0
- package/dist/utils/auth/request-token-using-refresh-token.util.js +9 -0
- package/dist/utils/auth/reset-password.util.d.ts +4 -0
- package/dist/utils/auth/reset-password.util.js +39 -0
- package/dist/utils/auth/send-reset-password-email.util.d.ts +3 -0
- package/dist/utils/auth/send-reset-password-email.util.js +23 -0
- package/dist/utils/auth/update-last-logged-in.util.d.ts +3 -0
- package/dist/utils/auth/update-last-logged-in.util.js +15 -0
- package/dist/utils/index.d.ts +8 -6
- package/dist/utils/index.js +8 -6
- package/dist/utils/jwt.utils.d.ts +2 -0
- package/dist/utils/jwt.utils.js +12 -0
- package/dist/utils/password.utils.js +8 -8
- package/package.json +3 -3
- package/dist/services/auth.service.d.ts +0 -49
- package/dist/services/auth.service.js +0 -277
- package/dist/services/jwt.service.d.ts +0 -4
- package/dist/services/jwt.service.js +0 -18
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { IQueryOptions, IUser, IUserContext } from "@loomcore/common/models";
|
|
2
|
-
import { Application, NextFunction, Request, Response } from "express";
|
|
1
|
+
import { type IQueryOptions, type IUser, type IUserContext } from "@loomcore/common/models";
|
|
2
|
+
import type { Application, NextFunction, Request, Response } from "express";
|
|
3
3
|
import { ApiController } from "../controllers/api.controller.js";
|
|
4
|
-
import { IDatabase } from "../databases/models/index.js";
|
|
5
|
-
import { Operation } from "../databases/operations/operation.js";
|
|
4
|
+
import type { IDatabase } from "../databases/models/index.js";
|
|
5
|
+
import type { Operation } from "../databases/operations/operation.js";
|
|
6
6
|
import { GenericApiService } from "../services/index.js";
|
|
7
7
|
import { MultiTenantApiService } from "../services/multi-tenant-api.service.js";
|
|
8
|
+
import * as testObjectsModule from "./test-objects.js";
|
|
8
9
|
import type { DbType } from "../databases/db-type.type.js";
|
|
9
10
|
import { type ICategory } from "./models/category.model.js";
|
|
10
11
|
import { type IProduct } from "./models/product.model.js";
|
|
11
12
|
import { type IProductWithCategory } from "./models/product-with-category.model.js";
|
|
12
|
-
declare function initialize(
|
|
13
|
+
declare function initialize(db: IDatabase): void;
|
|
13
14
|
declare function getRandomId(): string;
|
|
14
15
|
declare function isMongoDatabase(database: IDatabase): boolean;
|
|
15
16
|
declare function isPostgresDatabase(database: IDatabase): boolean;
|
|
@@ -64,8 +65,9 @@ declare const testUtils: {
|
|
|
64
65
|
deleteMetaOrg: typeof deleteMetaOrg;
|
|
65
66
|
deleteTestUser: typeof deleteTestUser;
|
|
66
67
|
getAuthToken: typeof getAuthToken;
|
|
68
|
+
getTestMetaOrgRefererUrl: typeof testObjectsModule.getTestMetaOrgRefererUrl;
|
|
67
69
|
initialize: typeof initialize;
|
|
68
|
-
|
|
70
|
+
setupTestConfig: typeof setupTestConfig;
|
|
69
71
|
loginWithTestUser: typeof loginWithTestUser;
|
|
70
72
|
newUser1Email: string;
|
|
71
73
|
newUser1Password: string;
|
|
@@ -1,37 +1,38 @@
|
|
|
1
|
-
import
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import { EmptyUserContext, getSystemUserContext, } from "@loomcore/common/models";
|
|
2
3
|
import { Type } from "@sinclair/typebox";
|
|
3
4
|
import { Value } from "@sinclair/typebox/value";
|
|
4
|
-
import crypto from "crypto";
|
|
5
5
|
import jwt from "jsonwebtoken";
|
|
6
6
|
import { ObjectId } from "mongodb";
|
|
7
7
|
import { ApiController } from "../controllers/api.controller.js";
|
|
8
8
|
import { MongoDBDatabase } from "../databases/mongo-db/mongo-db.database.js";
|
|
9
9
|
import { LeftJoin } from "../databases/operations/left-join.operation.js";
|
|
10
10
|
import { PostgresDatabase } from "../databases/postgres/postgres.database.js";
|
|
11
|
-
import {
|
|
12
|
-
import { JwtService } from "../services/jwt.service.js";
|
|
11
|
+
import { GenericApiService, UserService } from "../services/index.js";
|
|
13
12
|
import { MultiTenantApiService } from "../services/multi-tenant-api.service.js";
|
|
14
13
|
import { OrganizationService } from "../services/organization.service.js";
|
|
15
14
|
import * as testObjectsModule from "./test-objects.js";
|
|
16
|
-
const { getTestMetaOrg, getTestOrg, getTestMetaOrgUser, getTestMetaOrgUserContext, getTestOrgUserContext, setTestOrgId, setTestMetaOrgId, setTestMetaOrgUserId, setTestOrgUserId, } = testObjectsModule;
|
|
15
|
+
const { getTestMetaOrg, getTestMetaOrgRefererUrl, getTestOrg, getTestMetaOrgUser, getTestMetaOrgUserContext, getTestOrgUser, getTestOrgUserContext, setTestOrgId, setTestMetaOrgId, setTestMetaOrgUserId, setTestOrgUserId, } = testObjectsModule;
|
|
17
16
|
import { entityUtils } from "@loomcore/common/utils";
|
|
18
17
|
import { config, setBaseApiConfig } from "../config/index.js";
|
|
18
|
+
import { attemptLogin } from "../utils/auth/index.js";
|
|
19
19
|
import { apiUtils } from "../utils/index.js";
|
|
20
20
|
import { CategorySpec } from "./models/category.model.js";
|
|
21
21
|
import { ProductSpec } from "./models/product.model.js";
|
|
22
22
|
import { ProductWithCategoryPublicSpec, ProductWithCategorySpec, } from "./models/product-with-category.model.js";
|
|
23
23
|
import { TestEmailClient } from "./test-email-client.js";
|
|
24
|
-
import { getTestOrgUser } from "./test-objects.js";
|
|
25
24
|
let deviceIdCookie;
|
|
26
|
-
let
|
|
25
|
+
let database;
|
|
27
26
|
let organizationService;
|
|
27
|
+
let userService;
|
|
28
28
|
const JWT_SECRET = "test-secret";
|
|
29
29
|
const newUser1Email = "one@test.com";
|
|
30
|
-
const newUser1Password = "
|
|
30
|
+
const newUser1Password = "testone1";
|
|
31
31
|
const constDeviceIdCookie = crypto.randomBytes(16).toString("hex");
|
|
32
|
-
function initialize(
|
|
33
|
-
|
|
34
|
-
organizationService = new OrganizationService(
|
|
32
|
+
function initialize(db) {
|
|
33
|
+
database = db;
|
|
34
|
+
organizationService = new OrganizationService(db);
|
|
35
|
+
userService = new UserService(db);
|
|
35
36
|
deviceIdCookie = constDeviceIdCookie;
|
|
36
37
|
}
|
|
37
38
|
function getRandomId() {
|
|
@@ -95,7 +96,7 @@ async function setupTestUsers() {
|
|
|
95
96
|
}
|
|
96
97
|
}
|
|
97
98
|
async function createTestUsers() {
|
|
98
|
-
if (!
|
|
99
|
+
if (!organizationService || !userService) {
|
|
99
100
|
throw new Error("Database not initialized. Call initialize() first.");
|
|
100
101
|
}
|
|
101
102
|
try {
|
|
@@ -115,8 +116,8 @@ async function createTestUsers() {
|
|
|
115
116
|
else {
|
|
116
117
|
setTestOrgId(existingTestOrg._id);
|
|
117
118
|
}
|
|
118
|
-
const createdTestOrgUser = await
|
|
119
|
-
const createdMetaOrgUser = await
|
|
119
|
+
const createdTestOrgUser = await userService.create(getTestOrgUserContext(), getTestOrgUser());
|
|
120
|
+
const createdMetaOrgUser = await userService.create(getTestMetaOrgUserContext(), getTestMetaOrgUser());
|
|
120
121
|
if (!createdTestOrgUser || !createdMetaOrgUser) {
|
|
121
122
|
throw new Error("Failed to create test user");
|
|
122
123
|
}
|
|
@@ -130,39 +131,60 @@ async function createTestUsers() {
|
|
|
130
131
|
}
|
|
131
132
|
}
|
|
132
133
|
async function deleteTestUser() {
|
|
133
|
-
if (!
|
|
134
|
+
if (!organizationService || !userService) {
|
|
134
135
|
return;
|
|
135
136
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
.
|
|
139
|
-
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
137
|
+
const systemUserContext = getSystemUserContext();
|
|
138
|
+
const metaOrgUser = await userService
|
|
139
|
+
.findOne(systemUserContext, {
|
|
140
|
+
filters: { email: { eq: getTestMetaOrgUser().email.toLowerCase() } },
|
|
141
|
+
})
|
|
142
|
+
.catch(() => null);
|
|
143
|
+
if (metaOrgUser) {
|
|
144
|
+
await userService
|
|
145
|
+
.deleteById(systemUserContext, metaOrgUser._id)
|
|
146
|
+
.catch(() => { });
|
|
147
|
+
}
|
|
148
|
+
const testOrgUser = await userService
|
|
149
|
+
.findOne(systemUserContext, {
|
|
150
|
+
filters: { email: { eq: getTestOrgUser().email.toLowerCase() } },
|
|
151
|
+
})
|
|
152
|
+
.catch(() => null);
|
|
153
|
+
if (testOrgUser) {
|
|
154
|
+
await userService
|
|
155
|
+
.deleteById(systemUserContext, testOrgUser._id)
|
|
156
|
+
.catch(() => { });
|
|
157
|
+
}
|
|
158
|
+
const testOrg = await organizationService
|
|
159
|
+
.findOne(EmptyUserContext, {
|
|
160
|
+
filters: { code: { eq: getTestOrg().code } },
|
|
161
|
+
})
|
|
162
|
+
.catch(() => null);
|
|
163
|
+
if (testOrg) {
|
|
164
|
+
await organizationService
|
|
165
|
+
.deleteById(getTestMetaOrgUserContext(), testOrg._id)
|
|
166
|
+
.catch(() => { });
|
|
167
|
+
}
|
|
146
168
|
}
|
|
147
169
|
async function simulateloginWithTestUser() {
|
|
148
170
|
const req = {
|
|
149
171
|
cookies: {},
|
|
150
172
|
};
|
|
151
173
|
if (deviceIdCookie) {
|
|
152
|
-
req.cookies
|
|
174
|
+
req.cookies.deviceId = deviceIdCookie;
|
|
153
175
|
}
|
|
154
176
|
const res = {
|
|
155
|
-
cookie:
|
|
177
|
+
cookie: (name, value) => {
|
|
156
178
|
if (name === "deviceId") {
|
|
157
179
|
deviceIdCookie = value;
|
|
158
180
|
}
|
|
159
181
|
return res;
|
|
160
182
|
},
|
|
161
183
|
};
|
|
162
|
-
if (!
|
|
163
|
-
throw new Error("
|
|
184
|
+
if (!database) {
|
|
185
|
+
throw new Error("Database not initialized. Call initialize() first.");
|
|
164
186
|
}
|
|
165
|
-
const loginResponse = await
|
|
187
|
+
const loginResponse = await attemptLogin(database, getTestMetaOrgUser().email, testObjectsModule.TEST_META_ORG_USER_PASSWORD, deviceIdCookie, getTestMetaOrg());
|
|
166
188
|
if (!loginResponse?.tokens?.accessToken) {
|
|
167
189
|
throw new Error("Failed to login with test user");
|
|
168
190
|
}
|
|
@@ -170,11 +192,11 @@ async function simulateloginWithTestUser() {
|
|
|
170
192
|
}
|
|
171
193
|
function getAuthToken() {
|
|
172
194
|
const userContext = getTestMetaOrgUserContext();
|
|
173
|
-
const token =
|
|
195
|
+
const token = jwt.sign(userContext, JWT_SECRET, { expiresIn: 3600 });
|
|
174
196
|
return `Bearer ${token}`;
|
|
175
197
|
}
|
|
176
198
|
function verifyToken(token) {
|
|
177
|
-
return
|
|
199
|
+
return jwt.verify(token, JWT_SECRET);
|
|
178
200
|
}
|
|
179
201
|
export class CategoryService extends GenericApiService {
|
|
180
202
|
constructor(database) {
|
|
@@ -329,14 +351,15 @@ export class MultiTenantProductsController extends ApiController {
|
|
|
329
351
|
}
|
|
330
352
|
function configureJwtSecret() {
|
|
331
353
|
const originalJwtVerify = jwt.verify;
|
|
332
|
-
jwt.verify =
|
|
333
|
-
return originalJwtVerify(token, JWT_SECRET, options);
|
|
334
|
-
};
|
|
354
|
+
jwt.verify = (token, _secret, options) => originalJwtVerify(token, JWT_SECRET, options);
|
|
335
355
|
}
|
|
336
356
|
async function loginWithTestUser(agent) {
|
|
337
357
|
agent.set("Cookie", [`deviceId=${deviceIdCookie}`]);
|
|
338
358
|
const testUser = getTestMetaOrgUser();
|
|
339
|
-
const response = await agent
|
|
359
|
+
const response = await agent
|
|
360
|
+
.post("/api/auth/login")
|
|
361
|
+
.set("Referer", getTestMetaOrgRefererUrl())
|
|
362
|
+
.send({
|
|
340
363
|
email: testUser.email,
|
|
341
364
|
password: testUser.password,
|
|
342
365
|
});
|
|
@@ -365,8 +388,9 @@ const testUtils = {
|
|
|
365
388
|
deleteMetaOrg,
|
|
366
389
|
deleteTestUser,
|
|
367
390
|
getAuthToken,
|
|
391
|
+
getTestMetaOrgRefererUrl,
|
|
368
392
|
initialize,
|
|
369
|
-
|
|
393
|
+
setupTestConfig,
|
|
370
394
|
loginWithTestUser,
|
|
371
395
|
newUser1Email,
|
|
372
396
|
newUser1Password,
|
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import { Application } from
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
1
|
+
import { type Application } from "express";
|
|
2
|
+
import type { IDatabase } from "../databases/models/database.interface.js";
|
|
3
|
+
import type { ITestDatabase } from "./test-database.interface.js";
|
|
4
|
+
type TestExpressAppInitResult = {
|
|
5
|
+
app: Application;
|
|
6
|
+
database: IDatabase;
|
|
7
|
+
testDatabase: ITestDatabase;
|
|
8
|
+
agent: any;
|
|
9
|
+
};
|
|
10
|
+
declare function init(useMongoDb?: boolean): Promise<TestExpressAppInitResult>;
|
|
11
|
+
declare function setupErrorHandling(): Promise<void>;
|
|
12
|
+
declare function clearCollections(): Promise<void>;
|
|
13
|
+
declare function cleanup(): Promise<void>;
|
|
14
|
+
export declare const TestExpressApp: {
|
|
15
|
+
init: typeof init;
|
|
16
|
+
setupErrorHandling: typeof setupErrorHandling;
|
|
17
|
+
clearCollections: typeof clearCollections;
|
|
18
|
+
cleanup: typeof cleanup;
|
|
19
|
+
};
|
|
20
|
+
export {};
|
|
@@ -1,76 +1,80 @@
|
|
|
1
|
-
import
|
|
2
|
-
import bodyParser from
|
|
3
|
-
import cookieParser from
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
return this.initPromise;
|
|
23
|
-
}
|
|
24
|
-
this.initPromise = this._performInit(useMongoDb);
|
|
25
|
-
return this.initPromise;
|
|
1
|
+
import { initializeTypeBox } from "@loomcore/common/validation";
|
|
2
|
+
import bodyParser from "body-parser";
|
|
3
|
+
import cookieParser from "cookie-parser";
|
|
4
|
+
import express from "express";
|
|
5
|
+
import supertest from "supertest";
|
|
6
|
+
import { ensureUserContext } from "../middleware/ensure-user-context.js";
|
|
7
|
+
import { errorHandler } from "../middleware/error-handler.js";
|
|
8
|
+
import { setupTestConfig } from "./common-test.utils.js";
|
|
9
|
+
import { TestMongoDatabase } from "./mongo-db.test-database.js";
|
|
10
|
+
import { TestPostgresDatabase } from "./postgres.test-database.js";
|
|
11
|
+
let app;
|
|
12
|
+
let database;
|
|
13
|
+
let testDatabase;
|
|
14
|
+
let initPromise = null;
|
|
15
|
+
async function init(useMongoDb) {
|
|
16
|
+
if (useMongoDb === undefined) {
|
|
17
|
+
const testDb = process.env.TEST_DATABASE;
|
|
18
|
+
useMongoDb = testDb === "mongodb";
|
|
19
|
+
}
|
|
20
|
+
if (initPromise) {
|
|
21
|
+
return initPromise;
|
|
26
22
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
this.testDatabase = testPostgresDb;
|
|
39
|
-
this.database = await testPostgresDb.init();
|
|
40
|
-
}
|
|
23
|
+
initPromise = performInit(useMongoDb);
|
|
24
|
+
return initPromise;
|
|
25
|
+
}
|
|
26
|
+
async function performInit(useMongoDb) {
|
|
27
|
+
setupTestConfig(true, useMongoDb ? "mongodb" : "postgres");
|
|
28
|
+
initializeTypeBox();
|
|
29
|
+
if (!database) {
|
|
30
|
+
if (useMongoDb) {
|
|
31
|
+
const testMongoDb = new TestMongoDatabase();
|
|
32
|
+
testDatabase = testMongoDb;
|
|
33
|
+
database = await testMongoDb.init();
|
|
41
34
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
this.app.use(ensureUserContext);
|
|
47
|
-
this.app.use((req, res, next) => {
|
|
48
|
-
next();
|
|
49
|
-
});
|
|
35
|
+
else {
|
|
36
|
+
const testPostgresDb = new TestPostgresDatabase();
|
|
37
|
+
testDatabase = testPostgresDb;
|
|
38
|
+
database = await testPostgresDb.init();
|
|
50
39
|
}
|
|
51
|
-
const agent = supertest.agent(this.app);
|
|
52
|
-
return {
|
|
53
|
-
app: this.app,
|
|
54
|
-
database: this.database,
|
|
55
|
-
testDatabase: this.testDatabase,
|
|
56
|
-
agent
|
|
57
|
-
};
|
|
58
40
|
}
|
|
59
|
-
|
|
60
|
-
|
|
41
|
+
if (!app) {
|
|
42
|
+
app = express();
|
|
43
|
+
app.use(bodyParser.json());
|
|
44
|
+
app.use(cookieParser());
|
|
45
|
+
app.use(ensureUserContext);
|
|
46
|
+
app.use((req, res, next) => {
|
|
47
|
+
next();
|
|
48
|
+
});
|
|
61
49
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
50
|
+
const agent = supertest.agent(app);
|
|
51
|
+
return {
|
|
52
|
+
app,
|
|
53
|
+
database,
|
|
54
|
+
testDatabase,
|
|
55
|
+
agent,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
async function setupErrorHandling() {
|
|
59
|
+
app.use(errorHandler);
|
|
60
|
+
}
|
|
61
|
+
async function clearCollections() {
|
|
62
|
+
if (testDatabase) {
|
|
63
|
+
await testDatabase.clearCollections();
|
|
66
64
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
this.initPromise = null;
|
|
72
|
-
this.app = undefined;
|
|
73
|
-
this.database = undefined;
|
|
74
|
-
this.testDatabase = undefined;
|
|
65
|
+
}
|
|
66
|
+
async function cleanup() {
|
|
67
|
+
if (testDatabase) {
|
|
68
|
+
await testDatabase.cleanup();
|
|
75
69
|
}
|
|
70
|
+
initPromise = null;
|
|
71
|
+
app = undefined;
|
|
72
|
+
database = undefined;
|
|
73
|
+
testDatabase = undefined;
|
|
76
74
|
}
|
|
75
|
+
export const TestExpressApp = {
|
|
76
|
+
init,
|
|
77
|
+
setupErrorHandling,
|
|
78
|
+
clearCollections,
|
|
79
|
+
cleanup,
|
|
80
|
+
};
|
|
@@ -4,6 +4,11 @@ export declare let TEST_META_ORG_USER_ID: string | number;
|
|
|
4
4
|
export declare function setTestMetaOrgId(metaOrgId: string | number): void;
|
|
5
5
|
export declare function setTestMetaOrgUserId(userId: string | number): void;
|
|
6
6
|
export declare const TEST_META_ORG_USER_PASSWORD = "test-meta-org-user-password";
|
|
7
|
+
export declare const TEST_META_ORG_DOMAIN = "test-meta-org.example.com";
|
|
8
|
+
export declare const TEST_ORG_DOMAIN = "test-org.example.com";
|
|
9
|
+
export declare function getRefererUrlForOrg(org: Pick<IOrganization, "domain">): string;
|
|
10
|
+
export declare function getTestMetaOrgRefererUrl(): string;
|
|
11
|
+
export declare function getTestOrgRefererUrl(): string;
|
|
7
12
|
export declare function getTestMetaOrg(): IOrganization;
|
|
8
13
|
export declare function getTestMetaOrgUser(): IUser;
|
|
9
14
|
export declare function getTestMetaOrgUserContext(): IUserContext;
|
|
@@ -7,11 +7,26 @@ export function setTestMetaOrgUserId(userId) {
|
|
|
7
7
|
TEST_META_ORG_USER_ID = userId;
|
|
8
8
|
}
|
|
9
9
|
export const TEST_META_ORG_USER_PASSWORD = "test-meta-org-user-password";
|
|
10
|
+
export const TEST_META_ORG_DOMAIN = "test-meta-org.example.com";
|
|
11
|
+
export const TEST_ORG_DOMAIN = "test-org.example.com";
|
|
12
|
+
export function getRefererUrlForOrg(org) {
|
|
13
|
+
if (!org.domain) {
|
|
14
|
+
throw new Error("Organization domain is required for auth referer URL");
|
|
15
|
+
}
|
|
16
|
+
return `https://${org.domain}`;
|
|
17
|
+
}
|
|
18
|
+
export function getTestMetaOrgRefererUrl() {
|
|
19
|
+
return getRefererUrlForOrg(getTestMetaOrg());
|
|
20
|
+
}
|
|
21
|
+
export function getTestOrgRefererUrl() {
|
|
22
|
+
return getRefererUrlForOrg(getTestOrg());
|
|
23
|
+
}
|
|
10
24
|
export function getTestMetaOrg() {
|
|
11
25
|
return {
|
|
12
26
|
_id: TEST_META_ORG_ID,
|
|
13
27
|
name: "Test Meta Organization",
|
|
14
28
|
code: "test-meta-org",
|
|
29
|
+
domain: TEST_META_ORG_DOMAIN,
|
|
15
30
|
status: 1,
|
|
16
31
|
isMetaOrg: true,
|
|
17
32
|
_created: new Date(),
|
|
@@ -58,6 +73,7 @@ export function getTestOrg() {
|
|
|
58
73
|
_id: TEST_ORG_ID,
|
|
59
74
|
name: "Test Organization",
|
|
60
75
|
code: "test-org",
|
|
76
|
+
domain: TEST_ORG_DOMAIN,
|
|
61
77
|
status: 1,
|
|
62
78
|
isMetaOrg: false,
|
|
63
79
|
_created: new Date(),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { IDatabase } from "../databases/models/index.js";
|
|
2
|
-
import { IBaseApiConfig } from "../models/index.js";
|
|
1
|
+
import type { IDatabase } from "../databases/models/index.js";
|
|
2
|
+
import type { 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>;
|
|
@@ -36,7 +36,7 @@ export async function initSystemUserContext(database) {
|
|
|
36
36
|
}
|
|
37
37
|
if (!isSystemUserContextSet) {
|
|
38
38
|
const systemEmail = config.email?.systemEmailAddress || "system@example.com";
|
|
39
|
-
let metaOrg =
|
|
39
|
+
let metaOrg = null;
|
|
40
40
|
if (config.app.isMultiTenant) {
|
|
41
41
|
const { OrganizationService } = await import("../services/organization.service.js");
|
|
42
42
|
const organizationService = new OrganizationService(database);
|
|
@@ -45,7 +45,7 @@ export async function initSystemUserContext(database) {
|
|
|
45
45
|
throw new Error("Meta organization not found. Please create an organization with isMetaOrg=true before starting the API.");
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
|
-
initializeSystemUserContext(systemEmail, metaOrg);
|
|
48
|
+
initializeSystemUserContext(systemEmail, metaOrg ?? undefined);
|
|
49
49
|
isSystemUserContextSet = true;
|
|
50
50
|
}
|
|
51
51
|
else if (config.env !== "test") {
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import type { Application,
|
|
1
|
+
import type { Application, Request, Response } from "express";
|
|
2
2
|
import type { IDatabase } from "../databases/models/index.js";
|
|
3
|
-
import {
|
|
3
|
+
import { OrganizationService, UserService } from "../services/index.js";
|
|
4
4
|
export declare class AuthController {
|
|
5
|
-
|
|
5
|
+
database: IDatabase;
|
|
6
|
+
userService: UserService;
|
|
7
|
+
organizationService: OrganizationService;
|
|
6
8
|
constructor(app: Application, database: IDatabase);
|
|
7
9
|
mapRoutes(app: Application): void;
|
|
8
|
-
login(req: Request, res: Response
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
afterAuth(req: Request, res: Response, loginResponse: any): void;
|
|
10
|
+
login(req: Request, res: Response): Promise<void>;
|
|
11
|
+
requestTokenUsingRefreshToken(req: Request, res: Response): Promise<void>;
|
|
12
|
+
getUserContext(req: Request, res: Response): Promise<void>;
|
|
13
|
+
afterAuth(_req: Request, _res: Response, _loginResponse: any): void;
|
|
13
14
|
changePassword(req: Request, res: Response): Promise<void>;
|
|
14
15
|
forgotPassword(req: Request, res: Response): Promise<void>;
|
|
15
16
|
resetPassword(req: Request, res: Response): Promise<void>;
|