@arcis/node 1.6.2 → 1.6.4

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 (71) hide show
  1. package/README.md +9 -7
  2. package/dist/_third_party/rate-limit/abstract.d.ts +36 -0
  3. package/dist/_third_party/rate-limit/abstract.d.ts.map +1 -0
  4. package/dist/_third_party/rate-limit/bursty.d.ts +21 -0
  5. package/dist/_third_party/rate-limit/bursty.d.ts.map +1 -0
  6. package/dist/_third_party/rate-limit/index.d.ts +12 -0
  7. package/dist/_third_party/rate-limit/index.d.ts.map +1 -0
  8. package/dist/_third_party/rate-limit/memory-storage.d.ts +28 -0
  9. package/dist/_third_party/rate-limit/memory-storage.d.ts.map +1 -0
  10. package/dist/_third_party/rate-limit/memory.d.ts +23 -0
  11. package/dist/_third_party/rate-limit/memory.d.ts.map +1 -0
  12. package/dist/_third_party/rate-limit/record.d.ts +11 -0
  13. package/dist/_third_party/rate-limit/record.d.ts.map +1 -0
  14. package/dist/_third_party/rate-limit/types.d.ts +39 -0
  15. package/dist/_third_party/rate-limit/types.d.ts.map +1 -0
  16. package/dist/astro/index.js +405 -0
  17. package/dist/astro/index.js.map +1 -1
  18. package/dist/astro/index.mjs +405 -0
  19. package/dist/astro/index.mjs.map +1 -1
  20. package/dist/bun/index.js +405 -0
  21. package/dist/bun/index.js.map +1 -1
  22. package/dist/bun/index.mjs +405 -0
  23. package/dist/bun/index.mjs.map +1 -1
  24. package/dist/fastify/index.js +405 -0
  25. package/dist/fastify/index.js.map +1 -1
  26. package/dist/fastify/index.mjs +405 -0
  27. package/dist/fastify/index.mjs.map +1 -1
  28. package/dist/hono/index.js +405 -0
  29. package/dist/hono/index.js.map +1 -1
  30. package/dist/hono/index.mjs +405 -0
  31. package/dist/hono/index.mjs.map +1 -1
  32. package/dist/index.d.ts +2 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +752 -4
  35. package/dist/index.js.map +1 -1
  36. package/dist/index.mjs +752 -5
  37. package/dist/index.mjs.map +1 -1
  38. package/dist/koa/index.js +405 -0
  39. package/dist/koa/index.js.map +1 -1
  40. package/dist/koa/index.mjs +405 -0
  41. package/dist/koa/index.mjs.map +1 -1
  42. package/dist/middleware/brute-force.d.ts +69 -0
  43. package/dist/middleware/brute-force.d.ts.map +1 -0
  44. package/dist/middleware/index.js +700 -0
  45. package/dist/middleware/index.js.map +1 -1
  46. package/dist/middleware/index.mjs +700 -0
  47. package/dist/middleware/index.mjs.map +1 -1
  48. package/dist/middleware/nestjs.d.ts +50 -1
  49. package/dist/middleware/nestjs.d.ts.map +1 -1
  50. package/dist/middleware/protect.d.ts +9 -0
  51. package/dist/middleware/protect.d.ts.map +1 -1
  52. package/dist/nestjs/index.js +55 -1
  53. package/dist/nestjs/index.js.map +1 -1
  54. package/dist/nestjs/index.mjs +55 -2
  55. package/dist/nestjs/index.mjs.map +1 -1
  56. package/dist/nextjs/index.js +405 -0
  57. package/dist/nextjs/index.js.map +1 -1
  58. package/dist/nextjs/index.mjs +405 -0
  59. package/dist/nextjs/index.mjs.map +1 -1
  60. package/dist/nuxt/index.js +405 -0
  61. package/dist/nuxt/index.js.map +1 -1
  62. package/dist/nuxt/index.mjs +405 -0
  63. package/dist/nuxt/index.mjs.map +1 -1
  64. package/dist/sanitizers/prompt-injection.d.ts +3 -3
  65. package/dist/sanitizers/prompt-injection.d.ts.map +1 -1
  66. package/dist/sveltekit/index.js +405 -0
  67. package/dist/sveltekit/index.js.map +1 -1
  68. package/dist/sveltekit/index.mjs +405 -0
  69. package/dist/sveltekit/index.mjs.map +1 -1
  70. package/package.json +5 -5
  71. package/scripts/postinstall.cjs +1 -1
