@xeno-js/core 0.1.2 → 0.1.3

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.js CHANGED
@@ -1365,8 +1365,7 @@ var init_sentry_logger_factory = __esm({
1365
1365
  dsn: sentryConfig.dsn,
1366
1366
  environment: env,
1367
1367
  tracesSampleRate: env === "production" ? 0.1 : 1,
1368
- sendDefaultPii: false,
1369
- integrations: [new Sentry.Integrations.Http({ tracing: true })],
1368
+ integrations: [Sentry.httpIntegration()],
1370
1369
  beforeSend(event, hint) {
1371
1370
  const error = hint.originalException;
1372
1371
  if (error instanceof Error && error.name === "ZodError") {
@@ -1509,15 +1508,15 @@ var init_logger_utils = __esm({
1509
1508
  */
1510
1509
  async addLogger(container, opts) {
1511
1510
  const loggerDependencies = [];
1512
- const { Guards: Guards39, LOG_LEVEL: LOG_LEVEL7, TOKENS: TOKENS4 } = await import("@xeno-js/shared");
1513
- if (!Guards39.isDefined(opts) || opts.console) {
1511
+ const { Guards: Guards45, LOG_LEVEL: LOG_LEVEL7, TOKENS: TOKENS4 } = await import("@xeno-js/shared");
1512
+ if (!Guards45.isDefined(opts) || opts.console) {
1514
1513
  const { ConsoleLogger: ConsoleLogger2 } = await Promise.resolve().then(() => (init_console_logger(), console_logger_exports));
1515
1514
  container.addSingleton(TOKENS4.CONSOLE_LOGGER, () => new ConsoleLogger2(opts?.level));
1516
1515
  loggerDependencies.push(TOKENS4.CONSOLE_LOGGER);
1517
1516
  }
1518
1517
  const customLoggerFactories = [];
1519
- if (Guards39.isDefined(opts)) {
1520
- if (Guards39.isDefined(opts.sentry.config)) {
1518
+ if (Guards45.isDefined(opts)) {
1519
+ if (Guards45.isDefined(opts.sentry.config)) {
1521
1520
  const { SentryLoggerFactory: SentryLoggerFactory2 } = await Promise.resolve().then(() => (init_sentry_logger_factory(), sentry_logger_factory_exports));
1522
1521
  container.addSingleton(TOKENS4.SENTRY_LOGGER, () => {
1523
1522
  const factory = new SentryLoggerFactory2();
@@ -1525,7 +1524,7 @@ var init_logger_utils = __esm({
1525
1524
  });
1526
1525
  loggerDependencies.push(TOKENS4.SENTRY_LOGGER);
1527
1526
  }
1528
- if (Guards39.isDefined(opts.pino.config)) {
1527
+ if (Guards45.isDefined(opts.pino.config)) {
1529
1528
  const { PinoLoggerFactory: PinoLoggerFactory2 } = await Promise.resolve().then(() => (init_pino_logger_factory(), pino_logger_factory_exports));
1530
1529
  container.addSingleton(TOKENS4.PINO_LOGGER, () => {
1531
1530
  const factory = new PinoLoggerFactory2();
@@ -1533,10 +1532,10 @@ var init_logger_utils = __esm({
1533
1532
  });
1534
1533
  loggerDependencies.push(TOKENS4.PINO_LOGGER);
1535
1534
  }
1536
- if (!Guards39.isNullOrEmpty(opts.customLoggers)) {
1535
+ if (!Guards45.isNullOrEmpty(opts.customLoggers)) {
1537
1536
  const customLoggers = opts.customLoggers;
1538
1537
  customLoggers.forEach((f) => {
1539
- if (Guards39.isDefined(f)) {
1538
+ if (Guards45.isDefined(f)) {
1540
1539
  customLoggerFactories.push(f);
1541
1540
  }
1542
1541
  });
@@ -1556,8 +1555,30 @@ var init_logger_utils = __esm({
1556
1555
  }
1557
1556
  });
1558
1557
 
1558
+ // src/infrastructure/cache/inmemory.cache.ts
1559
+ var inmemory_cache_exports = {};
1560
+ __export(inmemory_cache_exports, {
1561
+ InMemoryCacheExtended: () => InMemoryCacheExtended
1562
+ });
1563
+ import { Guards as Guards19, InMemoryCache } from "@xeno-js/shared";
1564
+ var InMemoryCacheExtended;
1565
+ var init_inmemory_cache = __esm({
1566
+ "src/infrastructure/cache/inmemory.cache.ts"() {
1567
+ "use strict";
1568
+ InMemoryCacheExtended = class extends InMemoryCache {
1569
+ async increment(key, ttlSeconds) {
1570
+ const current = await this.get(key) ?? 0;
1571
+ const next = Number(current) + 1;
1572
+ const ttl = Guards19.isDefined(ttlSeconds) ? Number(ttlSeconds) : 60;
1573
+ await this.set(key, next, ttl);
1574
+ return next;
1575
+ }
1576
+ };
1577
+ }
1578
+ });
1579
+
1559
1580
  // src/infrastructure/cache/redis.cache.ts
1560
- import { Guards as Guards19, StringHelper } from "@xeno-js/shared";
1581
+ import { Guards as Guards20, StringHelper } from "@xeno-js/shared";
1561
1582
  var RedisCache;
1562
1583
  var init_redis_cache = __esm({
1563
1584
  "src/infrastructure/cache/redis.cache.ts"() {
@@ -1577,21 +1598,28 @@ var init_redis_cache = __esm({
1577
1598
  this._redisClient = _redisClient;
1578
1599
  }
1579
1600
  _redisClient;
1601
+ async increment(key, ttlSeconds) {
1602
+ const multi = this._redisClient.multi();
1603
+ multi.incr(key);
1604
+ multi.expire(key, ttlSeconds ?? 60);
1605
+ const results = await multi.exec();
1606
+ return results?.[0]?.[1] ?? 1;
1607
+ }
1580
1608
  async get(key) {
1581
1609
  const value = await this._redisClient.get(key);
1582
- if (!Guards19.isDefined(value)) {
1610
+ if (!Guards20.isDefined(value)) {
1583
1611
  return void 0;
1584
1612
  }
1585
1613
  return JSON.parse(value);
1586
1614
  }
1587
1615
  async set(key, value, ttl) {
1588
1616
  const stringValue = StringHelper.safeStringify(value);
1589
- const ttlOption = Guards19.isDefined(ttl) ? ttl : 86400;
1617
+ const ttlOption = Guards20.isDefined(ttl) ? ttl : 86400;
1590
1618
  await this._redisClient.set(key, stringValue, "EX", ttlOption);
1591
1619
  }
1592
1620
  async setIfAbsent(key, value, ttl) {
1593
1621
  const stringValue = StringHelper.safeStringify(value);
1594
- const ttlOption = Guards19.isDefined(ttl) ? ttl : 300;
1622
+ const ttlOption = Guards20.isDefined(ttl) ? ttl : 300;
1595
1623
  const result = await this._redisClient.set(key, stringValue, "EX", ttlOption, "NX");
1596
1624
  return result === "OK";
1597
1625
  }
@@ -1614,7 +1642,7 @@ var redis_cache_factory_exports = {};
1614
1642
  __export(redis_cache_factory_exports, {
1615
1643
  RedisCacheFactory: () => RedisCacheFactory
1616
1644
  });
1617
- import { Guards as Guards20 } from "@xeno-js/shared";
1645
+ import { Guards as Guards21 } from "@xeno-js/shared";
1618
1646
  import { Redis } from "ioredis";
1619
1647
  var RedisCacheFactory;
1620
1648
  var init_redis_cache_factory = __esm({
@@ -1639,10 +1667,10 @@ var init_redis_cache_factory = __esm({
1639
1667
  return delay;
1640
1668
  }
1641
1669
  };
1642
- if (Guards20.isDefined(password)) {
1670
+ if (Guards21.isDefined(password)) {
1643
1671
  redisOptions.password = password;
1644
1672
  }
1645
- if (Guards20.isDefined(username)) {
1673
+ if (Guards21.isDefined(username)) {
1646
1674
  redisOptions.username = username;
1647
1675
  }
1648
1676
  if (useTls) {
@@ -1680,8 +1708,8 @@ var init_cache_utils = __esm({
1680
1708
  * @link https://github.com/xeno-js/xeno-js
1681
1709
  */
1682
1710
  async addCache(container, opts) {
1683
- const { Guards: Guards39, TOKENS: TOKENS4 } = await import("@xeno-js/shared");
1684
- if (!opts.inMemory && !Guards39.isDefined(opts.redis)) {
1711
+ const { Guards: Guards45, TOKENS: TOKENS4 } = await import("@xeno-js/shared");
1712
+ if (!opts.inMemory && !Guards45.isDefined(opts.redis)) {
1685
1713
  throw new Error(
1686
1714
  "No cache strategies are configured. Please provide at least one cache strategy."
1687
1715
  );
@@ -1691,12 +1719,12 @@ var init_cache_utils = __esm({
1691
1719
  TOKENS4.CACHE_KEY_BUILDER,
1692
1720
  (c) => new CacheKeyBuilder(c.resolve(TOKENS4.IDENTITY_ACCESSOR))
1693
1721
  );
1694
- if (opts.inMemory || !Guards39.isDefined(opts.redis)) {
1695
- const { InMemoryCache } = await import("@xeno-js/shared");
1696
- container.addSingleton(TOKENS4.CACHE, () => new InMemoryCache());
1722
+ if (opts.inMemory || !Guards45.isDefined(opts.redis)) {
1723
+ const { InMemoryCacheExtended: InMemoryCacheExtended2 } = await Promise.resolve().then(() => (init_inmemory_cache(), inmemory_cache_exports));
1724
+ container.addSingleton(TOKENS4.CACHE, () => new InMemoryCacheExtended2());
1697
1725
  return;
1698
1726
  }
1699
- if (Guards39.isDefined(opts.redis)) {
1727
+ if (Guards45.isDefined(opts.redis)) {
1700
1728
  const { RedisCacheFactory: RedisCacheFactory2 } = await Promise.resolve().then(() => (init_redis_cache_factory(), redis_cache_factory_exports));
1701
1729
  container.addSingleton(TOKENS4.CACHE, () => {
1702
1730
  const config = opts.redis;
@@ -1709,7 +1737,7 @@ var init_cache_utils = __esm({
1709
1737
  });
1710
1738
 
1711
1739
  // src/infrastructure/services/allow_methods/allow-method.service.ts
1712
- import { Guards as Guards21 } from "@xeno-js/shared";
1740
+ import { Guards as Guards22 } from "@xeno-js/shared";
1713
1741
  var AllowMethodRegistry;
1714
1742
  var init_allow_method_service = __esm({
1715
1743
  "src/infrastructure/services/allow_methods/allow-method.service.ts"() {
@@ -1729,7 +1757,7 @@ var init_allow_method_service = __esm({
1729
1757
  check(path, method) {
1730
1758
  const cleanPath = this.normalizePath(path.split("?")[0].split("#")[0]);
1731
1759
  const staticMethods = this._staticRoutes.get(cleanPath);
1732
- if (Guards21.isDefined(staticMethods)) return staticMethods.includes(method);
1760
+ if (Guards22.isDefined(staticMethods)) return staticMethods.includes(method);
1733
1761
  for (const route of this._dynamicRoutes) {
1734
1762
  if (route.pattern.test(cleanPath)) return route.methods.includes(method);
1735
1763
  }
@@ -1766,7 +1794,7 @@ var init_allow_methods = __esm({
1766
1794
  });
1767
1795
 
1768
1796
  // src/infrastructure/services/allow_origins/allow-origin.http.ts
1769
- import { Guards as Guards22 } from "@xeno-js/shared";
1797
+ import { Guards as Guards23 } from "@xeno-js/shared";
1770
1798
  var AllowOrigin;
1771
1799
  var init_allow_origin_http = __esm({
1772
1800
  "src/infrastructure/services/allow_origins/allow-origin.http.ts"() {
@@ -1777,7 +1805,7 @@ var init_allow_origin_http = __esm({
1777
1805
  }
1778
1806
  _list;
1779
1807
  isAllowed(origin) {
1780
- if (Guards22.isNullOrEmpty(origin)) return true;
1808
+ if (Guards23.isNullOrEmpty(origin)) return true;
1781
1809
  const cleanOrigin = origin.trim().toLowerCase();
1782
1810
  for (const pattern of this._list) {
1783
1811
  const cleanPattern = pattern.trim().toLowerCase();
@@ -1787,7 +1815,7 @@ var init_allow_origin_http = __esm({
1787
1815
  const domainSuffix = cleanPattern.substring(1);
1788
1816
  if (cleanOrigin.endsWith(domainSuffix)) {
1789
1817
  const prefix = cleanOrigin.slice(0, cleanOrigin.length - domainSuffix.length);
1790
- if (!Guards22.isNullOrEmpty(prefix) && !prefix.includes(".")) return true;
1818
+ if (!Guards23.isNullOrEmpty(prefix) && !prefix.includes(".")) return true;
1791
1819
  }
1792
1820
  }
1793
1821
  }
@@ -1833,8 +1861,108 @@ var init_concurrency = __esm({
1833
1861
  }
1834
1862
  });
1835
1863
 
1864
+ // src/infrastructure/services/crypto/crypto.service.ts
1865
+ var EdgeCryptoService;
1866
+ var init_crypto_service = __esm({
1867
+ "src/infrastructure/services/crypto/crypto.service.ts"() {
1868
+ "use strict";
1869
+ EdgeCryptoService = class {
1870
+ randomBytes(size) {
1871
+ const buffer = new Uint8Array(size);
1872
+ crypto.getRandomValues(buffer);
1873
+ return buffer;
1874
+ }
1875
+ async hmacSha256(secret, data) {
1876
+ const encoder = new TextEncoder();
1877
+ const keyData = encoder.encode(secret);
1878
+ const messageData = encoder.encode(data);
1879
+ const cryptoKey = await crypto.subtle.importKey(
1880
+ "raw",
1881
+ keyData,
1882
+ { name: "HMAC", hash: "SHA-256" },
1883
+ false,
1884
+ ["sign"]
1885
+ );
1886
+ const signature = await crypto.subtle.sign("HMAC", cryptoKey, messageData);
1887
+ return btoa(String.fromCharCode(...new Uint8Array(signature))).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
1888
+ }
1889
+ timingSafeEqual(a, b) {
1890
+ if (a.length !== b.length) {
1891
+ return false;
1892
+ }
1893
+ let mismatch = 0;
1894
+ for (let i = 0; i < a.length; i++) {
1895
+ mismatch |= a[i] ^ b[i];
1896
+ }
1897
+ return mismatch === 0;
1898
+ }
1899
+ };
1900
+ }
1901
+ });
1902
+
1903
+ // src/infrastructure/services/crypto/index.ts
1904
+ var init_crypto = __esm({
1905
+ "src/infrastructure/services/crypto/index.ts"() {
1906
+ "use strict";
1907
+ init_crypto_service();
1908
+ }
1909
+ });
1910
+
1911
+ // src/infrastructure/services/csrf/csrf-token.service.ts
1912
+ import { Guards as Guards24 } from "@xeno-js/shared";
1913
+ var CsrfTokenService;
1914
+ var init_csrf_token_service = __esm({
1915
+ "src/infrastructure/services/csrf/csrf-token.service.ts"() {
1916
+ "use strict";
1917
+ CsrfTokenService = class {
1918
+ constructor(_secret, _cryptoService) {
1919
+ this._secret = _secret;
1920
+ this._cryptoService = _cryptoService;
1921
+ }
1922
+ _secret;
1923
+ _cryptoService;
1924
+ async generate(subject) {
1925
+ const randomBuffer = this._cryptoService.randomBytes(32);
1926
+ const nonce = btoa(String.fromCharCode(...randomBuffer)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
1927
+ const signature = await this._cryptoService.hmacSha256(
1928
+ this._secret,
1929
+ `${subject}.${nonce}`
1930
+ );
1931
+ return `${nonce}.${signature}`;
1932
+ }
1933
+ async validate(token, subject) {
1934
+ const separatorIndex = token.indexOf(".");
1935
+ if (separatorIndex <= 0)
1936
+ return false;
1937
+ const nonce = token.slice(0, separatorIndex);
1938
+ const signature = token.slice(separatorIndex + 1);
1939
+ if (Guards24.isNullOrEmpty(nonce) || Guards24.isNullOrEmpty(signature))
1940
+ return false;
1941
+ const expected = await this._cryptoService.hmacSha256(
1942
+ this._secret,
1943
+ `${subject}.${nonce}`
1944
+ );
1945
+ const encoder = new TextEncoder();
1946
+ const actualBuffer = encoder.encode(signature);
1947
+ const expectedBuffer = encoder.encode(expected);
1948
+ if (actualBuffer.length !== expectedBuffer.length)
1949
+ return false;
1950
+ return this._cryptoService.timingSafeEqual(actualBuffer, expectedBuffer);
1951
+ }
1952
+ };
1953
+ }
1954
+ });
1955
+
1956
+ // src/infrastructure/services/csrf/index.ts
1957
+ var init_csrf = __esm({
1958
+ "src/infrastructure/services/csrf/index.ts"() {
1959
+ "use strict";
1960
+ init_csrf_token_service();
1961
+ }
1962
+ });
1963
+
1836
1964
  // src/infrastructure/services/extractors/extract-bearer.extractor.ts
1837
- import { Guards as Guards23, StringHelper as StringHelper2 } from "@xeno-js/shared";
1965
+ import { Guards as Guards25, StringHelper as StringHelper2 } from "@xeno-js/shared";
1838
1966
  var BearerTokenExtractor;
1839
1967
  var init_extract_bearer_extractor = __esm({
1840
1968
  "src/infrastructure/services/extractors/extract-bearer.extractor.ts"() {
@@ -1842,16 +1970,16 @@ var init_extract_bearer_extractor = __esm({
1842
1970
  BearerTokenExtractor = class {
1843
1971
  extract(headers) {
1844
1972
  const authHeader = StringHelper2.getSingleValue(headers["authorization"]);
1845
- if (!Guards23.isDefined(authHeader)) {
1973
+ if (!Guards25.isDefined(authHeader)) {
1846
1974
  return void 0;
1847
1975
  }
1848
1976
  if (authHeader.toLowerCase().startsWith("bearer ")) {
1849
1977
  return authHeader.substring(7);
1850
1978
  }
1851
1979
  const cookieHeader = StringHelper2.getSingleValue(headers["cookie"]);
1852
- if (Guards23.isDefined(cookieHeader)) {
1980
+ if (Guards25.isDefined(cookieHeader)) {
1853
1981
  const match = /sb-access-token=([^;]+)/.exec(cookieHeader);
1854
- if (!Guards23.isNullOrEmpty(match) && Guards23.isDefined(match[1])) {
1982
+ if (!Guards25.isNullOrEmpty(match) && Guards25.isDefined(match[1])) {
1855
1983
  return match[1].trim();
1856
1984
  }
1857
1985
  }
@@ -1863,7 +1991,7 @@ var init_extract_bearer_extractor = __esm({
1863
1991
 
1864
1992
  // src/infrastructure/services/extractors/extract-ssr-bearer.extractor.ts
1865
1993
  import {
1866
- Guards as Guards24,
1994
+ Guards as Guards26,
1867
1995
  StringHelper as StringHelper3
1868
1996
  } from "@xeno-js/shared";
1869
1997
  var SupabaseSsrTokenExtractor;
@@ -1873,36 +2001,36 @@ var init_extract_ssr_bearer_extractor = __esm({
1873
2001
  SupabaseSsrTokenExtractor = class {
1874
2002
  extract(headers) {
1875
2003
  const authHeader = StringHelper3.getSingleValue(headers["authorization"]);
1876
- if (Guards24.isDefined(authHeader) && authHeader.toLowerCase().startsWith("bearer ")) {
2004
+ if (Guards26.isDefined(authHeader) && authHeader.toLowerCase().startsWith("bearer ")) {
1877
2005
  return authHeader.substring(7);
1878
2006
  }
1879
2007
  const cookieHeader = StringHelper3.getSingleValue(headers["cookie"]);
1880
- if (Guards24.isNullOrEmpty(cookieHeader)) return void 0;
2008
+ if (Guards26.isNullOrEmpty(cookieHeader)) return void 0;
1881
2009
  const cookies = cookieHeader.split(";").map((c) => c.trim());
1882
2010
  const tokenChunks = {};
1883
2011
  let unchunkedToken;
1884
2012
  for (const cookie of cookies) {
1885
2013
  const [name, ...rest] = cookie.split("=");
1886
- if (!Guards24.isDefined(name) || Guards24.isNullOrEmpty(rest)) continue;
2014
+ if (!Guards26.isDefined(name) || Guards26.isNullOrEmpty(rest)) continue;
1887
2015
  const value = decodeURIComponent(rest.join("="));
1888
- if (Guards24.isDefined(/^sb-[a-z0-9]+-auth-token$/.exec(name))) {
2016
+ if (Guards26.isDefined(/^sb-[a-z0-9]+-auth-token$/.exec(name))) {
1889
2017
  unchunkedToken = value;
1890
2018
  } else {
1891
2019
  const match = /^sb-[a-z0-9]+-auth-token\.(\d+)$/.exec(name);
1892
- if (Guards24.isDefined(match)) tokenChunks[parseInt(match[1], 10)] = value;
2020
+ if (Guards26.isDefined(match)) tokenChunks[parseInt(match[1], 10)] = value;
1893
2021
  }
1894
2022
  }
1895
2023
  let fullTokenString = unchunkedToken;
1896
- if (!Guards24.isDefined(fullTokenString) && Object.keys(tokenChunks).length > 0) {
2024
+ if (!Guards26.isDefined(fullTokenString) && Object.keys(tokenChunks).length > 0) {
1897
2025
  const indices = Object.keys(tokenChunks).map(Number).sort((a, b) => a - b);
1898
2026
  fullTokenString = indices.map((i) => tokenChunks[i]).join("");
1899
2027
  }
1900
- if (Guards24.isNullOrEmpty(fullTokenString)) return void 0;
2028
+ if (Guards26.isNullOrEmpty(fullTokenString)) return void 0;
1901
2029
  try {
1902
2030
  const parsed = StringHelper3.safeParse(fullTokenString);
1903
- if (Guards24.isDefined(parsed) && Guards24.isObject(parsed) && "access_token" in parsed) {
2031
+ if (Guards26.isDefined(parsed) && Guards26.isObject(parsed) && "access_token" in parsed) {
1904
2032
  const accessToken = parsed["access_token"];
1905
- if (Guards24.isString(accessToken)) return accessToken;
2033
+ if (Guards26.isString(accessToken)) return accessToken;
1906
2034
  }
1907
2035
  } catch {
1908
2036
  return void 0;
@@ -1912,9 +2040,39 @@ var init_extract_ssr_bearer_extractor = __esm({
1912
2040
  }
1913
2041
  });
1914
2042
 
2043
+ // src/infrastructure/services/extractors/http-cookie.extractor.ts
2044
+ import { Guards as Guards27 } from "@xeno-js/shared";
2045
+ var HttpCookieExtractor;
2046
+ var init_http_cookie_extractor = __esm({
2047
+ "src/infrastructure/services/extractors/http-cookie.extractor.ts"() {
2048
+ "use strict";
2049
+ HttpCookieExtractor = class {
2050
+ extract(cookie) {
2051
+ if (!Guards27.isDefined(cookie.header))
2052
+ return void 0;
2053
+ for (const rawCookie of cookie.header.split(";")) {
2054
+ const separatorIndex = rawCookie.indexOf("=");
2055
+ if (separatorIndex <= 0)
2056
+ continue;
2057
+ const name = rawCookie.slice(0, separatorIndex).trim();
2058
+ if (name !== cookie.name)
2059
+ continue;
2060
+ const value = rawCookie.slice(separatorIndex + 1).trim();
2061
+ try {
2062
+ return decodeURIComponent(value);
2063
+ } catch {
2064
+ return void 0;
2065
+ }
2066
+ }
2067
+ return void 0;
2068
+ }
2069
+ };
2070
+ }
2071
+ });
2072
+
1915
2073
  // src/infrastructure/services/extractors/http-header.extractor.ts
1916
2074
  import {
1917
- Guards as Guards25,
2075
+ Guards as Guards28,
1918
2076
  GuidHelper as GuidHelper4,
1919
2077
  HttpHelper,
1920
2078
  MathHelper,
@@ -1934,12 +2092,16 @@ var init_http_header_extractor = __esm({
1934
2092
  * @since 2025-09-30
1935
2093
  * @link https://github.com/xeno-js/xeno-js
1936
2094
  */
1937
- constructor(_bearerExtractor, _trustedIp) {
2095
+ constructor(_bearerExtractor, _cookieExtractor, _trustedIp, _cookieName) {
1938
2096
  this._bearerExtractor = _bearerExtractor;
2097
+ this._cookieExtractor = _cookieExtractor;
1939
2098
  this._trustedIp = _trustedIp;
2099
+ this._cookieName = _cookieName;
1940
2100
  }
1941
2101
  _bearerExtractor;
2102
+ _cookieExtractor;
1942
2103
  _trustedIp;
2104
+ _cookieName;
1943
2105
  extract(headers) {
1944
2106
  const correlationId = GuidHelper4.parse(StringHelper4.getSingleValue(headers["x-correlation-id"]));
1945
2107
  const requestId = GuidHelper4.parse(StringHelper4.getSingleValue(headers["x-request-id"]));
@@ -1955,7 +2117,14 @@ var init_http_header_extractor = __esm({
1955
2117
  const position = StringHelper4.getSingleValue(headers["x-sequence-position"]);
1956
2118
  const size = StringHelper4.getSingleValue(headers["x-sequence-size"]);
1957
2119
  const expiration = StringHelper4.getSingleValue(headers["x-expiration"]);
1958
- const csrf = StringHelper4.getSingleValue(headers["x-requested-with"]);
2120
+ const csrf = StringHelper4.getSingleValue(headers["x-csrf-token"]);
2121
+ const cookieHeader = StringHelper4.getSingleValue(headers["cookie"]);
2122
+ const csrfCookie = this._cookieExtractor.extract(
2123
+ {
2124
+ header: cookieHeader,
2125
+ name: this._cookieName
2126
+ }
2127
+ );
1959
2128
  const origin = StringHelper4.getSingleValue(headers["origin"]);
1960
2129
  const cleanOrigin = HttpHelper.sanitizeOriginUrl(origin);
1961
2130
  const referer = StringHelper4.getSingleValue(headers["referer"]);
@@ -1973,14 +2142,15 @@ var init_http_header_extractor = __esm({
1973
2142
  userAgent,
1974
2143
  returnAddress,
1975
2144
  csrf,
2145
+ csrfCookie,
1976
2146
  origin: cleanOrigin,
1977
2147
  referer: cleanReferer,
1978
2148
  sequence: {
1979
2149
  sequenceId,
1980
- position: Guards25.isDefined(position) ? MathHelper.toNumber(position) : void 0,
1981
- size: Guards25.isDefined(size) ? MathHelper.toNumber(size) : void 0
2150
+ position: Guards28.isDefined(position) ? MathHelper.toNumber(position) : void 0,
2151
+ size: Guards28.isDefined(size) ? MathHelper.toNumber(size) : void 0
1982
2152
  },
1983
- expiration: Guards25.isDefined(expiration) ? MathHelper.toNumber(expiration) : void 0
2153
+ expiration: Guards28.isDefined(expiration) ? MathHelper.toNumber(expiration) : void 0
1984
2154
  };
1985
2155
  return metadata;
1986
2156
  }
@@ -1994,6 +2164,7 @@ var init_extractors = __esm({
1994
2164
  "use strict";
1995
2165
  init_extract_bearer_extractor();
1996
2166
  init_extract_ssr_bearer_extractor();
2167
+ init_http_cookie_extractor();
1997
2168
  init_http_header_extractor();
1998
2169
  }
1999
2170
  });
@@ -2025,12 +2196,82 @@ var init_resiliences = __esm({
2025
2196
  }
2026
2197
  });
2027
2198
 
2199
+ // src/infrastructure/services/resolver/utils/socket.utils.ts
2200
+ import { Guards as Guards29 } from "@xeno-js/shared";
2201
+ var SocketIpExtractor;
2202
+ var init_socket_utils = __esm({
2203
+ "src/infrastructure/services/resolver/utils/socket.utils.ts"() {
2204
+ "use strict";
2205
+ SocketIpExtractor = Object.freeze({
2206
+ /**
2207
+ * @description Extracts the IP address of the remote socket from an incoming request.
2208
+ * @param req The incoming request object.
2209
+ * @returns The IP address of the remote socket, or undefined if not available.
2210
+ */
2211
+ extract(req) {
2212
+ if (Guards29.isDefined(req) && Guards29.isObject(req)) {
2213
+ const candidate = req;
2214
+ return candidate.socket?.remoteAddress ?? candidate.connection?.remoteAddress;
2215
+ }
2216
+ return void 0;
2217
+ }
2218
+ });
2219
+ }
2220
+ });
2221
+
2222
+ // src/infrastructure/services/resolver/utils/index.ts
2223
+ var init_utils = __esm({
2224
+ "src/infrastructure/services/resolver/utils/index.ts"() {
2225
+ "use strict";
2226
+ init_socket_utils();
2227
+ }
2228
+ });
2229
+
2230
+ // src/infrastructure/services/resolver/client-ip.resolver.ts
2231
+ import { Guards as Guards30 } from "@xeno-js/shared";
2232
+ var ClientIpResolver;
2233
+ var init_client_ip_resolver = __esm({
2234
+ "src/infrastructure/services/resolver/client-ip.resolver.ts"() {
2235
+ "use strict";
2236
+ init_utils();
2237
+ ClientIpResolver = class {
2238
+ constructor(_trustedProxies = []) {
2239
+ this._trustedProxies = _trustedProxies;
2240
+ }
2241
+ _trustedProxies;
2242
+ resolve(req, clientIp) {
2243
+ const socketIp = SocketIpExtractor.extract(req);
2244
+ if (!Guards30.isDefined(socketIp))
2245
+ return !Guards30.isNullOrEmpty(clientIp) ? clientIp.split(",")[0].trim() : void 0;
2246
+ const isTrustedProxy = this._trustedProxies.includes(socketIp);
2247
+ if (!isTrustedProxy)
2248
+ return socketIp;
2249
+ if (Guards30.isDefined(clientIp))
2250
+ return clientIp.split(",")[0].trim();
2251
+ return socketIp;
2252
+ }
2253
+ };
2254
+ }
2255
+ });
2256
+
2257
+ // src/infrastructure/services/resolver/index.ts
2258
+ var init_resolver = __esm({
2259
+ "src/infrastructure/services/resolver/index.ts"() {
2260
+ "use strict";
2261
+ init_client_ip_resolver();
2262
+ }
2263
+ });
2264
+
2028
2265
  // src/infrastructure/services/index.ts
2029
2266
  var services_exports = {};
2030
2267
  __export(services_exports, {
2031
2268
  AllowMethodRegistry: () => AllowMethodRegistry,
2032
2269
  AllowOrigin: () => AllowOrigin,
2033
2270
  BearerTokenExtractor: () => BearerTokenExtractor,
2271
+ ClientIpResolver: () => ClientIpResolver,
2272
+ CsrfTokenService: () => CsrfTokenService,
2273
+ EdgeCryptoService: () => EdgeCryptoService,
2274
+ HttpCookieExtractor: () => HttpCookieExtractor,
2034
2275
  HttpHeaderExtractor: () => HttpHeaderExtractor,
2035
2276
  PLimitConcurrencyService: () => PLimitConcurrencyService,
2036
2277
  ServiceResilience: () => ServiceResilience,
@@ -2042,8 +2283,11 @@ var init_services = __esm({
2042
2283
  init_allow_methods();
2043
2284
  init_allow_origins();
2044
2285
  init_concurrency();
2286
+ init_crypto();
2287
+ init_csrf();
2045
2288
  init_extractors();
2046
2289
  init_resiliences();
2290
+ init_resolver();
2047
2291
  }
2048
2292
  });
2049
2293
 
@@ -2106,7 +2350,7 @@ var init_axios_factory = __esm({
2106
2350
  });
2107
2351
 
2108
2352
  // src/infrastructure/factories/cockatiel-resilience.factory.ts
2109
- import { AppError as AppError13, Guards as Guards26, RESILIENCE_DEFAULTS } from "@xeno-js/shared";
2353
+ import { AppError as AppError13, Guards as Guards31, RESILIENCE_DEFAULTS } from "@xeno-js/shared";
2110
2354
  import {
2111
2355
  bulkhead,
2112
2356
  circuitBreaker,
@@ -2183,13 +2427,13 @@ var init_cockatiel_resilience_factory = __esm({
2183
2427
  return new ServiceResilience(wrap(bulkheadPolicy, circuitBreakerPolicy, retryPolicy));
2184
2428
  }
2185
2429
  isTransientError(error) {
2186
- if (!Guards26.isDefined(error) || !Guards26.isObject(error)) return false;
2430
+ if (!Guards31.isDefined(error) || !Guards31.isObject(error)) return false;
2187
2431
  let status;
2188
2432
  let isNetworkError = false;
2189
2433
  if (error instanceof AppError13) {
2190
2434
  status = error.status;
2191
2435
  const cause = error.cause;
2192
- if (Guards26.isDefined(cause) && Guards26.isString(cause.code)) {
2436
+ if (Guards31.isDefined(cause) && Guards31.isString(cause.code)) {
2193
2437
  isNetworkError = [
2194
2438
  "ECONNABORTED",
2195
2439
  "ECONNRESET",
@@ -2201,7 +2445,7 @@ var init_cockatiel_resilience_factory = __esm({
2201
2445
  } else {
2202
2446
  const err = error;
2203
2447
  status = err.status;
2204
- if (Guards26.isString(err.code)) {
2448
+ if (Guards31.isString(err.code)) {
2205
2449
  isNetworkError = [
2206
2450
  "ECONNABORTED",
2207
2451
  "ECONNRESET",
@@ -2212,7 +2456,7 @@ var init_cockatiel_resilience_factory = __esm({
2212
2456
  }
2213
2457
  }
2214
2458
  if (isNetworkError) return true;
2215
- if (Guards26.isDefined(status)) {
2459
+ if (Guards31.isDefined(status)) {
2216
2460
  return status === 408 || status === 429 || status >= 500 && status < 600;
2217
2461
  }
2218
2462
  return false;
@@ -2222,22 +2466,22 @@ var init_cockatiel_resilience_factory = __esm({
2222
2466
  let method;
2223
2467
  if (error instanceof AppError13) {
2224
2468
  const cause = error.cause;
2225
- if (Guards26.isDefined(cause) && Guards26.isDefined(cause.config) && Guards26.isString(cause.config.method)) {
2469
+ if (Guards31.isDefined(cause) && Guards31.isDefined(cause.config) && Guards31.isString(cause.config.method)) {
2226
2470
  method = cause.config.method.toUpperCase();
2227
2471
  }
2228
2472
  } else {
2229
2473
  const err = error;
2230
- if (Guards26.isDefined(err.config) && Guards26.isString(err.config.method)) {
2474
+ if (Guards31.isDefined(err.config) && Guards31.isString(err.config.method)) {
2231
2475
  method = err.config.method.toUpperCase();
2232
2476
  }
2233
2477
  }
2234
- if (Guards26.isNullOrEmpty(method)) return false;
2478
+ if (Guards31.isNullOrEmpty(method)) return false;
2235
2479
  const idempotentMethods = ["GET", "PUT", "DELETE", "HEAD", "OPTIONS"];
2236
2480
  return idempotentMethods.includes(method);
2237
2481
  }
2238
2482
  checkConfigValue(value, defaultValue, message) {
2239
- if (Guards26.isDefined(value)) {
2240
- Guards26.throwIfNegative(value, message);
2483
+ if (Guards31.isDefined(value)) {
2484
+ Guards31.throwIfNegative(value, message);
2241
2485
  return value;
2242
2486
  }
2243
2487
  return defaultValue;
@@ -2269,7 +2513,7 @@ var init_db_client_factory = __esm({
2269
2513
  });
2270
2514
 
2271
2515
  // src/infrastructure/context/request-context.ts
2272
- import { Guards as Guards27 } from "@xeno-js/shared";
2516
+ import { Guards as Guards32 } from "@xeno-js/shared";
2273
2517
  var NodeRequestContext;
2274
2518
  var init_request_context = __esm({
2275
2519
  "src/infrastructure/context/request-context.ts"() {
@@ -2301,7 +2545,7 @@ var init_request_context = __esm({
2301
2545
  }
2302
2546
  updateIdentity(identity) {
2303
2547
  const store = this._storage.getStore();
2304
- if (Guards27.isDefined(store) && Guards27.isDefined(store.context)) {
2548
+ if (Guards32.isDefined(store) && Guards32.isDefined(store.context)) {
2305
2549
  store.context = Object.freeze({
2306
2550
  ...store.context,
2307
2551
  identity: Object.freeze(identity)
@@ -2310,23 +2554,23 @@ var init_request_context = __esm({
2310
2554
  }
2311
2555
  getContext() {
2312
2556
  const store = this._storage.getStore();
2313
- if (!Guards27.isDefined(store)) return void 0;
2557
+ if (!Guards32.isDefined(store)) return void 0;
2314
2558
  const context = store.context;
2315
2559
  return Object.freeze(context);
2316
2560
  }
2317
2561
  getIdentity() {
2318
2562
  const store = this._storage.getStore();
2319
- if (!Guards27.isDefined(store)) return void 0;
2563
+ if (!Guards32.isDefined(store)) return void 0;
2320
2564
  return Object.freeze(store.context?.identity);
2321
2565
  }
2322
2566
  getScope() {
2323
2567
  const store = this._storage.getStore();
2324
- if (!Guards27.isDefined(store)) return void 0;
2568
+ if (!Guards32.isDefined(store)) return void 0;
2325
2569
  return store.scope;
2326
2570
  }
2327
2571
  getNetworkContext() {
2328
2572
  const store = this._storage.getStore();
2329
- if (!Guards27.isDefined(store)) return void 0;
2573
+ if (!Guards32.isDefined(store)) return void 0;
2330
2574
  return Object.freeze(store.context?.network);
2331
2575
  }
2332
2576
  };
@@ -2401,7 +2645,7 @@ var init_sql_light_db_client_factory = __esm({
2401
2645
  // src/infrastructure/factories/supabase.factory.ts
2402
2646
  import { createServerClient } from "@supabase/ssr";
2403
2647
  import {
2404
- Guards as Guards28,
2648
+ Guards as Guards33,
2405
2649
  SupabaseAuthService,
2406
2650
  SupabaseClaimsMapper,
2407
2651
  SupabaseSessionMapper
@@ -2415,7 +2659,7 @@ var init_supabase_factory = __esm({
2415
2659
  config,
2416
2660
  container
2417
2661
  }) {
2418
- if (!Guards28.isDefined(config.ssrOpts)) {
2662
+ if (!Guards33.isDefined(config.ssrOpts)) {
2419
2663
  throw new Error("ISsrCookieHandler is required for @supabase/ssr initialization.");
2420
2664
  }
2421
2665
  const cookieService = config.ssrOpts(container);
@@ -2443,7 +2687,7 @@ var user_context_factory_exports = {};
2443
2687
  __export(user_context_factory_exports, {
2444
2688
  UserContextFactory: () => UserContextFactory
2445
2689
  });
2446
- import { Guards as Guards29 } from "@xeno-js/shared";
2690
+ import { Guards as Guards34 } from "@xeno-js/shared";
2447
2691
  var UserContextFactory;
2448
2692
  var init_user_context_factory = __esm({
2449
2693
  "src/infrastructure/factories/user-context.factory.ts"() {
@@ -2468,7 +2712,7 @@ var init_user_context_factory = __esm({
2468
2712
  tenantId: void 0
2469
2713
  };
2470
2714
  const identity = this._identityFactory.getIdentity();
2471
- if (Guards29.isDefined(identity)) {
2715
+ if (Guards34.isDefined(identity)) {
2472
2716
  output.userId = identity.userId;
2473
2717
  output.tenantId = identity.tenantId;
2474
2718
  }
@@ -2561,8 +2805,8 @@ var init_auth_utils = __esm({
2561
2805
  const { TOKENS: TOKENS4 } = await import("@xeno-js/shared");
2562
2806
  const pipelines = [];
2563
2807
  const strategies = [];
2564
- const { Guards: Guards39 } = await import("@xeno-js/shared");
2565
- if (Guards39.isDefined(opts.policies)) {
2808
+ const { Guards: Guards45 } = await import("@xeno-js/shared");
2809
+ if (Guards45.isDefined(opts.policies)) {
2566
2810
  const { PolicyRegistry: PolicyRegistry2 } = await Promise.resolve().then(() => (init_application(), application_exports));
2567
2811
  container.addSingleton(TOKENS4.POLICY_REGISTRY, () => new PolicyRegistry2());
2568
2812
  const policyRegistry = opts.policies;
@@ -2571,16 +2815,16 @@ var init_auth_utils = __esm({
2571
2815
  for (const [intent, policy] of Object.entries(policyRegistry)) {
2572
2816
  const intentLower = intent.toLowerCase();
2573
2817
  registryInstance.addPolicy(intentLower, policy);
2574
- if (!Guards39.isNullOrEmpty(policy.roles)) {
2818
+ if (!Guards45.isNullOrEmpty(policy.roles)) {
2575
2819
  Policies.add("roles");
2576
2820
  }
2577
- if (!Guards39.isNullOrEmpty(policy.permissions)) {
2821
+ if (!Guards45.isNullOrEmpty(policy.permissions)) {
2578
2822
  Policies.add("permissions");
2579
2823
  }
2580
- if (!Guards39.isNullOrEmpty(policy.userId)) {
2824
+ if (!Guards45.isNullOrEmpty(policy.userId)) {
2581
2825
  Policies.add("userId");
2582
2826
  }
2583
- if (!Guards39.isNullOrEmpty(policy.tenantId)) {
2827
+ if (!Guards45.isNullOrEmpty(policy.tenantId)) {
2584
2828
  Policies.add("tenantId");
2585
2829
  }
2586
2830
  }
@@ -2629,10 +2873,10 @@ var init_auth_utils = __esm({
2629
2873
  strategies.push(TOKENS4.TENANT_AUTHORIZATION_PIPELINE);
2630
2874
  }
2631
2875
  }
2632
- if (!Guards39.isNullOrEmpty(opts.customAuthorizationStrategy)) {
2876
+ if (!Guards45.isNullOrEmpty(opts.customAuthorizationStrategy)) {
2633
2877
  const customStrategies = opts.customAuthorizationStrategy;
2634
2878
  customStrategies.forEach((strategyToken, index) => {
2635
- if (Guards39.isDefined(strategyToken)) {
2879
+ if (Guards45.isDefined(strategyToken)) {
2636
2880
  const token = `CUSTOM_AUTHORIZATION_STRATEGY_${index}`;
2637
2881
  container.addSingleton(token, (c) => {
2638
2882
  return strategyToken(c);
@@ -2775,7 +3019,7 @@ __export(unit_of_work_exports, {
2775
3019
  UnitOfWork: () => UnitOfWork
2776
3020
  });
2777
3021
  import { AppError as AppError14 } from "@xeno-js/shared";
2778
- import { Guards as Guards30 } from "@xeno-js/shared";
3022
+ import { Guards as Guards35 } from "@xeno-js/shared";
2779
3023
  var UnitOfWork;
2780
3024
  var init_unit_of_work = __esm({
2781
3025
  "src/infrastructure/transaction/unit-of-work.ts"() {
@@ -2810,9 +3054,9 @@ var init_unit_of_work = __esm({
2810
3054
  });
2811
3055
  }
2812
3056
  async dispose() {
2813
- if (Guards30.isDefined(this._ttx.state)) {
3057
+ if (Guards35.isDefined(this._ttx.state)) {
2814
3058
  try {
2815
- if (Guards30.hasMethod(this._ttx.state, "rollback")) {
3059
+ if (Guards35.hasMethod(this._ttx.state, "rollback")) {
2816
3060
  await this._ttx.state.rollback();
2817
3061
  }
2818
3062
  } finally {
@@ -2835,7 +3079,7 @@ var init_db_module = __esm({
2835
3079
  "use strict";
2836
3080
  DbModule = class {
2837
3081
  async configure(container, opts) {
2838
- const { Guards: Guards39, TOKENS: TOKENS4 } = await import("@xeno-js/shared");
3082
+ const { Guards: Guards45, TOKENS: TOKENS4 } = await import("@xeno-js/shared");
2839
3083
  const { DbUtils: DbUtils2 } = await Promise.resolve().then(() => (init_db_utils(), db_utils_exports));
2840
3084
  const db = opts.enableSqlLite ? await DbUtils2.addSqlLite(opts) : await DbUtils2.addDbClient(opts);
2841
3085
  const { TransactionState: TransactionState2 } = await Promise.resolve().then(() => (init_transaction_state(), transaction_state_exports));
@@ -2852,7 +3096,7 @@ var init_db_module = __esm({
2852
3096
  return new Proxy(db, {
2853
3097
  get(_target, prop, receiver) {
2854
3098
  const activeState = ttx.state;
2855
- if (Guards39.isDefined(activeState)) {
3099
+ if (Guards45.isDefined(activeState)) {
2856
3100
  if (prop === "transaction") {
2857
3101
  return activeState.transaction.bind(activeState);
2858
3102
  }
@@ -2889,14 +3133,14 @@ var init_http_utils = __esm({
2889
3133
  */
2890
3134
  async addAxios(container, opts) {
2891
3135
  const { NodeAxiosFactory: NodeAxiosFactory2 } = await Promise.resolve().then(() => (init_factories(), factories_exports));
2892
- const { Guards: Guards39 } = await import("@xeno-js/shared");
2893
- if (!Guards39.isDefined(opts.token)) {
3136
+ const { Guards: Guards45 } = await import("@xeno-js/shared");
3137
+ if (!Guards45.isDefined(opts.token)) {
2894
3138
  throw new Error("HttpConfig.token is required and must be defined.");
2895
3139
  }
2896
3140
  container.addSingleton(opts.token, () => {
2897
3141
  const factory = new NodeAxiosFactory2();
2898
3142
  const instance = factory.create(opts.client);
2899
- if (!Guards39.hasMethod(instance, "get") || !Guards39.hasMethod(instance, "post") || !Guards39.hasMethod(instance, "put") || !Guards39.hasMethod(instance, "patch") || !Guards39.hasMethod(instance, "delete")) {
3143
+ if (!Guards45.hasMethod(instance, "get") || !Guards45.hasMethod(instance, "post") || !Guards45.hasMethod(instance, "put") || !Guards45.hasMethod(instance, "patch") || !Guards45.hasMethod(instance, "delete")) {
2900
3144
  throw new Error(
2901
3145
  "The created HTTP client instance does not implement the required methods of IHttpClient."
2902
3146
  );
@@ -2923,8 +3167,8 @@ var init_http_utils = __esm({
2923
3167
  });
2924
3168
  },
2925
3169
  async addAllowOrigin(container, opts) {
2926
- const { Guards: Guards39 } = await import("@xeno-js/shared");
2927
- if (Guards39.isNullOrEmpty(opts)) throw new Error("At least an allow origin must be passed");
3170
+ const { Guards: Guards45 } = await import("@xeno-js/shared");
3171
+ if (Guards45.isNullOrEmpty(opts)) throw new Error("At least an allow origin must be passed");
2928
3172
  const { TOKENS: TOKENS4 } = await import("@xeno-js/shared");
2929
3173
  const { AllowOrigin: AllowOrigin2 } = await Promise.resolve().then(() => (init_services(), services_exports));
2930
3174
  const allowOrigin = [];
@@ -2984,13 +3228,13 @@ var init_validation_utils = __esm({
2984
3228
  * @link https://github.com/xeno-js/xeno-js
2985
3229
  */
2986
3230
  async addValidation(container, opts, logger) {
2987
- const { Guards: Guards39, TOKENS: TOKENS4 } = await import("@xeno-js/shared");
2988
- if (!Guards39.isDefined(opts.zod) && Guards39.isNullOrEmpty(opts.customValidationStrategy)) {
3231
+ const { Guards: Guards45, TOKENS: TOKENS4 } = await import("@xeno-js/shared");
3232
+ if (!Guards45.isDefined(opts.zod) && Guards45.isNullOrEmpty(opts.customValidationStrategy)) {
2989
3233
  return [];
2990
3234
  }
2991
3235
  const pipelines = [];
2992
3236
  const validationStrategies = [];
2993
- if (Guards39.isDefined(opts.zod)) {
3237
+ if (Guards45.isDefined(opts.zod)) {
2994
3238
  const config = opts.zod;
2995
3239
  const { ZodValidatorFactory: ZodValidatorFactory2 } = await Promise.resolve().then(() => (init_zod_validator_factory(), zod_validator_factory_exports));
2996
3240
  container.addSingleton(TOKENS4.ZOD_VALIDATOR, () => {
@@ -3004,9 +3248,9 @@ var init_validation_utils = __esm({
3004
3248
  validationStrategies.push(TOKENS4.SCHEMA_VALIDATION_STRATEGY);
3005
3249
  }
3006
3250
  const customValidationFactory = [];
3007
- if (!Guards39.isNullOrEmpty(opts.customValidationStrategy)) {
3251
+ if (!Guards45.isNullOrEmpty(opts.customValidationStrategy)) {
3008
3252
  for (const strategyToken of opts.customValidationStrategy) {
3009
- if (Guards39.isDefined(strategyToken)) {
3253
+ if (Guards45.isDefined(strategyToken)) {
3010
3254
  customValidationFactory.push(strategyToken);
3011
3255
  }
3012
3256
  }
@@ -3109,8 +3353,8 @@ var init_pipeline_utils = __esm({
3109
3353
  */
3110
3354
  async addCommand(container, opts) {
3111
3355
  const pipelines = [];
3112
- const { Guards: Guards39, TOKENS: TOKENS4 } = await import("@xeno-js/shared");
3113
- if (Guards39.isDefined(opts.idempotency)) {
3356
+ const { Guards: Guards45, TOKENS: TOKENS4 } = await import("@xeno-js/shared");
3357
+ if (Guards45.isDefined(opts.idempotency)) {
3114
3358
  const { IdempotencyStore: IdempotencyStore2 } = await Promise.resolve().then(() => (init_idempotency_store(), idempotency_store_exports));
3115
3359
  container.addSingleton(
3116
3360
  TOKENS4.IDEMPOTENCY_STORE,
@@ -3130,7 +3374,7 @@ var init_pipeline_utils = __esm({
3130
3374
  });
3131
3375
  pipelines.push(TOKENS4.IDEMPOTENCY_PIPELINE);
3132
3376
  }
3133
- if (Guards39.isDefined(opts.concurrency)) {
3377
+ if (Guards45.isDefined(opts.concurrency)) {
3134
3378
  const { ConcurrencyRetryPipeline: ConcurrencyRetryPipeline2 } = await Promise.resolve().then(() => (init_application(), application_exports));
3135
3379
  container.addSingleton(TOKENS4.CONCURRENCY_RETRY_PIPELINE, () => {
3136
3380
  const config = opts.concurrency;
@@ -3210,13 +3454,13 @@ var init_cqrs_module = __esm({
3210
3454
  return new PerformancePipeline2(logger, thresholdMs);
3211
3455
  });
3212
3456
  pipelines.push(TOKENS4.PERFORMANCE_PIPELINE);
3213
- const { Guards: Guards39 } = await import("@xeno-js/shared");
3214
- if (Guards39.isDefined(opts.authorization.policies) || Guards39.isDefined(opts.authorization.customAuthorizationStrategy)) {
3457
+ const { Guards: Guards45 } = await import("@xeno-js/shared");
3458
+ if (Guards45.isDefined(opts.authorization.policies) || Guards45.isDefined(opts.authorization.customAuthorizationStrategy)) {
3215
3459
  const { AuthUtils: AuthUtils2 } = await Promise.resolve().then(() => (init_auth_utils(), auth_utils_exports));
3216
3460
  const authPipelines = await AuthUtils2.addAuthZ(container, opts.authorization);
3217
3461
  pipelines.push(...authPipelines);
3218
3462
  }
3219
- if (Guards39.isDefined(opts.validation.zod) || Guards39.isDefined(opts.validation.customValidationStrategy)) {
3463
+ if (Guards45.isDefined(opts.validation.zod) || Guards45.isDefined(opts.validation.customValidationStrategy)) {
3220
3464
  const { ValidationUtils: ValidationUtils2 } = await Promise.resolve().then(() => (init_validation_utils(), validation_utils_exports));
3221
3465
  const logger = container.resolve(TOKENS4.LOGGER);
3222
3466
  const validationPipelines = await ValidationUtils2.addValidation(
@@ -3228,11 +3472,11 @@ var init_cqrs_module = __esm({
3228
3472
  }
3229
3473
  const commandPipelines = pipelines;
3230
3474
  const queryPipelines = pipelines;
3231
- if ((Guards39.isDefined(opts.commandBus.idempotency) || opts.queryBus.isEnabled) && opts.isCache) {
3475
+ if ((Guards45.isDefined(opts.commandBus.idempotency) || opts.queryBus.isEnabled) && opts.isCache) {
3232
3476
  const { CacheUtils: CacheUtils2 } = await Promise.resolve().then(() => (init_cache_utils(), cache_utils_exports));
3233
3477
  await CacheUtils2.addCache(container, { inMemory: true, redis: void 0 });
3234
3478
  }
3235
- if (Guards39.isDefined(opts.commandBus.idempotency) || Guards39.isDefined(opts.commandBus.concurrency)) {
3479
+ if (Guards45.isDefined(opts.commandBus.idempotency) || Guards45.isDefined(opts.commandBus.concurrency)) {
3236
3480
  const { PipelineUtils: PipelineUtils2 } = await Promise.resolve().then(() => (init_pipeline_utils(), pipeline_utils_exports));
3237
3481
  const newCommandPipelines = await PipelineUtils2.addCommand(container, {
3238
3482
  ...opts.commandBus,
@@ -3554,7 +3798,7 @@ var init_composite_middleware = __esm({
3554
3798
  });
3555
3799
 
3556
3800
  // src/presentation/middlewares/cors.middleware.ts
3557
- import { Guards as Guards31 } from "@xeno-js/shared";
3801
+ import { Guards as Guards36 } from "@xeno-js/shared";
3558
3802
  var CORSMiddleware;
3559
3803
  var init_cors_middleware = __esm({
3560
3804
  "src/presentation/middlewares/cors.middleware.ts"() {
@@ -3568,7 +3812,7 @@ var init_cors_middleware = __esm({
3568
3812
  const { network } = this._requestContext.getContext() ?? {};
3569
3813
  const origin = network?.origin;
3570
3814
  const response = await next();
3571
- if (Guards31.isDefined(origin))
3815
+ if (Guards36.isDefined(origin))
3572
3816
  response.headers = {
3573
3817
  ...response.headers ?? {},
3574
3818
  "Access-Control-Allow-Origin": origin,
@@ -3585,7 +3829,7 @@ var init_cors_middleware = __esm({
3585
3829
  import {
3586
3830
  ERROR_CODE_MESSAGES as ERROR_CODE_MESSAGES5,
3587
3831
  ERROR_CODES as ERROR_CODES6,
3588
- Guards as Guards32,
3832
+ Guards as Guards37,
3589
3833
  GuidHelper as GuidHelper9,
3590
3834
  HttpHelper as HttpHelper6,
3591
3835
  STATUS_CODES as STATUS_CODES7
@@ -3595,30 +3839,72 @@ var init_csrf_middleware = __esm({
3595
3839
  "src/presentation/middlewares/csrf.middleware.ts"() {
3596
3840
  "use strict";
3597
3841
  CsrfMiddleware = class {
3598
- constructor(_requestContext, _csrf) {
3842
+ constructor(_requestContext, _csrfTokenService) {
3599
3843
  this._requestContext = _requestContext;
3600
- this._csrf = _csrf;
3844
+ this._csrfTokenService = _csrfTokenService;
3601
3845
  }
3602
3846
  _requestContext;
3603
- _csrf;
3604
- /**
3605
- * @param requestContext Dati base della richiesta (metodo, path)
3606
- * @param headers Header HTTP della richiesta
3607
- * @param next Funzione delegata per passare al middleware successivo
3608
- */
3847
+ _csrfTokenService;
3609
3848
  async execute(req, _headers, next) {
3610
3849
  const method = req.method.toUpperCase();
3611
3850
  const isStateChanging = ["POST", "PUT", "DELETE", "PATCH"].includes(method);
3612
3851
  if (isStateChanging) {
3613
- const { network, tracing } = this._requestContext.getContext() ?? {};
3614
- if (!Guards32.isDefined(network?.csrf) || network.csrf.toLowerCase() !== this._csrf.toLowerCase()) {
3852
+ const { network, tracing, identity } = this._requestContext.getContext() ?? {};
3853
+ const headerToken = network?.csrf;
3854
+ const cookieToken = network?.csrfCookie;
3855
+ if (!Guards37.isDefined(headerToken) || !Guards37.isDefined(cookieToken)) {
3615
3856
  return HttpHelper6.error(
3616
3857
  {
3617
3858
  success: false,
3618
3859
  error: {
3619
3860
  code: ERROR_CODES6.FORBIDDEN,
3620
3861
  message: ERROR_CODE_MESSAGES5[ERROR_CODES6.FORBIDDEN],
3621
- details: "CSRF header is missing or invalid",
3862
+ details: "CSRF token missing",
3863
+ path: req.path
3864
+ },
3865
+ correlationId: tracing?.correlationId ?? GuidHelper9.generate(),
3866
+ requestId: network?.requestId ?? GuidHelper9.generate(),
3867
+ spanId: tracing?.spanId ?? GuidHelper9.generate(),
3868
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
3869
+ },
3870
+ STATUS_CODES7.FORBIDDEN,
3871
+ {
3872
+ "Content-Type": [network?.formatIndicator ?? "application/json"]
3873
+ }
3874
+ );
3875
+ }
3876
+ if (headerToken !== cookieToken) {
3877
+ return HttpHelper6.error(
3878
+ {
3879
+ success: false,
3880
+ error: {
3881
+ code: ERROR_CODES6.FORBIDDEN,
3882
+ message: ERROR_CODE_MESSAGES5[ERROR_CODES6.FORBIDDEN],
3883
+ details: "CSRF token mismatch",
3884
+ path: req.path
3885
+ },
3886
+ correlationId: tracing?.correlationId ?? GuidHelper9.generate(),
3887
+ requestId: network?.requestId ?? GuidHelper9.generate(),
3888
+ spanId: tracing?.spanId ?? GuidHelper9.generate(),
3889
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
3890
+ },
3891
+ STATUS_CODES7.FORBIDDEN,
3892
+ {
3893
+ "Content-Type": [network?.formatIndicator ?? "application/json"]
3894
+ }
3895
+ );
3896
+ }
3897
+ if (!Guards37.isDefined(identity?.userId) || !await this._csrfTokenService.validate(
3898
+ headerToken,
3899
+ identity?.userId
3900
+ )) {
3901
+ return HttpHelper6.error(
3902
+ {
3903
+ success: false,
3904
+ error: {
3905
+ code: ERROR_CODES6.FORBIDDEN,
3906
+ message: ERROR_CODE_MESSAGES5[ERROR_CODES6.FORBIDDEN],
3907
+ details: "CSRF token invalid",
3622
3908
  path: req.path
3623
3909
  },
3624
3910
  correlationId: tracing?.correlationId ?? GuidHelper9.generate(),
@@ -3639,8 +3925,51 @@ var init_csrf_middleware = __esm({
3639
3925
  }
3640
3926
  });
3641
3927
 
3928
+ // src/presentation/middlewares/csrf-cookie.middleware.ts
3929
+ import { Guards as Guards38 } from "@xeno-js/shared";
3930
+ var CsrfCookieMiddleware;
3931
+ var init_csrf_cookie_middleware = __esm({
3932
+ "src/presentation/middlewares/csrf-cookie.middleware.ts"() {
3933
+ "use strict";
3934
+ CsrfCookieMiddleware = class {
3935
+ constructor(_requestContext, _csrfTokenService, _csrf) {
3936
+ this._requestContext = _requestContext;
3937
+ this._csrfTokenService = _csrfTokenService;
3938
+ this._csrf = _csrf;
3939
+ }
3940
+ _requestContext;
3941
+ _csrfTokenService;
3942
+ _csrf;
3943
+ async execute(_req, _headers, next) {
3944
+ const response = await next();
3945
+ const context = this._requestContext.getContext();
3946
+ const identity = context?.identity;
3947
+ const network = context?.network;
3948
+ if (!Guards38.isDefined(identity?.userId))
3949
+ return response;
3950
+ if (Guards38.isDefined(network?.csrfCookie))
3951
+ return response;
3952
+ const token = await this._csrfTokenService.generate(identity.userId);
3953
+ const cookieName = this._csrf.cookieName ?? "__Host-xeno-csrf";
3954
+ const maxAge = this._csrf.cookieMaxAgeSeconds ?? 3600;
3955
+ const sameSite = this._csrf.sameSite ?? "lax";
3956
+ const cookie = `${cookieName}=${encodeURIComponent(token)}; Path=/; Secure; SameSite=${sameSite}; Max-Age=${maxAge}`;
3957
+ const existingCookies = response.headers["Set-Cookie"];
3958
+ response.headers = {
3959
+ ...response.headers ?? {},
3960
+ "Set-Cookie": [
3961
+ ...existingCookies ?? [],
3962
+ cookie
3963
+ ]
3964
+ };
3965
+ return response;
3966
+ }
3967
+ };
3968
+ }
3969
+ });
3970
+
3642
3971
  // src/presentation/middlewares/options.middleware.ts
3643
- import { Guards as Guards33, HttpHelper as HttpHelper7, STATUS_CODES as STATUS_CODES8 } from "@xeno-js/shared";
3972
+ import { Guards as Guards39, HttpHelper as HttpHelper7, STATUS_CODES as STATUS_CODES8 } from "@xeno-js/shared";
3644
3973
  var OptionsMiddleware;
3645
3974
  var init_options_middleware = __esm({
3646
3975
  "src/presentation/middlewares/options.middleware.ts"() {
@@ -3655,13 +3984,13 @@ var init_options_middleware = __esm({
3655
3984
  const network = this._requestContext.getNetworkContext();
3656
3985
  const origin = network?.origin;
3657
3986
  const headers = {};
3658
- if (Guards33.isDefined(origin)) {
3987
+ if (Guards39.isDefined(origin)) {
3659
3988
  headers["Access-Control-Allow-Origin"] = origin;
3660
3989
  headers["Access-Control-Allow-Credentials"] = "true";
3661
3990
  headers["Vary"] = "Origin";
3662
3991
  }
3663
- headers["Access-Control-Allow-Methods"] = "POST,GET,PUT,DELETE,OPTIONS";
3664
- headers["Access-Control-Allow-Headers"] = "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Type, Authorization, X-Correlation-Id";
3992
+ headers["Access-Control-Allow-Methods"] = "POST,GET,PUT,PATCH,DELETE,OPTIONS";
3993
+ headers["Access-Control-Allow-Headers"] = "X-CSRF-Token, Accept, Accept-Version, Content-Type, Authorization, X-Correlation-Id";
3665
3994
  return HttpHelper7.success(null, STATUS_CODES8.NO_CONTENT, {}, headers);
3666
3995
  }
3667
3996
  return await next();
@@ -3687,12 +4016,12 @@ var init_rate_limiter_middleware = __esm({
3687
4016
  _cache;
3688
4017
  _logger;
3689
4018
  _opts;
3690
- async execute(req, headers, next) {
4019
+ async execute(req, _headers, next) {
3691
4020
  const { network, tracing } = this._ctxAccessor.getContext() ?? {};
3692
4021
  const clientIp = network?.clientIp;
3693
4022
  const cacheKey = `rate_limit:${clientIp}`;
3694
- const currentHits = await this._cache.get(cacheKey) ?? 0;
3695
- if (currentHits >= this._opts.maxRequests) {
4023
+ const currentHits = await this._cache.increment(cacheKey, this._opts.windowSeconds);
4024
+ if (currentHits > this._opts.maxRequests) {
3696
4025
  this._logger.warn(`[RateLimit] IP ${clientIp} blocked on ${req.path}`);
3697
4026
  return HttpHelper8.error(
3698
4027
  {
@@ -3715,7 +4044,6 @@ var init_rate_limiter_middleware = __esm({
3715
4044
  }
3716
4045
  );
3717
4046
  }
3718
- await this._cache.set(cacheKey, currentHits + 1, this._opts.windowSeconds);
3719
4047
  return next();
3720
4048
  }
3721
4049
  };
@@ -3723,10 +4051,10 @@ var init_rate_limiter_middleware = __esm({
3723
4051
  });
3724
4052
 
3725
4053
  // src/presentation/mappers/context.mapper.ts
3726
- import { Guards as Guards34 } from "@xeno-js/shared";
4054
+ import { Guards as Guards40 } from "@xeno-js/shared";
3727
4055
  function _buildMessagingContext(meta) {
3728
- const hasSequenceData = Guards34.isDefined(meta.sequence?.sequenceId) || Guards34.isDefined(meta.sequence?.position) || Guards34.isDefined(meta.sequence?.size);
3729
- const hasMessagingData = hasSequenceData || Guards34.isDefined(meta.expiration) || Guards34.isDefined(meta.returnAddress);
4056
+ const hasSequenceData = Guards40.isDefined(meta.sequence?.sequenceId) || Guards40.isDefined(meta.sequence?.position) || Guards40.isDefined(meta.sequence?.size);
4057
+ const hasMessagingData = hasSequenceData || Guards40.isDefined(meta.expiration) || Guards40.isDefined(meta.returnAddress);
3730
4058
  const messaging = hasMessagingData ? {
3731
4059
  returnAddress: meta.returnAddress,
3732
4060
  expiration: meta.expiration,
@@ -3757,6 +4085,7 @@ var init_context_mapper = __esm({
3757
4085
  path,
3758
4086
  transport,
3759
4087
  csrf: metadata.csrf,
4088
+ csrfCookie: metadata.csrfCookie,
3760
4089
  origin: metadata.origin
3761
4090
  };
3762
4091
  const tracing = {
@@ -3805,13 +4134,15 @@ var init_request_middleware = __esm({
3805
4134
  * @since 2025-09-30
3806
4135
  * @link https://github.com/xeno-js/xeno-js
3807
4136
  */
3808
- constructor(_requestContext, _extractor, _logger) {
4137
+ constructor(_requestContext, _extractor, _resolver, _logger) {
3809
4138
  this._requestContext = _requestContext;
3810
4139
  this._extractor = _extractor;
4140
+ this._resolver = _resolver;
3811
4141
  this._logger = _logger;
3812
4142
  }
3813
4143
  _requestContext;
3814
4144
  _extractor;
4145
+ _resolver;
3815
4146
  _logger;
3816
4147
  async execute(req, headers, next) {
3817
4148
  const correlationId = GuidHelper11.generate();
@@ -3820,8 +4151,10 @@ var init_request_middleware = __esm({
3820
4151
  const formatIndicator = "application/json";
3821
4152
  try {
3822
4153
  const meta = this._extractor.extract(headers);
4154
+ const clientIp = this._resolver.resolve(req.transport.req, meta.clientIp);
3823
4155
  const metadata = {
3824
4156
  ...meta,
4157
+ clientIp,
3825
4158
  correlationId: meta.correlationId ?? correlationId,
3826
4159
  requestId: meta.requestId ?? requestId,
3827
4160
  spanId: meta.spanId ?? spanId,
@@ -3874,6 +4207,7 @@ var init_middlewares = __esm({
3874
4207
  init_composite_middleware();
3875
4208
  init_cors_middleware();
3876
4209
  init_csrf_middleware();
4210
+ init_csrf_cookie_middleware();
3877
4211
  init_options_middleware();
3878
4212
  init_rate_limiter_middleware();
3879
4213
  init_request_middleware();
@@ -3888,6 +4222,7 @@ __export(presentation_exports, {
3888
4222
  BaseController: () => BaseController,
3889
4223
  CORSMiddleware: () => CORSMiddleware,
3890
4224
  CompositeMiddleware: () => CompositeMiddleware,
4225
+ CsrfCookieMiddleware: () => CsrfCookieMiddleware,
3891
4226
  CsrfMiddleware: () => CsrfMiddleware,
3892
4227
  MethodCheckMiddleware: () => MethodCheckMiddleware,
3893
4228
  OptionsMiddleware: () => OptionsMiddleware,
@@ -3907,7 +4242,7 @@ var middleware_module_exports = {};
3907
4242
  __export(middleware_module_exports, {
3908
4243
  MiddlewareModule: () => MiddlewareModule
3909
4244
  });
3910
- import { Guards as Guards35 } from "@xeno-js/shared";
4245
+ import { Guards as Guards41 } from "@xeno-js/shared";
3911
4246
  var MiddlewareModule;
3912
4247
  var init_middleware_module = __esm({
3913
4248
  "src/infrastructure/modules/middleware.module.ts"() {
@@ -3926,15 +4261,19 @@ var init_middleware_module = __esm({
3926
4261
  const { BearerTokenExtractor: BearerTokenExtractor2 } = await Promise.resolve().then(() => (init_services(), services_exports));
3927
4262
  container.addSingleton(TOKENS4.BEARER_TOKEN_EXTRACTOR, () => new BearerTokenExtractor2());
3928
4263
  }
4264
+ const { HttpCookieExtractor: HttpCookieExtractor2 } = await Promise.resolve().then(() => (init_services(), services_exports));
4265
+ container.addSingleton("COOKIE_EXTRACTOR", () => new HttpCookieExtractor2());
3929
4266
  const { HttpHeaderExtractor: HttpHeaderExtractor2 } = await Promise.resolve().then(() => (init_services(), services_exports));
3930
4267
  container.addSingleton(
3931
4268
  TOKENS4.SERVICE_EXTRACTOR,
3932
- (c) => new HttpHeaderExtractor2(c.resolve(TOKENS4.BEARER_TOKEN_EXTRACTOR), opts.trustedIpHeader)
4269
+ (c) => new HttpHeaderExtractor2(c.resolve(TOKENS4.BEARER_TOKEN_EXTRACTOR), c.resolve("COOKIE_EXTRACTOR"), opts.trustedIpHeader, opts.csrf?.cookieName ?? "__Host-xeno-csrf")
3933
4270
  );
3934
4271
  if (!opts.isLogger) {
3935
4272
  const { LoggerUtils: LoggerUtils2 } = await Promise.resolve().then(() => (init_logger_utils(), logger_utils_exports));
3936
4273
  await LoggerUtils2.addLogger(container, void 0);
3937
4274
  }
4275
+ const { ClientIpResolver: ClientIpResolver2 } = await Promise.resolve().then(() => (init_services(), services_exports));
4276
+ container.addSingleton("IP_RESOLVER", () => new ClientIpResolver2(opts.trustedProxies));
3938
4277
  const middlewares = [TOKENS4.REQUEST_CONTEXT_MIDDLEWARE];
3939
4278
  const { RequestContextMiddleware: RequestContextMiddleware2 } = await Promise.resolve().then(() => (init_presentation(), presentation_exports));
3940
4279
  container.addSingleton(
@@ -3942,6 +4281,7 @@ var init_middleware_module = __esm({
3942
4281
  (c) => new RequestContextMiddleware2(
3943
4282
  c.resolve(TOKENS4.REQUEST_CONTEXT),
3944
4283
  c.resolve(TOKENS4.SERVICE_EXTRACTOR),
4284
+ c.resolve("IP_RESOLVER"),
3945
4285
  c.resolve(TOKENS4.LOGGER)
3946
4286
  )
3947
4287
  );
@@ -3953,7 +4293,9 @@ var init_middleware_module = __esm({
3953
4293
  );
3954
4294
  middlewares.push(TOKENS4.OPTIONS_MIDDLEWARE);
3955
4295
  }
3956
- if (!Guards35.isNullOrEmpty(opts.allowOrigins)) {
4296
+ if (!Guards41.isNullOrEmpty(opts.allowOrigins)) {
4297
+ if (Guards41.isDefined(opts.httpConfig.withCredentials) && opts.allowOrigins.includes("*"))
4298
+ throw new Error("Wildcard CORS origin is not allowed when withCredentials is set to true");
3957
4299
  const { AllowOrigin: AllowOrigin2 } = await Promise.resolve().then(() => (init_services(), services_exports));
3958
4300
  container.addSingleton("ALLOW_ORIGIN", () => {
3959
4301
  return new AllowOrigin2(opts.allowOrigins);
@@ -3975,7 +4317,7 @@ var init_middleware_module = __esm({
3975
4317
  });
3976
4318
  middlewares.push(TOKENS4.CORS_MIDDLEWARE);
3977
4319
  }
3978
- if (Guards35.isDefined(opts.routeRegistry)) {
4320
+ if (Guards41.isDefined(opts.routeRegistry)) {
3979
4321
  const registry = opts.routeRegistry;
3980
4322
  const { AllowMethodFactory: AllowMethodFactory2 } = await Promise.resolve().then(() => (init_factories(), factories_exports));
3981
4323
  container.addSingleton(TOKENS4.ALLOW_METHOD, () => new AllowMethodFactory2().create(registry));
@@ -3989,21 +4331,42 @@ var init_middleware_module = __esm({
3989
4331
  );
3990
4332
  middlewares.push(TOKENS4.METHOD_CHECK_MIDDLEWARE);
3991
4333
  }
3992
- if (Guards35.isDefined(opts.csrf)) {
4334
+ const { AuthenticationMiddleware: AuthenticationMiddleware2 } = await Promise.resolve().then(() => (init_presentation(), presentation_exports));
4335
+ container.addSingleton(TOKENS4.AUTH_MIDDLEWARE, (c) => {
4336
+ return new AuthenticationMiddleware2(
4337
+ c.resolve(TOKENS4.REQUEST_CONTEXT),
4338
+ c.resolve(TOKENS4.BEARER_TOKEN_EXTRACTOR),
4339
+ c.resolve(TOKENS4.GATE_KEEPER),
4340
+ c.resolve(TOKENS4.LOGGER)
4341
+ );
4342
+ });
4343
+ middlewares.push(TOKENS4.AUTH_MIDDLEWARE);
4344
+ if (Guards41.isDefined(opts.csrf)) {
3993
4345
  const csrf = opts.csrf;
4346
+ const { CsrfTokenService: CsrfTokenService2 } = await Promise.resolve().then(() => (init_services(), services_exports));
4347
+ container.addSingleton("CSRF_TOKEN_SERVICE", (c) => {
4348
+ return new CsrfTokenService2(
4349
+ csrf.secret,
4350
+ c.resolve("CRYPTO_SERVICE")
4351
+ );
4352
+ });
4353
+ const { CsrfCookieMiddleware: CsrfCookieMiddleware2 } = await Promise.resolve().then(() => (init_presentation(), presentation_exports));
4354
+ container.addSingleton("CSRF_COOKIE_MIDDLEWARE", (c) => {
4355
+ return new CsrfCookieMiddleware2(c.resolve(TOKENS4.REQUEST_CONTEXT), c.resolve("CSRF_TOKEN_SERVICE"), csrf);
4356
+ });
3994
4357
  const { CsrfMiddleware: CsrfMiddleware2 } = await Promise.resolve().then(() => (init_presentation(), presentation_exports));
3995
4358
  container.addSingleton(TOKENS4.CSRF_MIDDLEWARE, (c) => {
3996
- return new CsrfMiddleware2(c.resolve(TOKENS4.REQUEST_CONTEXT), csrf);
4359
+ return new CsrfMiddleware2(c.resolve(TOKENS4.REQUEST_CONTEXT), c.resolve("CSRF_TOKEN_SERVICE"));
3997
4360
  });
3998
4361
  middlewares.push(TOKENS4.CSRF_MIDDLEWARE);
3999
4362
  }
4000
- if (Guards35.isDefined(opts.rateLimite.maxRequests) || Guards35.isDefined(opts.rateLimite.windowSeconds)) {
4363
+ if (Guards41.isDefined(opts.rateLimite.maxRequests) || Guards41.isDefined(opts.rateLimite.windowSeconds)) {
4001
4364
  const maxRequests = opts.rateLimite.maxRequests ?? 30;
4002
- Guards35.throwIfNegative(maxRequests, "MaxRequests must be positive");
4003
- Guards35.throwIfNotInteger(maxRequests, "MaxRequests must be an integer");
4365
+ Guards41.throwIfNegative(maxRequests, "MaxRequests must be positive");
4366
+ Guards41.throwIfNotInteger(maxRequests, "MaxRequests must be an integer");
4004
4367
  const windowSeconds = opts.rateLimite.windowSeconds ?? 30;
4005
- Guards35.throwIfNegative(windowSeconds, "WindowSeconds must be positive");
4006
- Guards35.throwIfNotInteger(windowSeconds, "WindowSeconds must be an integer");
4368
+ Guards41.throwIfNegative(windowSeconds, "WindowSeconds must be positive");
4369
+ Guards41.throwIfNotInteger(windowSeconds, "WindowSeconds must be an integer");
4007
4370
  if (!opts.isCache) {
4008
4371
  const { CacheUtils: CacheUtils2 } = await Promise.resolve().then(() => (init_cache_utils(), cache_utils_exports));
4009
4372
  await CacheUtils2.addCache(container, { inMemory: true, redis: void 0 });
@@ -4022,16 +4385,6 @@ var init_middleware_module = __esm({
4022
4385
  });
4023
4386
  middlewares.push(TOKENS4.RATE_LIMITER_MIDDLEWARE);
4024
4387
  }
4025
- const { AuthenticationMiddleware: AuthenticationMiddleware2 } = await Promise.resolve().then(() => (init_presentation(), presentation_exports));
4026
- container.addSingleton(TOKENS4.AUTH_MIDDLEWARE, (c) => {
4027
- return new AuthenticationMiddleware2(
4028
- c.resolve(TOKENS4.REQUEST_CONTEXT),
4029
- c.resolve(TOKENS4.BEARER_TOKEN_EXTRACTOR),
4030
- c.resolve(TOKENS4.GATE_KEEPER),
4031
- c.resolve(TOKENS4.LOGGER)
4032
- );
4033
- });
4034
- middlewares.push(TOKENS4.AUTH_MIDDLEWARE);
4035
4388
  const { CompositeMiddleware: CompositeMiddleware2 } = await Promise.resolve().then(() => (init_presentation(), presentation_exports));
4036
4389
  container.addSingleton(TOKENS4.MIDDLEWARE, (c) => {
4037
4390
  const resolvedMiddleware = middlewares.map(
@@ -4101,7 +4454,7 @@ __export(index_exports, {
4101
4454
  init_application();
4102
4455
 
4103
4456
  // src/infrastructure/builder/app.builder.ts
4104
- import { Guards as Guards36, LOG_LEVEL as LOG_LEVEL6, TOKENS as TOKENS3 } from "@xeno-js/shared";
4457
+ import { Guards as Guards42, LOG_LEVEL as LOG_LEVEL6, TOKENS as TOKENS3 } from "@xeno-js/shared";
4105
4458
 
4106
4459
  // src/infrastructure/configuration/configuration.ts
4107
4460
  import { Guards as Guards13 } from "@xeno-js/shared";
@@ -4377,6 +4730,7 @@ var AppBuilder = class {
4377
4730
  () => new EnvironmentConfigurationService()
4378
4731
  );
4379
4732
  this._configuration = this._container.resolve(TOKENS3.CONFIGURATION_SERVICE);
4733
+ this._middlewareConfig.allowOrigins?.push(this._configuration.get("APP_URL") ?? `http://localhost:${this._configuration.getNumber("PORT", 3e3)}`);
4380
4734
  }
4381
4735
  // --- Module Configurations ---
4382
4736
  _modules = [];
@@ -4408,7 +4762,8 @@ var AppBuilder = class {
4408
4762
  optionsMiddleware: false,
4409
4763
  routeRegistry: void 0,
4410
4764
  trustedIpHeader: void 0,
4411
- allowOrigins: ["*"],
4765
+ trustedProxies: [],
4766
+ allowOrigins: [],
4412
4767
  cors: true
4413
4768
  };
4414
4769
  _httpConfig = {
@@ -4491,7 +4846,7 @@ var AppBuilder = class {
4491
4846
  pino: { config: void 0 },
4492
4847
  customLoggers: void 0
4493
4848
  };
4494
- if (Guards36.isDefined(setupAction) && Guards36.isDefined(config))
4849
+ if (Guards42.isDefined(setupAction) && Guards42.isDefined(config))
4495
4850
  setupAction(config, this._configuration);
4496
4851
  this._modules.push({
4497
4852
  priority: 3,
@@ -4517,7 +4872,7 @@ var AppBuilder = class {
4517
4872
  addCache(setupAction) {
4518
4873
  if (this._isCacheModuleQueued) return this;
4519
4874
  this._isCacheModuleQueued = true;
4520
- if (Guards36.isDefined(setupAction)) setupAction(this._config, this._configuration);
4875
+ if (Guards42.isDefined(setupAction)) setupAction(this._config, this._configuration);
4521
4876
  this._modules.push({
4522
4877
  priority: 3,
4523
4878
  name: "CacheModule",
@@ -4626,7 +4981,7 @@ var AppBuilder = class {
4626
4981
  * @link https://github.com/xeno-js/xeno-js
4627
4982
  */
4628
4983
  addPipeline(setupAction) {
4629
- if (Guards36.isDefined(setupAction)) {
4984
+ if (Guards42.isDefined(setupAction)) {
4630
4985
  setupAction(this._pipelineConfig, this._configuration);
4631
4986
  }
4632
4987
  this._queuePipelineModule();
@@ -4760,7 +5115,7 @@ var AppBuilder = class {
4760
5115
  console.error(`\u{1F449} Module: **${queued.name}**`);
4761
5116
  console.error(`\u{1F4DD} Reason: ${errorMessage}
4762
5117
  `);
4763
- if (error instanceof Error && Guards36.isDefined(error.stack)) {
5118
+ if (error instanceof Error && Guards42.isDefined(error.stack)) {
4764
5119
  console.error(error.stack);
4765
5120
  }
4766
5121
  throw new Error(`Bootstrap failed at [${queued.name}]: ${errorMessage}`, { cause: error });
@@ -4822,7 +5177,8 @@ var AppBuilder = class {
4822
5177
  ...this._middlewareConfig,
4823
5178
  isAuth: this._isAuthModuleQueued,
4824
5179
  isLogger: this._isLoggerModuleQueued,
4825
- isCache: this._isCacheModuleQueued || this._isPipelineModuleQueued
5180
+ isCache: this._isCacheModuleQueued || this._isPipelineModuleQueued,
5181
+ httpConfig: this._httpConfig.http.client
4826
5182
  });
4827
5183
  }
4828
5184
  });
@@ -4889,7 +5245,7 @@ init_validation_utils();
4889
5245
 
4890
5246
  // src/infrastructure/repositories/read-dao.ts
4891
5247
  import { AppError as AppError16, Result as Result17 } from "@xeno-js/shared";
4892
- import { Guards as Guards37 } from "@xeno-js/shared";
5248
+ import { Guards as Guards43 } from "@xeno-js/shared";
4893
5249
  var ReadDao = class {
4894
5250
  /**
4895
5251
  * Constructs a new ReadDao instance.
@@ -4911,7 +5267,7 @@ var ReadDao = class {
4911
5267
  async findById(id, ctx, signal) {
4912
5268
  AppError16.throwIfAborted(signal, "ReadDao.findById");
4913
5269
  const result = await this._dataSource.findById(id, ctx, signal);
4914
- if (Guards37.isNullOrEmpty(result)) return Result17.ok();
5270
+ if (Guards43.isNullOrEmpty(result)) return Result17.ok();
4915
5271
  const entity = this._mapper.toEntity(result);
4916
5272
  return Result17.ok(entity);
4917
5273
  }
@@ -4925,7 +5281,7 @@ var ReadDao = class {
4925
5281
 
4926
5282
  // src/infrastructure/repositories/repository.ts
4927
5283
  import { AppError as AppError17, Result as Result18 } from "@xeno-js/shared";
4928
- import { Guards as Guards38 } from "@xeno-js/shared";
5284
+ import { Guards as Guards44 } from "@xeno-js/shared";
4929
5285
  var Repository = class {
4930
5286
  /**
4931
5287
  * Constructs a new Repository instance.
@@ -4947,7 +5303,7 @@ var Repository = class {
4947
5303
  async findById(id, ctx, signal) {
4948
5304
  AppError17.throwIfAborted(signal, "Repository.findById");
4949
5305
  const result = await this._dataSource.findById(id, ctx, signal);
4950
- if (Guards38.isNullOrEmpty(result)) return Result18.ok();
5306
+ if (Guards44.isNullOrEmpty(result)) return Result18.ok();
4951
5307
  const entity = this._mapper.toEntity(result);
4952
5308
  return Result18.ok(entity);
4953
5309
  }
@@ -5005,4 +5361,13 @@ export {
5005
5361
  Specification,
5006
5362
  SupabaseServerAuthFactory
5007
5363
  };
5364
+ /**
5365
+ * @description The CsrfCookieMiddleware class implements the IMiddleware interface, providing a concrete implementation for handling CSRF token validation and cookie management. It checks the incoming request for a valid CSRF token and sets a CSRF cookie if necessary.
5366
+ *
5367
+ * @author Xeno
5368
+ * @version 1.0.0
5369
+ * @since 2025-09-30
5370
+ * @link https://github.com/xeno-js/xeno-js
5371
+ * @license MIT
5372
+ */
5008
5373
  //# sourceMappingURL=index.js.map