@vritti/api-sdk 0.3.3 → 0.3.5

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.
Files changed (133) hide show
  1. package/dist/auth.cjs +942 -0
  2. package/dist/auth.cjs.map +1 -0
  3. package/dist/auth.d.cts +95 -0
  4. package/dist/auth.d.ts +95 -0
  5. package/dist/auth.js +884 -0
  6. package/dist/auth.js.map +1 -0
  7. package/dist/cache.cjs +182 -14
  8. package/dist/cache.cjs.map +1 -1
  9. package/dist/cache.d.cts +48 -4
  10. package/dist/cache.d.ts +48 -4
  11. package/dist/cache.js +177 -12
  12. package/dist/cache.js.map +1 -1
  13. package/dist/catalog-resolver.cjs +226 -51
  14. package/dist/catalog-resolver.cjs.map +1 -1
  15. package/dist/catalog-resolver.d.cts +41 -19
  16. package/dist/catalog-resolver.d.ts +41 -19
  17. package/dist/catalog-resolver.js +212 -46
  18. package/dist/catalog-resolver.js.map +1 -1
  19. package/dist/code-pattern-BP4zkNtT.d.cts +12 -0
  20. package/dist/code-pattern-BP4zkNtT.d.ts +12 -0
  21. package/dist/context.cjs +93 -0
  22. package/dist/context.cjs.map +1 -0
  23. package/dist/context.d.cts +19 -0
  24. package/dist/context.d.ts +19 -0
  25. package/dist/context.js +64 -0
  26. package/dist/context.js.map +1 -0
  27. package/dist/countries.cjs +1559 -0
  28. package/dist/countries.cjs.map +1 -0
  29. package/dist/countries.d.cts +13 -0
  30. package/dist/countries.d.ts +13 -0
  31. package/dist/countries.js +1532 -0
  32. package/dist/countries.js.map +1 -0
  33. package/dist/data-table.cjs +1280 -0
  34. package/dist/data-table.cjs.map +1 -0
  35. package/dist/data-table.d.cts +123 -0
  36. package/dist/data-table.d.ts +123 -0
  37. package/dist/data-table.js +1260 -0
  38. package/dist/data-table.js.map +1 -0
  39. package/dist/database.cjs +1510 -0
  40. package/dist/database.cjs.map +1 -0
  41. package/dist/database.d.cts +287 -0
  42. package/dist/database.d.ts +287 -0
  43. package/dist/database.js +1469 -0
  44. package/dist/database.js.map +1 -0
  45. package/dist/decimal.d.cts +0 -1
  46. package/dist/decimal.d.ts +0 -1
  47. package/dist/decorators.cjs +1817 -0
  48. package/dist/decorators.cjs.map +1 -0
  49. package/dist/decorators.d.cts +24 -0
  50. package/dist/decorators.d.ts +24 -0
  51. package/dist/decorators.js +1780 -0
  52. package/dist/decorators.js.map +1 -0
  53. package/dist/drizzle-pg-core.cjs +25 -0
  54. package/dist/drizzle-pg-core.cjs.map +1 -1
  55. package/dist/drizzle-pg-core.d.cts +7 -0
  56. package/dist/drizzle-pg-core.d.ts +7 -0
  57. package/dist/drizzle-pg-core.js +22 -0
  58. package/dist/drizzle-pg-core.js.map +1 -1
  59. package/dist/exceptions.cjs +301 -0
  60. package/dist/exceptions.cjs.map +1 -0
  61. package/dist/exceptions.d.cts +90 -0
  62. package/dist/exceptions.d.ts +90 -0
  63. package/dist/exceptions.js +257 -0
  64. package/dist/exceptions.js.map +1 -0
  65. package/dist/filter.types-PuARU9XD.d.cts +50 -0
  66. package/dist/filter.types-PuARU9XD.d.ts +50 -0
  67. package/dist/filters.cjs +407 -0
  68. package/dist/filters.cjs.map +1 -0
  69. package/dist/filters.d.cts +55 -0
  70. package/dist/filters.d.ts +55 -0
  71. package/dist/filters.js +377 -0
  72. package/dist/filters.js.map +1 -0
  73. package/dist/index.cjs +0 -5423
  74. package/dist/index.cjs.map +1 -1
  75. package/dist/index.d.cts +93 -854
  76. package/dist/index.d.ts +93 -854
  77. package/dist/index.js +0 -5301
  78. package/dist/index.js.map +1 -1
  79. package/dist/is-country.decorator-CcNwSSr5.d.cts +5 -0
  80. package/dist/is-country.decorator-CcNwSSr5.d.ts +5 -0
  81. package/dist/license.d.cts +1 -1
  82. package/dist/license.d.ts +1 -1
  83. package/dist/lodash.cjs.map +1 -1
  84. package/dist/lodash.js.map +1 -1
  85. package/dist/logger.cjs +862 -0
  86. package/dist/logger.cjs.map +1 -0
  87. package/dist/logger.d.cts +118 -0
  88. package/dist/logger.d.ts +118 -0
  89. package/dist/logger.js +816 -0
  90. package/dist/logger.js.map +1 -0
  91. package/dist/migrate.cjs +2 -2
  92. package/dist/migrate.cjs.map +1 -1
  93. package/dist/migrate.d.cts +2 -0
  94. package/dist/migrate.d.ts +2 -0
  95. package/dist/migrate.js +2 -2
  96. package/dist/migrate.js.map +1 -1
  97. package/dist/money.cjs +18 -3
  98. package/dist/money.cjs.map +1 -1
  99. package/dist/money.d.cts +13 -13
  100. package/dist/money.d.ts +13 -13
  101. package/dist/money.js +18 -3
  102. package/dist/money.js.map +1 -1
  103. package/dist/nats.cjs +34 -35
  104. package/dist/nats.cjs.map +1 -1
  105. package/dist/nats.d.cts +14 -14
  106. package/dist/nats.d.ts +14 -14
  107. package/dist/nats.js +32 -33
  108. package/dist/nats.js.map +1 -1
  109. package/dist/root.cjs +225 -0
  110. package/dist/root.cjs.map +1 -0
  111. package/dist/root.d.cts +4 -0
  112. package/dist/root.d.ts +4 -0
  113. package/dist/root.js +200 -0
  114. package/dist/root.js.map +1 -0
  115. package/dist/{types-DQRwj5rr.d.cts → types-C9jPdQqH.d.cts} +32 -6
  116. package/dist/{types-DQRwj5rr.d.ts → types-C9jPdQqH.d.ts} +32 -6
  117. package/dist/types.cjs +19 -0
  118. package/dist/types.cjs.map +1 -0
  119. package/dist/types.d.cts +17 -0
  120. package/dist/types.d.ts +17 -0
  121. package/dist/types.js +1 -0
  122. package/dist/types.js.map +1 -0
  123. package/dist/utils.cjs +273 -0
  124. package/dist/utils.cjs.map +1 -0
  125. package/dist/utils.d.cts +8 -0
  126. package/dist/utils.d.ts +8 -0
  127. package/dist/utils.js +245 -0
  128. package/dist/utils.js.map +1 -0
  129. package/package.json +122 -1
  130. package/dist/cache.service-_SuJIcNA.d.cts +0 -20
  131. package/dist/cache.service-_SuJIcNA.d.ts +0 -20
  132. package/dist/fastify-augmentation-CQPBNS5a.d.cts +0 -105
  133. package/dist/fastify-augmentation-CQPBNS5a.d.ts +0 -105