@@ -33,7 +33,7 @@
33
33
  * `@nestjs/common` installed; non-NestJS users pay nothing.
34
34
  */
35
35
  import type { Request, Response, NextFunction } from 'express';
36
- import type { DynamicModule } from '@nestjs/common';
36
+ import type { CanActivate, DynamicModule, ExecutionContext } from '@nestjs/common';
37
37
  import type { ArcisOptions } from '../core/types';
38
38
  /** Injection token for `ArcisOptions` consumed by `ArcisMiddleware`'s factory. */
39
39
  export declare const ARCIS_OPTIONS: unique symbol;
@@ -50,10 +50,59 @@ export declare class ArcisMiddleware {
50
50
  /** Release rate-limiter intervals etc. Call from `OnApplicationShutdown`. */
51
51
  close(): void;
52
52
  }
53
+ /**
54
+ * NestJS Guard implementation of the Arcis stack.
55
+ *
56
+ * Class-middleware applied via `MiddlewareConsumer.apply().forRoutes()` does
57
+ * not reliably short-circuit NestJS's controller pipeline when an inner
58
+ * handler writes `res.status(403).end()` without calling Express's `next`.
59
+ * The controller resolution path runs anyway and the controller's return
60
+ * value overwrites the deny response. CI surfaced this with 0-of-8 attacks
61
+ * blocked on the NestJS example using the `MiddlewareConsumer` pattern.
62
+ *
63
+ * `CanActivate` runs in the correct NestJS lifecycle slot (after body-parse,
64
+ * before controller resolution) and is designed to deny via `return false`
65
+ * or by writing the response directly. When an Arcis handler writes a 403,
66
+ * the guard sees `res.headersSent === true` after it runs and returns
67
+ * `false`, which NestJS treats as a denial without re-running the
68
+ * controller. Successful traversal (no threats found) returns `true` and
69
+ * NestJS proceeds to the controller with the mutated (sanitized) req.
70
+ *
71
+ * Recommended over `ArcisMiddleware` for NestJS apps that want deny-on-
72
+ * detect behavior. `ArcisMiddleware` is retained for backward compat but
73
+ * is best suited for sanitize-only / observation-only usage.
74
+ *
75
+ * Register globally via the `APP_GUARD` token:
76
+ *
77
+ * ```ts
78
+ * import { APP_GUARD } from '@nestjs/core';
79
+ * import { ArcisGuard } from '@arcis/node/nestjs';
80
+ *
81
+ * @Module({
82
+ * providers: [
83
+ * {
84
+ * provide: APP_GUARD,
85
+ * useFactory: () => new ArcisGuard({ block: true }),
86
+ * },
87
+ * ],
88
+ * })
89
+ * export class AppModule {}
90
+ * ```
91
+ */
92
+ export declare class ArcisGuard implements CanActivate {
93
+ private readonly handlers;
94
+ constructor(options?: ArcisOptions);
95
+ canActivate(context: ExecutionContext): Promise<boolean>;
96
+ /** Release rate-limiter intervals etc. Call from `OnApplicationShutdown`. */
97
+ close(): void;
98
+ }
53
99
  /**
54
100
  * NestJS dynamic module. `ArcisModule.forRoot(options)` is the entry point.
55
101
  * Returns a plain `DynamicModule` literal so `@Module({})` is unnecessary on
56
102
  * `ArcisModule` itself; this keeps `@nestjs/common` purely a type-only import.
103
+ *
104
+ * Exports both `ArcisMiddleware` (for legacy `MiddlewareConsumer` consumers)
105
+ * and `ArcisGuard` (recommended; actually denies attacks on detect).
57
106
  */
