@loomcore/api 0.1.63 → 0.1.65
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.
|
@@ -49,16 +49,16 @@ export const getMongoInitialSchema = (config, emailClient) => {
|
|
|
49
49
|
migrations.push({
|
|
50
50
|
name: '00000000000003_schema-refresh-tokens',
|
|
51
51
|
up: async ({ context: db }) => {
|
|
52
|
-
await db.createCollection('
|
|
53
|
-
await db.collection('
|
|
54
|
-
await db.collection('
|
|
55
|
-
await db.collection('
|
|
52
|
+
await db.createCollection('refresh_tokens');
|
|
53
|
+
await db.collection('refresh_tokens').createIndex({ token: 1 }, { unique: true });
|
|
54
|
+
await db.collection('refresh_tokens').createIndex({ userId: 1 });
|
|
55
|
+
await db.collection('refresh_tokens').createIndex({ deviceId: 1 });
|
|
56
56
|
if (isMultiTenant) {
|
|
57
|
-
await db.collection('
|
|
57
|
+
await db.collection('refresh_tokens').createIndex({ _orgId: 1 });
|
|
58
58
|
}
|
|
59
59
|
},
|
|
60
60
|
down: async ({ context: db }) => {
|
|
61
|
-
await db.collection('
|
|
61
|
+
await db.collection('refresh_tokens').drop();
|
|
62
62
|
}
|
|
63
63
|
});
|
|
64
64
|
if (isAuthEnabled)
|
|
@@ -80,7 +80,7 @@ export const getPostgresInitialSchema = (config, emailClient) => {
|
|
|
80
80
|
up: async ({ context: pool }) => {
|
|
81
81
|
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
82
82
|
await pool.query(`
|
|
83
|
-
CREATE TABLE IF NOT EXISTS "
|
|
83
|
+
CREATE TABLE IF NOT EXISTS "refresh_tokens" (
|
|
84
84
|
"_id" INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
85
85
|
${orgColumnDef}
|
|
86
86
|
"token" VARCHAR(255) NOT NULL,
|
|
@@ -89,17 +89,46 @@ export const getPostgresInitialSchema = (config, emailClient) => {
|
|
|
89
89
|
"expiresOn" BIGINT NOT NULL,
|
|
90
90
|
"created" TIMESTAMPTZ NOT NULL,
|
|
91
91
|
"createdBy" INTEGER NOT NULL,
|
|
92
|
-
CONSTRAINT "
|
|
92
|
+
CONSTRAINT "fk_refresh_tokens_user" FOREIGN KEY ("userId") REFERENCES "users"("_id") ON DELETE CASCADE
|
|
93
93
|
)
|
|
94
94
|
`);
|
|
95
95
|
},
|
|
96
96
|
down: async ({ context: pool }) => {
|
|
97
|
-
await pool.query('DROP TABLE IF EXISTS "
|
|
97
|
+
await pool.query('DROP TABLE IF EXISTS "refresh_tokens"');
|
|
98
98
|
}
|
|
99
99
|
});
|
|
100
100
|
if (isAuthEnabled)
|
|
101
101
|
migrations.push({
|
|
102
|
-
name: '00000000000004_schema-
|
|
102
|
+
name: '00000000000004_schema-password-reset-tokens',
|
|
103
|
+
up: async ({ context: pool }) => {
|
|
104
|
+
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
105
|
+
const uniqueConstraint = isMultiTenant
|
|
106
|
+
? 'CONSTRAINT "uk_passwordResetTokens_email" UNIQUE ("_orgId", "email")'
|
|
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
|
+
)
|
|
123
|
+
`);
|
|
124
|
+
},
|
|
125
|
+
down: async ({ context: pool }) => {
|
|
126
|
+
await pool.query('DROP TABLE IF EXISTS "passwordResetTokens"');
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
if (isAuthEnabled)
|
|
130
|
+
migrations.push({
|
|
131
|
+
name: '00000000000005_schema-roles',
|
|
103
132
|
up: async ({ context: pool }) => {
|
|
104
133
|
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
105
134
|
const uniqueConstraint = isMultiTenant
|
|
@@ -121,7 +150,7 @@ export const getPostgresInitialSchema = (config, emailClient) => {
|
|
|
121
150
|
});
|
|
122
151
|
if (isAuthEnabled)
|
|
123
152
|
migrations.push({
|
|
124
|
-
name: '
|
|
153
|
+
name: '00000000000006_schema-user-roles',
|
|
125
154
|
up: async ({ context: pool }) => {
|
|
126
155
|
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
127
156
|
const uniqueConstraint = isMultiTenant
|
|
@@ -151,7 +180,7 @@ export const getPostgresInitialSchema = (config, emailClient) => {
|
|
|
151
180
|
});
|
|
152
181
|
if (isAuthEnabled)
|
|
153
182
|
migrations.push({
|
|
154
|
-
name: '
|
|
183
|
+
name: '00000000000007_schema-features',
|
|
155
184
|
up: async ({ context: pool }) => {
|
|
156
185
|
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
157
186
|
const uniqueConstraint = isMultiTenant
|
|
@@ -173,7 +202,7 @@ export const getPostgresInitialSchema = (config, emailClient) => {
|
|
|
173
202
|
});
|
|
174
203
|
if (isAuthEnabled)
|
|
175
204
|
migrations.push({
|
|
176
|
-
name: '
|
|
205
|
+
name: '00000000000008_schema-authorizations',
|
|
177
206
|
up: async ({ context: pool }) => {
|
|
178
207
|
const orgColumnDef = isMultiTenant ? '"_orgId" INTEGER,' : '';
|
|
179
208
|
const uniqueConstraint = isMultiTenant
|
|
@@ -206,7 +235,7 @@ export const getPostgresInitialSchema = (config, emailClient) => {
|
|
|
206
235
|
});
|
|
207
236
|
if (isMultiTenant) {
|
|
208
237
|
migrations.push({
|
|
209
|
-
name: '
|
|
238
|
+
name: '00000000000009_data-meta-org',
|
|
210
239
|
up: async ({ context: pool }) => {
|
|
211
240
|
const result = await pool.query(`
|
|
212
241
|
INSERT INTO "organizations" ("name", "code", "status", "isMetaOrg", "_created", "_createdBy", "_updated", "_updatedBy")
|
|
@@ -225,7 +254,7 @@ export const getPostgresInitialSchema = (config, emailClient) => {
|
|
|
225
254
|
}
|
|
226
255
|
if (isAuthEnabled) {
|
|
227
256
|
migrations.push({
|
|
228
|
-
name: '
|
|
257
|
+
name: '00000000000010_data-admin-user',
|
|
229
258
|
up: async ({ context: pool }) => {
|
|
230
259
|
const client = await pool.connect();
|
|
231
260
|
try {
|
|
@@ -233,7 +262,7 @@ export const getPostgresInitialSchema = (config, emailClient) => {
|
|
|
233
262
|
const authService = new AuthService(database, emailClient);
|
|
234
263
|
if (!isSystemUserContextInitialized()) {
|
|
235
264
|
const errorMessage = isMultiTenant
|
|
236
|
-
? 'SystemUserContext has not been initialized. The meta-org migration (
|
|
265
|
+
? 'SystemUserContext has not been initialized. The meta-org migration (00000000000009_data-meta-org) should have run before this migration. ' +
|
|
237
266
|
'This migration only runs if config.app.metaOrgName and config.app.metaOrgCode are provided. ' +
|
|
238
267
|
'Please ensure both values are set in your config.'
|
|
239
268
|
: 'BUG: SystemUserContext has not been initialized. For non-multi-tenant setups, SystemUserContext should be initialized before migrations run.';
|
|
@@ -266,7 +295,7 @@ export const getPostgresInitialSchema = (config, emailClient) => {
|
|
|
266
295
|
}
|
|
267
296
|
if (config.auth) {
|
|
268
297
|
migrations.push({
|
|
269
|
-
name: '
|
|
298
|
+
name: '00000000000011_data-admin-authorizations',
|
|
270
299
|
up: async ({ context: pool }) => {
|
|
271
300
|
const client = await pool.connect();
|
|
272
301
|
try {
|
|
@@ -20,7 +20,7 @@ export class AuthService extends MultiTenantApiService {
|
|
|
20
20
|
authConfig;
|
|
21
21
|
constructor(database, emailClient) {
|
|
22
22
|
super(database, 'users', 'user', UserSpec);
|
|
23
|
-
this.refreshTokenService = new GenericApiService(database, '
|
|
23
|
+
this.refreshTokenService = new GenericApiService(database, 'refresh_tokens', 'refresh_token', refreshTokenModelSpec);
|
|
24
24
|
this.passwordResetTokenService = new PasswordResetTokenService(database);
|
|
25
25
|
this.emailService = new EmailService(emailClient);
|
|
26
26
|
this.organizationService = new OrganizationService(database);
|
|
@@ -3,7 +3,7 @@ import { EmptyUserContext, PasswordResetTokenSpec } from '@loomcore/common/model
|
|
|
3
3
|
import { GenericApiService } from './generic-api-service/generic-api.service.js';
|
|
4
4
|
export class PasswordResetTokenService extends GenericApiService {
|
|
5
5
|
constructor(database) {
|
|
6
|
-
super(database, '
|
|
6
|
+
super(database, 'password_reset_tokens', 'password_reset_token', PasswordResetTokenSpec);
|
|
7
7
|
}
|
|
8
8
|
async createPasswordResetToken(email, expiresOn) {
|
|
9
9
|
const lowerCaseEmail = email.toLowerCase();
|