@loomcore/api 0.1.75 → 0.1.77
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 +77 -77
- package/dist/__tests__/postgres-test-migrations/postgres-test-schema.js +290 -239
- package/dist/__tests__/postgres.test-database.js +8 -8
- package/dist/databases/migrations/migration-runner.js +21 -21
- package/dist/databases/operations/__tests__/models/client-report.model.d.ts +25 -0
- package/dist/databases/operations/__tests__/models/client-report.model.js +3 -1
- package/dist/databases/operations/__tests__/models/policy.model.d.ts +32 -0
- package/dist/databases/operations/__tests__/models/policy.model.js +10 -0
- package/dist/databases/postgres/commands/postgres-batch-update.command.js +7 -7
- package/dist/databases/postgres/commands/postgres-create-many.command.js +4 -4
- 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/postgres-initial-schema.js +197 -197
- package/dist/databases/postgres/postgres.database.js +17 -17
- package/dist/databases/postgres/utils/build-join-clauses.js +277 -24
- package/dist/databases/postgres/utils/build-select-clause.js +38 -7
- package/dist/databases/postgres/utils/does-table-exist.util.js +4 -4
- package/dist/databases/postgres/utils/transform-join-results.js +102 -6
- package/package.json +92 -92
|
@@ -18,22 +18,22 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
18
18
|
migrations.push({
|
|
19
19
|
name: '00000000000001_schema-organizations',
|
|
20
20
|
up: async ({ context: pool }) => {
|
|
21
|
-
await pool.query(`
|
|
22
|
-
CREATE TABLE IF NOT EXISTS "organizations" (
|
|
23
|
-
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
24
|
-
"name" VARCHAR(255) NOT NULL UNIQUE,
|
|
25
|
-
"code" VARCHAR(255) NOT NULL UNIQUE,
|
|
26
|
-
"description" TEXT,
|
|
27
|
-
"status" INTEGER NOT NULL,
|
|
28
|
-
"isMetaOrg" BOOLEAN NOT NULL,
|
|
29
|
-
"authToken" TEXT,
|
|
30
|
-
"_created" TIMESTAMPTZ NOT NULL,
|
|
31
|
-
"_createdBy" INTEGER NOT NULL,
|
|
32
|
-
"_updated" TIMESTAMPTZ NOT NULL,
|
|
33
|
-
"_updatedBy" INTEGER NOT NULL,
|
|
34
|
-
"_deleted" TIMESTAMPTZ,
|
|
35
|
-
"_deletedBy" INTEGER
|
|
36
|
-
)
|
|
21
|
+
await pool.query(`
|
|
22
|
+
CREATE TABLE IF NOT EXISTS "organizations" (
|
|
23
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
24
|
+
"name" VARCHAR(255) NOT NULL UNIQUE,
|
|
25
|
+
"code" VARCHAR(255) NOT NULL UNIQUE,
|
|
26
|
+
"description" TEXT,
|
|
27
|
+
"status" INTEGER NOT NULL,
|
|
28
|
+
"isMetaOrg" BOOLEAN NOT NULL,
|
|
29
|
+
"authToken" TEXT,
|
|
30
|
+
"_created" TIMESTAMPTZ NOT NULL,
|
|
31
|
+
"_createdBy" INTEGER NOT NULL,
|
|
32
|
+
"_updated" TIMESTAMPTZ NOT NULL,
|
|
33
|
+
"_updatedBy" INTEGER NOT NULL,
|
|
34
|
+
"_deleted" TIMESTAMPTZ,
|
|
35
|
+
"_deletedBy" INTEGER
|
|
36
|
+
)
|
|
37
37
|
`);
|
|
38
38
|
},
|
|
39
39
|
down: async ({ context: pool }) => {
|
|
@@ -49,25 +49,25 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
49
49
|
const uniqueConstraint = isMultiTenant
|
|
50
50
|
? 'CONSTRAINT "uk_users_email" UNIQUE ("_orgId", "email")'
|
|
51
51
|
: 'CONSTRAINT "uk_users_email" UNIQUE ("email")';
|
|
52
|
-
await pool.query(`
|
|
53
|
-
CREATE TABLE IF NOT EXISTS "users" (
|
|
54
|
-
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
55
|
-
${orgColumnDef}
|
|
56
|
-
"email" VARCHAR(255) NOT NULL,
|
|
57
|
-
"firstName" VARCHAR(255),
|
|
58
|
-
"lastName" VARCHAR(255),
|
|
59
|
-
"displayName" VARCHAR(255),
|
|
60
|
-
"password" VARCHAR(255) NOT NULL,
|
|
61
|
-
"_lastLoggedIn" TIMESTAMPTZ,
|
|
62
|
-
"_lastPasswordChange" TIMESTAMPTZ,
|
|
63
|
-
"_created" TIMESTAMPTZ NOT NULL,
|
|
64
|
-
"_createdBy" INTEGER NOT NULL,
|
|
65
|
-
"_updated" TIMESTAMPTZ NOT NULL,
|
|
66
|
-
"_updatedBy" INTEGER NOT NULL,
|
|
67
|
-
"_deleted" TIMESTAMPTZ,
|
|
68
|
-
"_deletedBy" INTEGER,
|
|
69
|
-
${uniqueConstraint}
|
|
70
|
-
)
|
|
52
|
+
await pool.query(`
|
|
53
|
+
CREATE TABLE IF NOT EXISTS "users" (
|
|
54
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
55
|
+
${orgColumnDef}
|
|
56
|
+
"email" VARCHAR(255) NOT NULL,
|
|
57
|
+
"firstName" VARCHAR(255),
|
|
58
|
+
"lastName" VARCHAR(255),
|
|
59
|
+
"displayName" VARCHAR(255),
|
|
60
|
+
"password" VARCHAR(255) NOT NULL,
|
|
61
|
+
"_lastLoggedIn" TIMESTAMPTZ,
|
|
62
|
+
"_lastPasswordChange" TIMESTAMPTZ,
|
|
63
|
+
"_created" TIMESTAMPTZ NOT NULL,
|
|
64
|
+
"_createdBy" INTEGER NOT NULL,
|
|
65
|
+
"_updated" TIMESTAMPTZ NOT NULL,
|
|
66
|
+
"_updatedBy" INTEGER NOT NULL,
|
|
67
|
+
"_deleted" TIMESTAMPTZ,
|
|
68
|
+
"_deletedBy" INTEGER,
|
|
69
|
+
${uniqueConstraint}
|
|
70
|
+
)
|
|
71
71
|
`);
|
|
72
72
|
},
|
|
73
73
|
down: async ({ context: pool }) => {
|
|
@@ -79,18 +79,18 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
79
79
|
name: '00000000000003_schema-refresh-tokens',
|
|
80
80
|
up: async ({ context: pool }) => {
|
|
81
81
|
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
82
|
-
await pool.query(`
|
|
83
|
-
CREATE TABLE IF NOT EXISTS "refresh_tokens" (
|
|
84
|
-
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
85
|
-
${orgColumnDef}
|
|
86
|
-
"token" VARCHAR(255) NOT NULL,
|
|
87
|
-
"deviceId" VARCHAR(255) NOT NULL,
|
|
88
|
-
"userId" INTEGER NOT NULL,
|
|
89
|
-
"expiresOn" BIGINT NOT NULL,
|
|
90
|
-
"created" TIMESTAMPTZ NOT NULL,
|
|
91
|
-
"createdBy" INTEGER NOT NULL,
|
|
92
|
-
CONSTRAINT "fk_refresh_tokens_user" FOREIGN KEY ("userId") REFERENCES "users"("_id") ON DELETE CASCADE
|
|
93
|
-
)
|
|
82
|
+
await pool.query(`
|
|
83
|
+
CREATE TABLE IF NOT EXISTS "refresh_tokens" (
|
|
84
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
85
|
+
${orgColumnDef}
|
|
86
|
+
"token" VARCHAR(255) NOT NULL,
|
|
87
|
+
"deviceId" VARCHAR(255) NOT NULL,
|
|
88
|
+
"userId" INTEGER NOT NULL,
|
|
89
|
+
"expiresOn" BIGINT NOT NULL,
|
|
90
|
+
"created" TIMESTAMPTZ NOT NULL,
|
|
91
|
+
"createdBy" INTEGER NOT NULL,
|
|
92
|
+
CONSTRAINT "fk_refresh_tokens_user" FOREIGN KEY ("userId") REFERENCES "users"("_id") ON DELETE CASCADE
|
|
93
|
+
)
|
|
94
94
|
`);
|
|
95
95
|
},
|
|
96
96
|
down: async ({ context: pool }) => {
|
|
@@ -105,21 +105,21 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
105
105
|
const uniqueConstraint = isMultiTenant
|
|
106
106
|
? 'CONSTRAINT "uk_passwordResetTokens_email" UNIQUE ("_orgId", "email")'
|
|
107
107
|
: 'CONSTRAINT "uk_passwordResetTokens_email" UNIQUE ("email")';
|
|
108
|
-
await pool.query(`
|
|
109
|
-
CREATE TABLE IF NOT EXISTS "password_reset_tokens" (
|
|
110
|
-
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
111
|
-
${orgColumnDef}
|
|
112
|
-
"email" VARCHAR(255) NOT NULL,
|
|
113
|
-
"token" VARCHAR(255) NOT NULL,
|
|
114
|
-
"expiresOn" BIGINT NOT NULL,
|
|
115
|
-
"_created" TIMESTAMPTZ NOT NULL,
|
|
116
|
-
"_createdBy" INTEGER NOT NULL,
|
|
117
|
-
"_updated" TIMESTAMPTZ NOT NULL,
|
|
118
|
-
"_updatedBy" INTEGER NOT NULL,
|
|
119
|
-
"_deleted" TIMESTAMPTZ,
|
|
120
|
-
"_deletedBy" INTEGER,
|
|
121
|
-
${uniqueConstraint}
|
|
122
|
-
)
|
|
108
|
+
await pool.query(`
|
|
109
|
+
CREATE TABLE IF NOT EXISTS "password_reset_tokens" (
|
|
110
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
111
|
+
${orgColumnDef}
|
|
112
|
+
"email" VARCHAR(255) NOT NULL,
|
|
113
|
+
"token" VARCHAR(255) NOT NULL,
|
|
114
|
+
"expiresOn" BIGINT NOT NULL,
|
|
115
|
+
"_created" TIMESTAMPTZ NOT NULL,
|
|
116
|
+
"_createdBy" INTEGER NOT NULL,
|
|
117
|
+
"_updated" TIMESTAMPTZ NOT NULL,
|
|
118
|
+
"_updatedBy" INTEGER NOT NULL,
|
|
119
|
+
"_deleted" TIMESTAMPTZ,
|
|
120
|
+
"_deletedBy" INTEGER,
|
|
121
|
+
${uniqueConstraint}
|
|
122
|
+
)
|
|
123
123
|
`);
|
|
124
124
|
},
|
|
125
125
|
down: async ({ context: pool }) => {
|
|
@@ -134,14 +134,14 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
134
134
|
const uniqueConstraint = isMultiTenant
|
|
135
135
|
? 'CONSTRAINT "uk_roles_name" UNIQUE ("_orgId", "name")'
|
|
136
136
|
: 'CONSTRAINT "uk_roles_name" UNIQUE ("name")';
|
|
137
|
-
await pool.query(`
|
|
138
|
-
CREATE TABLE IF NOT EXISTS "roles" (
|
|
139
|
-
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
140
|
-
${orgColumnDef}
|
|
141
|
-
"name" VARCHAR(255) NOT NULL,
|
|
142
|
-
"description" TEXT,
|
|
143
|
-
${uniqueConstraint}
|
|
144
|
-
)
|
|
137
|
+
await pool.query(`
|
|
138
|
+
CREATE TABLE IF NOT EXISTS "roles" (
|
|
139
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
140
|
+
${orgColumnDef}
|
|
141
|
+
"name" VARCHAR(255) NOT NULL,
|
|
142
|
+
"description" TEXT,
|
|
143
|
+
${uniqueConstraint}
|
|
144
|
+
)
|
|
145
145
|
`);
|
|
146
146
|
},
|
|
147
147
|
down: async ({ context: pool }) => {
|
|
@@ -156,22 +156,22 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
156
156
|
const uniqueConstraint = isMultiTenant
|
|
157
157
|
? 'CONSTRAINT "uk_user_roles" UNIQUE ("_orgId", "userId", "roleId")'
|
|
158
158
|
: 'CONSTRAINT "uk_user_roles" UNIQUE ("userId", "roleId")';
|
|
159
|
-
await pool.query(`
|
|
160
|
-
CREATE TABLE IF NOT EXISTS "user_roles" (
|
|
161
|
-
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
162
|
-
${orgColumnDef}
|
|
163
|
-
"userId" INTEGER NOT NULL,
|
|
164
|
-
"roleId" INTEGER NOT NULL,
|
|
165
|
-
"_created" TIMESTAMPTZ NOT NULL,
|
|
166
|
-
"_createdBy" INTEGER NOT NULL,
|
|
167
|
-
"_updated" TIMESTAMPTZ NOT NULL,
|
|
168
|
-
"_updatedBy" INTEGER NOT NULL,
|
|
169
|
-
"_deleted" TIMESTAMPTZ,
|
|
170
|
-
"_deletedBy" INTEGER,
|
|
171
|
-
CONSTRAINT "fk_user_roles_user" FOREIGN KEY ("userId") REFERENCES "users"("_id") ON DELETE CASCADE,
|
|
172
|
-
CONSTRAINT "fk_user_roles_role" FOREIGN KEY ("roleId") REFERENCES "roles"("_id") ON DELETE CASCADE,
|
|
173
|
-
${uniqueConstraint}
|
|
174
|
-
)
|
|
159
|
+
await pool.query(`
|
|
160
|
+
CREATE TABLE IF NOT EXISTS "user_roles" (
|
|
161
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
162
|
+
${orgColumnDef}
|
|
163
|
+
"userId" INTEGER NOT NULL,
|
|
164
|
+
"roleId" INTEGER NOT NULL,
|
|
165
|
+
"_created" TIMESTAMPTZ NOT NULL,
|
|
166
|
+
"_createdBy" INTEGER NOT NULL,
|
|
167
|
+
"_updated" TIMESTAMPTZ NOT NULL,
|
|
168
|
+
"_updatedBy" INTEGER NOT NULL,
|
|
169
|
+
"_deleted" TIMESTAMPTZ,
|
|
170
|
+
"_deletedBy" INTEGER,
|
|
171
|
+
CONSTRAINT "fk_user_roles_user" FOREIGN KEY ("userId") REFERENCES "users"("_id") ON DELETE CASCADE,
|
|
172
|
+
CONSTRAINT "fk_user_roles_role" FOREIGN KEY ("roleId") REFERENCES "roles"("_id") ON DELETE CASCADE,
|
|
173
|
+
${uniqueConstraint}
|
|
174
|
+
)
|
|
175
175
|
`);
|
|
176
176
|
},
|
|
177
177
|
down: async ({ context: pool }) => {
|
|
@@ -186,14 +186,14 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
186
186
|
const uniqueConstraint = isMultiTenant
|
|
187
187
|
? 'CONSTRAINT "uk_features" UNIQUE ("_orgId", "name")'
|
|
188
188
|
: 'CONSTRAINT "uk_features" UNIQUE ("name")';
|
|
189
|
-
await pool.query(`
|
|
190
|
-
CREATE TABLE IF NOT EXISTS "features" (
|
|
191
|
-
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
192
|
-
${orgColumnDef}
|
|
193
|
-
"name" VARCHAR(255) NOT NULL,
|
|
194
|
-
"description" TEXT,
|
|
195
|
-
${uniqueConstraint}
|
|
196
|
-
)
|
|
189
|
+
await pool.query(`
|
|
190
|
+
CREATE TABLE IF NOT EXISTS "features" (
|
|
191
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
192
|
+
${orgColumnDef}
|
|
193
|
+
"name" VARCHAR(255) NOT NULL,
|
|
194
|
+
"description" TEXT,
|
|
195
|
+
${uniqueConstraint}
|
|
196
|
+
)
|
|
197
197
|
`);
|
|
198
198
|
},
|
|
199
199
|
down: async ({ context: pool }) => {
|
|
@@ -208,25 +208,25 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
208
208
|
const uniqueConstraint = isMultiTenant
|
|
209
209
|
? 'CONSTRAINT "uk_authorizations" UNIQUE ("_orgId", "roleId", "featureId")'
|
|
210
210
|
: 'CONSTRAINT "uk_authorizations" UNIQUE ("roleId", "featureId")';
|
|
211
|
-
await pool.query(`
|
|
212
|
-
CREATE TABLE IF NOT EXISTS "authorizations" (
|
|
213
|
-
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
214
|
-
${orgColumnDef}
|
|
215
|
-
"roleId" INTEGER NOT NULL,
|
|
216
|
-
"featureId" INTEGER NOT NULL,
|
|
217
|
-
"startDate" TIMESTAMPTZ,
|
|
218
|
-
"endDate" TIMESTAMPTZ,
|
|
219
|
-
"config" JSONB,
|
|
220
|
-
"_created" TIMESTAMPTZ NOT NULL,
|
|
221
|
-
"_createdBy" INTEGER NOT NULL,
|
|
222
|
-
"_updated" TIMESTAMPTZ NOT NULL,
|
|
223
|
-
"_updatedBy" INTEGER NOT NULL,
|
|
224
|
-
"_deleted" TIMESTAMPTZ,
|
|
225
|
-
"_deletedBy" INTEGER,
|
|
226
|
-
CONSTRAINT "fk_authorizations_role" FOREIGN KEY ("roleId") REFERENCES "roles"("_id") ON DELETE CASCADE,
|
|
227
|
-
CONSTRAINT "fk_authorizations_feature" FOREIGN KEY ("featureId") REFERENCES "features"("_id") ON DELETE CASCADE,
|
|
228
|
-
${uniqueConstraint}
|
|
229
|
-
)
|
|
211
|
+
await pool.query(`
|
|
212
|
+
CREATE TABLE IF NOT EXISTS "authorizations" (
|
|
213
|
+
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
214
|
+
${orgColumnDef}
|
|
215
|
+
"roleId" INTEGER NOT NULL,
|
|
216
|
+
"featureId" INTEGER NOT NULL,
|
|
217
|
+
"startDate" TIMESTAMPTZ,
|
|
218
|
+
"endDate" TIMESTAMPTZ,
|
|
219
|
+
"config" JSONB,
|
|
220
|
+
"_created" TIMESTAMPTZ NOT NULL,
|
|
221
|
+
"_createdBy" INTEGER NOT NULL,
|
|
222
|
+
"_updated" TIMESTAMPTZ NOT NULL,
|
|
223
|
+
"_updatedBy" INTEGER NOT NULL,
|
|
224
|
+
"_deleted" TIMESTAMPTZ,
|
|
225
|
+
"_deletedBy" INTEGER,
|
|
226
|
+
CONSTRAINT "fk_authorizations_role" FOREIGN KEY ("roleId") REFERENCES "roles"("_id") ON DELETE CASCADE,
|
|
227
|
+
CONSTRAINT "fk_authorizations_feature" FOREIGN KEY ("featureId") REFERENCES "features"("_id") ON DELETE CASCADE,
|
|
228
|
+
${uniqueConstraint}
|
|
229
|
+
)
|
|
230
230
|
`);
|
|
231
231
|
},
|
|
232
232
|
down: async ({ context: pool }) => {
|
|
@@ -237,10 +237,10 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
237
237
|
migrations.push({
|
|
238
238
|
name: '00000000000009_data-meta-org',
|
|
239
239
|
up: async ({ context: pool }) => {
|
|
240
|
-
const result = await pool.query(`
|
|
241
|
-
INSERT INTO "organizations" ("name", "code", "status", "isMetaOrg", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
242
|
-
VALUES ($1, $2, 1, true, NOW(), 0, NOW(), 0)
|
|
243
|
-
RETURNING "_id", "name", "code", "status", "isMetaOrg", "_created", "_createdBy", "_updated", "_updatedBy"
|
|
240
|
+
const result = await pool.query(`
|
|
241
|
+
INSERT INTO "organizations" ("name", "code", "status", "isMetaOrg", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
242
|
+
VALUES ($1, $2, 1, true, NOW(), 0, NOW(), 0)
|
|
243
|
+
RETURNING "_id", "name", "code", "status", "isMetaOrg", "_created", "_createdBy", "_updated", "_updatedBy"
|
|
244
244
|
`, [config.multiTenant?.metaOrgName, config.multiTenant?.metaOrgCode]);
|
|
245
245
|
if (result.rowCount === 0) {
|
|
246
246
|
throw new Error('Failed to create meta organization');
|
|
@@ -313,61 +313,61 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
313
313
|
await client.query('BEGIN');
|
|
314
314
|
try {
|
|
315
315
|
const roleResult = isMultiTenant
|
|
316
|
-
? await client.query(`
|
|
317
|
-
INSERT INTO "roles" ("_orgId", "name")
|
|
318
|
-
VALUES ($1, 'admin')
|
|
319
|
-
RETURNING "_id"
|
|
316
|
+
? await client.query(`
|
|
317
|
+
INSERT INTO "roles" ("_orgId", "name")
|
|
318
|
+
VALUES ($1, 'admin')
|
|
319
|
+
RETURNING "_id"
|
|
320
320
|
`, [metaOrg._id])
|
|
321
|
-
: await client.query(`
|
|
322
|
-
INSERT INTO "roles" ("name")
|
|
323
|
-
VALUES ('admin')
|
|
324
|
-
RETURNING "_id"
|
|
321
|
+
: await client.query(`
|
|
322
|
+
INSERT INTO "roles" ("name")
|
|
323
|
+
VALUES ('admin')
|
|
324
|
+
RETURNING "_id"
|
|
325
325
|
`);
|
|
326
326
|
if (roleResult.rowCount === 0) {
|
|
327
327
|
throw new Error('Failed to create admin role');
|
|
328
328
|
}
|
|
329
329
|
const roleId = roleResult.rows[0]._id;
|
|
330
330
|
const userRoleResult = isMultiTenant
|
|
331
|
-
? await client.query(`
|
|
332
|
-
INSERT INTO "user_roles" ("_orgId", "userId", "roleId", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
333
|
-
VALUES ($1, $2, $3, NOW(), 0, NOW(), 0)
|
|
331
|
+
? await client.query(`
|
|
332
|
+
INSERT INTO "user_roles" ("_orgId", "userId", "roleId", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
333
|
+
VALUES ($1, $2, $3, NOW(), 0, NOW(), 0)
|
|
334
334
|
`, [metaOrg._id, adminUser._id, roleId])
|
|
335
|
-
: await client.query(`
|
|
336
|
-
INSERT INTO "user_roles" ("userId", "roleId", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
337
|
-
VALUES ($1, $2, NOW(), 0, NOW(), 0)
|
|
335
|
+
: await client.query(`
|
|
336
|
+
INSERT INTO "user_roles" ("userId", "roleId", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
337
|
+
VALUES ($1, $2, NOW(), 0, NOW(), 0)
|
|
338
338
|
`, [adminUser._id, roleId]);
|
|
339
339
|
if (userRoleResult.rowCount === 0) {
|
|
340
340
|
throw new Error('Failed to create user role');
|
|
341
341
|
}
|
|
342
342
|
const featureResult = isMultiTenant
|
|
343
|
-
? await client.query(`
|
|
344
|
-
INSERT INTO "features" ("_orgId", "name")
|
|
345
|
-
VALUES ($1, 'admin')
|
|
346
|
-
RETURNING "_id"
|
|
343
|
+
? await client.query(`
|
|
344
|
+
INSERT INTO "features" ("_orgId", "name")
|
|
345
|
+
VALUES ($1, 'admin')
|
|
346
|
+
RETURNING "_id"
|
|
347
347
|
`, [metaOrg._id])
|
|
348
|
-
: await client.query(`
|
|
349
|
-
INSERT INTO "features" ("name")
|
|
350
|
-
VALUES ('admin')
|
|
351
|
-
RETURNING "_id"
|
|
348
|
+
: await client.query(`
|
|
349
|
+
INSERT INTO "features" ("name")
|
|
350
|
+
VALUES ('admin')
|
|
351
|
+
RETURNING "_id"
|
|
352
352
|
`);
|
|
353
353
|
if (featureResult.rowCount === 0) {
|
|
354
354
|
throw new Error('Failed to create admin feature');
|
|
355
355
|
}
|
|
356
356
|
const featureId = featureResult.rows[0]._id;
|
|
357
357
|
const authorizationResult = isMultiTenant
|
|
358
|
-
? await client.query(`
|
|
359
|
-
INSERT INTO "authorizations" (
|
|
360
|
-
"_orgId", "roleId", "featureId",
|
|
361
|
-
"_created", "_createdBy", "_updated", "_updatedBy"
|
|
362
|
-
)
|
|
363
|
-
VALUES ($1, $2, $3, NOW(), 0, NOW(), 0)
|
|
358
|
+
? await client.query(`
|
|
359
|
+
INSERT INTO "authorizations" (
|
|
360
|
+
"_orgId", "roleId", "featureId",
|
|
361
|
+
"_created", "_createdBy", "_updated", "_updatedBy"
|
|
362
|
+
)
|
|
363
|
+
VALUES ($1, $2, $3, NOW(), 0, NOW(), 0)
|
|
364
364
|
`, [metaOrg._id, roleId, featureId])
|
|
365
|
-
: await client.query(`
|
|
366
|
-
INSERT INTO "authorizations" (
|
|
367
|
-
"roleId", "featureId",
|
|
368
|
-
"_created", "_createdBy", "_updated", "_updatedBy"
|
|
369
|
-
)
|
|
370
|
-
VALUES ($1, $2, NOW(), 0, NOW(), 0)
|
|
365
|
+
: await client.query(`
|
|
366
|
+
INSERT INTO "authorizations" (
|
|
367
|
+
"roleId", "featureId",
|
|
368
|
+
"_created", "_createdBy", "_updated", "_updatedBy"
|
|
369
|
+
)
|
|
370
|
+
VALUES ($1, $2, NOW(), 0, NOW(), 0)
|
|
371
371
|
`, [roleId, featureId]);
|
|
372
372
|
if (authorizationResult.rowCount === 0) {
|
|
373
373
|
throw new Error('Failed to create admin authorization');
|
|
@@ -394,61 +394,61 @@ export const getPostgresInitialSchema = (config) => {
|
|
|
394
394
|
await client.query('BEGIN');
|
|
395
395
|
try {
|
|
396
396
|
if (isMultiTenant) {
|
|
397
|
-
await client.query(`
|
|
398
|
-
DELETE FROM "authorizations"
|
|
399
|
-
WHERE "_orgId" = $1
|
|
400
|
-
AND "featureId" IN (
|
|
401
|
-
SELECT "_id" FROM "features"
|
|
402
|
-
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
403
|
-
)
|
|
404
|
-
AND "roleId" IN (
|
|
405
|
-
SELECT "_id" FROM "roles"
|
|
406
|
-
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
407
|
-
)
|
|
397
|
+
await client.query(`
|
|
398
|
+
DELETE FROM "authorizations"
|
|
399
|
+
WHERE "_orgId" = $1
|
|
400
|
+
AND "featureId" IN (
|
|
401
|
+
SELECT "_id" FROM "features"
|
|
402
|
+
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
403
|
+
)
|
|
404
|
+
AND "roleId" IN (
|
|
405
|
+
SELECT "_id" FROM "roles"
|
|
406
|
+
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
407
|
+
)
|
|
408
408
|
`, [metaOrg._id]);
|
|
409
|
-
await client.query(`
|
|
410
|
-
DELETE FROM "features"
|
|
411
|
-
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
409
|
+
await client.query(`
|
|
410
|
+
DELETE FROM "features"
|
|
411
|
+
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
412
412
|
`, [metaOrg._id]);
|
|
413
|
-
await client.query(`
|
|
414
|
-
DELETE FROM "user_roles"
|
|
415
|
-
WHERE "_orgId" = $1
|
|
416
|
-
AND "roleId" IN (
|
|
417
|
-
SELECT "_id" FROM "roles"
|
|
418
|
-
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
419
|
-
)
|
|
413
|
+
await client.query(`
|
|
414
|
+
DELETE FROM "user_roles"
|
|
415
|
+
WHERE "_orgId" = $1
|
|
416
|
+
AND "roleId" IN (
|
|
417
|
+
SELECT "_id" FROM "roles"
|
|
418
|
+
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
419
|
+
)
|
|
420
420
|
`, [metaOrg._id]);
|
|
421
|
-
await client.query(`
|
|
422
|
-
DELETE FROM "roles"
|
|
423
|
-
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
421
|
+
await client.query(`
|
|
422
|
+
DELETE FROM "roles"
|
|
423
|
+
WHERE "_orgId" = $1 AND "name" = 'admin'
|
|
424
424
|
`, [metaOrg._id]);
|
|
425
425
|
}
|
|
426
426
|
else {
|
|
427
|
-
await client.query(`
|
|
428
|
-
DELETE FROM "authorizations"
|
|
429
|
-
WHERE "featureId" IN (
|
|
430
|
-
SELECT "_id" FROM "features"
|
|
431
|
-
WHERE "name" = 'admin'
|
|
432
|
-
)
|
|
433
|
-
AND "roleId" IN (
|
|
434
|
-
SELECT "_id" FROM "roles"
|
|
435
|
-
WHERE "name" = 'admin'
|
|
436
|
-
)
|
|
427
|
+
await client.query(`
|
|
428
|
+
DELETE FROM "authorizations"
|
|
429
|
+
WHERE "featureId" IN (
|
|
430
|
+
SELECT "_id" FROM "features"
|
|
431
|
+
WHERE "name" = 'admin'
|
|
432
|
+
)
|
|
433
|
+
AND "roleId" IN (
|
|
434
|
+
SELECT "_id" FROM "roles"
|
|
435
|
+
WHERE "name" = 'admin'
|
|
436
|
+
)
|
|
437
437
|
`);
|
|
438
|
-
await client.query(`
|
|
439
|
-
DELETE FROM "features"
|
|
440
|
-
WHERE "name" = 'admin'
|
|
438
|
+
await client.query(`
|
|
439
|
+
DELETE FROM "features"
|
|
440
|
+
WHERE "name" = 'admin'
|
|
441
441
|
`);
|
|
442
|
-
await client.query(`
|
|
443
|
-
DELETE FROM "user_roles"
|
|
444
|
-
WHERE "roleId" IN (
|
|
445
|
-
SELECT "_id" FROM "roles"
|
|
446
|
-
WHERE "name" = 'admin'
|
|
447
|
-
)
|
|
442
|
+
await client.query(`
|
|
443
|
+
DELETE FROM "user_roles"
|
|
444
|
+
WHERE "roleId" IN (
|
|
445
|
+
SELECT "_id" FROM "roles"
|
|
446
|
+
WHERE "name" = 'admin'
|
|
447
|
+
)
|
|
448
448
|
`);
|
|
449
|
-
await client.query(`
|
|
450
|
-
DELETE FROM "roles"
|
|
451
|
-
WHERE "name" = 'admin'
|
|
449
|
+
await client.query(`
|
|
450
|
+
DELETE FROM "roles"
|
|
451
|
+
WHERE "name" = 'admin'
|
|
452
452
|
`);
|
|
453
453
|
}
|
|
454
454
|
await client.query('COMMIT');
|
|
@@ -68,23 +68,23 @@ export class PostgresDatabase {
|
|
|
68
68
|
}
|
|
69
69
|
async getUserAuthorizations(userId, orgId) {
|
|
70
70
|
const now = new Date();
|
|
71
|
-
let query = `
|
|
72
|
-
SELECT DISTINCT
|
|
73
|
-
ur."userId" as "userId",
|
|
74
|
-
r."name" as "role",
|
|
75
|
-
f."name" as "feature",
|
|
76
|
-
a."config",
|
|
77
|
-
a."_id",
|
|
78
|
-
a."_orgId"
|
|
79
|
-
FROM "user_roles" ur
|
|
80
|
-
INNER JOIN "roles" r ON ur."roleId" = r."_id"
|
|
81
|
-
INNER JOIN "authorizations" a ON r."_id" = a."roleId"
|
|
82
|
-
INNER JOIN "features" f ON a."featureId" = f."_id"
|
|
83
|
-
WHERE ur."userId" = $1
|
|
84
|
-
AND ur."_deleted" IS NULL
|
|
85
|
-
AND a."_deleted" IS NULL
|
|
86
|
-
AND (a."startDate" IS NULL OR a."startDate" <= $2)
|
|
87
|
-
AND (a."endDate" IS NULL OR a."endDate" >= $2)
|
|
71
|
+
let query = `
|
|
72
|
+
SELECT DISTINCT
|
|
73
|
+
ur."userId" as "userId",
|
|
74
|
+
r."name" as "role",
|
|
75
|
+
f."name" as "feature",
|
|
76
|
+
a."config",
|
|
77
|
+
a."_id",
|
|
78
|
+
a."_orgId"
|
|
79
|
+
FROM "user_roles" ur
|
|
80
|
+
INNER JOIN "roles" r ON ur."roleId" = r."_id"
|
|
81
|
+
INNER JOIN "authorizations" a ON r."_id" = a."roleId"
|
|
82
|
+
INNER JOIN "features" f ON a."featureId" = f."_id"
|
|
83
|
+
WHERE ur."userId" = $1
|
|
84
|
+
AND ur."_deleted" IS NULL
|
|
85
|
+
AND a."_deleted" IS NULL
|
|
86
|
+
AND (a."startDate" IS NULL OR a."startDate" <= $2)
|
|
87
|
+
AND (a."endDate" IS NULL OR a."endDate" >= $2)
|
|
88
88
|
`;
|
|
89
89
|
const values = [userId, now];
|
|
90
90
|
if (orgId) {
|