nucleus-core-ts 0.9.600 → 0.9.701

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.
@@ -0,0 +1 @@
1
+ export {};
@@ -1,7 +1,12 @@
1
1
  import { Elysia } from 'elysia';
2
2
  import type { CreateSessionParams } from '../login';
3
3
  import type { AuthRouteConfig } from '../types';
4
- export declare function createImpersonateRoute(config: AuthRouteConfig, signAccessToken: (userId: string, roles?: string[], claims?: string[], tenant?: string) => string, signRefreshToken: (userId: string) => string, createSession: (params: CreateSessionParams) => Promise<string>, saveSessionToDb?: (sessionId: string, params: CreateSessionParams, schemaName?: string) => Promise<{
4
+ export declare function createImpersonateRoute(config: AuthRouteConfig, signAccessToken: (userId: string, roles?: string[], claims?: string[], tenant?: string) => string, signRefreshToken: (userId: string) => string, verifyRefreshToken: (token: string) => {
5
+ valid: boolean;
6
+ payload?: {
7
+ sub: string;
8
+ };
9
+ }, createSession: (params: CreateSessionParams) => Promise<string>, saveSessionToDb?: (sessionId: string, params: CreateSessionParams, schemaName?: string) => Promise<{
5
10
  requiresApproval?: boolean;
6
11
  sessionId?: string;
7
12
  } | undefined>, cookieConfig?: {
@@ -9,6 +9,26 @@ interface MagicLinkToken {
9
9
  tokenHash: string;
10
10
  expiresAt: Date;
11
11
  }
12
+ /**
13
+ * Build the Set-Cookie for the short-lived, single-use OAuth `state` CSRF cookie.
14
+ *
15
+ * Path is ALWAYS `/`, NOT the backend's internal OAuth `basePath`. The cookie is
16
+ * set when the browser starts the flow and must be re-sent on the provider's
17
+ * callback, but the EXTERNAL callback path is decided by the deployment's
18
+ * ingress/proxy (commonly `/api/auth/oauth/<provider>/callback` or
19
+ * `/oauth/<provider>`) and routinely differs from the backend-internal basePath
20
+ * (`/auth/oauth`). A basePath-scoped cookie then silently fails the browser's
21
+ * path match on the callback, the cookie is never attached, and the M6 CSRF
22
+ * check rejects the login with `invalid_state`. `Path=/` makes the cookie
23
+ * round-trip regardless of how the edge remaps the OAuth routes. `SameSite=Lax`
24
+ * is required so the top-level GET redirect back from the IdP still carries it;
25
+ * the cookie stays HttpOnly + single-use, so the wider path does not weaken CSRF.
26
+ */
27
+ export declare function buildOAuthStateCookie(value: string, opts: {
28
+ maxAge: number;
29
+ secure?: boolean;
30
+ domain?: string;
31
+ }): string;
12
32
  export declare function createOAuthRoutes(config: AuthRouteConfig, oauthService: OAuthService, signAccessToken: (userId: string, roles?: string[], claims?: string[], tenant?: string) => string, signRefreshToken: (userId: string) => string, createSession: (params: CreateSessionParams) => Promise<string>, saveSessionToDb?: (sessionId: string, params: CreateSessionParams, schemaName?: string) => Promise<{
13
33
  requiresApproval?: boolean;
14
34
  sessionId?: string;
@@ -16,6 +16,23 @@ export declare function signNewAccessToken({ sessionData, options, refreshTokenI
16
16
  /** H9: tenant schema to bind into the token (x-tenant-schema). */
17
17
  tenant?: string;
18
18
  }): string;
19
+ /**
20
+ * Resolve the shared `pg` Pool options from `database.pool`, applying safe
21
+ * defaults. `max` bounds the total connections one instance holds (the guard
22
+ * against "53300 too many clients"); `idleTimeoutMillis` reaps idle clients;
23
+ * `connectionTimeoutMillis` fails fast under exhaustion instead of hanging.
24
+ */
25
+ export declare function resolveDbPoolConfig(pool?: {
26
+ max?: number;
27
+ idleTimeoutMillis?: number;
28
+ connectionTimeoutMillis?: number;
29
+ maxUses?: number;
30
+ }): {
31
+ max: number;
32
+ idleTimeoutMillis: number;
33
+ connectionTimeoutMillis: number;
34
+ maxUses?: number;
35
+ };
19
36
  export declare function toAudit(payload: AuditPayload | null, summary: string, opts?: {
20
37
  /** Override the actor for this audit (e.g. the user behind a revoked/forged token). */
21
38
  userId?: string | null;
@@ -123,6 +123,21 @@ export interface NucleusConfigOptions {
123
123
  database: {
124
124
  url?: string;
125
125
  type?: 'postgres';
126
+ /**
127
+ * Connection-pool tuning for the single shared `pg` Pool. A multi-tenant
128
+ * deployment uses ONE pool for all tenant schemas (schema is switched per
129
+ * query), so `max` bounds the TOTAL connections one app instance holds —
130
+ * keep it well under Postgres `max_connections` divided by the number of
131
+ * instances to avoid "53300 too many clients". Idle connections are reaped
132
+ * after `idleTimeoutMillis`; acquiring a connection fails fast after
133
+ * `connectionTimeoutMillis` (surfacing exhaustion instead of hanging).
134
+ */
135
+ pool?: {
136
+ max?: number;
137
+ idleTimeoutMillis?: number;
138
+ connectionTimeoutMillis?: number;
139
+ maxUses?: number;
140
+ };
126
141
  isMultiTenant?: boolean;
127
142
  schemas?: string[];
128
143
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nucleus-core-ts",
3
- "version": "0.9.600",
3
+ "version": "0.9.701",
4
4
  "description": "Production-ready, enterprise-grade TypeScript framework for building multi-tenant APIs",
5
5
  "author": "Hidayet Can \u00d6zcan <hidayetcan@gmail.com>",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -31,6 +31,27 @@
31
31
  "postgres"
32
32
  ]
33
33
  },
34
+ "pool": {
35
+ "type": "object",
36
+ "properties": {
37
+ "max": {
38
+ "type": "number"
39
+ },
40
+ "idleTimeoutMillis": {
41
+ "type": "number",
42
+ "description": "default 10"
43
+ },
44
+ "connectionTimeoutMillis": {
45
+ "type": "number",
46
+ "description": "default 30000"
47
+ },
48
+ "maxUses": {
49
+ "type": "number",
50
+ "description": "default 10000"
51
+ }
52
+ },
53
+ "description": "Connection-pool tuning for the single shared `pg` Pool. A multi-tenant deployment uses ONE pool for all tenant schemas (schema is switched per query), so `max` bounds the TOTAL connections one app instance holds — keep it well under Postgres `max_connections` divided by the number of instances to avoid \"53300 too many clients\". Idle connections are reaped after `idleTimeoutMillis`; acquiring a connection fails fast after `connectionTimeoutMillis` (surfacing exhaustion instead of hanging)."
54
+ },
34
55
  "isMultiTenant": {
35
56
  "type": "boolean"
36
57
  },