58
107
  export declare class ArcisModule {
59
108
  static forRoot(options?: ArcisOptions): DynamicModule;
@@ -1 +1 @@
1
- {"version":3,"file":"nestjs.d.ts","sourceRoot":"","sources":["../../src/middleware/nestjs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAkB,MAAM,SAAS,CAAC;AAC/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,KAAK,EAAE,YAAY,EAAwB,MAAM,eAAe,CAAC;AAExE,kFAAkF;AAClF,eAAO,MAAM,aAAa,eAA0B,CAAC;AAErD;;;;;GAKG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuB;gBAEpC,OAAO,GAAE,YAAiB;IAItC,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI;IAsB1D,6EAA6E;IAC7E,KAAK,IAAI,IAAI;CAGd;AAED;;;;GAIG;AACH,qBAAa,WAAW;IACtB,MAAM,CAAC,OAAO,CAAC,OAAO,GAAE,YAAiB,GAAG,aAAa;CAc1D;AAED,eAAe,WAAW,CAAC"}
1
+ {"version":3,"file":"nestjs.d.ts","sourceRoot":"","sources":["../../src/middleware/nestjs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAkB,MAAM,SAAS,CAAC;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEnF,OAAO,KAAK,EAAE,YAAY,EAAwB,MAAM,eAAe,CAAC;AAExE,kFAAkF;AAClF,eAAO,MAAM,aAAa,eAA0B,CAAC;AAErD;;;;;GAKG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuB;gBAEpC,OAAO,GAAE,YAAiB;IAItC,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI;IAsB1D,6EAA6E;IAC7E,KAAK,IAAI,IAAI;CAGd;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,qBAAa,UAAW,YAAW,WAAW;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuB;gBAEpC,OAAO,GAAE,YAAiB;IAItC,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAoDxD,6EAA6E;IAC7E,KAAK,IAAI,IAAI;CAGd;AAED;;;;;;;GAOG;AACH,qBAAa,WAAW;IACtB,MAAM,CAAC,OAAO,CAAC,OAAO,GAAE,YAAiB,GAAG,aAAa;CAmB1D;AAED,eAAe,WAAW,CAAC"}
@@ -35,6 +35,7 @@ import { type BotProtectionOptions } from './bot-detection';
35
35
  import { type CsrfOptions } from './csrf';
36
36
  import type { CorsOptions } from './cors';
37
37
  import { type SignupProtectionOptions } from './signup-protection';
38
+ import { type BruteForceOptions } from './brute-force';
38
39
  import type { RateLimitOptions, SanitizeOptions } from '../core/types';
39
40
  import { CorrelationWindow } from './correlation';
40
41
  /**
@@ -75,6 +76,14 @@ export interface ProtectLoginOptions {
75
76
  sanitize?: LayerOverride<SanitizeOptions>;
76
77
  /** Optional correlation-window wiring (improvements.md §1.4). */
77
78
  correlation?: CorrelationOptions;
79
+ /**
80
+ * Optional brute-force layer. When enabled, layers a bursty limiter
81
+ * on top of the fast rate-limit window: N attempts in `slowDuration`
82
+ * seconds trips a `blockDuration`-second semi-permanent block.
83
+ * Defaults to disabled (preserves existing behavior); pass `true`
84
+ * for safe defaults or an options object to customize.
85
+ */
86
+ bruteForce?: boolean | BruteForceOptions;
78
87
  }
79
88
  export interface ProtectSignupOptions {
80
89
  rateLimit?: LayerOverride<RateLimitOptions>;
@@ -1 +1 @@
1
- {"version":3,"file":"protect.d.ts","sourceRoot":"","sources":["../../src/middleware/protect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,OAAO,EAAiB,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAC;AAE1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EAAoB,KAAK,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAErF,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAmDD;;;;GAIG;AACH,KAAK,aAAa,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC;AAE9C,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC5C,GAAG,CAAC,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;IAC1C,IAAI,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC1C,iEAAiE;IACjE,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC5C,GAAG,CAAC,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;IAC1C,QAAQ,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC1C,sFAAsF;IACtF,MAAM,CAAC,EAAE,aAAa,CAAC,uBAAuB,CAAC,CAAC;IAChD,iEAAiE;IACjE,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC5C,6EAA6E;IAC7E,IAAI,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC1C,iEAAiE;IACjE,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAaD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,cAAc,EAAE,CA0BhF;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,cAAc,EAAE,CA0BlF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,cAAc,EAAE,CAsB5E"}
1
+ {"version":3,"file":"protect.d.ts","sourceRoot":"","sources":["../../src/middleware/protect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,OAAO,EAAiB,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAC;AAE1D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EAAoB,KAAK,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAwB,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAmDD;;;;GAIG;AACH,KAAK,aAAa,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC;AAE9C,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC5C,GAAG,CAAC,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;IAC1C,IAAI,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC1C,iEAAiE;IACjE,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,GAAG,iBAAiB,CAAC;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC5C,GAAG,CAAC,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;IAC1C,QAAQ,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC1C,sFAAsF;IACtF,MAAM,CAAC,EAAE,aAAa,CAAC,uBAAuB,CAAC,CAAC;IAChD,iEAAiE;IACjE,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,CAAC,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;IAC5C,6EAA6E;IAC7E,IAAI,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAClC,QAAQ,CAAC,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC1C,iEAAiE;IACjE,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAaD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,cAAc,EAAE,CAgChF;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,cAAc,EAAE,CA0BlF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,cAAc,EAAE,CAsB5E"}
@@ -1752,6 +1752,54 @@ var ArcisMiddleware = class {
1752
1752
  this.handlers.close();
1753
1753
  }
1754
1754
  };
1755
+ var ArcisGuard = class {
1756
+ constructor(options = {}) {
1757
+ this.handlers = arcis(options);
1758
+ }
1759
+ canActivate(context) {
1760
+ const http = context.switchToHttp();
1761
+ const req = http.getRequest();
1762
+ const res = http.getResponse();
1763
+ return new Promise((resolve, reject) => {
1764
+ const handlers = this.handlers;
1765
+ let i = 0;
1766
+ const run = (err) => {
1767
+ if (err !== void 0) {
1768
+ reject(err);
1769
+ return;
1770
+ }
1771
+ if (res.headersSent) {
1772
+ resolve(false);
1773
+ return;
1774
+ }
1775
+ const handler = handlers[i++];
1776
+ if (!handler) {
1777
+ resolve(!res.headersSent);
1778
+ return;
1779
+ }
1780
+ let advanced = false;
1781
+ const wrappedNext = (innerErr) => {
1782
+ advanced = true;
1783
+ run(innerErr);
1784
+ };
1785
+ try {
1786
+ handler(req, res, wrappedNext);
1787
+ } catch (caught) {
1788
+ reject(caught);
1789
+ return;
1790
+ }
1791
+ if (!advanced && res.headersSent) {
1792
+ resolve(false);
1793
+ }
1794
+ };
1795
+ run();
1796
+ });
1797
+ }
1798
+ /** Release rate-limiter intervals etc. Call from `OnApplicationShutdown`. */
1799
+ close() {
1800
+ this.handlers.close();
1801
+ }
1802
+ };
1755
1803
  var ArcisModule = class _ArcisModule {
1756
1804
  static forRoot(options = {}) {
1757
1805
  return {
@@ -1762,15 +1810,21 @@ var ArcisModule = class _ArcisModule {
1762
1810
  provide: ArcisMiddleware,
1763
1811
  useFactory: (opts) => new ArcisMiddleware(opts),
1764
1812
  inject: [ARCIS_OPTIONS]
1813
+ },
1814
+ {
1815
+ provide: ArcisGuard,
1816
+ useFactory: (opts) => new ArcisGuard(opts),
1817
+ inject: [ARCIS_OPTIONS]
1765
1818
  }
1766
1819
  ],
1767
- exports: [ArcisMiddleware]
1820
+ exports: [ArcisMiddleware, ArcisGuard]
1768
1821
  };
1769
1822
  }
1770
1823
  };
1771
1824
  var nestjs_default = ArcisModule;
1772
1825
 
1773
1826
  exports.ARCIS_OPTIONS = ARCIS_OPTIONS;
1827
+ exports.ArcisGuard = ArcisGuard;
1774
1828
  exports.ArcisMiddleware = ArcisMiddleware;
1775
1829
  exports.ArcisModule = ArcisModule;
1776
1830
  exports.default = nestjs_default;