@loomcore/api 0.1.38 → 0.1.41
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__/common-test.utils.js +2 -11
- package/dist/__tests__/postgres-test-migrations/100-create-test-entities-table.migration.js +22 -22
- package/dist/__tests__/postgres-test-migrations/101-create-categories-table.migration.js +12 -12
- package/dist/__tests__/postgres-test-migrations/102-create-products-table.migration.js +21 -21
- package/dist/__tests__/postgres-test-migrations/103-create-test-items-table.migration.js +20 -20
- package/dist/__tests__/postgres.test-database.js +8 -8
- package/dist/controllers/api.controller.js +10 -10
- package/dist/controllers/auth.controller.js +4 -4
- package/dist/controllers/organizations.controller.js +3 -3
- package/dist/controllers/users.controller.js +9 -9
- package/dist/databases/migrations/migration-runner.d.ts +1 -0
- package/dist/databases/migrations/migration-runner.js +6 -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 +9 -9
- package/dist/databases/postgres/migrations/006-create-admin-user.migration.js +3 -3
- package/dist/databases/postgres/migrations/007-create-roles-table.migration.js +14 -14
- package/dist/databases/postgres/migrations/008-create-user-roles-table.migration.js +24 -24
- package/dist/databases/postgres/migrations/009-create-features-table.migration.js +14 -14
- package/dist/databases/postgres/migrations/010-create-authorizations-table.migration.js +26 -26
- package/dist/databases/postgres/migrations/011-create-admin-authorization.migration.js +44 -44
- package/dist/databases/postgres/migrations/database-builder.js +4 -4
- package/dist/databases/postgres/postgres.database.js +17 -17
- 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/middleware/index.d.ts +1 -1
- package/dist/middleware/index.js +1 -1
- package/dist/middleware/is-authorized.d.ts +3 -0
- package/dist/middleware/is-authorized.js +40 -0
- package/package.json +88 -88
- package/dist/middleware/is-authenticated.d.ts +0 -2
- package/dist/middleware/is-authenticated.js +0 -27
|
@@ -12,27 +12,27 @@ export class CreateOrganizationsTableMigration {
|
|
|
12
12
|
await this.client.query('BEGIN');
|
|
13
13
|
const tableExists = await doesTableExist(this.client, 'organizations');
|
|
14
14
|
if (!tableExists) {
|
|
15
|
-
await this.client.query(`
|
|
16
|
-
CREATE TABLE "organizations" (
|
|
17
|
-
"_id" VARCHAR(255) PRIMARY KEY,
|
|
18
|
-
"name" VARCHAR(255) NOT NULL UNIQUE,
|
|
19
|
-
"code" VARCHAR(255) NOT NULL UNIQUE,
|
|
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 UNIQUE,
|
|
19
|
+
"code" VARCHAR(255) NOT NULL UNIQUE,
|
|
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
|
-
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
|
await this.client.query('ROLLBACK');
|
|
@@ -51,17 +51,17 @@ export class CreateOrganizationsTableMigration {
|
|
|
51
51
|
await this.client.query('BEGIN');
|
|
52
52
|
const tableExists = await doesTableExist(this.client, 'organizations');
|
|
53
53
|
if (tableExists) {
|
|
54
|
-
await this.client.query(`
|
|
55
|
-
DROP TABLE "organizations";
|
|
54
|
+
await this.client.query(`
|
|
55
|
+
DROP TABLE "organizations";
|
|
56
56
|
`);
|
|
57
57
|
}
|
|
58
|
-
const updateResult = await this.client.query(`
|
|
59
|
-
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
58
|
+
const updateResult = await this.client.query(`
|
|
59
|
+
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
60
60
|
`);
|
|
61
61
|
if (updateResult.rowCount === 0) {
|
|
62
62
|
await this.client.query('ROLLBACK');
|
|
63
63
|
return {
|
|
64
|
-
success: false, error: new Error(`Error updating migration record for index ${this.index}: Migration record not found.
|
|
64
|
+
success: false, error: new Error(`Error updating migration record for index ${this.index}: Migration record not found.
|
|
65
65
|
Migration index: ${this.index}`)
|
|
66
66
|
};
|
|
67
67
|
}
|
|
@@ -16,30 +16,30 @@ export class CreateUsersTableMigration {
|
|
|
16
16
|
const fkConstraint = config.app.isMultiTenant
|
|
17
17
|
? ',\n CONSTRAINT "fk_users_organization" FOREIGN KEY ("_orgId") REFERENCES "organizations"("_id") ON DELETE CASCADE'
|
|
18
18
|
: '';
|
|
19
|
-
await this.client.query(`
|
|
20
|
-
CREATE TABLE "users" (
|
|
21
|
-
"_id" VARCHAR(255) PRIMARY KEY,
|
|
22
|
-
"_orgId" VARCHAR(255),
|
|
23
|
-
"email" VARCHAR(255) NOT NULL,
|
|
24
|
-
"firstName" VARCHAR(255),
|
|
25
|
-
"lastName" VARCHAR(255),
|
|
26
|
-
"displayName" VARCHAR(255),
|
|
27
|
-
"password" VARCHAR(255) NOT NULL,
|
|
28
|
-
"_lastLoggedIn" TIMESTAMP,
|
|
29
|
-
"_lastPasswordChange" TIMESTAMP,
|
|
30
|
-
"_created" TIMESTAMP NOT NULL,
|
|
31
|
-
"_createdBy" VARCHAR(255) NOT NULL,
|
|
32
|
-
"_updated" TIMESTAMP NOT NULL,
|
|
33
|
-
"_updatedBy" VARCHAR(255) NOT NULL,
|
|
34
|
-
"_deleted" TIMESTAMP,
|
|
35
|
-
"_deletedBy" VARCHAR(255),
|
|
36
|
-
CONSTRAINT "uk_users_email" UNIQUE ("_orgId", "email")${fkConstraint}
|
|
37
|
-
)
|
|
19
|
+
await this.client.query(`
|
|
20
|
+
CREATE TABLE "users" (
|
|
21
|
+
"_id" VARCHAR(255) PRIMARY KEY,
|
|
22
|
+
"_orgId" VARCHAR(255),
|
|
23
|
+
"email" VARCHAR(255) NOT NULL,
|
|
24
|
+
"firstName" VARCHAR(255),
|
|
25
|
+
"lastName" VARCHAR(255),
|
|
26
|
+
"displayName" VARCHAR(255),
|
|
27
|
+
"password" VARCHAR(255) NOT NULL,
|
|
28
|
+
"_lastLoggedIn" TIMESTAMP,
|
|
29
|
+
"_lastPasswordChange" TIMESTAMP,
|
|
30
|
+
"_created" TIMESTAMP NOT NULL,
|
|
31
|
+
"_createdBy" VARCHAR(255) NOT NULL,
|
|
32
|
+
"_updated" TIMESTAMP NOT NULL,
|
|
33
|
+
"_updatedBy" VARCHAR(255) NOT NULL,
|
|
34
|
+
"_deleted" TIMESTAMP,
|
|
35
|
+
"_deletedBy" VARCHAR(255),
|
|
36
|
+
CONSTRAINT "uk_users_email" UNIQUE ("_orgId", "email")${fkConstraint}
|
|
37
|
+
)
|
|
38
38
|
`);
|
|
39
39
|
}
|
|
40
|
-
const result = await this.client.query(`
|
|
41
|
-
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
42
|
-
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
40
|
+
const result = await this.client.query(`
|
|
41
|
+
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
42
|
+
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
43
43
|
`);
|
|
44
44
|
if (result.rowCount === 0) {
|
|
45
45
|
await this.client.query('ROLLBACK');
|
|
@@ -56,11 +56,11 @@ export class CreateUsersTableMigration {
|
|
|
56
56
|
async revert() {
|
|
57
57
|
try {
|
|
58
58
|
await this.client.query('BEGIN');
|
|
59
|
-
await this.client.query(`
|
|
60
|
-
DROP TABLE "users";
|
|
59
|
+
await this.client.query(`
|
|
60
|
+
DROP TABLE "users";
|
|
61
61
|
`);
|
|
62
|
-
const updateResult = await this.client.query(`
|
|
63
|
-
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
62
|
+
const updateResult = await this.client.query(`
|
|
63
|
+
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
64
64
|
`);
|
|
65
65
|
if (updateResult.rowCount === 0) {
|
|
66
66
|
await this.client.query('ROLLBACK');
|
|
@@ -16,22 +16,22 @@ export class CreateRefreshTokenTableMigration {
|
|
|
16
16
|
const fkConstraint = config.app.isMultiTenant
|
|
17
17
|
? ',\n CONSTRAINT "fk_refreshTokens_organization" FOREIGN KEY ("_orgId") REFERENCES "organizations"("_id") ON DELETE CASCADE'
|
|
18
18
|
: '';
|
|
19
|
-
await this.client.query(`
|
|
20
|
-
CREATE TABLE "refreshTokens" (
|
|
21
|
-
"_id" VARCHAR(255) PRIMARY KEY,
|
|
22
|
-
"_orgId" VARCHAR(255),
|
|
23
|
-
"token" VARCHAR(255) NOT NULL,
|
|
24
|
-
"deviceId" VARCHAR(255) NOT NULL,
|
|
25
|
-
"userId" VARCHAR(255) NOT NULL,
|
|
26
|
-
"expiresOn" BIGINT NOT NULL,
|
|
27
|
-
"created" TIMESTAMP NOT NULL,
|
|
28
|
-
"createdBy" VARCHAR(255) NOT NULL${fkConstraint}
|
|
29
|
-
)
|
|
19
|
+
await this.client.query(`
|
|
20
|
+
CREATE TABLE "refreshTokens" (
|
|
21
|
+
"_id" VARCHAR(255) PRIMARY KEY,
|
|
22
|
+
"_orgId" VARCHAR(255),
|
|
23
|
+
"token" VARCHAR(255) NOT NULL,
|
|
24
|
+
"deviceId" VARCHAR(255) NOT NULL,
|
|
25
|
+
"userId" VARCHAR(255) NOT NULL,
|
|
26
|
+
"expiresOn" BIGINT NOT NULL,
|
|
27
|
+
"created" TIMESTAMP NOT NULL,
|
|
28
|
+
"createdBy" VARCHAR(255) NOT NULL${fkConstraint}
|
|
29
|
+
)
|
|
30
30
|
`);
|
|
31
31
|
}
|
|
32
|
-
const result = await this.client.query(`
|
|
33
|
-
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
34
|
-
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
32
|
+
const result = await this.client.query(`
|
|
33
|
+
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
34
|
+
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
35
35
|
`);
|
|
36
36
|
if (result.rowCount === 0) {
|
|
37
37
|
await this.client.query('ROLLBACK');
|
|
@@ -50,12 +50,12 @@ export class CreateRefreshTokenTableMigration {
|
|
|
50
50
|
await this.client.query('BEGIN');
|
|
51
51
|
const tableExists = await doesTableExist(this.client, 'refreshTokens');
|
|
52
52
|
if (tableExists) {
|
|
53
|
-
await this.client.query(`
|
|
54
|
-
DROP TABLE "refreshTokens";
|
|
53
|
+
await this.client.query(`
|
|
54
|
+
DROP TABLE "refreshTokens";
|
|
55
55
|
`);
|
|
56
56
|
}
|
|
57
|
-
const updateResult = await this.client.query(`
|
|
58
|
-
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
57
|
+
const updateResult = await this.client.query(`
|
|
58
|
+
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
59
59
|
`);
|
|
60
60
|
if (updateResult.rowCount === 0) {
|
|
61
61
|
await this.client.query('ROLLBACK');
|
|
@@ -11,19 +11,19 @@ export class CreateMetaOrgMigration {
|
|
|
11
11
|
const _id = randomUUID().toString();
|
|
12
12
|
try {
|
|
13
13
|
await this.client.query('BEGIN');
|
|
14
|
-
const orgResult = await this.client.query(`
|
|
15
|
-
INSERT INTO "organizations" ("_id", "name", "code", "status", "isMetaOrg", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
16
|
-
VALUES ('${_id}', '${config.app.metaOrgName}', '${config.app.metaOrgCode}', 1, true, NOW(), 'system', NOW(), 'system')
|
|
17
|
-
RETURNING "_id", "name", "code", "status", "isMetaOrg", "_created", "_createdBy", "_updated", "_updatedBy";
|
|
14
|
+
const orgResult = await this.client.query(`
|
|
15
|
+
INSERT INTO "organizations" ("_id", "name", "code", "status", "isMetaOrg", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
16
|
+
VALUES ('${_id}', '${config.app.metaOrgName}', '${config.app.metaOrgCode}', 1, true, NOW(), 'system', NOW(), 'system')
|
|
17
|
+
RETURNING "_id", "name", "code", "status", "isMetaOrg", "_created", "_createdBy", "_updated", "_updatedBy";
|
|
18
18
|
`);
|
|
19
19
|
if (orgResult.rowCount === 0) {
|
|
20
20
|
await this.client.query('ROLLBACK');
|
|
21
21
|
return { success: false, error: new Error(`Error creating meta org: No row returned`) };
|
|
22
22
|
}
|
|
23
23
|
initializeSystemUserContext(config.email?.systemEmailAddress || 'system@example.com', orgResult.rows[0]);
|
|
24
|
-
const migrationResult = await this.client.query(`
|
|
25
|
-
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
26
|
-
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
24
|
+
const migrationResult = await this.client.query(`
|
|
25
|
+
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
26
|
+
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
27
27
|
`);
|
|
28
28
|
if (migrationResult.rowCount === 0) {
|
|
29
29
|
await this.client.query('ROLLBACK');
|
|
@@ -45,8 +45,8 @@ export class CreateMetaOrgMigration {
|
|
|
45
45
|
await this.client.query('ROLLBACK');
|
|
46
46
|
return { success: false, error: new Error(`Error reverting meta org: No row returned`) };
|
|
47
47
|
}
|
|
48
|
-
const updateResult = await this.client.query(`
|
|
49
|
-
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
48
|
+
const updateResult = await this.client.query(`
|
|
49
|
+
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
50
50
|
`);
|
|
51
51
|
if (updateResult.rowCount === 0) {
|
|
52
52
|
await this.client.query('ROLLBACK');
|
|
@@ -31,9 +31,9 @@ export class CreateAdminUserMigration {
|
|
|
31
31
|
return { success: false, error: new Error(`Error creating admin user: ${error.message}`) };
|
|
32
32
|
}
|
|
33
33
|
try {
|
|
34
|
-
const result = await this.client.query(`
|
|
35
|
-
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
36
|
-
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
34
|
+
const result = await this.client.query(`
|
|
35
|
+
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
36
|
+
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
37
37
|
`);
|
|
38
38
|
if (result.rowCount === 0) {
|
|
39
39
|
console.error(`Error inserting migration ${this.index} to migrations table: No row returned`);
|
|
@@ -16,18 +16,18 @@ export class CreateRoleTableMigration {
|
|
|
16
16
|
const fkConstraint = config.app.isMultiTenant
|
|
17
17
|
? ',\n CONSTRAINT "fk_roles_organization" FOREIGN KEY ("_orgId") REFERENCES "organizations"("_id") ON DELETE CASCADE'
|
|
18
18
|
: '';
|
|
19
|
-
await this.client.query(`
|
|
20
|
-
CREATE TABLE "roles" (
|
|
21
|
-
"_id" VARCHAR(255) PRIMARY KEY,
|
|
22
|
-
"_orgId" VARCHAR(255),
|
|
23
|
-
"name" VARCHAR(255) NOT NULL,
|
|
24
|
-
CONSTRAINT "uk_roles_name" UNIQUE ("_orgId", "name")${fkConstraint}
|
|
25
|
-
)
|
|
19
|
+
await this.client.query(`
|
|
20
|
+
CREATE TABLE "roles" (
|
|
21
|
+
"_id" VARCHAR(255) PRIMARY KEY,
|
|
22
|
+
"_orgId" VARCHAR(255),
|
|
23
|
+
"name" VARCHAR(255) NOT NULL,
|
|
24
|
+
CONSTRAINT "uk_roles_name" UNIQUE ("_orgId", "name")${fkConstraint}
|
|
25
|
+
)
|
|
26
26
|
`);
|
|
27
27
|
}
|
|
28
|
-
const result = await this.client.query(`
|
|
29
|
-
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
30
|
-
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
28
|
+
const result = await this.client.query(`
|
|
29
|
+
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
30
|
+
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
31
31
|
`);
|
|
32
32
|
if (result.rowCount === 0) {
|
|
33
33
|
await this.client.query('ROLLBACK');
|
|
@@ -44,11 +44,11 @@ export class CreateRoleTableMigration {
|
|
|
44
44
|
async revert() {
|
|
45
45
|
try {
|
|
46
46
|
await this.client.query('BEGIN');
|
|
47
|
-
await this.client.query(`
|
|
48
|
-
DROP TABLE "roles";
|
|
47
|
+
await this.client.query(`
|
|
48
|
+
DROP TABLE "roles";
|
|
49
49
|
`);
|
|
50
|
-
const updateResult = await this.client.query(`
|
|
51
|
-
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
50
|
+
const updateResult = await this.client.query(`
|
|
51
|
+
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
52
52
|
`);
|
|
53
53
|
if (updateResult.rowCount === 0) {
|
|
54
54
|
await this.client.query('ROLLBACK');
|
|
@@ -16,28 +16,28 @@ export class CreateUserRolesTableMigration {
|
|
|
16
16
|
const fkConstraint = config.app.isMultiTenant
|
|
17
17
|
? '\n CONSTRAINT "fk_user_roles_organization" FOREIGN KEY ("_orgId") REFERENCES "organizations"("_id") ON DELETE CASCADE,'
|
|
18
18
|
: '';
|
|
19
|
-
await this.client.query(`
|
|
20
|
-
CREATE TABLE "user_roles" (
|
|
21
|
-
"_id" VARCHAR(255) PRIMARY KEY,
|
|
22
|
-
"_orgId" VARCHAR(255),
|
|
23
|
-
"userId" VARCHAR(255) NOT NULL,
|
|
24
|
-
"roleId" VARCHAR(255) NOT NULL,
|
|
25
|
-
"_created" TIMESTAMP NOT NULL,
|
|
26
|
-
"_createdBy" VARCHAR(255) NOT NULL,
|
|
27
|
-
"_updated" TIMESTAMP NOT NULL,
|
|
28
|
-
"_updatedBy" VARCHAR(255) NOT NULL,
|
|
29
|
-
"_deleted" TIMESTAMP,
|
|
30
|
-
"_deletedBy" VARCHAR(255),
|
|
31
|
-
${fkConstraint}
|
|
32
|
-
CONSTRAINT "fk_user_roles_user" FOREIGN KEY ("userId") REFERENCES "users"("_id") ON DELETE CASCADE,
|
|
33
|
-
CONSTRAINT "fk_user_roles_role" FOREIGN KEY ("roleId") REFERENCES "roles"("_id") ON DELETE CASCADE,
|
|
34
|
-
CONSTRAINT "uk_user_roles" UNIQUE ("_orgId", "userId", "roleId")
|
|
35
|
-
)
|
|
19
|
+
await this.client.query(`
|
|
20
|
+
CREATE TABLE "user_roles" (
|
|
21
|
+
"_id" VARCHAR(255) PRIMARY KEY,
|
|
22
|
+
"_orgId" VARCHAR(255),
|
|
23
|
+
"userId" VARCHAR(255) NOT NULL,
|
|
24
|
+
"roleId" VARCHAR(255) NOT NULL,
|
|
25
|
+
"_created" TIMESTAMP NOT NULL,
|
|
26
|
+
"_createdBy" VARCHAR(255) NOT NULL,
|
|
27
|
+
"_updated" TIMESTAMP NOT NULL,
|
|
28
|
+
"_updatedBy" VARCHAR(255) NOT NULL,
|
|
29
|
+
"_deleted" TIMESTAMP,
|
|
30
|
+
"_deletedBy" VARCHAR(255),
|
|
31
|
+
${fkConstraint}
|
|
32
|
+
CONSTRAINT "fk_user_roles_user" FOREIGN KEY ("userId") REFERENCES "users"("_id") ON DELETE CASCADE,
|
|
33
|
+
CONSTRAINT "fk_user_roles_role" FOREIGN KEY ("roleId") REFERENCES "roles"("_id") ON DELETE CASCADE,
|
|
34
|
+
CONSTRAINT "uk_user_roles" UNIQUE ("_orgId", "userId", "roleId")
|
|
35
|
+
)
|
|
36
36
|
`);
|
|
37
37
|
}
|
|
38
|
-
const result = await this.client.query(`
|
|
39
|
-
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
40
|
-
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
38
|
+
const result = await this.client.query(`
|
|
39
|
+
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
40
|
+
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
41
41
|
`);
|
|
42
42
|
if (result.rowCount === 0) {
|
|
43
43
|
await this.client.query('ROLLBACK');
|
|
@@ -54,11 +54,11 @@ export class CreateUserRolesTableMigration {
|
|
|
54
54
|
async revert() {
|
|
55
55
|
try {
|
|
56
56
|
await this.client.query('BEGIN');
|
|
57
|
-
await this.client.query(`
|
|
58
|
-
DROP TABLE "user_roles";
|
|
57
|
+
await this.client.query(`
|
|
58
|
+
DROP TABLE "user_roles";
|
|
59
59
|
`);
|
|
60
|
-
const updateResult = await this.client.query(`
|
|
61
|
-
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
60
|
+
const updateResult = await this.client.query(`
|
|
61
|
+
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
62
62
|
`);
|
|
63
63
|
if (updateResult.rowCount === 0) {
|
|
64
64
|
await this.client.query('ROLLBACK');
|
|
@@ -16,18 +16,18 @@ export class CreateFeaturesTableMigration {
|
|
|
16
16
|
const fkConstraint = config.app.isMultiTenant
|
|
17
17
|
? ',\n CONSTRAINT "fk_features_organization" FOREIGN KEY ("_orgId") REFERENCES "organizations"("_id") ON DELETE CASCADE'
|
|
18
18
|
: '';
|
|
19
|
-
await this.client.query(`
|
|
20
|
-
CREATE TABLE "features" (
|
|
21
|
-
"_id" VARCHAR(255) PRIMARY KEY,
|
|
22
|
-
"_orgId" VARCHAR(255),
|
|
23
|
-
"name" VARCHAR(255) NOT NULL,
|
|
24
|
-
CONSTRAINT "uk_features" UNIQUE ("_orgId", "name")${fkConstraint}
|
|
25
|
-
)
|
|
19
|
+
await this.client.query(`
|
|
20
|
+
CREATE TABLE "features" (
|
|
21
|
+
"_id" VARCHAR(255) PRIMARY KEY,
|
|
22
|
+
"_orgId" VARCHAR(255),
|
|
23
|
+
"name" VARCHAR(255) NOT NULL,
|
|
24
|
+
CONSTRAINT "uk_features" UNIQUE ("_orgId", "name")${fkConstraint}
|
|
25
|
+
)
|
|
26
26
|
`);
|
|
27
27
|
}
|
|
28
|
-
const result = await this.client.query(`
|
|
29
|
-
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
30
|
-
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
28
|
+
const result = await this.client.query(`
|
|
29
|
+
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
30
|
+
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
31
31
|
`);
|
|
32
32
|
if (result.rowCount === 0) {
|
|
33
33
|
await this.client.query('ROLLBACK');
|
|
@@ -44,11 +44,11 @@ export class CreateFeaturesTableMigration {
|
|
|
44
44
|
async revert() {
|
|
45
45
|
try {
|
|
46
46
|
await this.client.query('BEGIN');
|
|
47
|
-
await this.client.query(`
|
|
48
|
-
DROP TABLE "features";
|
|
47
|
+
await this.client.query(`
|
|
48
|
+
DROP TABLE "features";
|
|
49
49
|
`);
|
|
50
|
-
const updateResult = await this.client.query(`
|
|
51
|
-
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
50
|
+
const updateResult = await this.client.query(`
|
|
51
|
+
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
52
52
|
`);
|
|
53
53
|
if (updateResult.rowCount === 0) {
|
|
54
54
|
await this.client.query('ROLLBACK');
|
|
@@ -16,30 +16,30 @@ export class CreateAuthorizationsTableMigration {
|
|
|
16
16
|
const fkConstraint = config.app.isMultiTenant
|
|
17
17
|
? ',\n CONSTRAINT "fk_authorizations_organization" FOREIGN KEY ("_orgId") REFERENCES "organizations"("_id") ON DELETE CASCADE'
|
|
18
18
|
: '';
|
|
19
|
-
await this.client.query(`
|
|
20
|
-
CREATE TABLE "authorizations" (
|
|
21
|
-
"_id" VARCHAR(255) PRIMARY KEY,
|
|
22
|
-
"_orgId" VARCHAR(255),
|
|
23
|
-
"roleId" VARCHAR(255) NOT NULL,
|
|
24
|
-
"featureId" VARCHAR(255) NOT NULL,
|
|
25
|
-
"startDate" TIMESTAMP,
|
|
26
|
-
"endDate" TIMESTAMP,
|
|
27
|
-
"config" JSONB,
|
|
28
|
-
"_created" TIMESTAMP NOT NULL,
|
|
29
|
-
"_createdBy" VARCHAR(255) NOT NULL,
|
|
30
|
-
"_updated" TIMESTAMP NOT NULL,
|
|
31
|
-
"_updatedBy" VARCHAR(255) NOT NULL,
|
|
32
|
-
"_deleted" TIMESTAMP,
|
|
33
|
-
"_deletedBy" VARCHAR(255),
|
|
34
|
-
CONSTRAINT "fk_authorizations_role" FOREIGN KEY ("roleId") REFERENCES "roles"("_id") ON DELETE CASCADE,
|
|
35
|
-
CONSTRAINT "fk_authorizations_feature" FOREIGN KEY ("featureId") REFERENCES "features"("_id") ON DELETE CASCADE,
|
|
36
|
-
CONSTRAINT "uk_authorizations" UNIQUE ("_orgId", "roleId", "featureId")${fkConstraint}
|
|
37
|
-
)
|
|
19
|
+
await this.client.query(`
|
|
20
|
+
CREATE TABLE "authorizations" (
|
|
21
|
+
"_id" VARCHAR(255) PRIMARY KEY,
|
|
22
|
+
"_orgId" VARCHAR(255),
|
|
23
|
+
"roleId" VARCHAR(255) NOT NULL,
|
|
24
|
+
"featureId" VARCHAR(255) NOT NULL,
|
|
25
|
+
"startDate" TIMESTAMP,
|
|
26
|
+
"endDate" TIMESTAMP,
|
|
27
|
+
"config" JSONB,
|
|
28
|
+
"_created" TIMESTAMP NOT NULL,
|
|
29
|
+
"_createdBy" VARCHAR(255) NOT NULL,
|
|
30
|
+
"_updated" TIMESTAMP NOT NULL,
|
|
31
|
+
"_updatedBy" VARCHAR(255) NOT NULL,
|
|
32
|
+
"_deleted" TIMESTAMP,
|
|
33
|
+
"_deletedBy" VARCHAR(255),
|
|
34
|
+
CONSTRAINT "fk_authorizations_role" FOREIGN KEY ("roleId") REFERENCES "roles"("_id") ON DELETE CASCADE,
|
|
35
|
+
CONSTRAINT "fk_authorizations_feature" FOREIGN KEY ("featureId") REFERENCES "features"("_id") ON DELETE CASCADE,
|
|
36
|
+
CONSTRAINT "uk_authorizations" UNIQUE ("_orgId", "roleId", "featureId")${fkConstraint}
|
|
37
|
+
)
|
|
38
38
|
`);
|
|
39
39
|
}
|
|
40
|
-
const result = await this.client.query(`
|
|
41
|
-
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
42
|
-
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
40
|
+
const result = await this.client.query(`
|
|
41
|
+
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
42
|
+
VALUES ('${_id}', ${this.index}, TRUE, FALSE);
|
|
43
43
|
`);
|
|
44
44
|
if (result.rowCount === 0) {
|
|
45
45
|
await this.client.query('ROLLBACK');
|
|
@@ -56,11 +56,11 @@ export class CreateAuthorizationsTableMigration {
|
|
|
56
56
|
async revert() {
|
|
57
57
|
try {
|
|
58
58
|
await this.client.query('BEGIN');
|
|
59
|
-
await this.client.query(`
|
|
60
|
-
DROP TABLE "authorizations";
|
|
59
|
+
await this.client.query(`
|
|
60
|
+
DROP TABLE "authorizations";
|
|
61
61
|
`);
|
|
62
|
-
const updateResult = await this.client.query(`
|
|
63
|
-
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
62
|
+
const updateResult = await this.client.query(`
|
|
63
|
+
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = '${this.index}';
|
|
64
64
|
`);
|
|
65
65
|
if (updateResult.rowCount === 0) {
|
|
66
66
|
await this.client.query('ROLLBACK');
|
|
@@ -27,47 +27,47 @@ export class CreateAdminAuthorizationMigration {
|
|
|
27
27
|
}
|
|
28
28
|
await this.client.query('BEGIN');
|
|
29
29
|
const roleId = randomUUID().toString();
|
|
30
|
-
const roleResult = await this.client.query(`
|
|
31
|
-
INSERT INTO "roles" ("_id", "_orgId", "name")
|
|
32
|
-
VALUES ($1, $2, 'admin')
|
|
30
|
+
const roleResult = await this.client.query(`
|
|
31
|
+
INSERT INTO "roles" ("_id", "_orgId", "name")
|
|
32
|
+
VALUES ($1, $2, 'admin')
|
|
33
33
|
`, [roleId, metaOrg?._id]);
|
|
34
34
|
if (roleResult.rowCount === 0) {
|
|
35
35
|
await this.client.query('ROLLBACK');
|
|
36
36
|
return { success: false, error: new Error('Failed to create admin role') };
|
|
37
37
|
}
|
|
38
38
|
const userRoleId = randomUUID().toString();
|
|
39
|
-
const userRoleResult = await this.client.query(`
|
|
40
|
-
INSERT INTO "user_roles" ("_id", "_orgId", "userId", "roleId", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
41
|
-
VALUES ($1, $2, $3, $4, NOW(), 'system', NOW(), 'system')
|
|
39
|
+
const userRoleResult = await this.client.query(`
|
|
40
|
+
INSERT INTO "user_roles" ("_id", "_orgId", "userId", "roleId", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
41
|
+
VALUES ($1, $2, $3, $4, NOW(), 'system', NOW(), 'system')
|
|
42
42
|
`, [userRoleId, metaOrg?._id, adminUser?._id, roleId]);
|
|
43
43
|
if (userRoleResult.rowCount === 0) {
|
|
44
44
|
await this.client.query('ROLLBACK');
|
|
45
45
|
return { success: false, error: new Error('Failed to create user role') };
|
|
46
46
|
}
|
|
47
47
|
const featureId = randomUUID().toString();
|
|
48
|
-
const featureResult = await this.client.query(`
|
|
49
|
-
INSERT INTO "features" ("_id", "_orgId", "name")
|
|
50
|
-
VALUES ($1, $2, 'admin')
|
|
48
|
+
const featureResult = await this.client.query(`
|
|
49
|
+
INSERT INTO "features" ("_id", "_orgId", "name")
|
|
50
|
+
VALUES ($1, $2, 'admin')
|
|
51
51
|
`, [featureId, metaOrg?._id]);
|
|
52
52
|
if (featureResult.rowCount === 0) {
|
|
53
53
|
await this.client.query('ROLLBACK');
|
|
54
54
|
return { success: false, error: new Error('Failed to create admin feature') };
|
|
55
55
|
}
|
|
56
56
|
const authorizationId = randomUUID().toString();
|
|
57
|
-
const authorizationResult = await this.client.query(`
|
|
58
|
-
INSERT INTO "authorizations" (
|
|
59
|
-
"_id", "_orgId", "roleId", "featureId",
|
|
60
|
-
"_created", "_createdBy", "_updated", "_updatedBy"
|
|
61
|
-
)
|
|
62
|
-
VALUES ($1, $2, $3, $4, NOW(), 'system', NOW(), 'system')
|
|
57
|
+
const authorizationResult = await this.client.query(`
|
|
58
|
+
INSERT INTO "authorizations" (
|
|
59
|
+
"_id", "_orgId", "roleId", "featureId",
|
|
60
|
+
"_created", "_createdBy", "_updated", "_updatedBy"
|
|
61
|
+
)
|
|
62
|
+
VALUES ($1, $2, $3, $4, NOW(), 'system', NOW(), 'system')
|
|
63
63
|
`, [authorizationId, metaOrg?._id, roleId, featureId]);
|
|
64
64
|
if (authorizationResult.rowCount === 0) {
|
|
65
65
|
await this.client.query('ROLLBACK');
|
|
66
66
|
return { success: false, error: new Error('Failed to create admin authorization') };
|
|
67
67
|
}
|
|
68
|
-
const migrationResult = await this.client.query(`
|
|
69
|
-
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
70
|
-
VALUES ($1, $2, TRUE, FALSE)
|
|
68
|
+
const migrationResult = await this.client.query(`
|
|
69
|
+
INSERT INTO "migrations" ("_id", "index", "hasRun", "reverted")
|
|
70
|
+
VALUES ($1, $2, TRUE, FALSE)
|
|
71
71
|
`, [_id, this.index]);
|
|
72
72
|
if (migrationResult.rowCount === 0) {
|
|
73
73
|
await this.client.query('ROLLBACK');
|
|
@@ -84,36 +84,36 @@ export class CreateAdminAuthorizationMigration {
|
|
|
84
84
|
async revert(metaOrgId) {
|
|
85
85
|
try {
|
|
86
86
|
await this.client.query('BEGIN');
|
|
87
|
-
await this.client.query(`
|
|
88
|
-
DELETE FROM "authorizations"
|
|
89
|
-
WHERE "_orgId" = $1
|
|
90
|
-
AND "_featureId" IN (
|
|
91
|
-
SELECT "_id" FROM "features"
|
|
92
|
-
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
93
|
-
)
|
|
94
|
-
AND "_roleId" IN (
|
|
95
|
-
SELECT "_id" FROM "roles"
|
|
96
|
-
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
97
|
-
)
|
|
87
|
+
await this.client.query(`
|
|
88
|
+
DELETE FROM "authorizations"
|
|
89
|
+
WHERE "_orgId" = $1
|
|
90
|
+
AND "_featureId" IN (
|
|
91
|
+
SELECT "_id" FROM "features"
|
|
92
|
+
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
93
|
+
)
|
|
94
|
+
AND "_roleId" IN (
|
|
95
|
+
SELECT "_id" FROM "roles"
|
|
96
|
+
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
97
|
+
)
|
|
98
98
|
`, [metaOrgId]);
|
|
99
|
-
await this.client.query(`
|
|
100
|
-
DELETE FROM "features"
|
|
101
|
-
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
99
|
+
await this.client.query(`
|
|
100
|
+
DELETE FROM "features"
|
|
101
|
+
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
102
102
|
`, [metaOrgId]);
|
|
103
|
-
await this.client.query(`
|
|
104
|
-
DELETE FROM "user_roles"
|
|
105
|
-
WHERE "_orgId" = $1
|
|
106
|
-
AND "_roleId" IN (
|
|
107
|
-
SELECT "_id" FROM "roles"
|
|
108
|
-
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
109
|
-
)
|
|
103
|
+
await this.client.query(`
|
|
104
|
+
DELETE FROM "user_roles"
|
|
105
|
+
WHERE "_orgId" = $1
|
|
106
|
+
AND "_roleId" IN (
|
|
107
|
+
SELECT "_id" FROM "roles"
|
|
108
|
+
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
109
|
+
)
|
|
110
110
|
`, [metaOrgId]);
|
|
111
|
-
await this.client.query(`
|
|
112
|
-
DELETE FROM "roles"
|
|
113
|
-
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
111
|
+
await this.client.query(`
|
|
112
|
+
DELETE FROM "roles"
|
|
113
|
+
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
114
114
|
`, [metaOrgId]);
|
|
115
|
-
const updateResult = await this.client.query(`
|
|
116
|
-
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = $1
|
|
115
|
+
const updateResult = await this.client.query(`
|
|
116
|
+
UPDATE "migrations" SET "reverted" = TRUE WHERE "index" = $1
|
|
117
117
|
`, [this.index]);
|
|
118
118
|
if (updateResult.rowCount === 0) {
|
|
119
119
|
await this.client.query('ROLLBACK');
|
|
@@ -42,10 +42,10 @@ export class DatabaseBuilder {
|
|
|
42
42
|
async build() {
|
|
43
43
|
let runMigrations = [];
|
|
44
44
|
if (await doesTableExist(this.client, 'migrations')) {
|
|
45
|
-
const migrations = await this.client.query(`
|
|
46
|
-
SELECT "_id", "index"
|
|
47
|
-
FROM migrations
|
|
48
|
-
WHERE "hasRun" = TRUE AND "reverted" = FALSE
|
|
45
|
+
const migrations = await this.client.query(`
|
|
46
|
+
SELECT "_id", "index"
|
|
47
|
+
FROM migrations
|
|
48
|
+
WHERE "hasRun" = TRUE AND "reverted" = FALSE
|
|
49
49
|
`);
|
|
50
50
|
runMigrations = migrations.rows.map((row) => {
|
|
51
51
|
return row.index;
|