@nextsparkjs/core 0.1.0-beta.166 → 0.1.0-beta.168
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hooks/useAuth.d.ts +2 -1
- package/dist/hooks/useAuth.d.ts.map +1 -1
- package/dist/hooks/useAuth.js +13 -8
- package/dist/lib/api/entity/generic-handler.d.ts.map +1 -1
- package/dist/lib/api/entity/generic-handler.js +23 -3
- package/dist/lib/auth-context.d.ts +5 -0
- package/dist/lib/auth-context.d.ts.map +1 -1
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js +28 -5
- package/dist/lib/config/app.config.d.ts.map +1 -1
- package/dist/lib/config/app.config.js +9 -1
- package/dist/lib/config/types.d.ts +17 -0
- package/dist/lib/config/types.d.ts.map +1 -1
- package/dist/lib/db.d.ts +28 -5
- package/dist/lib/db.d.ts.map +1 -1
- package/dist/lib/db.js +38 -16
- package/dist/lib/entities/types.d.ts +20 -3
- package/dist/lib/entities/types.d.ts.map +1 -1
- package/dist/lib/services/team-member.service.d.ts.map +1 -1
- package/dist/lib/services/team-member.service.js +2 -1
- package/dist/lib/services/team.service.d.ts.map +1 -1
- package/dist/lib/services/team.service.js +2 -2
- package/dist/lib/teams/actions.d.ts.map +1 -1
- package/dist/lib/teams/actions.js +4 -3
- package/dist/migrations/001_better_auth_and_functions.sql +70 -0
- package/dist/migrations/002_auth_tables.sql +90 -10
- package/dist/migrations/007_teams_table.sql +10 -4
- package/dist/migrations/008_team_members_table.sql +1 -1
- package/dist/migrations/009_team_invitations_table.sql +1 -1
- package/dist/migrations/010_teams_functions_triggers.sql +6 -48
- package/dist/migrations/013_billing_subscriptions.sql +61 -31
- package/dist/migrations/016_billing_events.sql +17 -3
- package/dist/migrations/017_scheduled_actions_table.sql +9 -7
- package/dist/migrations/022_rls_runtime_roles.sql +87 -0
- package/dist/styles/classes.json +1 -1
- package/dist/templates/app/api/auth/[...all]/route.ts +14 -1
- package/migrations/001_better_auth_and_functions.sql +70 -0
- package/migrations/002_auth_tables.sql +90 -10
- package/migrations/007_teams_table.sql +10 -4
- package/migrations/008_team_members_table.sql +1 -1
- package/migrations/009_team_invitations_table.sql +1 -1
- package/migrations/010_teams_functions_triggers.sql +6 -48
- package/migrations/013_billing_subscriptions.sql +61 -31
- package/migrations/016_billing_events.sql +17 -3
- package/migrations/017_scheduled_actions_table.sql +9 -7
- package/migrations/022_rls_runtime_roles.sql +87 -0
- package/package.json +2 -2
- package/scripts/db/run-migrations.mjs +13 -2
- package/templates/app/api/auth/[...all]/route.ts +14 -1
- package/templates/next.config.mjs +1 -4
package/dist/hooks/useAuth.d.ts
CHANGED
|
@@ -41,11 +41,12 @@ export declare function useAuth(): {
|
|
|
41
41
|
updatedAt: Date;
|
|
42
42
|
};
|
|
43
43
|
}>;
|
|
44
|
-
signUp: ({ email, password, firstName, lastName }: {
|
|
44
|
+
signUp: ({ email, password, firstName, lastName, intent }: {
|
|
45
45
|
email: string;
|
|
46
46
|
password: string;
|
|
47
47
|
firstName?: string;
|
|
48
48
|
lastName?: string;
|
|
49
|
+
intent?: string;
|
|
49
50
|
}) => Promise<NonNullable<{
|
|
50
51
|
token: null;
|
|
51
52
|
user: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAuth.d.ts","sourceRoot":"","sources":["../../src/hooks/useAuth.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAS9C,wBAAgB,OAAO;
|
|
1
|
+
{"version":3,"file":"useAuth.d.ts","sourceRoot":"","sources":["../../src/hooks/useAuth.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAS9C,wBAAgB,OAAO;UAuMS,WAAW,GAAG,IAAI;;;;;;;;;;;;;;;;;;;;;;;8CAjMa;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;;+DAmBvC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;;;;gCAkC1H,MAAM;2BAYX,MAAM;;;;;;;;;;;kCA6BC,MAAM,UAAU,MAAM;;;;;;;;;;;sCAwClB,MAAM,eAAe,MAAM;;;;;;;;;;;;;;;;;;;;qCA8B5B,MAAM;;;;;;;;;;;;;;;EA6C3D"}
|
package/dist/hooks/useAuth.js
CHANGED
|
@@ -23,14 +23,19 @@ function useAuth() {
|
|
|
23
23
|
}
|
|
24
24
|
return data;
|
|
25
25
|
};
|
|
26
|
-
const handleSignUp = async ({ email, password, firstName, lastName }) => {
|
|
27
|
-
const { data, error } = await authClient.signUp.email(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
const handleSignUp = async ({ email, password, firstName, lastName, intent }) => {
|
|
27
|
+
const { data, error } = await authClient.signUp.email(
|
|
28
|
+
{
|
|
29
|
+
email,
|
|
30
|
+
password,
|
|
31
|
+
name: `${firstName || ""} ${lastName || ""}`.trim() || email.split("@")[0],
|
|
32
|
+
firstName,
|
|
33
|
+
lastName
|
|
34
|
+
},
|
|
35
|
+
// Optional signup intent, sent as the `x-signup-intent` header. The signup
|
|
36
|
+
// route maps it to an initial team role (AUTH_CONFIG.signupIntent).
|
|
37
|
+
intent ? { headers: { "x-signup-intent": intent } } : void 0
|
|
38
|
+
);
|
|
34
39
|
if (error) {
|
|
35
40
|
throw new Error(error.message || "Failed to create account");
|
|
36
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generic-handler.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/entity/generic-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"generic-handler.d.ts","sourceRoot":"","sources":["../../../../src/lib/api/entity/generic-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AA8iBvD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAugBnF;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAmZrF;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CA0MpJ;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAyXtJ;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAoJtJ;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAEtF"}
|
|
@@ -208,9 +208,13 @@ async function resolveOwnershipFilter(entityConfig, userId, teamId, isBypass, au
|
|
|
208
208
|
if (!ownershipFilter.roles.includes(userRole)) {
|
|
209
209
|
return { applies: false };
|
|
210
210
|
}
|
|
211
|
-
|
|
211
|
+
if (!ownershipFilter.linkedBy) {
|
|
212
|
+
return { applies: true, field: ownershipFilter.field, value: userId };
|
|
213
|
+
}
|
|
214
|
+
const { table, userField, valueField, softDelete } = ownershipFilter.linkedBy;
|
|
215
|
+
const softDeleteClause = softDelete === false ? "" : ' AND "deletedAt" IS NULL';
|
|
212
216
|
const linkedRow = await queryOneWithRLS(
|
|
213
|
-
`SELECT "${valueField}" FROM "${table}" WHERE "${userField}" = $1 AND "teamId" = $2
|
|
217
|
+
`SELECT "${valueField}" FROM "${table}" WHERE "${userField}" = $1 AND "teamId" = $2${softDeleteClause}`,
|
|
214
218
|
[userId, teamId],
|
|
215
219
|
userId
|
|
216
220
|
);
|
|
@@ -232,7 +236,15 @@ async function checkSessionPermission(authResult, entitySlug, action, teamId, re
|
|
|
232
236
|
);
|
|
233
237
|
return addCorsHeaders(response, request);
|
|
234
238
|
}
|
|
235
|
-
} catch {
|
|
239
|
+
} catch (error) {
|
|
240
|
+
console.error(`[GenericHandler] Permission check errored for ${entitySlug}.${action}:`, error);
|
|
241
|
+
const response = createApiError(
|
|
242
|
+
`Permission check failed for ${entitySlug}.${action}`,
|
|
243
|
+
500,
|
|
244
|
+
void 0,
|
|
245
|
+
"PERMISSION_CHECK_FAILED"
|
|
246
|
+
);
|
|
247
|
+
return addCorsHeaders(response, request);
|
|
236
248
|
}
|
|
237
249
|
return null;
|
|
238
250
|
}
|
|
@@ -317,6 +329,10 @@ async function handleGenericList(request) {
|
|
|
317
329
|
}
|
|
318
330
|
teamId = teamValidation.teamId;
|
|
319
331
|
isBypass = teamValidation.isBypass;
|
|
332
|
+
if (!isBypass && teamId) {
|
|
333
|
+
const permDenied = await checkSessionPermission(authResult, resolution.entityConfig.slug, "list", teamId, request);
|
|
334
|
+
if (permDenied) return permDenied;
|
|
335
|
+
}
|
|
320
336
|
}
|
|
321
337
|
const pagination = parsePaginationParams(request);
|
|
322
338
|
const metaParams = parseMetaParams(request);
|
|
@@ -921,6 +937,10 @@ async function handleGenericRead(request, { params }) {
|
|
|
921
937
|
}
|
|
922
938
|
teamId = teamValidation.teamId;
|
|
923
939
|
isBypass = teamValidation.isBypass;
|
|
940
|
+
if (!isBypass && teamId) {
|
|
941
|
+
const permDenied = await checkSessionPermission(authResult, resolution.entityConfig.slug, "read", teamId, request);
|
|
942
|
+
if (permDenied) return permDenied;
|
|
943
|
+
}
|
|
924
944
|
}
|
|
925
945
|
const entityConfig = resolution.entityConfig;
|
|
926
946
|
const tableName = getTableName(entityConfig);
|
|
@@ -30,6 +30,11 @@ export interface SignupContext {
|
|
|
30
30
|
* Should create the global work team.
|
|
31
31
|
*/
|
|
32
32
|
isFirstUserSingleTenant?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Optional signup intent for the current request. The user.create hook maps it
|
|
35
|
+
* to an initial team role via AUTH_CONFIG.signupIntent.
|
|
36
|
+
*/
|
|
37
|
+
signupIntent?: string;
|
|
33
38
|
}
|
|
34
39
|
/**
|
|
35
40
|
* AsyncLocalStorage instance for signup context
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-context.d.ts","sourceRoot":"","sources":["../../src/lib/auth-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAE/C;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAE1B;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB;;;OAGG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"auth-context.d.ts","sourceRoot":"","sources":["../../src/lib/auth-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAE/C;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAE1B;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB;;;OAGG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAA;IAEjC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,eAAO,MAAM,oBAAoB,kCAAyC,CAAA;AAE1E;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,GAAG,SAAS,CAE5D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAGhD;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,OAAO,EAAE,aAAa,EACtB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAEZ"}
|
package/dist/lib/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAWA,OAAO,EAAgF,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/auth.js
CHANGED
|
@@ -13,16 +13,17 @@ import { I18N_CONFIG, USER_ROLES_CONFIG, TEAMS_CONFIG, AUTH_CONFIG, APP_CONFIG_M
|
|
|
13
13
|
import { getUserFlags } from "./services/user-flags.service.js";
|
|
14
14
|
import { TeamService } from "./services/team.service.js";
|
|
15
15
|
import { TeamMemberService } from "./services/team-member.service.js";
|
|
16
|
-
import { shouldSkipTeamCreation } from "./auth-context.js";
|
|
16
|
+
import { shouldSkipTeamCreation, getSignupContext } from "./auth-context.js";
|
|
17
17
|
import { isDomainAllowed } from "./auth/registration-helpers.js";
|
|
18
18
|
import { registrationGuardPlugin } from "./auth/registration-guard-plugin.js";
|
|
19
19
|
import { getCorsOrigins } from "./utils/cors.js";
|
|
20
20
|
const isProd = process.env.NODE_ENV === "production";
|
|
21
21
|
const baseUrl = process.env.BETTER_AUTH_URL || process.env.NEXT_PUBLIC_APP_URL || "http://localhost:5173";
|
|
22
22
|
const emailService = EmailFactory.create();
|
|
23
|
-
const databaseUrl = process.env.DATABASE_URL;
|
|
23
|
+
const databaseUrl = process.env.DATABASE_SERVICE_URL || process.env.DATABASE_URL;
|
|
24
24
|
const cleanUrl = stripSSLParams(databaseUrl);
|
|
25
|
-
const
|
|
25
|
+
const isPoolerUrl = /:6543(\/|$|\?)/.test(databaseUrl) || /pooler/i.test(databaseUrl);
|
|
26
|
+
const connectionString = isPoolerUrl ? cleanUrl.includes("?") ? `${cleanUrl}&pgbouncer=true` : `${cleanUrl}?pgbouncer=true` : cleanUrl;
|
|
26
27
|
const pool = new Pool({
|
|
27
28
|
connectionString,
|
|
28
29
|
ssl: parseSSLConfig(databaseUrl),
|
|
@@ -30,6 +31,26 @@ const pool = new Pool({
|
|
|
30
31
|
idleTimeoutMillis: 3e4,
|
|
31
32
|
max: 20
|
|
32
33
|
});
|
|
34
|
+
async function applySignupIntentRole(user, teamId) {
|
|
35
|
+
var _a, _b, _c;
|
|
36
|
+
const cfg = AUTH_CONFIG.signupIntent;
|
|
37
|
+
if (!(cfg == null ? void 0 : cfg.enabled)) return;
|
|
38
|
+
const intent = (_a = getSignupContext()) == null ? void 0 : _a.signupIntent;
|
|
39
|
+
if (!intent) return;
|
|
40
|
+
const mappedRole = (_b = cfg.roleMap) == null ? void 0 : _b[intent];
|
|
41
|
+
if (!mappedRole) return;
|
|
42
|
+
const validTeamRoles = ((_c = APP_CONFIG_MERGED.teamRoles) == null ? void 0 : _c.availableTeamRoles) ?? [];
|
|
43
|
+
if (!validTeamRoles.includes(mappedRole) || mappedRole === "owner") return;
|
|
44
|
+
try {
|
|
45
|
+
await pool.query(
|
|
46
|
+
`UPDATE "team_members" SET role = $1, "updatedAt" = NOW() WHERE "teamId" = $2 AND "userId" = $3`,
|
|
47
|
+
[mappedRole, teamId, user.id]
|
|
48
|
+
);
|
|
49
|
+
console.log(`[Teams] Applied signup intent '${intent}' -> role '${mappedRole}' for user ${user.id} on team ${teamId}`);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.error(`[Teams] Failed to apply signup intent role for user ${user.id}:`, error);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
33
54
|
const auth = betterAuth({
|
|
34
55
|
database: pool,
|
|
35
56
|
secret: process.env.BETTER_AUTH_SECRET,
|
|
@@ -241,10 +262,12 @@ const auth = betterAuth({
|
|
|
241
262
|
const teamsMode = TEAMS_CONFIG.mode;
|
|
242
263
|
switch (teamsMode) {
|
|
243
264
|
case "single-user":
|
|
244
|
-
case "multi-tenant":
|
|
245
|
-
await TeamService.create(user.id);
|
|
265
|
+
case "multi-tenant": {
|
|
266
|
+
const createdTeam = await TeamService.create(user.id);
|
|
246
267
|
console.log(`[Teams] Team created for user ${user.id} (mode: ${teamsMode})`);
|
|
268
|
+
await applySignupIntentRole(user, createdTeam.id);
|
|
247
269
|
break;
|
|
270
|
+
}
|
|
248
271
|
case "single-tenant":
|
|
249
272
|
const existingTeam = await TeamService.getGlobal();
|
|
250
273
|
if (!existingTeam) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.config.d.ts","sourceRoot":"","sources":["../../../src/lib/config/app.config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAMxC,eAAO,MAAM,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"app.config.d.ts","sourceRoot":"","sources":["../../../src/lib/config/app.config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAMxC,eAAO,MAAM,kBAAkB,EAAE,SA2ehC,CAAA"}
|
|
@@ -375,7 +375,15 @@ const DEFAULT_APP_CONFIG = {
|
|
|
375
375
|
* token, claim-account flow). The `sendVerificationEmail` function
|
|
376
376
|
* remains exported and can still be called explicitly when needed.
|
|
377
377
|
*/
|
|
378
|
-
sendVerificationEmailOnSignup: true
|
|
378
|
+
sendVerificationEmailOnSignup: true,
|
|
379
|
+
/**
|
|
380
|
+
* Signup intent → initial team role mapping. Disabled by default; an app
|
|
381
|
+
* enables it and maps intent values to team roles in its app.config.ts.
|
|
382
|
+
*/
|
|
383
|
+
signupIntent: {
|
|
384
|
+
enabled: false,
|
|
385
|
+
roleMap: {}
|
|
386
|
+
}
|
|
379
387
|
},
|
|
380
388
|
// =============================================================================
|
|
381
389
|
// MOBILE NAVIGATION CONFIGURATION
|
|
@@ -357,6 +357,21 @@ export interface AuthProvidersConfig {
|
|
|
357
357
|
* Controls authentication behavior including registration modes
|
|
358
358
|
* and provider visibility. Configured at theme level.
|
|
359
359
|
*/
|
|
360
|
+
/**
|
|
361
|
+
* Signup intent → initial team role mapping.
|
|
362
|
+
*
|
|
363
|
+
* When enabled, a signup request can carry an intent (the `x-signup-intent`
|
|
364
|
+
* header). After the user's team is auto-created, the intent is looked up in
|
|
365
|
+
* `roleMap`; if it names a configured team role, the user's membership in that
|
|
366
|
+
* team is set to that role. The mapping is app-controlled: only `roleMap` entries
|
|
367
|
+
* that name a configured team role take effect.
|
|
368
|
+
*/
|
|
369
|
+
export interface SignupIntentConfig {
|
|
370
|
+
/** Accept the `intent` field at signup and apply the role mapping. Default: false. */
|
|
371
|
+
enabled?: boolean;
|
|
372
|
+
/** intent value → initial team_member role (must be a configured team role). */
|
|
373
|
+
roleMap?: Record<string, string>;
|
|
374
|
+
}
|
|
360
375
|
export interface AuthConfig {
|
|
361
376
|
/** Registration settings */
|
|
362
377
|
registration: AuthRegistrationConfig;
|
|
@@ -378,6 +393,8 @@ export interface AuthConfig {
|
|
|
378
393
|
* link-based verification explicitly when they need to.
|
|
379
394
|
*/
|
|
380
395
|
sendVerificationEmailOnSignup?: boolean;
|
|
396
|
+
/** Map a signup `intent` to the initial team role of the user's auto-created team. */
|
|
397
|
+
signupIntent?: SignupIntentConfig;
|
|
381
398
|
}
|
|
382
399
|
/**
|
|
383
400
|
* Public Auth Config
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/config/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE1C;;;;GAIG;AACH,MAAM,MAAM,SAAS,GACjB,aAAa,GACb,eAAe,GACf,cAAc,CAAA;AAElB;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC/B,+BAA+B;IAC/B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,qCAAqC;IACrC,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,iBAAiB;IACjB,IAAI,EAAE,SAAS,CAAA;IACf,yBAAyB;IACzB,OAAO,CAAC,EAAE,kBAAkB,CAAA;CAC7B;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAA;IAEV,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAA;IAEhB,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAA;IAEb,kCAAkC;IAClC,IAAI,EAAE,QAAQ,CAAA;IAEd,2DAA2D;IAC3D,OAAO,EAAE,OAAO,CAAA;IAEhB,uEAAuE;IACvE,SAAS,CAAC,EAAE,OAAO,CAAA;IAEnB,8CAA8C;IAC9C,MAAM,CAAC,EAAE,aAAa,GAAG,WAAW,CAAA;CACrC;AAED;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,gDAAgD;IAChD,EAAE,EAAE,MAAM,CAAA;IAEV,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAA;IAEhB,sBAAsB;IACtB,IAAI,EAAE,MAAM,CAAA;IAEZ,kCAAkC;IAClC,IAAI,EAAE,QAAQ,CAAA;IAEd,2DAA2D;IAC3D,OAAO,EAAE,OAAO,CAAA;IAEhB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAElB;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,kCAAkC;IAClC,KAAK,EAAE,aAAa,EAAE,CAAA;IAEtB,8CAA8C;IAC9C,cAAc,EAAE,iBAAiB,EAAE,CAAA;CACpC;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE;QACR,WAAW,EAAE,OAAO,CAAA;QACpB,MAAM,EAAE,OAAO,CAAA;QACf,aAAa,EAAE,OAAO,CAAA;QACtB,IAAI,EAAE,OAAO,CAAA;QACb,KAAK,EAAE,OAAO,CAAA;QACd,KAAK,EAAE,OAAO,CAAA;QACd,QAAQ,EAAE,OAAO,CAAA;KAClB,CAAA;CACF;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE;QACL,OAAO,EAAE,kBAAkB,CAAA;QAC3B,OAAO,EAAE,kBAAkB,CAAA;QAC3B,OAAO,EAAE,kBAAkB,CAAA;QAC3B,QAAQ,EAAE,kBAAkB,CAAA;KAC7B,CAAA;CACF;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,6DAA6D;IAC7D,OAAO,EAAE,OAAO,CAAA;IAEhB,uEAAuE;IACvE,IAAI,CAAC,EAAE,OAAO,CAAA;IAEd,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,UAAU;IACzB,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAA;IAEhB,kEAAkE;IAClE,YAAY,CAAC,EAAE,OAAO,CAAA;IAEtB,iDAAiD;IACjD,aAAa,EAAE,OAAO,CAAA;IAEtB,yDAAyD;IACzD,WAAW,EAAE,OAAO,CAAA;IAEpB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,kBAAkB,CAAA;IAE3B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,kBAAkB,CAAA;CAChC;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,EAAE,EAAE,MAAM,CAAA;IAEV,2BAA2B;IAC3B,KAAK,EAAE,MAAM,CAAA;IAEb,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAA;IAEZ,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAA;IAEhB,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4CAA4C;IAC5C,OAAO,EAAE,OAAO,CAAA;IAEhB,mDAAmD;IACnD,KAAK,EAAE,cAAc,EAAE,CAAA;CACxB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,aAAa,EAAE,SAAS,MAAM,EAAE,CAAA;IAEhC,wCAAwC;IACxC,eAAe,EAAE,MAAM,CAAA;IAEvB,+BAA+B;IAC/B,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAA;IAErC,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEjC,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAEpC,wBAAwB;IACxB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACrC;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAA;IAEd,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAA;IAEpB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IAEnB,uCAAuC;IACvC,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,8BAA8B;IAC9B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAA;IAEhD,gEAAgE;IAChE,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,sBAAsB;IACrC,8CAA8C;IAC9C,OAAO,EAAE,OAAO,CAAA;IAEhB,4DAA4D;IAC5D,aAAa,EAAE,MAAM,CAAA;IAErB,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAA;IAEjB,iDAAiD;IACjD,cAAc,EAAE,MAAM,CAAA;IAEtB;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAEzB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IAEnB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,cAAc,CAAA;IAEzB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE;QACd,qFAAqF;QACrF,aAAa,EAAE,MAAM,CAAA;KACtB,CAAA;CACF;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,wDAAwD;IACxD,SAAS,EAAE,MAAM,CAAA;IACjB,0GAA0G;IAC1G,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,0GAA0G;IAC1G,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,oFAAoF;IACpF,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,qEAAqE;IACrE,gBAAgB,EAAE,MAAM,EAAE,CAAA;CAC3B;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,mBAAmB,GAAG,aAAa,GAAG,iBAAiB,CAAA;AAE/F;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,wBAAwB;IACxB,IAAI,EAAE,gBAAgB,CAAA;IAEtB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE;QACP;;;WAGG;QACH,OAAO,CAAC,EAAE,OAAO,CAAA;KAClB,CAAA;CACF;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,4BAA4B;IAC5B,YAAY,EAAE,sBAAsB,CAAA;IAEpC,8BAA8B;IAC9B,SAAS,CAAC,EAAE,mBAAmB,CAAA;IAE/B;;;;;;;;;;;;;;OAcG;IACH,6BAA6B,CAAC,EAAE,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/config/types.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/db.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export declare function parseSSLConfig(databaseUrl: string): false | {
|
|
|
22
22
|
rejectUnauthorized: boolean;
|
|
23
23
|
};
|
|
24
24
|
declare const pool: Pool;
|
|
25
|
+
declare const servicePool: Pool;
|
|
25
26
|
/**
|
|
26
27
|
* Validate userId format to prevent SQL injection in SET LOCAL commands
|
|
27
28
|
*
|
|
@@ -43,6 +44,10 @@ declare const pool: Pool;
|
|
|
43
44
|
* @internal Exported for testing only
|
|
44
45
|
*/
|
|
45
46
|
export declare function validateUserId(userId: string): void;
|
|
47
|
+
export interface RLSOptions {
|
|
48
|
+
/** Force the service (RLS-bypass) pool even if a userId is provided. */
|
|
49
|
+
service?: boolean;
|
|
50
|
+
}
|
|
46
51
|
/**
|
|
47
52
|
* Execute a query with RLS context
|
|
48
53
|
* Sets the current user ID for Row Level Security policies via app.user_id
|
|
@@ -52,17 +57,17 @@ export declare function validateUserId(userId: string): void;
|
|
|
52
57
|
* @param userId - User ID for RLS context (optional - if not provided, runs without RLS context)
|
|
53
58
|
* @returns Query result rows
|
|
54
59
|
*/
|
|
55
|
-
export declare function queryWithRLS<T = unknown>(query: string, params?: unknown[], userId?: string | null): Promise<T[]>;
|
|
60
|
+
export declare function queryWithRLS<T = unknown>(query: string, params?: unknown[], userId?: string | null, options?: RLSOptions): Promise<T[]>;
|
|
56
61
|
/**
|
|
57
62
|
* Execute a single query and return the first row
|
|
58
63
|
* Useful for queries that return a single result
|
|
59
64
|
*/
|
|
60
|
-
export declare function queryOneWithRLS<T = unknown>(query: string, params?: unknown[], userId?: string | null): Promise<T | null>;
|
|
65
|
+
export declare function queryOneWithRLS<T = unknown>(query: string, params?: unknown[], userId?: string | null, options?: RLSOptions): Promise<T | null>;
|
|
61
66
|
/**
|
|
62
67
|
* Execute a mutation (INSERT, UPDATE, DELETE) with RLS context
|
|
63
68
|
* Returns the affected rows
|
|
64
69
|
*/
|
|
65
|
-
export declare function mutateWithRLS<T = unknown>(query: string, params?: unknown[], userId?: string | null): Promise<{
|
|
70
|
+
export declare function mutateWithRLS<T = unknown>(query: string, params?: unknown[], userId?: string | null, options?: RLSOptions): Promise<{
|
|
66
71
|
rows: T[];
|
|
67
72
|
rowCount: number;
|
|
68
73
|
}>;
|
|
@@ -81,7 +86,25 @@ export declare function mutateWithRLS<T = unknown>(query: string, params?: unkno
|
|
|
81
86
|
* throw error;
|
|
82
87
|
* }
|
|
83
88
|
*/
|
|
84
|
-
export declare function getTransactionClient(userId?: string | null): Promise<{
|
|
89
|
+
export declare function getTransactionClient(userId?: string | null, options?: RLSOptions): Promise<{
|
|
90
|
+
query: <T = unknown>(query: string, params?: unknown[]) => Promise<T[]>;
|
|
91
|
+
queryOne: <T = unknown>(query: string, params?: unknown[]) => Promise<T>;
|
|
92
|
+
mutate: <T = unknown>(query: string, params?: unknown[]) => Promise<{
|
|
93
|
+
rows: T[];
|
|
94
|
+
rowCount: number;
|
|
95
|
+
}>;
|
|
96
|
+
commit: () => Promise<void>;
|
|
97
|
+
rollback: () => Promise<void>;
|
|
98
|
+
}>;
|
|
99
|
+
/**
|
|
100
|
+
* Get a transaction client on the SERVICE (RLS-bypass) pool.
|
|
101
|
+
*
|
|
102
|
+
* Use for privileged system bootstraps that carry a userId but must bypass RLS
|
|
103
|
+
* because they create the FIRST membership/subscription of a brand-new team
|
|
104
|
+
* (which no membership-based policy can satisfy). Authorization for these
|
|
105
|
+
* operations is enforced at the API/action layer, not by RLS.
|
|
106
|
+
*/
|
|
107
|
+
export declare function getServiceTransactionClient(): Promise<{
|
|
85
108
|
query: <T = unknown>(query: string, params?: unknown[]) => Promise<T[]>;
|
|
86
109
|
queryOne: <T = unknown>(query: string, params?: unknown[]) => Promise<T>;
|
|
87
110
|
mutate: <T = unknown>(query: string, params?: unknown[]) => Promise<{
|
|
@@ -113,7 +136,7 @@ export declare function queryRows<T = unknown>(text: string, params?: unknown[])
|
|
|
113
136
|
* Useful for queries that return a single result
|
|
114
137
|
*/
|
|
115
138
|
export declare function queryOne<T = unknown>(text: string, params?: unknown[]): Promise<T | null>;
|
|
116
|
-
export { pool };
|
|
139
|
+
export { pool, servicePool };
|
|
117
140
|
/**
|
|
118
141
|
* Get the shared database pool
|
|
119
142
|
* Use this instead of creating new Pool instances
|
package/dist/lib/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/lib/db.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,IAAI,CAAC;AAQ3C;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAe1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,KAAK,GAAG;IAAE,kBAAkB,EAAE,OAAO,CAAA;CAAE,CAiD3F;AAQD,QAAA,MAAM,IAAI,MAMR,CAAC;
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/lib/db.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/db.js
CHANGED
|
@@ -58,6 +58,14 @@ const pool = new Pool({
|
|
|
58
58
|
idleTimeoutMillis: 3e4,
|
|
59
59
|
connectionTimeoutMillis: 1e4
|
|
60
60
|
});
|
|
61
|
+
const serviceDatabaseUrl = process.env.DATABASE_SERVICE_URL || databaseUrl;
|
|
62
|
+
const servicePool = serviceDatabaseUrl === databaseUrl ? pool : new Pool({
|
|
63
|
+
connectionString: stripSSLParams(serviceDatabaseUrl),
|
|
64
|
+
ssl: parseSSLConfig(serviceDatabaseUrl),
|
|
65
|
+
max: 20,
|
|
66
|
+
idleTimeoutMillis: 3e4,
|
|
67
|
+
connectionTimeoutMillis: 1e4
|
|
68
|
+
});
|
|
61
69
|
function validateUserId(userId) {
|
|
62
70
|
const isProduction = process.env.NODE_ENV === "production";
|
|
63
71
|
if (userId.includes("'") || userId.includes('"') || userId.includes("\\") || userId.includes(";")) {
|
|
@@ -73,23 +81,27 @@ function validateUserId(userId) {
|
|
|
73
81
|
throw new Error("Invalid userId format - must be valid UUID or alphanumeric");
|
|
74
82
|
}
|
|
75
83
|
}
|
|
76
|
-
async function acquireClient() {
|
|
84
|
+
async function acquireClient(useService = false) {
|
|
77
85
|
if (isShuttingDown) {
|
|
78
86
|
throw new Error("Database pool is shutting down. Cannot acquire new connections.");
|
|
79
87
|
}
|
|
80
|
-
const client = await pool.connect();
|
|
88
|
+
const client = await (useService ? servicePool : pool).connect();
|
|
81
89
|
activeConnections++;
|
|
82
90
|
return client;
|
|
83
91
|
}
|
|
92
|
+
function shouldUseService(userId, options) {
|
|
93
|
+
return (options == null ? void 0 : options.service) === true || !userId;
|
|
94
|
+
}
|
|
84
95
|
function releaseClient(client) {
|
|
85
96
|
activeConnections = Math.max(0, activeConnections - 1);
|
|
86
97
|
client.release();
|
|
87
98
|
}
|
|
88
|
-
async function queryWithRLS(query2, params = [], userId) {
|
|
89
|
-
const
|
|
99
|
+
async function queryWithRLS(query2, params = [], userId, options) {
|
|
100
|
+
const useService = shouldUseService(userId, options);
|
|
101
|
+
const client = await acquireClient(useService);
|
|
90
102
|
try {
|
|
91
103
|
await client.query("BEGIN");
|
|
92
|
-
if (userId) {
|
|
104
|
+
if (userId && !useService) {
|
|
93
105
|
validateUserId(userId);
|
|
94
106
|
await client.query(`SET LOCAL app.user_id = '${userId.replace(/'/g, "''")}'`);
|
|
95
107
|
}
|
|
@@ -103,15 +115,16 @@ async function queryWithRLS(query2, params = [], userId) {
|
|
|
103
115
|
releaseClient(client);
|
|
104
116
|
}
|
|
105
117
|
}
|
|
106
|
-
async function queryOneWithRLS(query2, params = [], userId) {
|
|
107
|
-
const rows = await queryWithRLS(query2, params, userId);
|
|
118
|
+
async function queryOneWithRLS(query2, params = [], userId, options) {
|
|
119
|
+
const rows = await queryWithRLS(query2, params, userId, options);
|
|
108
120
|
return rows[0] || null;
|
|
109
121
|
}
|
|
110
|
-
async function mutateWithRLS(query2, params = [], userId) {
|
|
111
|
-
const
|
|
122
|
+
async function mutateWithRLS(query2, params = [], userId, options) {
|
|
123
|
+
const useService = shouldUseService(userId, options);
|
|
124
|
+
const client = await acquireClient(useService);
|
|
112
125
|
try {
|
|
113
126
|
await client.query("BEGIN");
|
|
114
|
-
if (userId) {
|
|
127
|
+
if (userId && !useService) {
|
|
115
128
|
validateUserId(userId);
|
|
116
129
|
await client.query(`SET LOCAL app.user_id = '${userId.replace(/'/g, "''")}'`);
|
|
117
130
|
}
|
|
@@ -128,11 +141,12 @@ async function mutateWithRLS(query2, params = [], userId) {
|
|
|
128
141
|
releaseClient(client);
|
|
129
142
|
}
|
|
130
143
|
}
|
|
131
|
-
async function getTransactionClient(userId) {
|
|
132
|
-
const
|
|
144
|
+
async function getTransactionClient(userId, options) {
|
|
145
|
+
const useService = shouldUseService(userId, options);
|
|
146
|
+
const client = await acquireClient(useService);
|
|
133
147
|
try {
|
|
134
148
|
await client.query("BEGIN");
|
|
135
|
-
if (userId) {
|
|
149
|
+
if (userId && !useService) {
|
|
136
150
|
validateUserId(userId);
|
|
137
151
|
await client.query(`SET LOCAL app.user_id = '${userId.replace(/'/g, "''")}'`);
|
|
138
152
|
}
|
|
@@ -154,19 +168,22 @@ async function getTransactionClient(userId) {
|
|
|
154
168
|
}
|
|
155
169
|
};
|
|
156
170
|
}
|
|
171
|
+
function getServiceTransactionClient() {
|
|
172
|
+
return getTransactionClient(null, { service: true });
|
|
173
|
+
}
|
|
157
174
|
async function query(text, params) {
|
|
158
|
-
const result = await
|
|
175
|
+
const result = await servicePool.query(text, params);
|
|
159
176
|
return {
|
|
160
177
|
rows: result.rows,
|
|
161
178
|
rowCount: result.rowCount || 0
|
|
162
179
|
};
|
|
163
180
|
}
|
|
164
181
|
async function queryRows(text, params) {
|
|
165
|
-
const result = await
|
|
182
|
+
const result = await servicePool.query(text, params);
|
|
166
183
|
return result.rows;
|
|
167
184
|
}
|
|
168
185
|
async function queryOne(text, params) {
|
|
169
|
-
const result = await
|
|
186
|
+
const result = await servicePool.query(text, params);
|
|
170
187
|
return result.rows[0] || null;
|
|
171
188
|
}
|
|
172
189
|
function getPool() {
|
|
@@ -224,6 +241,9 @@ async function gracefulShutdown(timeoutMs = 3e4) {
|
|
|
224
241
|
}
|
|
225
242
|
try {
|
|
226
243
|
await pool.end();
|
|
244
|
+
if (servicePool !== pool) {
|
|
245
|
+
await servicePool.end();
|
|
246
|
+
}
|
|
227
247
|
console.log("[DB] Database pool closed successfully.");
|
|
228
248
|
} catch (error) {
|
|
229
249
|
console.error("[DB] Error closing database pool:", error);
|
|
@@ -263,6 +283,7 @@ export {
|
|
|
263
283
|
checkDatabaseConnection,
|
|
264
284
|
getPool,
|
|
265
285
|
getPoolStats,
|
|
286
|
+
getServiceTransactionClient,
|
|
266
287
|
getTransactionClient,
|
|
267
288
|
gracefulShutdown,
|
|
268
289
|
isPoolHealthy,
|
|
@@ -274,6 +295,7 @@ export {
|
|
|
274
295
|
queryOneWithRLS,
|
|
275
296
|
queryRows,
|
|
276
297
|
queryWithRLS,
|
|
298
|
+
servicePool,
|
|
277
299
|
stripSSLParams,
|
|
278
300
|
validateUserId
|
|
279
301
|
};
|
|
@@ -105,7 +105,14 @@ export interface EntityConfig {
|
|
|
105
105
|
*
|
|
106
106
|
* When a user's team role matches one of the listed roles, the generic
|
|
107
107
|
* CRUD handler scopes LIST/READ/UPDATE queries to only the records that
|
|
108
|
-
* belong to the user
|
|
108
|
+
* belong to the user.
|
|
109
|
+
*
|
|
110
|
+
* Two modes:
|
|
111
|
+
* - **Direct field** (omit `linkedBy`): the entity row already carries the
|
|
112
|
+
* owner id, so `field` is matched directly against the current user's id
|
|
113
|
+
* (e.g. `field: 'userId'`). Works for entities WITHOUT a `deletedAt` column.
|
|
114
|
+
* - **Linked lookup** (provide `linkedBy`): the filter value is resolved from
|
|
115
|
+
* a related table.
|
|
109
116
|
*
|
|
110
117
|
* Roles NOT listed in `roles` see all records unfiltered.
|
|
111
118
|
*/
|
|
@@ -114,14 +121,24 @@ export interface EntityConfig {
|
|
|
114
121
|
roles: string[];
|
|
115
122
|
/** Column in the entity table to filter by */
|
|
116
123
|
field: string;
|
|
117
|
-
/**
|
|
118
|
-
|
|
124
|
+
/**
|
|
125
|
+
* Lookup to resolve the filter value from a linked record. Omit for
|
|
126
|
+
* direct-field ownership (the entity row carries the owner id; the filter
|
|
127
|
+
* value is the current user's id).
|
|
128
|
+
*/
|
|
129
|
+
linkedBy?: {
|
|
119
130
|
/** Table to query for the linked record */
|
|
120
131
|
table: string;
|
|
121
132
|
/** Column in that table referencing the current user's id */
|
|
122
133
|
userField: string;
|
|
123
134
|
/** Column whose value becomes the filter value */
|
|
124
135
|
valueField: string;
|
|
136
|
+
/**
|
|
137
|
+
* Whether the linked table is soft-deletable. When true (default), the
|
|
138
|
+
* lookup appends `AND "deletedAt" IS NULL`. Set `false` for tables
|
|
139
|
+
* without a `deletedAt` column to avoid an undefined-column error.
|
|
140
|
+
*/
|
|
141
|
+
softDelete?: boolean;
|
|
125
142
|
};
|
|
126
143
|
/** Per-role field write restrictions on PATCH */
|
|
127
144
|
fieldGuards?: Array<{
|