@loomcore/api 0.1.21 → 0.1.23
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/LICENSE +201 -201
- package/README.md +49 -49
- package/dist/__tests__/postgres-test-migrations/001-create-test-entities-table.migration.js +24 -24
- package/dist/__tests__/postgres-test-migrations/002-create-categories-table.migration.js +14 -14
- package/dist/__tests__/postgres-test-migrations/003-create-products-table.migration.js +23 -23
- package/dist/__tests__/postgres-test-migrations/004-create-test-users-table.migration.js +27 -27
- package/dist/__tests__/postgres-test-migrations/005-create-test-items-table.migration.js +22 -22
- package/dist/__tests__/postgres.test-database.js +8 -8
- package/dist/controllers/auth.controller.js +3 -4
- package/dist/databases/migrations/migration-runner.d.ts +15 -0
- package/dist/databases/migrations/migration-runner.js +118 -0
- package/dist/databases/postgres/commands/postgres-batch-update.command.js +7 -7
- package/dist/databases/postgres/commands/postgres-create-many.command.js +10 -10
- package/dist/databases/postgres/commands/postgres-create.command.js +4 -4
- package/dist/databases/postgres/commands/postgres-full-update-by-id.command.js +13 -13
- package/dist/databases/postgres/commands/postgres-partial-update-by-id.command.js +7 -7
- package/dist/databases/postgres/commands/postgres-update.command.js +7 -7
- package/dist/databases/postgres/migrations/001-create-migrations-table.migration.js +12 -12
- package/dist/databases/postgres/migrations/002-create-organizations-table.migration.js +24 -24
- package/dist/databases/postgres/migrations/003-create-users-table.migration.js +26 -26
- package/dist/databases/postgres/migrations/004-create-refresh-tokens-table.migration.js +18 -18
- package/dist/databases/postgres/migrations/005-create-meta-org.migration.js +7 -7
- package/dist/databases/postgres/migrations/006-create-admin-user.migration.js +3 -3
- package/dist/databases/postgres/migrations/setup-for-auth.migration.js +4 -4
- package/dist/databases/postgres/migrations/setup-for-multitenant.migration.js +4 -4
- package/dist/databases/postgres/utils/build-select-clause.js +6 -6
- package/dist/databases/postgres/utils/does-table-exist.util.js +4 -4
- package/dist/services/auth.service.d.ts +3 -3
- package/dist/services/auth.service.js +13 -7
- package/dist/services/multi-tenant-api.service.js +1 -1
- package/package.json +88 -87
|
@@ -17,10 +17,10 @@ export async function update(client, queryObject, entity, operations, pluralReso
|
|
|
17
17
|
const originalIndex = parseInt(num, 10);
|
|
18
18
|
return `$${originalIndex + updateValues.length}`;
|
|
19
19
|
});
|
|
20
|
-
const updateQuery = `
|
|
21
|
-
UPDATE "${pluralResourceName}"
|
|
22
|
-
SET ${setClause}
|
|
23
|
-
${whereClauseWithAdjustedParams}
|
|
20
|
+
const updateQuery = `
|
|
21
|
+
UPDATE "${pluralResourceName}"
|
|
22
|
+
SET ${setClause}
|
|
23
|
+
${whereClauseWithAdjustedParams}
|
|
24
24
|
`;
|
|
25
25
|
const allUpdateValues = [...updateValues, ...whereValues];
|
|
26
26
|
const result = await client.query(updateQuery, allUpdateValues);
|
|
@@ -29,9 +29,9 @@ export async function update(client, queryObject, entity, operations, pluralReso
|
|
|
29
29
|
}
|
|
30
30
|
const joinClauses = buildJoinClauses(operations);
|
|
31
31
|
const orderByClause = buildOrderByClause(queryObject);
|
|
32
|
-
const selectQuery = `
|
|
33
|
-
SELECT * FROM "${pluralResourceName}" ${joinClauses}
|
|
34
|
-
${whereClause} ${orderByClause}
|
|
32
|
+
const selectQuery = `
|
|
33
|
+
SELECT * FROM "${pluralResourceName}" ${joinClauses}
|
|
34
|
+
${whereClause} ${orderByClause}
|
|
35
35
|
`.trim();
|
|
36
36
|
const selectResult = await client.query(selectQuery, whereValues);
|
|
37
37
|
return selectResult.rows;
|
|
@@ -8,13 +8,13 @@ export class CreateMigrationTableMigration {
|
|
|
8
8
|
async execute() {
|
|
9
9
|
const _id = randomUUID().toString();
|
|
10
10
|
try {
|
|
11
|
-
await this.client.query(`
|
|
12
|
-
CREATE TABLE "migrations" (
|
|
13
|
-
"_id" VARCHAR(255) PRIMARY KEY,
|
|
14
|
-
"index" INTEGER NOT NULL,
|
|
15
|
-
"hasRun" BOOLEAN NOT NULL,
|
|
16
|
-
"reverted" BOOLEAN NOT NULL
|
|
17
|
-
)
|
|
11
|
+
await this.client.query(`
|
|
12
|
+
CREATE TABLE "migrations" (
|
|
13
|
+
"_id" VARCHAR(255) PRIMARY KEY,
|
|
14
|
+
"index" INTEGER NOT NULL,
|
|
15
|
+
"hasRun" BOOLEAN NOT NULL,
|
|
16
|
+
"reverted" BOOLEAN NOT NULL
|
|
17
|
+
)
|
|
18
18
|
`);
|
|
19
19
|
}
|
|
20
20
|
catch (error) {
|
|
@@ -23,9 +23,9 @@ export class CreateMigrationTableMigration {
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
try {
|
|
26
|
-
const result = await this.client.query(`
|
|
27
|
-
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
28
|
-
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
26
|
+
const result = await this.client.query(`
|
|
27
|
+
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
28
|
+
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
29
29
|
`);
|
|
30
30
|
if (result.rowCount === 0) {
|
|
31
31
|
return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: No row returned`) };
|
|
@@ -38,8 +38,8 @@ export class CreateMigrationTableMigration {
|
|
|
38
38
|
}
|
|
39
39
|
async revert() {
|
|
40
40
|
try {
|
|
41
|
-
const result = await this.client.query(`
|
|
42
|
-
DROP TABLE "migrations";
|
|
41
|
+
const result = await this.client.query(`
|
|
42
|
+
DROP TABLE "migrations";
|
|
43
43
|
`);
|
|
44
44
|
if (result.rowCount === 0) {
|
|
45
45
|
return { success: false, error: new Error(`Error dropping migrations table: No row returned`) };
|
|
@@ -12,22 +12,22 @@ export class CreateOrganizationsTableMigration {
|
|
|
12
12
|
async execute() {
|
|
13
13
|
const _id = randomUUID().toString();
|
|
14
14
|
try {
|
|
15
|
-
await this.client.query(`
|
|
16
|
-
CREATE TABLE "organizations" (
|
|
17
|
-
"_id" VARCHAR(255) PRIMARY KEY,
|
|
18
|
-
"name" VARCHAR(255) NOT NULL,
|
|
19
|
-
"code" VARCHAR(255) NOT NULL,
|
|
20
|
-
"description" TEXT,
|
|
21
|
-
"status" INTEGER NOT NULL,
|
|
22
|
-
"isMetaOrg" BOOLEAN NOT NULL,
|
|
23
|
-
"authToken" TEXT,
|
|
24
|
-
"_created" TIMESTAMP NOT NULL,
|
|
25
|
-
"_createdBy" VARCHAR(255) NOT NULL,
|
|
26
|
-
"_updated" TIMESTAMP NOT NULL,
|
|
27
|
-
"_updatedBy" VARCHAR(255) NOT NULL,
|
|
28
|
-
"_deleted" TIMESTAMP,
|
|
29
|
-
"_deletedBy" VARCHAR(255)
|
|
30
|
-
)
|
|
15
|
+
await this.client.query(`
|
|
16
|
+
CREATE TABLE "organizations" (
|
|
17
|
+
"_id" VARCHAR(255) PRIMARY KEY,
|
|
18
|
+
"name" VARCHAR(255) NOT NULL,
|
|
19
|
+
"code" VARCHAR(255) NOT NULL,
|
|
20
|
+
"description" TEXT,
|
|
21
|
+
"status" INTEGER NOT NULL,
|
|
22
|
+
"isMetaOrg" BOOLEAN NOT NULL,
|
|
23
|
+
"authToken" TEXT,
|
|
24
|
+
"_created" TIMESTAMP NOT NULL,
|
|
25
|
+
"_createdBy" VARCHAR(255) NOT NULL,
|
|
26
|
+
"_updated" TIMESTAMP NOT NULL,
|
|
27
|
+
"_updatedBy" VARCHAR(255) NOT NULL,
|
|
28
|
+
"_deleted" TIMESTAMP,
|
|
29
|
+
"_deletedBy" VARCHAR(255)
|
|
30
|
+
)
|
|
31
31
|
`);
|
|
32
32
|
}
|
|
33
33
|
catch (error) {
|
|
@@ -39,9 +39,9 @@ export class CreateOrganizationsTableMigration {
|
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
try {
|
|
42
|
-
const result = await this.client.query(`
|
|
43
|
-
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
44
|
-
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
42
|
+
const result = await this.client.query(`
|
|
43
|
+
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
44
|
+
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
45
45
|
`);
|
|
46
46
|
if (result.rowCount === 0) {
|
|
47
47
|
return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: No row returned`) };
|
|
@@ -54,8 +54,8 @@ export class CreateOrganizationsTableMigration {
|
|
|
54
54
|
}
|
|
55
55
|
async revert() {
|
|
56
56
|
try {
|
|
57
|
-
const result = await this.client.query(`
|
|
58
|
-
DROP TABLE "organizations";
|
|
57
|
+
const result = await this.client.query(`
|
|
58
|
+
DROP TABLE "organizations";
|
|
59
59
|
`);
|
|
60
60
|
if (result.rowCount === 0) {
|
|
61
61
|
return { success: false, error: new Error(`Error dropping organizations table: No row returned`) };
|
|
@@ -65,12 +65,12 @@ export class CreateOrganizationsTableMigration {
|
|
|
65
65
|
return { success: false, error: new Error(`Error dropping organizations table: ${error.message}`) };
|
|
66
66
|
}
|
|
67
67
|
try {
|
|
68
|
-
const result = await this.client.query(`
|
|
69
|
-
Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
68
|
+
const result = await this.client.query(`
|
|
69
|
+
Update "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
70
70
|
`);
|
|
71
71
|
if (result.rowCount === 0) {
|
|
72
72
|
return {
|
|
73
|
-
success: false, error: new Error(`Error updating migration record for index ${this.index}: Migration record not found.
|
|
73
|
+
success: false, error: new Error(`Error updating migration record for index ${this.index}: Migration record not found.
|
|
74
74
|
Migration index: ${this.index}`)
|
|
75
75
|
};
|
|
76
76
|
}
|
|
@@ -8,25 +8,25 @@ export class CreateUsersTableMigration {
|
|
|
8
8
|
async execute(_orgId) {
|
|
9
9
|
const _id = randomUUID().toString();
|
|
10
10
|
try {
|
|
11
|
-
await this.client.query(`
|
|
12
|
-
CREATE TABLE "users" (
|
|
13
|
-
"_id" VARCHAR(255) PRIMARY KEY,
|
|
14
|
-
"_orgId" VARCHAR(255),
|
|
15
|
-
"email" VARCHAR(255) NOT NULL,
|
|
16
|
-
"firstName" VARCHAR(255),
|
|
17
|
-
"lastName" VARCHAR(255),
|
|
18
|
-
"displayName" VARCHAR(255),
|
|
19
|
-
"password" VARCHAR(255) NOT NULL,
|
|
20
|
-
"roles" TEXT[],
|
|
21
|
-
"_lastLoggedIn" TIMESTAMP,
|
|
22
|
-
"_lastPasswordChange" TIMESTAMP,
|
|
23
|
-
"_created" TIMESTAMP NOT NULL,
|
|
24
|
-
"_createdBy" VARCHAR(255) NOT NULL,
|
|
25
|
-
"_updated" TIMESTAMP NOT NULL,
|
|
26
|
-
"_updatedBy" VARCHAR(255) NOT NULL,
|
|
27
|
-
"_deleted" TIMESTAMP,
|
|
28
|
-
"_deletedBy" VARCHAR(255)
|
|
29
|
-
)
|
|
11
|
+
await this.client.query(`
|
|
12
|
+
CREATE TABLE "users" (
|
|
13
|
+
"_id" VARCHAR(255) PRIMARY KEY,
|
|
14
|
+
"_orgId" VARCHAR(255),
|
|
15
|
+
"email" VARCHAR(255) NOT NULL,
|
|
16
|
+
"firstName" VARCHAR(255),
|
|
17
|
+
"lastName" VARCHAR(255),
|
|
18
|
+
"displayName" VARCHAR(255),
|
|
19
|
+
"password" VARCHAR(255) NOT NULL,
|
|
20
|
+
"roles" TEXT[],
|
|
21
|
+
"_lastLoggedIn" TIMESTAMP,
|
|
22
|
+
"_lastPasswordChange" TIMESTAMP,
|
|
23
|
+
"_created" TIMESTAMP NOT NULL,
|
|
24
|
+
"_createdBy" VARCHAR(255) NOT NULL,
|
|
25
|
+
"_updated" TIMESTAMP NOT NULL,
|
|
26
|
+
"_updatedBy" VARCHAR(255) NOT NULL,
|
|
27
|
+
"_deleted" TIMESTAMP,
|
|
28
|
+
"_deletedBy" VARCHAR(255)
|
|
29
|
+
)
|
|
30
30
|
`);
|
|
31
31
|
}
|
|
32
32
|
catch (error) {
|
|
@@ -38,9 +38,9 @@ export class CreateUsersTableMigration {
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
try {
|
|
41
|
-
const result = await this.client.query(`
|
|
42
|
-
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
43
|
-
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
41
|
+
const result = await this.client.query(`
|
|
42
|
+
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
43
|
+
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
44
44
|
`);
|
|
45
45
|
if (result.rowCount === 0) {
|
|
46
46
|
return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: No row returned`) };
|
|
@@ -53,8 +53,8 @@ export class CreateUsersTableMigration {
|
|
|
53
53
|
}
|
|
54
54
|
async revert() {
|
|
55
55
|
try {
|
|
56
|
-
const result = await this.client.query(`
|
|
57
|
-
DROP TABLE "users";
|
|
56
|
+
const result = await this.client.query(`
|
|
57
|
+
DROP TABLE "users";
|
|
58
58
|
`);
|
|
59
59
|
if (result.rowCount === 0) {
|
|
60
60
|
return { success: false, error: new Error(`Error dropping users table: No row returned`) };
|
|
@@ -64,8 +64,8 @@ export class CreateUsersTableMigration {
|
|
|
64
64
|
return { success: false, error: new Error(`Error dropping users table: ${error.message}`) };
|
|
65
65
|
}
|
|
66
66
|
try {
|
|
67
|
-
const result = await this.client.query(`
|
|
68
|
-
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
67
|
+
const result = await this.client.query(`
|
|
68
|
+
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
69
69
|
`);
|
|
70
70
|
if (result.rowCount === 0) {
|
|
71
71
|
return { success: false, error: new Error(`Error updating migration record for index ${this.index}: No row returned`) };
|
|
@@ -8,17 +8,17 @@ export class CreateRefreshTokenTableMigration {
|
|
|
8
8
|
async execute(_orgId) {
|
|
9
9
|
const _id = randomUUID().toString();
|
|
10
10
|
try {
|
|
11
|
-
await this.client.query(`
|
|
12
|
-
CREATE TABLE "refreshTokens" (
|
|
13
|
-
"_id" VARCHAR(255) PRIMARY KEY,
|
|
14
|
-
"_orgId" VARCHAR(255),
|
|
15
|
-
"token" VARCHAR(255) NOT NULL,
|
|
16
|
-
"deviceId" VARCHAR(255) NOT NULL,
|
|
17
|
-
"userId" VARCHAR(255) NOT NULL,
|
|
18
|
-
"expiresOn" BIGINT NOT NULL,
|
|
19
|
-
"created" TIMESTAMP NOT NULL,
|
|
20
|
-
"createdBy" VARCHAR(255) NOT NULL
|
|
21
|
-
)
|
|
11
|
+
await this.client.query(`
|
|
12
|
+
CREATE TABLE "refreshTokens" (
|
|
13
|
+
"_id" VARCHAR(255) PRIMARY KEY,
|
|
14
|
+
"_orgId" VARCHAR(255),
|
|
15
|
+
"token" VARCHAR(255) NOT NULL,
|
|
16
|
+
"deviceId" VARCHAR(255) NOT NULL,
|
|
17
|
+
"userId" VARCHAR(255) NOT NULL,
|
|
18
|
+
"expiresOn" BIGINT NOT NULL,
|
|
19
|
+
"created" TIMESTAMP NOT NULL,
|
|
20
|
+
"createdBy" VARCHAR(255) NOT NULL
|
|
21
|
+
)
|
|
22
22
|
`);
|
|
23
23
|
}
|
|
24
24
|
catch (error) {
|
|
@@ -30,9 +30,9 @@ export class CreateRefreshTokenTableMigration {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
try {
|
|
33
|
-
const result = await this.client.query(`
|
|
34
|
-
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
35
|
-
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
33
|
+
const result = await this.client.query(`
|
|
34
|
+
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
35
|
+
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
36
36
|
`);
|
|
37
37
|
if (result.rowCount === 0) {
|
|
38
38
|
return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: No row returned`) };
|
|
@@ -45,8 +45,8 @@ export class CreateRefreshTokenTableMigration {
|
|
|
45
45
|
}
|
|
46
46
|
async revert() {
|
|
47
47
|
try {
|
|
48
|
-
const result = await this.client.query(`
|
|
49
|
-
DROP TABLE "refreshTokens";
|
|
48
|
+
const result = await this.client.query(`
|
|
49
|
+
DROP TABLE "refreshTokens";
|
|
50
50
|
`);
|
|
51
51
|
if (result.rowCount === 0) {
|
|
52
52
|
return { success: false, error: new Error(`Error dropping refresh token table: No row returned`) };
|
|
@@ -56,8 +56,8 @@ export class CreateRefreshTokenTableMigration {
|
|
|
56
56
|
return { success: false, error: new Error(`Error dropping refresh token table: ${error.message}`) };
|
|
57
57
|
}
|
|
58
58
|
try {
|
|
59
|
-
const result = await this.client.query(`
|
|
60
|
-
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
59
|
+
const result = await this.client.query(`
|
|
60
|
+
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
61
61
|
`);
|
|
62
62
|
if (result.rowCount === 0) {
|
|
63
63
|
return { success: false, error: new Error(`Error updating migration record for index ${this.index}: No row returned`) };
|
|
@@ -12,8 +12,8 @@ export class CreateMetaOrgMigration {
|
|
|
12
12
|
async execute() {
|
|
13
13
|
const _id = randomUUID().toString();
|
|
14
14
|
try {
|
|
15
|
-
const result = await this.client.query(`
|
|
16
|
-
INSERT INTO "organizations" ("_id", "name", "code", "status", "isMetaOrg", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
15
|
+
const result = await this.client.query(`
|
|
16
|
+
INSERT INTO "organizations" ("_id", "name", "code", "status", "isMetaOrg", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
17
17
|
VALUES ('${_id}', '${this.orgName}', '${this.orgCode}', 1, true, NOW(), 'system', NOW(), 'system');`);
|
|
18
18
|
if (result.rowCount === 0) {
|
|
19
19
|
return { success: false, error: new Error(`Error creating meta org: No row returned`) };
|
|
@@ -23,9 +23,9 @@ export class CreateMetaOrgMigration {
|
|
|
23
23
|
return { success: false, error: new Error(`Error creating meta org: ${error.message}`) };
|
|
24
24
|
}
|
|
25
25
|
try {
|
|
26
|
-
const result = await this.client.query(`
|
|
27
|
-
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
28
|
-
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
26
|
+
const result = await this.client.query(`
|
|
27
|
+
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
28
|
+
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
29
29
|
`);
|
|
30
30
|
if (result.rowCount === 0) {
|
|
31
31
|
return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: No row returned`) };
|
|
@@ -47,8 +47,8 @@ export class CreateMetaOrgMigration {
|
|
|
47
47
|
return { success: false, error: new Error(`Error reverting meta org: ${error.message}`) };
|
|
48
48
|
}
|
|
49
49
|
try {
|
|
50
|
-
const result = await this.client.query(`
|
|
51
|
-
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
50
|
+
const result = await this.client.query(`
|
|
51
|
+
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
52
52
|
`);
|
|
53
53
|
if (result.rowCount === 0) {
|
|
54
54
|
return { success: false, error: new Error(`Error updating migration record for index ${this.index}: No row returned`) };
|
|
@@ -34,9 +34,9 @@ export class CreateAdminUserMigration {
|
|
|
34
34
|
return { success: false, error: new Error(`Error creating admin user: ${error.message}`) };
|
|
35
35
|
}
|
|
36
36
|
try {
|
|
37
|
-
const result = await this.client.query(`
|
|
38
|
-
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
39
|
-
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
37
|
+
const result = await this.client.query(`
|
|
38
|
+
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
39
|
+
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
40
40
|
`);
|
|
41
41
|
if (result.rowCount === 0) {
|
|
42
42
|
return { success: false, error: new Error(`Error inserting migration ${this.index} to migrations table: No row returned`) };
|
|
@@ -7,10 +7,10 @@ import { getSystemUserContext } from "@loomcore/common/models";
|
|
|
7
7
|
export async function setupDatabaseForAuth(client, adminUsername, adminPassword) {
|
|
8
8
|
let runMigrations = [];
|
|
9
9
|
if (await doesTableExist(client, 'migrations')) {
|
|
10
|
-
const migrations = await client.query(`
|
|
11
|
-
SELECT "_id", "index"
|
|
12
|
-
FROM migrations
|
|
13
|
-
WHERE "hasRun" = TRUE AND "reverted" = FALSE
|
|
10
|
+
const migrations = await client.query(`
|
|
11
|
+
SELECT "_id", "index"
|
|
12
|
+
FROM migrations
|
|
13
|
+
WHERE "hasRun" = TRUE AND "reverted" = FALSE
|
|
14
14
|
`);
|
|
15
15
|
runMigrations = migrations.rows.map((row) => {
|
|
16
16
|
return row.index;
|
|
@@ -10,10 +10,10 @@ export async function setupDatabaseForMultitenant(client, orgName, orgCode) {
|
|
|
10
10
|
let runMigrations = [];
|
|
11
11
|
let metaOrgId = randomUUID().toString();
|
|
12
12
|
if (await doesTableExist(client, 'migrations')) {
|
|
13
|
-
const migrations = await client.query(`
|
|
14
|
-
SELECT "_id", "index"
|
|
15
|
-
FROM migrations
|
|
16
|
-
WHERE "hasRun" = TRUE AND "reverted" = FALSE
|
|
13
|
+
const migrations = await client.query(`
|
|
14
|
+
SELECT "_id", "index"
|
|
15
|
+
FROM migrations
|
|
16
|
+
WHERE "hasRun" = TRUE AND "reverted" = FALSE
|
|
17
17
|
`);
|
|
18
18
|
runMigrations = migrations.rows.map((row) => {
|
|
19
19
|
return row.index;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { Join } from '../../operations/join.operation.js';
|
|
2
2
|
async function getTableColumns(client, tableName) {
|
|
3
|
-
const result = await client.query(`
|
|
4
|
-
SELECT column_name
|
|
5
|
-
FROM information_schema.columns
|
|
6
|
-
WHERE table_schema = current_schema()
|
|
7
|
-
AND table_name = $1
|
|
8
|
-
ORDER BY ordinal_position
|
|
3
|
+
const result = await client.query(`
|
|
4
|
+
SELECT column_name
|
|
5
|
+
FROM information_schema.columns
|
|
6
|
+
WHERE table_schema = current_schema()
|
|
7
|
+
AND table_name = $1
|
|
8
|
+
ORDER BY ordinal_position
|
|
9
9
|
`, [tableName]);
|
|
10
10
|
return result.rows.map(row => row.column_name);
|
|
11
11
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export async function doesTableExist(client, tableName) {
|
|
2
|
-
const result = await client.query(`
|
|
3
|
-
SELECT EXISTS (
|
|
4
|
-
SELECT 1 FROM information_schema.tables WHERE table_schema = current_schema() AND table_name = $1
|
|
5
|
-
)
|
|
2
|
+
const result = await client.query(`
|
|
3
|
+
SELECT EXISTS (
|
|
4
|
+
SELECT 1 FROM information_schema.tables WHERE table_schema = current_schema() AND table_name = $1
|
|
5
|
+
)
|
|
6
6
|
`, [tableName]);
|
|
7
7
|
return result.rows[0].exists;
|
|
8
8
|
}
|
|
@@ -21,7 +21,7 @@ export declare class AuthService extends MultiTenantApiService<IUser> {
|
|
|
21
21
|
} | null>;
|
|
22
22
|
getUserByEmail(email: string): Promise<IUser | null>;
|
|
23
23
|
createUser(userContext: IUserContext, user: Partial<IUser>): Promise<IUser | null>;
|
|
24
|
-
requestTokenUsingRefreshToken(
|
|
24
|
+
requestTokenUsingRefreshToken(refreshToken: string, deviceId: string): Promise<ITokenResponse | null>;
|
|
25
25
|
changeLoggedInUsersPassword(userContext: IUserContext, body: any): Promise<UpdateResult>;
|
|
26
26
|
changePassword(userContext: IUserContext, queryObject: any, password: string): Promise<UpdateResult>;
|
|
27
27
|
createNewTokens(userContext: IUserContext, activeRefreshToken: IRefreshToken): Promise<{
|
|
@@ -29,8 +29,8 @@ export declare class AuthService extends MultiTenantApiService<IUser> {
|
|
|
29
29
|
refreshToken: string;
|
|
30
30
|
expiresOn: number;
|
|
31
31
|
}>;
|
|
32
|
-
getActiveRefreshToken(
|
|
33
|
-
createNewRefreshToken(userId: string, deviceId: string,
|
|
32
|
+
getActiveRefreshToken(refreshToken: string, deviceId: string): Promise<IRefreshToken | null>;
|
|
33
|
+
createNewRefreshToken(userId: string, deviceId: string, orgId?: string): Promise<IRefreshToken | null>;
|
|
34
34
|
sendResetPasswordEmail(emailAddress: string): Promise<void>;
|
|
35
35
|
resetPassword(email: string, passwordResetToken: string, password: string): Promise<UpdateResult>;
|
|
36
36
|
deleteRefreshTokensForDevice(deviceId: string): Promise<import("../databases/models/delete-result.js").DeleteResult>;
|
|
@@ -44,7 +44,7 @@ export class AuthService extends MultiTenantApiService {
|
|
|
44
44
|
async logUserIn(userContext, deviceId) {
|
|
45
45
|
const payload = userContext;
|
|
46
46
|
const accessToken = this.generateJwt(payload);
|
|
47
|
-
const refreshTokenObject = await this.createNewRefreshToken(userContext.user._id, deviceId,
|
|
47
|
+
const refreshTokenObject = await this.createNewRefreshToken(userContext.user._id, deviceId, userContext._orgId);
|
|
48
48
|
const accessTokenExpiresOn = this.getExpiresOnFromSeconds(config.auth.jwtExpirationInSeconds);
|
|
49
49
|
let loginResponse = null;
|
|
50
50
|
if (refreshTokenObject) {
|
|
@@ -88,10 +88,16 @@ export class AuthService extends MultiTenantApiService {
|
|
|
88
88
|
const createdUser = await this.create(userContext, user);
|
|
89
89
|
return createdUser;
|
|
90
90
|
}
|
|
91
|
-
async requestTokenUsingRefreshToken(
|
|
91
|
+
async requestTokenUsingRefreshToken(refreshToken, deviceId) {
|
|
92
92
|
let tokens = null;
|
|
93
|
-
const activeRefreshToken = await this.getActiveRefreshToken(
|
|
93
|
+
const activeRefreshToken = await this.getActiveRefreshToken(refreshToken, deviceId);
|
|
94
94
|
if (activeRefreshToken) {
|
|
95
|
+
const systemUserContext = getSystemUserContext();
|
|
96
|
+
const user = await this.getById(systemUserContext, activeRefreshToken.userId);
|
|
97
|
+
const userContext = {
|
|
98
|
+
_orgId: user._orgId,
|
|
99
|
+
user: user
|
|
100
|
+
};
|
|
95
101
|
tokens = await this.createNewTokens(userContext, activeRefreshToken);
|
|
96
102
|
}
|
|
97
103
|
return tokens;
|
|
@@ -121,8 +127,8 @@ export class AuthService extends MultiTenantApiService {
|
|
|
121
127
|
};
|
|
122
128
|
return tokenResponse;
|
|
123
129
|
}
|
|
124
|
-
async getActiveRefreshToken(
|
|
125
|
-
const refreshTokenResult = await this.refreshTokenService.findOne(
|
|
130
|
+
async getActiveRefreshToken(refreshToken, deviceId) {
|
|
131
|
+
const refreshTokenResult = await this.refreshTokenService.findOne(EmptyUserContext, { filters: { token: { eq: refreshToken }, deviceId: { eq: deviceId } } });
|
|
126
132
|
let activeRefreshToken = null;
|
|
127
133
|
if (refreshTokenResult) {
|
|
128
134
|
const now = Date.now();
|
|
@@ -133,8 +139,8 @@ export class AuthService extends MultiTenantApiService {
|
|
|
133
139
|
}
|
|
134
140
|
return activeRefreshToken;
|
|
135
141
|
}
|
|
136
|
-
async createNewRefreshToken(userId, deviceId,
|
|
137
|
-
const expiresOn =
|
|
142
|
+
async createNewRefreshToken(userId, deviceId, orgId) {
|
|
143
|
+
const expiresOn = this.getExpiresOnFromDays(config.auth.refreshTokenExpirationInDays);
|
|
138
144
|
const newRefreshToken = {
|
|
139
145
|
_orgId: orgId,
|
|
140
146
|
token: this.generateRefreshToken(),
|
|
@@ -11,7 +11,7 @@ export class MultiTenantApiService extends GenericApiService {
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
prepareQuery(userContext, queryOptions, operations) {
|
|
14
|
-
if (!config?.app?.isMultiTenant) {
|
|
14
|
+
if (!config?.app?.isMultiTenant || userContext?.user?._id === 'system') {
|
|
15
15
|
return super.prepareQuery(userContext, queryOptions, operations);
|
|
16
16
|
}
|
|
17
17
|
if (!userContext || !userContext._orgId) {
|