@vritti/api-sdk 0.1.1 → 0.1.2
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/index.cjs +155 -75
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +195 -18
- package/dist/index.d.ts +195 -18
- package/dist/index.js +140 -68
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -10,6 +10,183 @@ import { FastifyRequest, FastifyReply } from 'fastify';
|
|
|
10
10
|
import { Observable } from 'rxjs';
|
|
11
11
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* api-sdk Configuration System
|
|
15
|
+
*
|
|
16
|
+
* Similar to quantum-ui's config pattern - provides a type-safe configuration system
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* // In vritti-api-nexus/src/main.ts
|
|
21
|
+
* import { configureApiSdk } from '@vritti/api-sdk';
|
|
22
|
+
*
|
|
23
|
+
* configureApiSdk({
|
|
24
|
+
* cookie: {
|
|
25
|
+
* refreshCookieName: 'vritti_refresh',
|
|
26
|
+
* refreshCookieMaxAge: 30 * 24 * 60 * 60 * 1000, // 30 days
|
|
27
|
+
* },
|
|
28
|
+
* jwt: {
|
|
29
|
+
* accessTokenExpiry: '15m',
|
|
30
|
+
* refreshTokenExpiry: '30d',
|
|
31
|
+
* validateTokenBinding: true,
|
|
32
|
+
* },
|
|
33
|
+
* guard: {
|
|
34
|
+
* tenantHeaderName: 'x-tenant-id',
|
|
35
|
+
* },
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* Cookie configuration options
|
|
41
|
+
*/
|
|
42
|
+
interface CookieConfig {
|
|
43
|
+
/**
|
|
44
|
+
* The name of the httpOnly cookie containing the refresh token
|
|
45
|
+
* @default 'vritti_refresh'
|
|
46
|
+
*/
|
|
47
|
+
refreshCookieName: string;
|
|
48
|
+
/**
|
|
49
|
+
* Max age of the refresh cookie in milliseconds
|
|
50
|
+
* @default 2592000000 (30 days)
|
|
51
|
+
*/
|
|
52
|
+
refreshCookieMaxAge: number;
|
|
53
|
+
/**
|
|
54
|
+
* Cookie path
|
|
55
|
+
* @default '/'
|
|
56
|
+
*/
|
|
57
|
+
refreshCookiePath: string;
|
|
58
|
+
/**
|
|
59
|
+
* Whether the cookie is secure (HTTPS only)
|
|
60
|
+
* @default true in production
|
|
61
|
+
*/
|
|
62
|
+
refreshCookieSecure: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* SameSite attribute for the cookie
|
|
65
|
+
* @default 'strict'
|
|
66
|
+
*/
|
|
67
|
+
refreshCookieSameSite: 'strict' | 'lax' | 'none';
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* JWT token configuration options
|
|
71
|
+
*/
|
|
72
|
+
interface JwtConfig {
|
|
73
|
+
/**
|
|
74
|
+
* Access token expiry time
|
|
75
|
+
* @default '15m'
|
|
76
|
+
*/
|
|
77
|
+
accessTokenExpiry: string;
|
|
78
|
+
/**
|
|
79
|
+
* Refresh token expiry time
|
|
80
|
+
* @default '30d'
|
|
81
|
+
*/
|
|
82
|
+
refreshTokenExpiry: string;
|
|
83
|
+
/**
|
|
84
|
+
* Onboarding token expiry time
|
|
85
|
+
* @default '24h'
|
|
86
|
+
*/
|
|
87
|
+
onboardingTokenExpiry: string;
|
|
88
|
+
/**
|
|
89
|
+
* Whether to validate refresh token binding (hash in access token)
|
|
90
|
+
* @default true
|
|
91
|
+
*/
|
|
92
|
+
validateTokenBinding: boolean;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Auth guard configuration options
|
|
96
|
+
*/
|
|
97
|
+
interface GuardConfig {
|
|
98
|
+
/**
|
|
99
|
+
* Header name for tenant ID
|
|
100
|
+
* @default 'x-tenant-id'
|
|
101
|
+
*/
|
|
102
|
+
tenantHeaderName: string;
|
|
103
|
+
/**
|
|
104
|
+
* Header name for authorization
|
|
105
|
+
* @default 'authorization'
|
|
106
|
+
*/
|
|
107
|
+
authHeaderName: string;
|
|
108
|
+
/**
|
|
109
|
+
* Token prefix (e.g., 'Bearer')
|
|
110
|
+
* @default 'Bearer'
|
|
111
|
+
*/
|
|
112
|
+
tokenPrefix: string;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Complete api-sdk configuration interface
|
|
116
|
+
*/
|
|
117
|
+
interface ApiSdkConfig {
|
|
118
|
+
/**
|
|
119
|
+
* Cookie configuration
|
|
120
|
+
*/
|
|
121
|
+
cookie?: Partial<CookieConfig>;
|
|
122
|
+
/**
|
|
123
|
+
* JWT token configuration
|
|
124
|
+
*/
|
|
125
|
+
jwt?: Partial<JwtConfig>;
|
|
126
|
+
/**
|
|
127
|
+
* Auth guard configuration
|
|
128
|
+
*/
|
|
129
|
+
guard?: Partial<GuardConfig>;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Full configuration type with all properties required
|
|
133
|
+
*/
|
|
134
|
+
interface FullConfig {
|
|
135
|
+
cookie: CookieConfig;
|
|
136
|
+
jwt: JwtConfig;
|
|
137
|
+
guard: GuardConfig;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Helper function to define configuration with type safety
|
|
141
|
+
* Similar to Tailwind's defineConfig()
|
|
142
|
+
*/
|
|
143
|
+
declare function defineConfig(config: ApiSdkConfig): ApiSdkConfig;
|
|
144
|
+
/**
|
|
145
|
+
* Configure api-sdk with user settings
|
|
146
|
+
* This should be called once in the application's bootstrap (main.ts)
|
|
147
|
+
*/
|
|
148
|
+
declare function configureApiSdk(userConfig: ApiSdkConfig): void;
|
|
149
|
+
/**
|
|
150
|
+
* Get the current configuration
|
|
151
|
+
*/
|
|
152
|
+
declare function getConfig(): FullConfig;
|
|
153
|
+
/**
|
|
154
|
+
* Reset configuration to defaults (for testing)
|
|
155
|
+
*/
|
|
156
|
+
declare function resetConfig(): void;
|
|
157
|
+
/**
|
|
158
|
+
* Get refresh cookie options (convenience method)
|
|
159
|
+
*/
|
|
160
|
+
declare function getRefreshCookieOptions(): {
|
|
161
|
+
httpOnly: boolean;
|
|
162
|
+
secure: boolean;
|
|
163
|
+
sameSite: "strict" | "lax" | "none";
|
|
164
|
+
path: string;
|
|
165
|
+
maxAge: number;
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* Get JWT expiry settings (convenience method)
|
|
169
|
+
*/
|
|
170
|
+
declare function getJwtExpiry(): {
|
|
171
|
+
access: string;
|
|
172
|
+
refresh: string;
|
|
173
|
+
onboarding: string;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Hash a token using SHA-256
|
|
178
|
+
* @param token The token to hash
|
|
179
|
+
* @returns The hex-encoded SHA-256 hash
|
|
180
|
+
*/
|
|
181
|
+
declare function hashToken(token: string): string;
|
|
182
|
+
/**
|
|
183
|
+
* Verify a token against its expected hash using constant-time comparison
|
|
184
|
+
* @param token The token to verify
|
|
185
|
+
* @param expectedHash The expected SHA-256 hash
|
|
186
|
+
* @returns true if the token matches the hash
|
|
187
|
+
*/
|
|
188
|
+
declare function verifyTokenHash(token: string, expectedHash: string): boolean;
|
|
189
|
+
|
|
13
190
|
/**
|
|
14
191
|
* Global authentication configuration module
|
|
15
192
|
*
|
|
@@ -663,7 +840,8 @@ declare abstract class PrimaryBaseRepository<TTable extends PgTable, TInsert = I
|
|
|
663
840
|
protected readonly logger: Logger;
|
|
664
841
|
/**
|
|
665
842
|
* The table name extracted from the Drizzle table at runtime.
|
|
666
|
-
*
|
|
843
|
+
* Stored in camelCase to match Drizzle's query object keys.
|
|
844
|
+
* Example: 'email_verifications' -> 'emailVerifications'
|
|
667
845
|
*/
|
|
668
846
|
private readonly tableName;
|
|
669
847
|
/**
|
|
@@ -1185,8 +1363,8 @@ declare class RequestService {
|
|
|
1185
1363
|
*/
|
|
1186
1364
|
getAccessToken(): string | null;
|
|
1187
1365
|
/**
|
|
1188
|
-
* Extract refresh token from
|
|
1189
|
-
* Cookie name
|
|
1366
|
+
* Extract refresh token from httpOnly cookie
|
|
1367
|
+
* Cookie name is configurable via api-sdk config
|
|
1190
1368
|
* @returns Refresh token or null if not found
|
|
1191
1369
|
*/
|
|
1192
1370
|
getRefreshToken(): string | null;
|
|
@@ -1204,27 +1382,27 @@ declare class RequestService {
|
|
|
1204
1382
|
}
|
|
1205
1383
|
|
|
1206
1384
|
/**
|
|
1207
|
-
* Vritti Authentication Guard - Validates JWT tokens and tenant context
|
|
1385
|
+
* Vritti Authentication Guard - Validates JWT access tokens and tenant context
|
|
1208
1386
|
*
|
|
1209
|
-
* This guard performs
|
|
1387
|
+
* This guard performs access token validation and attaches user data to request.
|
|
1388
|
+
* NOTE: Refresh tokens are NOT validated here - they are only validated in
|
|
1389
|
+
* /auth/token and /auth/refresh endpoints (session.service.ts).
|
|
1210
1390
|
*
|
|
1211
1391
|
* Validation Flow:
|
|
1212
1392
|
* 1. Checks if endpoint is marked with @Public() decorator → skip all validation
|
|
1213
1393
|
* 2. Checks if endpoint is marked with @Onboarding() decorator:
|
|
1214
1394
|
* - Requires token type='onboarding'
|
|
1215
1395
|
* - Validates JWT signature and expiry only
|
|
1216
|
-
* - Skips tenant
|
|
1396
|
+
* - Skips tenant validation
|
|
1217
1397
|
* - Attaches user data to request.user
|
|
1218
1398
|
* 3. For regular endpoints (no decorator):
|
|
1219
1399
|
* - Rejects tokens with type='onboarding'
|
|
1220
1400
|
* - Validates access token (JWT signature, expiry, nbf)
|
|
1221
|
-
* - Validates refresh token from session-id cookie
|
|
1222
1401
|
* - Validates tenant exists and is ACTIVE
|
|
1223
1402
|
* - Attaches user data to request.user
|
|
1224
1403
|
*
|
|
1225
1404
|
* Token Format:
|
|
1226
1405
|
* - Access Token: "Authorization: Bearer <jwt_token>"
|
|
1227
|
-
* - Refresh Token: "session-id" cookie
|
|
1228
1406
|
*
|
|
1229
1407
|
* Token Types:
|
|
1230
1408
|
* - type='onboarding': Limited access during registration flow (@Onboarding endpoints only)
|
|
@@ -1232,11 +1410,9 @@ declare class RequestService {
|
|
|
1232
1410
|
*
|
|
1233
1411
|
* Environment Variables Required:
|
|
1234
1412
|
* - JWT_SECRET: Secret key to verify access tokens (required)
|
|
1235
|
-
* - JWT_REFRESH_SECRET: Secret key for refresh tokens (optional, falls back to JWT_SECRET)
|
|
1236
1413
|
*
|
|
1237
1414
|
* Error Responses:
|
|
1238
1415
|
* - 401: Invalid/expired access token
|
|
1239
|
-
* - 401: Invalid/expired refresh token
|
|
1240
1416
|
* - 401: Tenant not found or inactive
|
|
1241
1417
|
* - 401: Tenant identifier not found
|
|
1242
1418
|
* - 401: Token type mismatch (onboarding token on regular endpoint or vice versa)
|
|
@@ -1284,14 +1460,15 @@ declare class VrittiAuthGuard implements CanActivate {
|
|
|
1284
1460
|
*/
|
|
1285
1461
|
private validateAccessToken;
|
|
1286
1462
|
/**
|
|
1287
|
-
* Validate refresh token
|
|
1288
|
-
*
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
*
|
|
1463
|
+
* Validate that the access token is bound to the refresh token in the cookie.
|
|
1464
|
+
* This prevents token theft - a stolen access token is useless without the
|
|
1465
|
+
* corresponding refresh token cookie.
|
|
1466
|
+
*
|
|
1467
|
+
* @param context - The execution context containing the request
|
|
1468
|
+
* @param validatedToken - The decoded and validated JWT token
|
|
1469
|
+
* @throws UnauthorizedException if token binding validation fails
|
|
1293
1470
|
*/
|
|
1294
|
-
private
|
|
1471
|
+
private validateRefreshTokenBinding;
|
|
1295
1472
|
}
|
|
1296
1473
|
|
|
1297
1474
|
/**
|
|
@@ -2317,4 +2494,4 @@ declare function generateCorrelationId(): string;
|
|
|
2317
2494
|
*/
|
|
2318
2495
|
declare function addCorrelationIdToResponse(reply: FastifyReply, correlationId: string, headerName?: string): void;
|
|
2319
2496
|
|
|
2320
|
-
export { type ApiErrorResponse, AuthConfigModule, BadGatewayException, BadRequestException, BaseFieldException, ConflictException, type CorrelationContext, CorrelationIdMiddleware, CsrfGuard, DEFAULT_CORRELATION_HEADER, DatabaseModule, type DatabaseModuleOptions, type FieldError, ForbiddenException, GoneException, HttpExceptionFilter, HttpLoggerInterceptor, type HttpLoggerOptions, HttpModule, InternalServerErrorException, LOGGER_MODULE_OPTIONS, type LogFormat, type LogLevel, type LogMetadata, LoggerModule, type LoggerModuleAsyncOptions, type LoggerModuleOptions, type LoggerOptionsFactory, LoggerService, MethodNotAllowedException, NotAcceptableException, NotFoundException, NotImplementedException, Onboarding, PayloadTooLargeException, PrimaryBaseRepository, PrimaryDatabaseService, type PrimaryDbConfig, type ProblemDetails, Public, type RegisteredSchema, RequestTimeoutException, type SchemaRegistry, ServiceUnavailableException, Tenant, TenantBaseRepository, TenantContextService, TenantDatabaseService, type TenantInfo, TooManyRequestsException, type TypedDrizzleClient, UnauthorizedException, UnprocessableEntityException, UnsupportedMediaTypeException, ValidationException, VrittiAuthGuard, addCorrelationIdToResponse, correlationStorage, generateCorrelationId, getCorrelationContext, getHttpStatusTitle, runWithCorrelationContext, updateCorrelationContext };
|
|
2497
|
+
export { type ApiErrorResponse, type ApiSdkConfig, AuthConfigModule, BadGatewayException, BadRequestException, BaseFieldException, ConflictException, type CookieConfig, type CorrelationContext, CorrelationIdMiddleware, CsrfGuard, DEFAULT_CORRELATION_HEADER, DatabaseModule, type DatabaseModuleOptions, type FieldError, ForbiddenException, GoneException, type GuardConfig, HttpExceptionFilter, HttpLoggerInterceptor, type HttpLoggerOptions, HttpModule, InternalServerErrorException, type JwtConfig, LOGGER_MODULE_OPTIONS, type LogFormat, type LogLevel, type LogMetadata, LoggerModule, type LoggerModuleAsyncOptions, type LoggerModuleOptions, type LoggerOptionsFactory, LoggerService, MethodNotAllowedException, NotAcceptableException, NotFoundException, NotImplementedException, Onboarding, PayloadTooLargeException, PrimaryBaseRepository, PrimaryDatabaseService, type PrimaryDbConfig, type ProblemDetails, Public, type RegisteredSchema, RequestTimeoutException, type SchemaRegistry, ServiceUnavailableException, Tenant, TenantBaseRepository, TenantContextService, TenantDatabaseService, type TenantInfo, TooManyRequestsException, type TypedDrizzleClient, UnauthorizedException, UnprocessableEntityException, UnsupportedMediaTypeException, ValidationException, VrittiAuthGuard, addCorrelationIdToResponse, configureApiSdk, correlationStorage, defineConfig, generateCorrelationId, getConfig, getCorrelationContext, getHttpStatusTitle, getJwtExpiry, getRefreshCookieOptions, hashToken, resetConfig, runWithCorrelationContext, updateCorrelationContext, verifyTokenHash };
|
package/dist/index.d.ts
CHANGED
|
@@ -10,6 +10,183 @@ import { FastifyRequest, FastifyReply } from 'fastify';
|
|
|
10
10
|
import { Observable } from 'rxjs';
|
|
11
11
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
12
12
|
|
|
13
|
+
/**
|
|
14
|
+
* api-sdk Configuration System
|
|
15
|
+
*
|
|
16
|
+
* Similar to quantum-ui's config pattern - provides a type-safe configuration system
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* // In vritti-api-nexus/src/main.ts
|
|
21
|
+
* import { configureApiSdk } from '@vritti/api-sdk';
|
|
22
|
+
*
|
|
23
|
+
* configureApiSdk({
|
|
24
|
+
* cookie: {
|
|
25
|
+
* refreshCookieName: 'vritti_refresh',
|
|
26
|
+
* refreshCookieMaxAge: 30 * 24 * 60 * 60 * 1000, // 30 days
|
|
27
|
+
* },
|
|
28
|
+
* jwt: {
|
|
29
|
+
* accessTokenExpiry: '15m',
|
|
30
|
+
* refreshTokenExpiry: '30d',
|
|
31
|
+
* validateTokenBinding: true,
|
|
32
|
+
* },
|
|
33
|
+
* guard: {
|
|
34
|
+
* tenantHeaderName: 'x-tenant-id',
|
|
35
|
+
* },
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
/**
|
|
40
|
+
* Cookie configuration options
|
|
41
|
+
*/
|
|
42
|
+
interface CookieConfig {
|
|
43
|
+
/**
|
|
44
|
+
* The name of the httpOnly cookie containing the refresh token
|
|
45
|
+
* @default 'vritti_refresh'
|
|
46
|
+
*/
|
|
47
|
+
refreshCookieName: string;
|
|
48
|
+
/**
|
|
49
|
+
* Max age of the refresh cookie in milliseconds
|
|
50
|
+
* @default 2592000000 (30 days)
|
|
51
|
+
*/
|
|
52
|
+
refreshCookieMaxAge: number;
|
|
53
|
+
/**
|
|
54
|
+
* Cookie path
|
|
55
|
+
* @default '/'
|
|
56
|
+
*/
|
|
57
|
+
refreshCookiePath: string;
|
|
58
|
+
/**
|
|
59
|
+
* Whether the cookie is secure (HTTPS only)
|
|
60
|
+
* @default true in production
|
|
61
|
+
*/
|
|
62
|
+
refreshCookieSecure: boolean;
|
|
63
|
+
/**
|
|
64
|
+
* SameSite attribute for the cookie
|
|
65
|
+
* @default 'strict'
|
|
66
|
+
*/
|
|
67
|
+
refreshCookieSameSite: 'strict' | 'lax' | 'none';
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* JWT token configuration options
|
|
71
|
+
*/
|
|
72
|
+
interface JwtConfig {
|
|
73
|
+
/**
|
|
74
|
+
* Access token expiry time
|
|
75
|
+
* @default '15m'
|
|
76
|
+
*/
|
|
77
|
+
accessTokenExpiry: string;
|
|
78
|
+
/**
|
|
79
|
+
* Refresh token expiry time
|
|
80
|
+
* @default '30d'
|
|
81
|
+
*/
|
|
82
|
+
refreshTokenExpiry: string;
|
|
83
|
+
/**
|
|
84
|
+
* Onboarding token expiry time
|
|
85
|
+
* @default '24h'
|
|
86
|
+
*/
|
|
87
|
+
onboardingTokenExpiry: string;
|
|
88
|
+
/**
|
|
89
|
+
* Whether to validate refresh token binding (hash in access token)
|
|
90
|
+
* @default true
|
|
91
|
+
*/
|
|
92
|
+
validateTokenBinding: boolean;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Auth guard configuration options
|
|
96
|
+
*/
|
|
97
|
+
interface GuardConfig {
|
|
98
|
+
/**
|
|
99
|
+
* Header name for tenant ID
|
|
100
|
+
* @default 'x-tenant-id'
|
|
101
|
+
*/
|
|
102
|
+
tenantHeaderName: string;
|
|
103
|
+
/**
|
|
104
|
+
* Header name for authorization
|
|
105
|
+
* @default 'authorization'
|
|
106
|
+
*/
|
|
107
|
+
authHeaderName: string;
|
|
108
|
+
/**
|
|
109
|
+
* Token prefix (e.g., 'Bearer')
|
|
110
|
+
* @default 'Bearer'
|
|
111
|
+
*/
|
|
112
|
+
tokenPrefix: string;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Complete api-sdk configuration interface
|
|
116
|
+
*/
|
|
117
|
+
interface ApiSdkConfig {
|
|
118
|
+
/**
|
|
119
|
+
* Cookie configuration
|
|
120
|
+
*/
|
|
121
|
+
cookie?: Partial<CookieConfig>;
|
|
122
|
+
/**
|
|
123
|
+
* JWT token configuration
|
|
124
|
+
*/
|
|
125
|
+
jwt?: Partial<JwtConfig>;
|
|
126
|
+
/**
|
|
127
|
+
* Auth guard configuration
|
|
128
|
+
*/
|
|
129
|
+
guard?: Partial<GuardConfig>;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Full configuration type with all properties required
|
|
133
|
+
*/
|
|
134
|
+
interface FullConfig {
|
|
135
|
+
cookie: CookieConfig;
|
|
136
|
+
jwt: JwtConfig;
|
|
137
|
+
guard: GuardConfig;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Helper function to define configuration with type safety
|
|
141
|
+
* Similar to Tailwind's defineConfig()
|
|
142
|
+
*/
|
|
143
|
+
declare function defineConfig(config: ApiSdkConfig): ApiSdkConfig;
|
|
144
|
+
/**
|
|
145
|
+
* Configure api-sdk with user settings
|
|
146
|
+
* This should be called once in the application's bootstrap (main.ts)
|
|
147
|
+
*/
|
|
148
|
+
declare function configureApiSdk(userConfig: ApiSdkConfig): void;
|
|
149
|
+
/**
|
|
150
|
+
* Get the current configuration
|
|
151
|
+
*/
|
|
152
|
+
declare function getConfig(): FullConfig;
|
|
153
|
+
/**
|
|
154
|
+
* Reset configuration to defaults (for testing)
|
|
155
|
+
*/
|
|
156
|
+
declare function resetConfig(): void;
|
|
157
|
+
/**
|
|
158
|
+
* Get refresh cookie options (convenience method)
|
|
159
|
+
*/
|
|
160
|
+
declare function getRefreshCookieOptions(): {
|
|
161
|
+
httpOnly: boolean;
|
|
162
|
+
secure: boolean;
|
|
163
|
+
sameSite: "strict" | "lax" | "none";
|
|
164
|
+
path: string;
|
|
165
|
+
maxAge: number;
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* Get JWT expiry settings (convenience method)
|
|
169
|
+
*/
|
|
170
|
+
declare function getJwtExpiry(): {
|
|
171
|
+
access: string;
|
|
172
|
+
refresh: string;
|
|
173
|
+
onboarding: string;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Hash a token using SHA-256
|
|
178
|
+
* @param token The token to hash
|
|
179
|
+
* @returns The hex-encoded SHA-256 hash
|
|
180
|
+
*/
|
|
181
|
+
declare function hashToken(token: string): string;
|
|
182
|
+
/**
|
|
183
|
+
* Verify a token against its expected hash using constant-time comparison
|
|
184
|
+
* @param token The token to verify
|
|
185
|
+
* @param expectedHash The expected SHA-256 hash
|
|
186
|
+
* @returns true if the token matches the hash
|
|
187
|
+
*/
|
|
188
|
+
declare function verifyTokenHash(token: string, expectedHash: string): boolean;
|
|
189
|
+
|
|
13
190
|
/**
|
|
14
191
|
* Global authentication configuration module
|
|
15
192
|
*
|
|
@@ -663,7 +840,8 @@ declare abstract class PrimaryBaseRepository<TTable extends PgTable, TInsert = I
|
|
|
663
840
|
protected readonly logger: Logger;
|
|
664
841
|
/**
|
|
665
842
|
* The table name extracted from the Drizzle table at runtime.
|
|
666
|
-
*
|
|
843
|
+
* Stored in camelCase to match Drizzle's query object keys.
|
|
844
|
+
* Example: 'email_verifications' -> 'emailVerifications'
|
|
667
845
|
*/
|
|
668
846
|
private readonly tableName;
|
|
669
847
|
/**
|
|
@@ -1185,8 +1363,8 @@ declare class RequestService {
|
|
|
1185
1363
|
*/
|
|
1186
1364
|
getAccessToken(): string | null;
|
|
1187
1365
|
/**
|
|
1188
|
-
* Extract refresh token from
|
|
1189
|
-
* Cookie name
|
|
1366
|
+
* Extract refresh token from httpOnly cookie
|
|
1367
|
+
* Cookie name is configurable via api-sdk config
|
|
1190
1368
|
* @returns Refresh token or null if not found
|
|
1191
1369
|
*/
|
|
1192
1370
|
getRefreshToken(): string | null;
|
|
@@ -1204,27 +1382,27 @@ declare class RequestService {
|
|
|
1204
1382
|
}
|
|
1205
1383
|
|
|
1206
1384
|
/**
|
|
1207
|
-
* Vritti Authentication Guard - Validates JWT tokens and tenant context
|
|
1385
|
+
* Vritti Authentication Guard - Validates JWT access tokens and tenant context
|
|
1208
1386
|
*
|
|
1209
|
-
* This guard performs
|
|
1387
|
+
* This guard performs access token validation and attaches user data to request.
|
|
1388
|
+
* NOTE: Refresh tokens are NOT validated here - they are only validated in
|
|
1389
|
+
* /auth/token and /auth/refresh endpoints (session.service.ts).
|
|
1210
1390
|
*
|
|
1211
1391
|
* Validation Flow:
|
|
1212
1392
|
* 1. Checks if endpoint is marked with @Public() decorator → skip all validation
|
|
1213
1393
|
* 2. Checks if endpoint is marked with @Onboarding() decorator:
|
|
1214
1394
|
* - Requires token type='onboarding'
|
|
1215
1395
|
* - Validates JWT signature and expiry only
|
|
1216
|
-
* - Skips tenant
|
|
1396
|
+
* - Skips tenant validation
|
|
1217
1397
|
* - Attaches user data to request.user
|
|
1218
1398
|
* 3. For regular endpoints (no decorator):
|
|
1219
1399
|
* - Rejects tokens with type='onboarding'
|
|
1220
1400
|
* - Validates access token (JWT signature, expiry, nbf)
|
|
1221
|
-
* - Validates refresh token from session-id cookie
|
|
1222
1401
|
* - Validates tenant exists and is ACTIVE
|
|
1223
1402
|
* - Attaches user data to request.user
|
|
1224
1403
|
*
|
|
1225
1404
|
* Token Format:
|
|
1226
1405
|
* - Access Token: "Authorization: Bearer <jwt_token>"
|
|
1227
|
-
* - Refresh Token: "session-id" cookie
|
|
1228
1406
|
*
|
|
1229
1407
|
* Token Types:
|
|
1230
1408
|
* - type='onboarding': Limited access during registration flow (@Onboarding endpoints only)
|
|
@@ -1232,11 +1410,9 @@ declare class RequestService {
|
|
|
1232
1410
|
*
|
|
1233
1411
|
* Environment Variables Required:
|
|
1234
1412
|
* - JWT_SECRET: Secret key to verify access tokens (required)
|
|
1235
|
-
* - JWT_REFRESH_SECRET: Secret key for refresh tokens (optional, falls back to JWT_SECRET)
|
|
1236
1413
|
*
|
|
1237
1414
|
* Error Responses:
|
|
1238
1415
|
* - 401: Invalid/expired access token
|
|
1239
|
-
* - 401: Invalid/expired refresh token
|
|
1240
1416
|
* - 401: Tenant not found or inactive
|
|
1241
1417
|
* - 401: Tenant identifier not found
|
|
1242
1418
|
* - 401: Token type mismatch (onboarding token on regular endpoint or vice versa)
|
|
@@ -1284,14 +1460,15 @@ declare class VrittiAuthGuard implements CanActivate {
|
|
|
1284
1460
|
*/
|
|
1285
1461
|
private validateAccessToken;
|
|
1286
1462
|
/**
|
|
1287
|
-
* Validate refresh token
|
|
1288
|
-
*
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
*
|
|
1463
|
+
* Validate that the access token is bound to the refresh token in the cookie.
|
|
1464
|
+
* This prevents token theft - a stolen access token is useless without the
|
|
1465
|
+
* corresponding refresh token cookie.
|
|
1466
|
+
*
|
|
1467
|
+
* @param context - The execution context containing the request
|
|
1468
|
+
* @param validatedToken - The decoded and validated JWT token
|
|
1469
|
+
* @throws UnauthorizedException if token binding validation fails
|
|
1293
1470
|
*/
|
|
1294
|
-
private
|
|
1471
|
+
private validateRefreshTokenBinding;
|
|
1295
1472
|
}
|
|
1296
1473
|
|
|
1297
1474
|
/**
|
|
@@ -2317,4 +2494,4 @@ declare function generateCorrelationId(): string;
|
|
|
2317
2494
|
*/
|
|
2318
2495
|
declare function addCorrelationIdToResponse(reply: FastifyReply, correlationId: string, headerName?: string): void;
|
|
2319
2496
|
|
|
2320
|
-
export { type ApiErrorResponse, AuthConfigModule, BadGatewayException, BadRequestException, BaseFieldException, ConflictException, type CorrelationContext, CorrelationIdMiddleware, CsrfGuard, DEFAULT_CORRELATION_HEADER, DatabaseModule, type DatabaseModuleOptions, type FieldError, ForbiddenException, GoneException, HttpExceptionFilter, HttpLoggerInterceptor, type HttpLoggerOptions, HttpModule, InternalServerErrorException, LOGGER_MODULE_OPTIONS, type LogFormat, type LogLevel, type LogMetadata, LoggerModule, type LoggerModuleAsyncOptions, type LoggerModuleOptions, type LoggerOptionsFactory, LoggerService, MethodNotAllowedException, NotAcceptableException, NotFoundException, NotImplementedException, Onboarding, PayloadTooLargeException, PrimaryBaseRepository, PrimaryDatabaseService, type PrimaryDbConfig, type ProblemDetails, Public, type RegisteredSchema, RequestTimeoutException, type SchemaRegistry, ServiceUnavailableException, Tenant, TenantBaseRepository, TenantContextService, TenantDatabaseService, type TenantInfo, TooManyRequestsException, type TypedDrizzleClient, UnauthorizedException, UnprocessableEntityException, UnsupportedMediaTypeException, ValidationException, VrittiAuthGuard, addCorrelationIdToResponse, correlationStorage, generateCorrelationId, getCorrelationContext, getHttpStatusTitle, runWithCorrelationContext, updateCorrelationContext };
|
|
2497
|
+
export { type ApiErrorResponse, type ApiSdkConfig, AuthConfigModule, BadGatewayException, BadRequestException, BaseFieldException, ConflictException, type CookieConfig, type CorrelationContext, CorrelationIdMiddleware, CsrfGuard, DEFAULT_CORRELATION_HEADER, DatabaseModule, type DatabaseModuleOptions, type FieldError, ForbiddenException, GoneException, type GuardConfig, HttpExceptionFilter, HttpLoggerInterceptor, type HttpLoggerOptions, HttpModule, InternalServerErrorException, type JwtConfig, LOGGER_MODULE_OPTIONS, type LogFormat, type LogLevel, type LogMetadata, LoggerModule, type LoggerModuleAsyncOptions, type LoggerModuleOptions, type LoggerOptionsFactory, LoggerService, MethodNotAllowedException, NotAcceptableException, NotFoundException, NotImplementedException, Onboarding, PayloadTooLargeException, PrimaryBaseRepository, PrimaryDatabaseService, type PrimaryDbConfig, type ProblemDetails, Public, type RegisteredSchema, RequestTimeoutException, type SchemaRegistry, ServiceUnavailableException, Tenant, TenantBaseRepository, TenantContextService, TenantDatabaseService, type TenantInfo, TooManyRequestsException, type TypedDrizzleClient, UnauthorizedException, UnprocessableEntityException, UnsupportedMediaTypeException, ValidationException, VrittiAuthGuard, addCorrelationIdToResponse, configureApiSdk, correlationStorage, defineConfig, generateCorrelationId, getConfig, getCorrelationContext, getHttpStatusTitle, getJwtExpiry, getRefreshCookieOptions, hashToken, resetConfig, runWithCorrelationContext, updateCorrelationContext, verifyTokenHash };
|