package/dist/auth.js ADDED
@@ -0,0 +1,884 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/auth/auth.config.ts
5
+ var AUTH_CONFIG = Symbol("AUTH_CONFIG");
6
+ var AUTH_CONFIG_DEFAULTS = {
7
+ cookie: {
8
+ refreshCookieName: "vritti_refresh",
9
+ refreshCookieMaxAge: 30 * 24 * 60 * 60 * 1e3,
10
+ refreshCookiePath: "/",
11
+ refreshCookieSecure: process.env.NODE_ENV === "production",
12
+ refreshCookieSameSite: "strict",
13
+ refreshCookieDomain: "localhost"
14
+ },
15
+ guard: {
16
+ authHeaderName: "authorization",
17
+ tokenPrefix: "Bearer",
18
+ csrfExemptSessionTypes: [],
19
+ csrfExemptTransports: [],
20
+ refreshTokenBindingExemptSessionTypes: []
21
+ }
22
+ };
23
+ var TokenType = /* @__PURE__ */ (function(TokenType2) {
24
+ TokenType2["ACCESS"] = "access";
25
+ TokenType2["REFRESH"] = "refresh";
26
+ return TokenType2;
27
+ })({});
28
+
29
+ // src/auth/auth-config.module.ts
30
+ import { Global as Global2, Module as Module2 } from "@nestjs/common";
31
+ import { ConfigModule, ConfigService } from "@nestjs/config";
32
+ import { APP_GUARD, Reflector as Reflector2 } from "@nestjs/core";
33
+ import { JwtModule } from "@nestjs/jwt";
34
+
35
+ // src/request/request.module.ts
36
+ import { Global, Module } from "@nestjs/common";
37
+
38
+ // src/request/services/request.service.ts
39
+ import { Inject, Injectable, Scope } from "@nestjs/common";
40
+ import { REQUEST } from "@nestjs/core";
41
+
42
+ // src/context/resolve-request.ts
43
+ function resolveInjectedRequest(injected) {
44
+ const candidate = injected;
45
+ if (candidate && candidate.headers === void 0 && candidate.req) {
46
+ return candidate.req;
47
+ }
48
+ return injected;
49
+ }
50
+ __name(resolveInjectedRequest, "resolveInjectedRequest");
51
+
52
+ // src/request/services/request.service.ts
53
+ function _ts_decorate(decorators, target, key, desc) {
54
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
55
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
56
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
57
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
58
+ }
59
+ __name(_ts_decorate, "_ts_decorate");
60
+ function _ts_metadata(k, v) {
61
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
62
+ }
63
+ __name(_ts_metadata, "_ts_metadata");
64
+ function _ts_param(paramIndex, decorator) {
65
+ return function(target, key) {
66
+ decorator(target, key, paramIndex);
67
+ };
68
+ }
69
+ __name(_ts_param, "_ts_param");
70
+ var RequestService = class {
71
+ static {
72
+ __name(this, "RequestService");
73
+ }
74
+ injectedRequest;
75
+ config;
76
+ constructor(injectedRequest, config) {
77
+ this.injectedRequest = injectedRequest;
78
+ this.config = config;
79
+ }
80
+ // Unwraps the GraphQL { req, reply } context wrapper so every accessor below works across both transports
81
+ get request() {
82
+ return resolveInjectedRequest(this.injectedRequest);
83
+ }
84
+ // Extracts the bearer access token from the Authorization header
85
+ getAccessToken() {
86
+ const authHeader = this.request.headers?.[this.config.guard.authHeaderName];
87
+ if (!authHeader || typeof authHeader !== "string") {
88
+ return null;
89
+ }
90
+ const [type, token] = authHeader.split(" ") ?? [];
91
+ return type === this.config.guard.tokenPrefix && token ? token : null;
92
+ }
93
+ // Extracts the refresh token from the configured httpOnly cookie
94
+ getRefreshToken() {
95
+ try {
96
+ const cookies = this.request.cookies;
97
+ if (cookies && typeof cookies === "object") {
98
+ const refreshToken = cookies[this.config.cookie.refreshCookieName];
99
+ if (refreshToken) {
100
+ return refreshToken;
101
+ }
102
+ }
103
+ return null;
104
+ } catch (_error) {
105
+ return null;
106
+ }
107
+ }
108
+ // Returns the value of a specific request header by key
109
+ getHeader(key) {
110
+ return this.request.headers?.[key];
111
+ }
112
+ // Returns the request hostname (without port)
113
+ getHostname() {
114
+ return this.request.hostname ?? "";
115
+ }
116
+ // Returns all request headers
117
+ getAllHeaders() {
118
+ return this.request.headers || {};
119
+ }
120
+ };
121
+ RequestService = _ts_decorate([
122
+ Injectable({
123
+ scope: Scope.REQUEST
124
+ }),
125
+ _ts_param(0, Inject(REQUEST)),
126
+ _ts_param(1, Inject(AUTH_CONFIG)),
127
+ _ts_metadata("design:type", Function),
128
+ _ts_metadata("design:paramtypes", [
129
+ typeof FastifyRequest === "undefined" ? Object : FastifyRequest,
130
+ typeof AuthConfig === "undefined" ? Object : AuthConfig
131
+ ])
132
+ ], RequestService);
133
+
134
+ // src/request/request.module.ts
135
+ function _ts_decorate2(decorators, target, key, desc) {
136
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
137
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
138
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
139
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
140
+ }
141
+ __name(_ts_decorate2, "_ts_decorate");
142
+ var RequestModule = class {
143
+ static {
144
+ __name(this, "RequestModule");
145
+ }
146
+ };
147
+ RequestModule = _ts_decorate2([
148
+ Global(),
149
+ Module({
150
+ providers: [
151
+ RequestService
152
+ ],
153
+ exports: [
154
+ RequestService
155
+ ]
156
+ })
157
+ ], RequestModule);
158
+
159
+ // src/auth/guards/vritti-auth.guard.ts
160
+ import { ForbiddenException, Inject as Inject3, Injectable as Injectable3, Logger as Logger2, Scope as Scope2, UnauthorizedException as UnauthorizedException2 } from "@nestjs/common";
161
+ import { SSE_METADATA } from "@nestjs/common/constants";
162
+ import { Reflector } from "@nestjs/core";
163
+
164
+ // src/context/extractors/graphql.extractor.ts
165
+ var graphqlExtractor = {
166
+ getRequest: /* @__PURE__ */ __name((host) => host.getArgByIndex(2).req, "getRequest"),
167
+ getResponse: /* @__PURE__ */ __name((host) => host.getArgByIndex(2).reply, "getResponse")
168
+ };
169
+
170
+ // src/context/extractors/http.extractor.ts
171
+ var httpExtractor = {
172
+ getRequest: /* @__PURE__ */ __name((host) => host.switchToHttp().getRequest(), "getRequest"),
173
+ getResponse: /* @__PURE__ */ __name((host) => host.switchToHttp().getResponse(), "getResponse")
174
+ };
175
+
176
+ // src/context/context.registry.ts
177
+ var registry = /* @__PURE__ */ new Map([
178
+ [
179
+ "http",
180
+ httpExtractor
181
+ ],
182
+ [
183
+ "graphql",
184
+ graphqlExtractor
185
+ ]
186
+ ]);
187
+ function resolveExtractor(type) {
188
+ return registry.get(type) ?? httpExtractor;
189
+ }
190
+ __name(resolveExtractor, "resolveExtractor");
191
+
192
+ // src/context/get-request.ts
193
+ function getRequestFromContext(host) {
194
+ return resolveExtractor(host.getType()).getRequest(host);
195
+ }
196
+ __name(getRequestFromContext, "getRequestFromContext");
197
+
198
+ // src/context/get-response.ts
199
+ function getResponseFromContext(host) {
200
+ return resolveExtractor(host.getType()).getResponse(host);
201
+ }
202
+ __name(getResponseFromContext, "getResponseFromContext");
203
+
204
+ // src/auth/decorators/require-session.decorator.ts
205
+ import { SetMetadata } from "@nestjs/common";
206
+ var REQUIRE_SESSION_KEY = "requiredSessionTypes";
207
+ var RequireSession = /* @__PURE__ */ __name((...types) => SetMetadata(REQUIRE_SESSION_KEY, types), "RequireSession");
208
+
209
+ // src/auth/decorators/skip-csrf.decorator.ts
210
+ import { SetMetadata as SetMetadata2 } from "@nestjs/common";
211
+ var SKIP_CSRF_KEY = "skipCsrf";
212
+ var SkipCsrf = /* @__PURE__ */ __name(() => SetMetadata2(SKIP_CSRF_KEY, true), "SkipCsrf");
213
+
214
+ // src/auth/services/token.service.ts
215
+ import { Inject as Inject2, Injectable as Injectable2, Logger, UnauthorizedException } from "@nestjs/common";
216
+ import { JwtService } from "@nestjs/jwt";
217
+
218
+ // src/utils/time.utils.ts
219
+ function parseExpiryToMs(expiry) {
220
+ const match = expiry.match(/^(\d+)([smhdwy])$/);
221
+ if (!match) throw new Error(`Invalid expiry format: ${expiry}`);
222
+ const [, digits = "", unit = ""] = match;
223
+ const value = Number.parseInt(digits, 10);
224
+ const multipliers = {
225
+ s: 1e3,
226
+ m: 6e4,
227
+ h: 36e5,
228
+ d: 864e5,
229
+ w: 6048e5,
230
+ y: 31536e6
231
+ };
232
+ const multiplier = multipliers[unit];
233
+ if (multiplier === void 0) throw new Error(`Invalid expiry format: ${expiry}`);
234
+ return value * multiplier;
235
+ }
236
+ __name(parseExpiryToMs, "parseExpiryToMs");
237
+
238
+ // src/auth/utils/token-hash.util.ts
239
+ import * as crypto from "crypto";
240
+ function hashToken(token) {
241
+ return crypto.createHash("sha256").update(token).digest("hex");
242
+ }
243
+ __name(hashToken, "hashToken");
244
+ function verifyTokenHash(token, expectedHash) {
245
+ const computedHash = hashToken(token);
246
+ if (computedHash.length !== expectedHash.length) return false;
247
+ return crypto.timingSafeEqual(Buffer.from(computedHash, "hex"), Buffer.from(expectedHash, "hex"));
248
+ }
249
+ __name(verifyTokenHash, "verifyTokenHash");
250
+
251
+ // src/auth/services/token.service.ts
252
+ function _ts_decorate3(decorators, target, key, desc) {
253
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
254
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
255
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
256
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
257
+ }
258
+ __name(_ts_decorate3, "_ts_decorate");
259
+ function _ts_metadata2(k, v) {
260
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
261
+ }
262
+ __name(_ts_metadata2, "_ts_metadata");
263
+ function _ts_param2(paramIndex, decorator) {
264
+ return function(target, key) {
265
+ decorator(target, key, paramIndex);
266
+ };
267
+ }
268
+ __name(_ts_param2, "_ts_param");
269
+ var TokenService = class _TokenService {
270
+ static {
271
+ __name(this, "TokenService");
272
+ }
273
+ jwtService;
274
+ config;
275
+ logger = new Logger(_TokenService.name);
276
+ constructor(jwtService, config) {
277
+ this.jwtService = jwtService;
278
+ this.config = config;
279
+ }
280
+ // ---- Generation ----
281
+ // Generates an access token bound to the given refresh token
282
+ generateAccessToken(sessionInfo, refreshToken) {
283
+ const { userId, sessionId, sessionType, ...metadata } = sessionInfo;
284
+ return this.jwtService.sign({
285
+ sessionType,
286
+ tokenType: TokenType.ACCESS,
287
+ userId,
288
+ sessionId,
289
+ refreshTokenHash: hashToken(refreshToken),
290
+ ...metadata
291
+ }, {
292
+ expiresIn: this.config.tokenExpiry.access
293
+ });
294
+ }
295
+ // Generates a refresh token for session persistence
296
+ generateRefreshToken(sessionInfo) {
297
+ const { userId, sessionId, sessionType, ...metadata } = sessionInfo;
298
+ return this.jwtService.sign({
299
+ sessionType,
300
+ tokenType: TokenType.REFRESH,
301
+ userId,
302
+ sessionId,
303
+ ...metadata
304
+ }, {
305
+ expiresIn: this.config.tokenExpiry.refresh
306
+ });
307
+ }
308
+ // Signs an arbitrary payload with optional JWT options
309
+ sign(payload, options) {
310
+ return this.jwtService.sign(payload, options);
311
+ }
312
+ // Verifies a token and ensures it matches the expected token type
313
+ verify(token, expectedType) {
314
+ try {
315
+ const payload = this.jwtService.verify(token);
316
+ if (payload.tokenType !== expectedType) {
317
+ throw new Error(`Expected ${expectedType} token, got ${payload.tokenType}`);
318
+ }
319
+ return payload;
320
+ } catch (error) {
321
+ this.logger.error(`Failed to verify ${expectedType} token`, error);
322
+ throw error;
323
+ }
324
+ }
325
+ // Returns the expiry as a Date for the given token type
326
+ getExpiryTime(type) {
327
+ return new Date(Date.now() + parseExpiryToMs(this.config.tokenExpiry[type]));
328
+ }
329
+ // Returns the token lifetime in seconds for the given type
330
+ getExpiryInSeconds(type) {
331
+ return Math.floor(parseExpiryToMs(this.config.tokenExpiry[type]) / 1e3);
332
+ }
333
+ // ---- Validation ----
334
+ // Decodes and validates an access token JWT
335
+ validateAccessToken(token) {
336
+ try {
337
+ const decoded = this.jwtService.verify(token);
338
+ if (decoded.tokenType !== TokenType.ACCESS) {
339
+ throw new UnauthorizedException("Invalid token type");
340
+ }
341
+ return decoded;
342
+ } catch (error) {
343
+ if (error instanceof UnauthorizedException) throw error;
344
+ const jwtError = error;
345
+ switch (jwtError.name) {
346
+ case "TokenExpiredError":
347
+ throw new UnauthorizedException("Access token has expired");
348
+ case "JsonWebTokenError":
349
+ throw new UnauthorizedException("Invalid access token");
350
+ case "NotBeforeError":
351
+ throw new UnauthorizedException("Access token not yet valid");
352
+ default:
353
+ throw new UnauthorizedException("Access token validation failed");
354
+ }
355
+ }
356
+ }
357
+ // Decodes and validates a refresh token JWT
358
+ validateRefreshToken(token) {
359
+ try {
360
+ const decoded = this.jwtService.verify(token);
361
+ if (decoded.tokenType !== TokenType.REFRESH) {
362
+ throw new UnauthorizedException("Invalid token type");
363
+ }
364
+ return decoded;
365
+ } catch (error) {
366
+ if (error instanceof UnauthorizedException) throw error;
367
+ throw new UnauthorizedException("Invalid or expired session");
368
+ }
369
+ }
370
+ // Validates that the access token is bound to the refresh token
371
+ validateTokenBinding(accessToken, refreshToken) {
372
+ if (!verifyTokenHash(refreshToken, accessToken.refreshTokenHash)) {
373
+ throw new UnauthorizedException("Session validation failed");
374
+ }
375
+ }
376
+ };
377
+ TokenService = _ts_decorate3([
378
+ Injectable2(),
379
+ _ts_param2(1, Inject2(AUTH_CONFIG)),
380
+ _ts_metadata2("design:type", Function),
381
+ _ts_metadata2("design:paramtypes", [
382
+ typeof JwtService === "undefined" ? Object : JwtService,
383
+ typeof AuthConfig === "undefined" ? Object : AuthConfig
384
+ ])
385
+ ], TokenService);
386
+
387
+ // src/auth/guards/vritti-auth.guard.ts
388
+ function _ts_decorate4(decorators, target, key, desc) {
389
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
390
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
391
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
392
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
393
+ }
394
+ __name(_ts_decorate4, "_ts_decorate");
395
+ function _ts_metadata3(k, v) {
396
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
397
+ }
398
+ __name(_ts_metadata3, "_ts_metadata");
399
+ function _ts_param3(paramIndex, decorator) {
400
+ return function(target, key) {
401
+ decorator(target, key, paramIndex);
402
+ };
403
+ }
404
+ __name(_ts_param3, "_ts_param");
405
+ var VrittiAuthGuard = class _VrittiAuthGuard {
406
+ static {
407
+ __name(this, "VrittiAuthGuard");
408
+ }
409
+ reflector;
410
+ requestService;
411
+ tokenService;
412
+ config;
413
+ logger = new Logger2(_VrittiAuthGuard.name);
414
+ constructor(reflector, requestService, tokenService, config) {
415
+ this.reflector = reflector;
416
+ this.requestService = requestService;
417
+ this.tokenService = tokenService;
418
+ this.config = config;
419
+ }
420
+ async canActivate(context) {
421
+ const request = getRequestFromContext(context);
422
+ const reply = getResponseFromContext(context);
423
+ const route = `${request.method} ${request.url}`;
424
+ request.authConfig = this.config;
425
+ const csrfExemptTransports = this.config.guard.csrfExemptTransports ?? [];
426
+ const skipCsrf = this.reflector.getAllAndOverride(SKIP_CSRF_KEY, [
427
+ context.getHandler(),
428
+ context.getClass()
429
+ ]) || csrfExemptTransports.includes(context.getType());
430
+ const isPublic = this.reflector.getAllAndOverride("isPublic", [
431
+ context.getHandler(),
432
+ context.getClass()
433
+ ]);
434
+ if (isPublic) {
435
+ if (!skipCsrf) {
436
+ await this.validateCsrf(request, reply);
437
+ }
438
+ this.logger.debug(`${route} \u2014 public endpoint, skipping auth`);
439
+ return true;
440
+ }
441
+ const requiredSessionTypes = this.reflector.getAllAndOverride(REQUIRE_SESSION_KEY, [
442
+ context.getHandler(),
443
+ context.getClass()
444
+ ]);
445
+ const isSseEndpoint = this.reflector.get(SSE_METADATA, context.getHandler());
446
+ if (isSseEndpoint) {
447
+ this.logger.debug(`${route} \u2014 SSE endpoint, authenticating via refresh cookie`);
448
+ return this.handleSseAuth(request, requiredSessionTypes);
449
+ }
450
+ const sessionType = await this.handleHttpAuth(request, requiredSessionTypes);
451
+ const csrfExemptSessionTypes = this.config.guard.csrfExemptSessionTypes ?? [];
452
+ if (!skipCsrf && !csrfExemptSessionTypes.includes(sessionType)) {
453
+ await this.validateCsrf(request, reply);
454
+ }
455
+ return true;
456
+ }
457
+ // Authenticates standard HTTP requests using the access token from Authorization header
458
+ async handleHttpAuth(request, requiredSessionTypes) {
459
+ const route = `${request.method} ${request.url}`;
460
+ const accessToken = this.requestService.getAccessToken();
461
+ if (!accessToken) {
462
+ this.logger.warn(`${route} \u2014 no access token found`);
463
+ throw new UnauthorizedException2("Access token not found");
464
+ }
465
+ const decoded = this.tokenService.validateAccessToken(accessToken);
466
+ const refreshTokenBindingExemptSessionTypes = this.config.guard.refreshTokenBindingExemptSessionTypes ?? [];
467
+ if (!refreshTokenBindingExemptSessionTypes.includes(decoded.sessionType)) {
468
+ const refreshToken = this.requestService.getRefreshToken();
469
+ if (!refreshToken) {
470
+ throw new UnauthorizedException2("Session validation failed");
471
+ }
472
+ this.tokenService.validateTokenBinding(decoded, refreshToken);
473
+ }
474
+ if (requiredSessionTypes?.length && !requiredSessionTypes.includes(decoded.sessionType)) {
475
+ this.logger.warn(`${route} \u2014 session type ${decoded.sessionType} not in allowed: [${requiredSessionTypes.join(", ")}]`);
476
+ throw new UnauthorizedException2(`${decoded.sessionType} sessions cannot access this endpoint`);
477
+ }
478
+ const { tokenType: _tokenType, refreshTokenHash: _hash, exp: _exp, iat: _iat, ...sessionInfo } = decoded;
479
+ request.sessionInfo = sessionInfo;
480
+ const onAuthenticated = this.config.guard.onAuthenticated;
481
+ if (onAuthenticated) {
482
+ await onAuthenticated(this.requestService, request.sessionInfo);
483
+ }
484
+ this.logger.debug(`${route} \u2014 authenticated user: ${decoded.userId} (${decoded.sessionType})`);
485
+ return decoded.sessionType;
486
+ }
487
+ // Authenticates SSE connections using the refresh token httpOnly cookie
488
+ handleSseAuth(request, requiredSessionTypes) {
489
+ const refreshToken = this.requestService.getRefreshToken();
490
+ if (!refreshToken) {
491
+ this.logger.warn(`SSE ${request.url} \u2014 no refresh token cookie`);
492
+ throw new UnauthorizedException2("Authentication required");
493
+ }
494
+ const decoded = this.tokenService.validateRefreshToken(refreshToken);
495
+ if (requiredSessionTypes?.length && !requiredSessionTypes.includes(decoded.sessionType)) {
496
+ this.logger.warn(`SSE ${request.url} \u2014 session type ${decoded.sessionType} not allowed`);
497
+ throw new UnauthorizedException2(`${decoded.sessionType} sessions cannot access this endpoint`);
498
+ }
499
+ const { tokenType: _tokenType, exp: _exp, iat: _iat, ...sessionInfo } = decoded;
500
+ request.sessionInfo = sessionInfo;
501
+ this.logger.debug(`SSE ${request.url} \u2014 authenticated user: ${decoded.userId} (${decoded.sessionType})`);
502
+ return true;
503
+ }
504
+ // Validates CSRF token for state-changing requests
505
+ async validateCsrf(request, reply) {
506
+ const safeMethods = [
507
+ "GET",
508
+ "HEAD",
509
+ "OPTIONS"
510
+ ];
511
+ if (safeMethods.includes(request.method)) return;
512
+ try {
513
+ const fastifyInstance = request.server;
514
+ const csrfProtection = fastifyInstance.csrfProtection;
515
+ if (!csrfProtection) {
516
+ throw new ForbiddenException("CSRF protection not configured");
517
+ }
518
+ await new Promise((resolve, reject) => {
519
+ const originalSend = reply.send.bind(reply);
520
+ reply.send = () => {
521
+ reply.send = originalSend;
522
+ reject(new Error("CSRF validation failed"));
523
+ return reply;
524
+ };
525
+ csrfProtection(request, reply, (err) => {
526
+ reply.send = originalSend;
527
+ if (err) reject(err);
528
+ else resolve();
529
+ });
530
+ });
531
+ } catch (_error) {
532
+ this.logger.warn(`${request.method} ${request.url} \u2014 CSRF validation failed`);
533
+ throw new ForbiddenException({
534
+ errors: [
535
+ {
536
+ field: "csrf",
537
+ message: "Invalid or missing CSRF token"
538
+ }
539
+ ],
540
+ message: "CSRF validation failed"
541
+ });
542
+ }
543
+ }
544
+ };
545
+ VrittiAuthGuard = _ts_decorate4([
546
+ Injectable3({
547
+ scope: Scope2.REQUEST
548
+ }),
549
+ _ts_param3(3, Inject3(AUTH_CONFIG)),
550
+ _ts_metadata3("design:type", Function),
551
+ _ts_metadata3("design:paramtypes", [
552
+ typeof Reflector === "undefined" ? Object : Reflector,
553
+ typeof RequestService === "undefined" ? Object : RequestService,
554
+ typeof TokenService === "undefined" ? Object : TokenService,
555
+ typeof AuthConfig === "undefined" ? Object : AuthConfig
556
+ ])
557
+ ], VrittiAuthGuard);
558
+
559
+ // src/auth/auth-config.module.ts
560
+ function _ts_decorate5(decorators, target, key, desc) {
561
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
562
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
563
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
564
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
565
+ }
566
+ __name(_ts_decorate5, "_ts_decorate");
567
+ function mergeWithDefaults(input) {
568
+ return {
569
+ tokenExpiry: input.tokenExpiry,
570
+ cookie: {
571
+ ...AUTH_CONFIG_DEFAULTS.cookie,
572
+ ...input.cookie ?? {}
573
+ },
574
+ guard: {
575
+ ...AUTH_CONFIG_DEFAULTS.guard,
576
+ ...input.guard ?? {}
577
+ }
578
+ };
579
+ }
580
+ __name(mergeWithDefaults, "mergeWithDefaults");
581
+ var AuthConfigModule = class _AuthConfigModule {
582
+ static {
583
+ __name(this, "AuthConfigModule");
584
+ }
585
+ // Registers JWT, TokenService, and global VrittiAuthGuard
586
+ static forRootAsync(options) {
587
+ return {
588
+ module: _AuthConfigModule,
589
+ imports: [
590
+ ConfigModule,
591
+ RequestModule,
592
+ JwtModule.registerAsync({
593
+ imports: [
594
+ ConfigModule
595
+ ],
596
+ inject: [
597
+ ConfigService
598
+ ],
599
+ useFactory: /* @__PURE__ */ __name((config) => ({
600
+ secret: config.getOrThrow("JWT_SECRET"),
601
+ signOptions: {
602
+ algorithm: "HS256"
603
+ }
604
+ }), "useFactory")
605
+ })
606
+ ],
607
+ providers: [
608
+ {
609
+ provide: Reflector2,
610
+ useClass: Reflector2
611
+ },
612
+ {
613
+ provide: APP_GUARD,
614
+ useClass: VrittiAuthGuard
615
+ },
616
+ {
617
+ provide: AUTH_CONFIG,
618
+ useFactory: /* @__PURE__ */ __name(async (...args) => {
619
+ const input = await options.useFactory(...args);
620
+ return mergeWithDefaults(input);
621
+ }, "useFactory"),
622
+ inject: options.inject || []
623
+ },
624
+ TokenService
625
+ ],
626
+ exports: [
627
+ JwtModule,
628
+ TokenService,
629
+ AUTH_CONFIG
630
+ ]
631
+ };
632
+ }
633
+ };
634
+ AuthConfigModule = _ts_decorate5([
635
+ Global2(),
636
+ Module2({})
637
+ ], AuthConfigModule);
638
+
639
+ // src/auth/decorators/access-token.decorator.ts
640
+ import { createParamDecorator } from "@nestjs/common";
641
+ var AccessToken = createParamDecorator((_data, ctx) => {
642
+ const request = getRequestFromContext(ctx);
643
+ const authHeader = request.headers.authorization;
644
+ return authHeader?.replace("Bearer ", "") || "";
645
+ });
646
+
647
+ // src/auth/decorators/client-ip.decorator.ts
648
+ import { createParamDecorator as createParamDecorator2 } from "@nestjs/common";
649
+ var ClientIp = createParamDecorator2((_data, ctx) => {
650
+ return getRequestFromContext(ctx).ip;
651
+ });
652
+
653
+ // src/auth/decorators/cookie-domain.decorator.ts
654
+ import { createParamDecorator as createParamDecorator3 } from "@nestjs/common";
655
+ var CookieDomain = createParamDecorator3((_data, ctx) => {
656
+ const request = getRequestFromContext(ctx);
657
+ const forwarded = request.headers["x-forwarded-host"];
658
+ const raw = Array.isArray(forwarded) ? forwarded[0] : forwarded;
659
+ const hostStr = raw ?? request.hostname;
660
+ const domain = hostStr.split(":")[0] ?? hostStr;
661
+ const baseDomain = request.authConfig?.cookie.refreshCookieDomain ?? AUTH_CONFIG_DEFAULTS.cookie.refreshCookieDomain ?? "";
662
+ return domain.endsWith(`.${baseDomain}`) ? domain : baseDomain;
663
+ });
664
+
665
+ // src/auth/decorators/cookie-name.decorator.ts
666
+ import { createParamDecorator as createParamDecorator4 } from "@nestjs/common";
667
+ var CookieName = createParamDecorator4((_data, ctx) => {
668
+ const request = getRequestFromContext(ctx);
669
+ return request.authConfig?.cookie.refreshCookieName ?? AUTH_CONFIG_DEFAULTS.cookie.refreshCookieName;
670
+ });
671
+
672
+ // src/auth/decorators/hostname.decorator.ts
673
+ import { createParamDecorator as createParamDecorator5 } from "@nestjs/common";
674
+ var Hostname = createParamDecorator5((_data, ctx) => {
675
+ const request = getRequestFromContext(ctx);
676
+ const forwarded = request.headers["x-forwarded-host"];
677
+ const raw = Array.isArray(forwarded) ? forwarded[0] : forwarded;
678
+ const hostStr = raw ?? request.hostname;
679
+ return hostStr.split(":")[0] ?? hostStr;
680
+ });
681
+
682
+ // src/auth/decorators/public.decorator.ts
683
+ import { SetMetadata as SetMetadata3 } from "@nestjs/common";
684
+ var Public = /* @__PURE__ */ __name(() => SetMetadata3("isPublic", true), "Public");
685
+
686
+ // src/auth/decorators/refresh-cookie-options.decorator.ts
687
+ import { createParamDecorator as createParamDecorator6 } from "@nestjs/common";
688
+
689
+ // src/exceptions/bad-gateway.exception.ts
690
+ import { HttpStatus } from "@nestjs/common";
691
+
692
+ // src/exceptions/base-field.exception.ts
693
+ import { HttpException } from "@nestjs/common";
694
+ var HttpProblemException = class extends HttpException {
695
+ static {
696
+ __name(this, "HttpProblemException");
697
+ }
698
+ constructor(detailOrOptions, httpStatus) {
699
+ const options = typeof detailOrOptions === "string" ? {
700
+ detail: detailOrOptions
701
+ } : detailOrOptions;
702
+ super({
703
+ type: options.type ?? "about:blank",
704
+ label: options.label,
705
+ detail: options.detail,
706
+ errors: options.errors ?? []
707
+ }, httpStatus);
708
+ }
709
+ };
710
+
711
+ // src/exceptions/bad-request.exception.ts
712
+ import { HttpStatus as HttpStatus2 } from "@nestjs/common";
713
+
714
+ // src/exceptions/conflict.exception.ts
715
+ import { HttpStatus as HttpStatus3 } from "@nestjs/common";
716
+
717
+ // src/exceptions/forbidden.exception.ts
718
+ import { HttpStatus as HttpStatus4 } from "@nestjs/common";
719
+
720
+ // src/exceptions/gone.exception.ts
721
+ import { HttpStatus as HttpStatus5 } from "@nestjs/common";
722
+
723
+ // src/exceptions/internal-server-error.exception.ts
724
+ import { HttpStatus as HttpStatus6 } from "@nestjs/common";
725
+
726
+ // src/exceptions/method-not-allowed.exception.ts
727
+ import { HttpStatus as HttpStatus7 } from "@nestjs/common";
728
+
729
+ // src/exceptions/not-acceptable.exception.ts
730
+ import { HttpStatus as HttpStatus8 } from "@nestjs/common";
731
+
732
+ // src/exceptions/not-found.exception.ts
733
+ import { HttpStatus as HttpStatus9 } from "@nestjs/common";
734
+
735
+ // src/exceptions/not-implemented.exception.ts
736
+ import { HttpStatus as HttpStatus10 } from "@nestjs/common";
737
+
738
+ // src/exceptions/payload-too-large.exception.ts
739
+ import { HttpStatus as HttpStatus11 } from "@nestjs/common";
740
+
741
+ // src/exceptions/request-timeout.exception.ts
742
+ import { HttpStatus as HttpStatus12 } from "@nestjs/common";
743
+
744
+ // src/exceptions/service-unavailable.exception.ts
745
+ import { HttpStatus as HttpStatus13 } from "@nestjs/common";
746
+
747
+ // src/exceptions/too-many-requests.exception.ts
748
+ import { HttpStatus as HttpStatus14 } from "@nestjs/common";
749
+
750
+ // src/exceptions/unauthorized.exception.ts
751
+ import { HttpStatus as HttpStatus15 } from "@nestjs/common";
752
+ var UnauthorizedException3 = class extends HttpProblemException {
753
+ static {
754
+ __name(this, "UnauthorizedException");
755
+ }
756
+ constructor(detailOrOptions) {
757
+ super(detailOrOptions ?? "Unauthorized", HttpStatus15.UNAUTHORIZED);
758
+ }
759
+ };
760
+
761
+ // src/exceptions/unprocessable-entity.exception.ts
762
+ import { HttpStatus as HttpStatus16 } from "@nestjs/common";
763
+
764
+ // src/exceptions/unsupported-media-type.exception.ts
765
+ import { HttpStatus as HttpStatus17 } from "@nestjs/common";
766
+
767
+ // src/exceptions/validation.exception.ts
768
+ import { HttpStatus as HttpStatus18 } from "@nestjs/common";
769
+
770
+ // src/auth/decorators/refresh-cookie-options.decorator.ts
771
+ function buildCookieOptionsForHost(cookieConfig, hostname) {
772
+ const baseDomain = cookieConfig.refreshCookieDomain;
773
+ if (!baseDomain) {
774
+ throw new Error("refreshCookieDomain must be configured before using @RefreshCookieOptions()");
775
+ }
776
+ if (!hostname.endsWith(`.${baseDomain}`)) {
777
+ throw new UnauthorizedException3("Invalid request host.");
778
+ }
779
+ return {
780
+ httpOnly: true,
781
+ secure: cookieConfig.refreshCookieSecure,
782
+ sameSite: cookieConfig.refreshCookieSameSite,
783
+ path: cookieConfig.refreshCookiePath,
784
+ maxAge: cookieConfig.refreshCookieMaxAge,
785
+ domain: hostname
786
+ };
787
+ }
788
+ __name(buildCookieOptionsForHost, "buildCookieOptionsForHost");
789
+ var RefreshCookieOptions = createParamDecorator6((_data, ctx) => {
790
+ const request = getRequestFromContext(ctx);
791
+ const forwarded = request.headers["x-forwarded-host"];
792
+ const raw = Array.isArray(forwarded) ? forwarded[0] : forwarded;
793
+ const hostStr = raw ?? request.hostname;
794
+ const domain = hostStr.split(":")[0] ?? hostStr;
795
+ const cookieConfig = request.authConfig?.cookie ?? AUTH_CONFIG_DEFAULTS.cookie;
796
+ return buildCookieOptionsForHost(cookieConfig, domain);
797
+ });
798
+
799
+ // src/auth/decorators/refresh-token-cookie.decorator.ts
800
+ import { createParamDecorator as createParamDecorator7 } from "@nestjs/common";
801
+ var RefreshTokenCookie = createParamDecorator7((_data, ctx) => {
802
+ const request = getRequestFromContext(ctx);
803
+ const cookies = request.cookies ?? {};
804
+ const cookieName = request.authConfig?.cookie.refreshCookieName ?? AUTH_CONFIG_DEFAULTS.cookie.refreshCookieName;
805
+ return cookies[cookieName];
806
+ });
807
+
808
+ // src/auth/decorators/session-data.decorator.ts
809
+ import { createParamDecorator as createParamDecorator8 } from "@nestjs/common";
810
+ var SessionData = createParamDecorator8((_data, ctx) => {
811
+ const request = getRequestFromContext(ctx);
812
+ const sessionInfo = request.sessionInfo;
813
+ if (!sessionInfo?.sessionId) {
814
+ throw new Error("Session info not found on request. Ensure route is protected by auth guard.");
815
+ }
816
+ return {
817
+ userId: sessionInfo.userId,
818
+ sessionId: sessionInfo.sessionId,
819
+ sessionType: sessionInfo.sessionType
820
+ };
821
+ });
822
+
823
+ // src/auth/decorators/subdomain.decorator.ts
824
+ import { createParamDecorator as createParamDecorator9 } from "@nestjs/common";
825
+ var Subdomain = createParamDecorator9((_data, ctx) => {
826
+ const request = getRequestFromContext(ctx);
827
+ const origin = request.headers.origin;
828
+ if (origin) {
829
+ try {
830
+ const url = new URL(origin);
831
+ return url.hostname.split(".")[0];
832
+ } catch {
833
+ }
834
+ }
835
+ const forwarded = request.headers["x-forwarded-host"];
836
+ const host = Array.isArray(forwarded) ? forwarded[0] : forwarded;
837
+ if (host) return host.split(".")[0];
838
+ return void 0;
839
+ });
840
+
841
+ // src/auth/decorators/user-agent.decorator.ts
842
+ import { createParamDecorator as createParamDecorator10 } from "@nestjs/common";
843
+ var UserAgent = createParamDecorator10((_data, ctx) => {
844
+ const userAgent = getRequestFromContext(ctx).headers["user-agent"];
845
+ return Array.isArray(userAgent) ? userAgent[0] : userAgent;
846
+ });
847
+
848
+ // src/auth/decorators/user-id.decorator.ts
849
+ import { createParamDecorator as createParamDecorator11 } from "@nestjs/common";
850
+ var UserId = createParamDecorator11((_data, ctx) => {
851
+ const request = getRequestFromContext(ctx);
852
+ const sessionInfo = request.sessionInfo;
853
+ if (!sessionInfo?.userId) {
854
+ throw new Error("User ID not found on request. Ensure route is protected by auth guard.");
855
+ }
856
+ return sessionInfo.userId;
857
+ });
858
+ export {
859
+ AUTH_CONFIG,
860
+ AUTH_CONFIG_DEFAULTS,
861
+ AccessToken,
862
+ AuthConfigModule,
863
+ ClientIp,
864
+ CookieDomain,
865
+ CookieName,
866
+ Hostname,
867
+ Public,
868
+ REQUIRE_SESSION_KEY,
869
+ RefreshCookieOptions,
870
+ RefreshTokenCookie,
871
+ RequireSession,
872
+ SKIP_CSRF_KEY,
873
+ SessionData,
874
+ SkipCsrf,
875
+ Subdomain,
876
+ TokenService,
877
+ TokenType,
878
+ UserAgent,
879
+ UserId,
880
+ VrittiAuthGuard,
881
+ hashToken,
882
+ verifyTokenHash
883
+ };
884
+ //# sourceMappingURL=auth.js.map