@nestjs-kit/better-auth 2.1.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/README.md +3 -3
  2. package/dist/admin.cjs +3 -4
  3. package/dist/admin.d.cts +1 -3
  4. package/dist/admin.d.cts.map +1 -1
  5. package/dist/admin.d.mts +1 -3
  6. package/dist/admin.d.mts.map +1 -1
  7. package/dist/admin.mjs +3 -4
  8. package/dist/api-key.cjs +4 -5
  9. package/dist/api-key.d.cts +1 -3
  10. package/dist/api-key.d.cts.map +1 -1
  11. package/dist/api-key.d.mts +1 -3
  12. package/dist/api-key.d.mts.map +1 -1
  13. package/dist/api-key.mjs +4 -5
  14. package/dist/{auth-contracts-Brh_Qko9.d.cts → auth-contracts-CADGyI0O.d.mts} +3 -53
  15. package/dist/auth-contracts-CADGyI0O.d.mts.map +1 -0
  16. package/dist/{auth-contracts-Cz7C4_Ch.d.mts → auth-contracts-zvt8ysoZ.d.cts} +3 -53
  17. package/dist/auth-contracts-zvt8ysoZ.d.cts.map +1 -0
  18. package/dist/{auth-decorators-Cu_nxWnF.cjs → auth-decorators-CJKE9wlT.cjs} +8 -10
  19. package/dist/{auth-decorators-Cu_nxWnF.cjs.map → auth-decorators-CJKE9wlT.cjs.map} +1 -1
  20. package/dist/{auth-decorators-B1mFnGJ6.mjs → auth-decorators-CkNkLNpU.mjs} +8 -10
  21. package/dist/{auth-decorators-B1mFnGJ6.mjs.map → auth-decorators-CkNkLNpU.mjs.map} +1 -1
  22. package/dist/{auth-errors-C3rbTV9p.mjs → auth-errors-JjxGDVSt.mjs} +3 -5
  23. package/dist/{auth-errors-C3rbTV9p.mjs.map → auth-errors-JjxGDVSt.mjs.map} +1 -1
  24. package/dist/{auth-errors-DmiKl0L_.cjs → auth-errors-RW7hOVI-.cjs} +3 -5
  25. package/dist/{auth-errors-DmiKl0L_.cjs.map → auth-errors-RW7hOVI-.cjs.map} +1 -1
  26. package/dist/{auth-guard-h9QB_l11.mjs → auth-guard-Da92QEK5.mjs} +4 -5
  27. package/dist/{auth-guard-h9QB_l11.mjs.map → auth-guard-Da92QEK5.mjs.map} +1 -1
  28. package/dist/{auth-guard-CLyhAEEj.cjs → auth-guard-wapEh_M_.cjs} +4 -5
  29. package/dist/{auth-guard-CLyhAEEj.cjs.map → auth-guard-wapEh_M_.cjs.map} +1 -1
  30. package/dist/{auth-module-BgcY2HpA.cjs → auth-module-ab60-WJZ.cjs} +28 -47
  31. package/dist/auth-module-ab60-WJZ.cjs.map +1 -0
  32. package/dist/{auth-module-CtHx3gRU.mjs → auth-module-uy3BBWwR.mjs} +28 -47
  33. package/dist/auth-module-uy3BBWwR.mjs.map +1 -0
  34. package/dist/{auth-scope-interceptor-BjxAL1-S.cjs → auth-scope-interceptor-Bui20-Ps.cjs} +5 -7
  35. package/dist/{auth-scope-interceptor-BjxAL1-S.cjs.map → auth-scope-interceptor-Bui20-Ps.cjs.map} +1 -1
  36. package/dist/{auth-scope-interceptor-DYPn3b8M.mjs → auth-scope-interceptor-CvCQ52dV.mjs} +5 -7
  37. package/dist/{auth-scope-interceptor-DYPn3b8M.mjs.map → auth-scope-interceptor-CvCQ52dV.mjs.map} +1 -1
  38. package/dist/{bridge-protocol-c66aEkr5.mjs → bridge-protocol-CmRsff2P.mjs} +2 -3
  39. package/dist/{bridge-protocol-BDw8opAG.cjs.map → bridge-protocol-CmRsff2P.mjs.map} +1 -1
  40. package/dist/{bridge-protocol-BDw8opAG.cjs → bridge-protocol-DNFhIKdo.cjs} +2 -3
  41. package/dist/{bridge-protocol-c66aEkr5.mjs.map → bridge-protocol-DNFhIKdo.cjs.map} +1 -1
  42. package/dist/{decorate-Dt0e9K6R.mjs → decorate-bO-rBn-G.mjs} +5 -9
  43. package/dist/{decorate-Dt0e9K6R.mjs.map → decorate-bO-rBn-G.mjs.map} +1 -1
  44. package/dist/{decorate-Cr4Q7bNE.cjs → decorate-fMNf0caZ.cjs} +5 -9
  45. package/dist/{decorate-Cr4Q7bNE.cjs.map → decorate-fMNf0caZ.cjs.map} +1 -1
  46. package/dist/express.cjs +3 -4
  47. package/dist/express.d.cts +1 -3
  48. package/dist/express.d.cts.map +1 -1
  49. package/dist/express.d.mts +1 -3
  50. package/dist/express.d.mts.map +1 -1
  51. package/dist/express.mjs +3 -4
  52. package/dist/fastify.cjs +2 -3
  53. package/dist/fastify.d.cts +1 -3
  54. package/dist/fastify.d.cts.map +1 -1
  55. package/dist/fastify.d.mts +1 -3
  56. package/dist/fastify.d.mts.map +1 -1
  57. package/dist/fastify.mjs +2 -3
  58. package/dist/graphql.cjs +7 -9
  59. package/dist/graphql.cjs.map +1 -1
  60. package/dist/graphql.d.cts +1 -3
  61. package/dist/graphql.d.cts.map +1 -1
  62. package/dist/graphql.d.mts +1 -3
  63. package/dist/graphql.d.mts.map +1 -1
  64. package/dist/graphql.mjs +7 -9
  65. package/dist/graphql.mjs.map +1 -1
  66. package/dist/index.cjs +7 -7
  67. package/dist/index.d.cts +1 -1
  68. package/dist/index.d.mts +1 -1
  69. package/dist/index.mjs +7 -7
  70. package/dist/microservices.cjs +4 -6
  71. package/dist/microservices.cjs.map +1 -1
  72. package/dist/microservices.d.cts +1 -5
  73. package/dist/microservices.d.cts.map +1 -1
  74. package/dist/microservices.d.mts +1 -5
  75. package/dist/microservices.d.mts.map +1 -1
  76. package/dist/microservices.mjs +3 -5
  77. package/dist/microservices.mjs.map +1 -1
  78. package/dist/organization.cjs +3 -4
  79. package/dist/organization.d.cts +1 -3
  80. package/dist/organization.d.cts.map +1 -1
  81. package/dist/organization.d.mts +1 -3
  82. package/dist/organization.d.mts.map +1 -1
  83. package/dist/organization.mjs +3 -4
  84. package/dist/{platform-CZl7TY8j.mjs → platform-BKYVzAv1.mjs} +3 -5
  85. package/dist/{platform-CZl7TY8j.mjs.map → platform-BKYVzAv1.mjs.map} +1 -1
  86. package/dist/{platform-YICqqYv6.cjs → platform-C67dxSls.cjs} +3 -5
  87. package/dist/{platform-YICqqYv6.cjs.map → platform-C67dxSls.cjs.map} +1 -1
  88. package/dist/platform.cjs +1 -1
  89. package/dist/platform.d.cts +0 -2
  90. package/dist/platform.d.cts.map +1 -1
  91. package/dist/platform.d.mts +0 -2
  92. package/dist/platform.d.mts.map +1 -1
  93. package/dist/platform.mjs +1 -1
  94. package/dist/plugin.cjs +4 -8
  95. package/dist/plugin.cjs.map +1 -1
  96. package/dist/plugin.d.cts +0 -4
  97. package/dist/plugin.d.cts.map +1 -1
  98. package/dist/plugin.d.mts +0 -4
  99. package/dist/plugin.d.mts.map +1 -1
  100. package/dist/plugin.mjs +4 -8
  101. package/dist/plugin.mjs.map +1 -1
  102. package/dist/{principal-readings-Ied2staw.mjs → principal-readings-BuXTU0-2.mjs} +3 -4
  103. package/dist/{principal-readings-Ied2staw.mjs.map → principal-readings-BuXTU0-2.mjs.map} +1 -1
  104. package/dist/{principal-readings-Chmt6rQV.cjs → principal-readings-JLNT58k0.cjs} +3 -4
  105. package/dist/{principal-readings-Chmt6rQV.cjs.map → principal-readings-JLNT58k0.cjs.map} +1 -1
  106. package/dist/{rolldown-runtime-VH7oDXx4.cjs → rolldown-runtime-CmQyd0Gu.cjs} +1 -2
  107. package/dist/testing/conformance.cjs +24 -31
  108. package/dist/testing/conformance.cjs.map +1 -1
  109. package/dist/testing/conformance.d.cts +4 -14
  110. package/dist/testing/conformance.d.cts.map +1 -1
  111. package/dist/testing/conformance.d.mts +4 -14
  112. package/dist/testing/conformance.d.mts.map +1 -1
  113. package/dist/testing/conformance.mjs +23 -30
  114. package/dist/testing/conformance.mjs.map +1 -1
  115. package/dist/testing.cjs +6 -7
  116. package/dist/testing.d.cts +1 -3
  117. package/dist/testing.d.cts.map +1 -1
  118. package/dist/testing.d.mts +1 -3
  119. package/dist/testing.d.mts.map +1 -1
  120. package/dist/testing.mjs +6 -7
  121. package/dist/websockets.cjs +7 -10
  122. package/dist/websockets.cjs.map +1 -1
  123. package/dist/websockets.d.cts +1 -7
  124. package/dist/websockets.d.cts.map +1 -1
  125. package/dist/websockets.d.mts +1 -7
  126. package/dist/websockets.d.mts.map +1 -1
  127. package/dist/websockets.mjs +7 -10
  128. package/dist/websockets.mjs.map +1 -1
  129. package/package.json +24 -24
  130. package/dist/auth-contracts-Brh_Qko9.d.cts.map +0 -1
  131. package/dist/auth-contracts-Cz7C4_Ch.d.mts.map +0 -1
  132. package/dist/auth-module-BgcY2HpA.cjs.map +0 -1
  133. package/dist/auth-module-CtHx3gRU.mjs.map +0 -1
package/dist/testing.cjs CHANGED
@@ -1,11 +1,11 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_auth_errors = require("./auth-errors-DmiKl0L_.cjs");
3
- const require_decorate = require("./decorate-Cr4Q7bNE.cjs");
4
- const require_auth_scope_interceptor = require("./auth-scope-interceptor-BjxAL1-S.cjs");
5
- const require_bridge_protocol = require("./bridge-protocol-BDw8opAG.cjs");
6
- const require_principal_readings = require("./principal-readings-Chmt6rQV.cjs");
2
+ const require_auth_errors = require("./auth-errors-RW7hOVI-.cjs");
3
+ const require_auth_scope_interceptor = require("./auth-scope-interceptor-Bui20-Ps.cjs");
4
+ const require_decorate = require("./decorate-fMNf0caZ.cjs");
5
+ const require_bridge_protocol = require("./bridge-protocol-DNFhIKdo.cjs");
6
+ const require_principal_readings = require("./principal-readings-JLNT58k0.cjs");
7
7
  let rxjs = require("rxjs");
8
- //#region src/testing.ts
8
+ // src/testing.ts
9
9
  const TEST_APP = Symbol.for("@nestjs-kit/better-auth:test-app");
10
10
  const TEST_APP_CLOSE = Symbol.for("@nestjs-kit/better-auth:test-app-close");
11
11
  const TEST_OVERRIDES = Symbol.for("@nestjs-kit/better-auth:test-overrides");
@@ -209,7 +209,6 @@ function overrideAuthGuard(builder, impl) {
209
209
  });
210
210
  return builder;
211
211
  }
212
- //#endregion
213
212
  exports.authHeadersFor = authHeadersFor;
214
213
  exports.initTestApp = initTestApp;
215
214
  exports.overrideAuthGuard = overrideAuthGuard;
@@ -1,7 +1,6 @@
1
- import { Ct as AuthPrincipal, ht as TransportCall, it as PrincipalSource, tt as PrincipalRequest, u as AuthorizationDecision, xt as AuthLike } from "./auth-contracts-Brh_Qko9.cjs";
1
+ import { Ct as AuthPrincipal, ht as TransportCall, it as PrincipalSource, tt as PrincipalRequest, u as AuthorizationDecision, xt as AuthLike } from "./auth-contracts-zvt8ysoZ.cjs";
2
2
  import { CanActivate, ExecutionContext, INestApplication } from "@nestjs/common";
3
3
  import { TestingModuleBuilder } from "@nestjs/testing";
4
- //#region src/testing.d.ts
5
4
  type FixedPrincipal = AuthPrincipal | null | ((call: TransportCall) => AuthPrincipal | null);
6
5
  type Decide = (policyId: string, params: unknown, principal: AuthPrincipal) => AuthorizationDecision | undefined | Promise<AuthorizationDecision | undefined>;
7
6
  /**
@@ -59,6 +58,5 @@ export declare function stampPrincipal(context: ExecutionContext, principal: Aut
59
58
  export declare function overrideAuthGuard(builder: TestingModuleBuilder, impl: CanActivate | {
60
59
  principal: AuthPrincipal | null | ((ctx: ExecutionContext) => AuthPrincipal | null);
61
60
  }): TestingModuleBuilder;
62
- //#endregion
63
61
  export {};
64
62
  //# sourceMappingURL=testing.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing.d.cts","names":[],"sources":["../src/testing.ts"],"mappings":";;;;KAoDK,iBACD,yBAEE,MAAM,kBAAkB;KACzB,UACH,kBACA,iBACA,WAAW,kBAET,oCAEA,QAAQ;;;;;;;;;;wBAoEU,YAAY,UAAU,kBAC1C,KAAK,GACL;EAAW,aAAa,aAAa;IACpC,QAAQ;;wBA2CW,eACpB,MAAM,UACN,iBACC,QAAQ;;;;;;wBAmBK,kBACd,SAAS,sBACT,WAAW,gBACX;EAAW;IACV;;;;;wBAiCa,kBACd,SAAS,sBACT,QAAQ,SACP;;wBAmBa,cACd,WAAW,kBAAkB,KAAK,qBAAqB,uBACvD;EACE;EACA;EACA;IAED;;;;;;;;wBA0Ba,eACd,SAAS,kBACT,WAAW,sBACX;EAAW;;;;;;;;;;;wBAoCG,kBACd,SAAS,sBACT,MACI;EAEE,WACI,yBAEE,KAAK,qBAAqB;IAErC"}
1
+ {"version":3,"file":"testing.d.cts","names":[],"sources":["../src/testing.ts"],"mappings":";;;KAoDK,iBACD,yBAEE,MAAM,kBAAkB;KACzB,UACH,kBACA,iBACA,WAAW,kBAET,oCAEA,QAAQ;;;;;;;;;;wBAoEU,YAAY,UAAU,kBAC1C,KAAK,GACL;EAAW,aAAa,aAAa;IACpC,QAAQ;;wBA2CW,eACpB,MAAM,UACN,iBACC,QAAQ;;;;;;wBAmBK,kBACd,SAAS,sBACT,WAAW,gBACX;EAAW;IACV;;;;;wBAiCa,kBACd,SAAS,sBACT,QAAQ,SACP;;wBAmBa,cACd,WAAW,kBAAkB,KAAK,qBAAqB,uBACvD;EACE;EACA;EACA;IAED;;;;;;;;wBA0Ba,eACd,SAAS,kBACT,WAAW,sBACX;EAAW;;;;;;;;;;;wBAoCG,kBACd,SAAS,sBACT,MACI;EAEE,WACI,yBAEE,KAAK,qBAAqB;IAErC"}
@@ -1,7 +1,6 @@
1
- import { Ct as AuthPrincipal, ht as TransportCall, it as PrincipalSource, tt as PrincipalRequest, u as AuthorizationDecision, xt as AuthLike } from "./auth-contracts-Cz7C4_Ch.mjs";
1
+ import { Ct as AuthPrincipal, ht as TransportCall, it as PrincipalSource, tt as PrincipalRequest, u as AuthorizationDecision, xt as AuthLike } from "./auth-contracts-CADGyI0O.mjs";
2
2
  import { CanActivate, ExecutionContext, INestApplication } from "@nestjs/common";
3
3
  import { TestingModuleBuilder } from "@nestjs/testing";
4
- //#region src/testing.d.ts
5
4
  type FixedPrincipal = AuthPrincipal | null | ((call: TransportCall) => AuthPrincipal | null);
6
5
  type Decide = (policyId: string, params: unknown, principal: AuthPrincipal) => AuthorizationDecision | undefined | Promise<AuthorizationDecision | undefined>;
7
6
  /**
@@ -59,6 +58,5 @@ export declare function stampPrincipal(context: ExecutionContext, principal: Aut
59
58
  export declare function overrideAuthGuard(builder: TestingModuleBuilder, impl: CanActivate | {
60
59
  principal: AuthPrincipal | null | ((ctx: ExecutionContext) => AuthPrincipal | null);
61
60
  }): TestingModuleBuilder;
62
- //#endregion
63
61
  export {};
64
62
  //# sourceMappingURL=testing.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing.d.mts","names":[],"sources":["../src/testing.ts"],"mappings":";;;;KAoDK,iBACD,yBAEE,MAAM,kBAAkB;KACzB,UACH,kBACA,iBACA,WAAW,kBAET,oCAEA,QAAQ;;;;;;;;;;wBAoEU,YAAY,UAAU,kBAC1C,KAAK,GACL;EAAW,aAAa,aAAa;IACpC,QAAQ;;wBA2CW,eACpB,MAAM,UACN,iBACC,QAAQ;;;;;;wBAmBK,kBACd,SAAS,sBACT,WAAW,gBACX;EAAW;IACV;;;;;wBAiCa,kBACd,SAAS,sBACT,QAAQ,SACP;;wBAmBa,cACd,WAAW,kBAAkB,KAAK,qBAAqB,uBACvD;EACE;EACA;EACA;IAED;;;;;;;;wBA0Ba,eACd,SAAS,kBACT,WAAW,sBACX;EAAW;;;;;;;;;;;wBAoCG,kBACd,SAAS,sBACT,MACI;EAEE,WACI,yBAEE,KAAK,qBAAqB;IAErC"}
1
+ {"version":3,"file":"testing.d.mts","names":[],"sources":["../src/testing.ts"],"mappings":";;;KAoDK,iBACD,yBAEE,MAAM,kBAAkB;KACzB,UACH,kBACA,iBACA,WAAW,kBAET,oCAEA,QAAQ;;;;;;;;;;wBAoEU,YAAY,UAAU,kBAC1C,KAAK,GACL;EAAW,aAAa,aAAa;IACpC,QAAQ;;wBA2CW,eACpB,MAAM,UACN,iBACC,QAAQ;;;;;;wBAmBK,kBACd,SAAS,sBACT,WAAW,gBACX;EAAW;IACV;;;;;wBAiCa,kBACd,SAAS,sBACT,QAAQ,SACP;;wBAmBa,cACd,WAAW,kBAAkB,KAAK,qBAAqB,uBACvD;EACE;EACA;EACA;IAED;;;;;;;;wBA0Ba,eACd,SAAS,kBACT,WAAW,sBACX;EAAW;;;;;;;;;;;wBAoCG,kBACd,SAAS,sBACT,MACI;EAEE,WACI,yBAEE,KAAK,qBAAqB;IAErC"}
package/dist/testing.mjs CHANGED
@@ -1,10 +1,10 @@
1
- import { n as BetterAuthConfigurationError } from "./auth-errors-C3rbTV9p.mjs";
2
- import { C as PRINCIPAL_RESOLVER, D as ROUTE_PLANNER, M as TRANSPORT_REGISTRY, O as SCOPE_CORE, T as REQUEST_SCOPE, f as GUARD_CORE, m as INSTANCE_REGISTRY, y as POLICY_INVOKER } from "./decorate-Dt0e9K6R.mjs";
3
- import { a as absent, n as ScopeCore, o as authenticated, r as ChainPrincipalResolver } from "./auth-scope-interceptor-DYPn3b8M.mjs";
4
- import { t as BRIDGE_HANDLE } from "./bridge-protocol-c66aEkr5.mjs";
5
- import { n as stampResult, r as stampedReading, t as PrincipalReadings } from "./principal-readings-Ied2staw.mjs";
1
+ import { n as BetterAuthConfigurationError } from "./auth-errors-JjxGDVSt.mjs";
2
+ import { a as absent, n as ScopeCore, o as authenticated, r as ChainPrincipalResolver } from "./auth-scope-interceptor-CvCQ52dV.mjs";
3
+ import { C as PRINCIPAL_RESOLVER, D as ROUTE_PLANNER, M as TRANSPORT_REGISTRY, O as SCOPE_CORE, T as REQUEST_SCOPE, f as GUARD_CORE, m as INSTANCE_REGISTRY, y as POLICY_INVOKER } from "./decorate-bO-rBn-G.mjs";
4
+ import { t as BRIDGE_HANDLE } from "./bridge-protocol-CmRsff2P.mjs";
5
+ import { n as stampResult, r as stampedReading, t as PrincipalReadings } from "./principal-readings-BuXTU0-2.mjs";
6
6
  import { isObservable, lastValueFrom } from "rxjs";
7
- //#region src/testing.ts
7
+ // src/testing.ts
8
8
  const TEST_APP = Symbol.for("@nestjs-kit/better-auth:test-app");
9
9
  const TEST_APP_CLOSE = Symbol.for("@nestjs-kit/better-auth:test-app-close");
10
10
  const TEST_OVERRIDES = Symbol.for("@nestjs-kit/better-auth:test-overrides");
@@ -208,7 +208,6 @@ function overrideAuthGuard(builder, impl) {
208
208
  });
209
209
  return builder;
210
210
  }
211
- //#endregion
212
211
  export { authHeadersFor, initTestApp, overrideAuthGuard, overrideDecisions, overridePrincipal, stampPrincipal, testPrincipal };
213
212
 
214
213
  //# sourceMappingURL=testing.mjs.map
@@ -1,12 +1,12 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_auth_errors = require("./auth-errors-DmiKl0L_.cjs");
3
- const require_decorate = require("./decorate-Cr4Q7bNE.cjs");
4
- const require_bridge_protocol = require("./bridge-protocol-BDw8opAG.cjs");
5
- const require_platform = require("./platform-YICqqYv6.cjs");
2
+ const require_auth_errors = require("./auth-errors-RW7hOVI-.cjs");
3
+ const require_bridge_protocol = require("./bridge-protocol-DNFhIKdo.cjs");
4
+ const require_platform = require("./platform-C67dxSls.cjs");
5
+ const require_decorate = require("./decorate-fMNf0caZ.cjs");
6
6
  let _nestjs_common = require("@nestjs/common");
7
7
  let _nestjs_core = require("@nestjs/core");
8
8
  let _nestjs_websockets = require("@nestjs/websockets");
9
- //#region src/ws-connection-auth.ts
9
+ // src/ws-connection-auth.ts
10
10
  function wsCloseCodeFor(failure) {
11
11
  return failure.status === 401 ? 4401 : failure.status === 403 ? 4403 : 4429;
12
12
  }
@@ -159,8 +159,7 @@ WsConnectionAuth = require_decorate.__decorate([
159
159
  Object
160
160
  ])
161
161
  ], WsConnectionAuth);
162
- //#endregion
163
- //#region src/socket-io-transport.ts
162
+ // src/socket-io-transport.ts
164
163
  /** Convert only mapped headers here: native Headers errors can quote the credential. */
165
164
  function mappedCredentialHeaders(input) {
166
165
  const headers = new Headers();
@@ -297,8 +296,7 @@ function socketIoTransport(options = {}) {
297
296
  advise: (context) => quotaAdvice(context, ttl)
298
297
  });
299
298
  }
300
- //#endregion
301
- //#region src/ws-transport.ts
299
+ // src/ws-transport.ts
302
300
  function recordUpgradeRequest(client, request) {
303
301
  Object.defineProperty(client, require_bridge_protocol.UPGRADE_REQUEST, {
304
302
  value: Object.freeze({
@@ -378,7 +376,6 @@ function wsTransport(options = {}) {
378
376
  advise: (context) => quotaAdvice(context, ttl)
379
377
  });
380
378
  }
381
- //#endregion
382
379
  exports.UPGRADE_REQUEST = require_bridge_protocol.UPGRADE_REQUEST;
383
380
  exports.WS_CONNECTION_AUTH = require_decorate.WS_CONNECTION_AUTH;
384
381
  Object.defineProperty(exports, "WsConnectionAuth", {
@@ -1 +1 @@
1
- {"version":3,"file":"websockets.cjs","names":["isConfigurationError","isInfrastructureError","readErrorProperty","Logger","BetterAuthConfigurationError","isAuthFailure","AuthFailures","Inject","INSTANCE_REGISTRY","PRINCIPAL_RESOLVER","TRANSPORT_REGISTRY","AuthFailures","WsException","BetterAuthConfigurationError","MetadataScanner","EXTENSION_DEFINITION","WS_CONNECTION_AUTH","toWebHeaders","upgradeRequestUrl","UPGRADE_REQUEST","toWebHeaders","BetterAuthConfigurationError","upgradeRequestUrl"],"sources":["../src/ws-connection-auth.ts","../src/socket-io-transport.ts","../src/ws-transport.ts"],"sourcesContent":["import {\n type ContextType,\n type ExecutionContext,\n Inject,\n Logger,\n type Type,\n} from \"@nestjs/common\";\nimport type { PrincipalResolver, PrincipalResult } from \"./auth-contracts.js\";\nimport {\n AuthFailures,\n isAuthFailure,\n isConfigurationError,\n isInfrastructureError,\n BetterAuthConfigurationError,\n type AuthFailure,\n} from \"./auth-errors.js\";\nimport {\n INSTANCE_REGISTRY,\n PRINCIPAL_RESOLVER,\n TRANSPORT_REGISTRY,\n} from \"./auth-tokens.js\";\nimport { readErrorProperty } from \"./error-redactor.js\";\nimport type { InstanceLookup } from \"./instance-registry.js\";\nimport type { TransportRegistry } from \"./transport-registry.js\";\n\nexport { WS_CONNECTION_AUTH } from \"./auth-tokens.js\";\nexport function wsCloseCodeFor(failure: AuthFailure): 4401 | 4403 | 4429 {\n return failure.status === 401 ? 4401 : failure.status === 403 ? 4403 : 4429;\n}\n\nconst STACK_FRAME = /^\\s+at .+:\\d+:\\d+\\)?$/;\n\n/**\n * Describes an unexpected connection-authentication error for the server log. Package\n * errors carry fixed messages and already-redacted causes. Application and runtime error\n * messages can quote client credentials (native Headers errors do), so only their name\n * and stack frames are kept.\n */\nexport function connectionErrorLog(error: unknown): {\n message: string;\n stack?: string;\n} {\n const text = (value: unknown) =>\n typeof value === \"string\" ? value : undefined;\n let summary: string;\n if (isConfigurationError(error)) {\n summary = `${error.code}: ${error.detail}`;\n } else if (isInfrastructureError(error)) {\n const cause = readErrorProperty(error, \"cause\");\n summary = `${error.message} (${text(readErrorProperty(cause, \"name\")) ?? \"Error\"}: ${text(readErrorProperty(cause, \"message\")) ?? \"\"})`;\n } else {\n const name = text(readErrorProperty(error, \"name\"));\n summary = `${name !== undefined && /^[\\w$.]{1,64}$/.test(name) ? name : typeof error} (message withheld)`;\n }\n const frames = (text(readErrorProperty(error, \"stack\")) ?? \"\")\n .split(/\\r?\\n/)\n .filter((line) => STACK_FRAME.test(line));\n return {\n message: `WebSocket connection authentication failed: ${summary}`,\n stack: frames.length > 0 ? [summary, ...frames].join(\"\\n\") : undefined,\n };\n}\n\n/**\n * The `ws` execution context of a connection before any gateway handler runs. Nest exports no\n * public factory for execution contexts, so this implements the public `ExecutionContext`\n * interface with the values Nest's internal host reports for the arguments `[client, undefined]`.\n */\nexport class ConnectionExecutionContext implements ExecutionContext {\n readonly #args: unknown[];\n\n constructor(client: object) {\n this.#args = [client, undefined];\n }\n\n getType<TContext extends string = ContextType>(): TContext {\n return \"ws\" as TContext;\n }\n\n /** No handler runs yet, so there is no class; Nest's host reports `null` as well. */\n getClass<T>(): Type<T> {\n return null as unknown as Type<T>;\n }\n\n /** No handler runs yet; Nest's host reports `null` as well. */\n getHandler(): ReturnType<ExecutionContext[\"getHandler\"]> {\n return null as unknown as ReturnType<ExecutionContext[\"getHandler\"]>;\n }\n\n getArgs<T extends unknown[] = unknown[]>(): T {\n return this.#args as T;\n }\n\n getArgByIndex<T>(index: number): T {\n return this.#args[index] as T;\n }\n\n switchToHttp(): ReturnType<ExecutionContext[\"switchToHttp\"]> {\n return {\n getRequest: <T>() => this.getArgByIndex<T>(0),\n getResponse: <T>() => this.getArgByIndex<T>(1),\n getNext: <T>() => this.getArgByIndex<T>(2),\n };\n }\n\n switchToRpc(): ReturnType<ExecutionContext[\"switchToRpc\"]> {\n return {\n getData: <T>() => this.getArgByIndex<T>(0),\n getContext: <T>() => this.getArgByIndex<T>(1),\n };\n }\n\n switchToWs(): ReturnType<ExecutionContext[\"switchToWs\"]> {\n return {\n getClient: <T>() => this.getArgByIndex<T>(0),\n getData: <T>() => this.getArgByIndex<T>(1),\n getPattern: () => this.getArgByIndex<string>(this.#args.length - 1),\n };\n }\n}\n\n/** Connection authentication delegates to the same origin and principal kernel as messages. */\nexport class WsConnectionAuth {\n private readonly logger = new Logger(\"BetterAuth\");\n\n constructor(\n @Inject(INSTANCE_REGISTRY) private readonly instances: InstanceLookup,\n @Inject(PRINCIPAL_RESOLVER) private readonly resolver: PrincipalResolver,\n @Inject(TRANSPORT_REGISTRY) private readonly transports: TransportRegistry,\n ) {}\n\n async authenticate(\n client: unknown,\n options: { instance?: string } = {},\n ): Promise<PrincipalResult> {\n if (typeof client !== \"object\" || client === null) {\n throw BetterAuthConfigurationError.atRequest(\n \"INVALID_WS_CLIENT\",\n \"Connection authentication requires a WebSocket client.\",\n );\n }\n const context = new ConnectionExecutionContext(client);\n const transport = this.transports.select(context);\n const call = this.transports.describe(context, transport);\n const entry = this.instances.get(options.instance ?? \"default\");\n const browser = call.browser;\n if (browser && entry.options.originCheck?.mode !== \"off\") {\n const failure = await entry.handle.checkOrigin(browser, \"cookie\");\n if (failure) {\n return { outcome: \"rejected\", failure };\n }\n }\n const accepts = new Set(\n entry.sources\n .filter((source) => source.acceptance === \"default\")\n .flatMap((source) => [...source.kinds]),\n );\n try {\n return await this.resolver.resolve(call, {\n auth: entry.handle,\n accepts,\n sourceSet: JSON.stringify(\n entry.sources.flatMap((source, index) =>\n source.kinds.some((kind) => accepts.has(kind)) ? [index] : [],\n ),\n ),\n freshness:\n entry.options.session !== false &&\n entry.options.session?.freshness === \"authoritative\"\n ? \"authoritative\"\n : \"default\",\n });\n } catch (error) {\n if (isAuthFailure(error)) {\n return { outcome: \"rejected\", failure: error };\n }\n throw error;\n }\n }\n\n socketIoMiddleware(\n options: { required?: boolean; instance?: string } = {},\n ): (socket: unknown, next: (error?: Error) => void) => void {\n return (socket, next) => {\n void this.authenticate(socket, options).then(\n (result) => {\n const failure =\n result.outcome === \"rejected\"\n ? result.failure\n : result.outcome === \"absent\" && options.required\n ? AuthFailures.unauthenticated()\n : undefined;\n if (!failure) {\n next();\n return;\n }\n next(\n Object.assign(new Error(failure.message), {\n data: {\n status: \"error\",\n statusCode: failure.status,\n code: failure.code,\n ...(failure.reason ? { reason: failure.reason } : {}),\n message: failure.message,\n },\n }),\n );\n },\n (error: unknown) => {\n const log = connectionErrorLog(error);\n this.logger.error(log.message, log.stack);\n next(\n Object.assign(new Error(\"Internal server error\"), {\n data: {\n status: \"error\",\n statusCode: 500,\n message: \"Internal server error\",\n },\n }),\n );\n },\n );\n };\n }\n}\n","import type { IncomingHttpHeaders } from \"node:http\";\nimport type { ExecutionContext } from \"@nestjs/common\";\nimport { MetadataScanner } from \"@nestjs/core\";\nimport {\n SubscribeMessage,\n WebSocketGateway,\n WsException,\n} from \"@nestjs/websockets\";\nimport {\n type AuthTransport,\n type BootAdvice,\n type BootAdviceContext,\n type ExtensionDefinition,\n type TransportCall,\n type TransportValidationContext,\n} from \"./auth-contracts.js\";\nimport {\n AuthFailures,\n BetterAuthConfigurationError,\n type AuthFailure,\n} from \"./auth-errors.js\";\nimport { EXTENSION_DEFINITION } from \"./bridge-protocol.js\";\nimport { toWebHeaders, upgradeRequestUrl } from \"./platform.js\";\nimport { WsConnectionAuth, WS_CONNECTION_AUTH } from \"./ws-connection-auth.js\";\n\nexport interface WsTransportOptions<C> {\n /** Replaces principal credentials without changing the browser handshake used for origin checks. */\n credentials?: (client: C) => HeadersInit | undefined;\n /** Defaults to zero. Positive values delay revocation for non-authoritative messages. */\n principalTtlMs?: number;\n /** Every message handler requires explicit guard and scope coverage on every Nest major. */\n gatewayCoverage?: \"error\" | \"warn\" | \"off\";\n}\nexport interface SocketIoClientLike {\n readonly handshake: {\n readonly headers: IncomingHttpHeaders;\n readonly auth?: Record<string, unknown>;\n readonly address?: string;\n readonly url?: string;\n readonly secure?: boolean;\n };\n}\n/** Convert only mapped headers here: native Headers errors can quote the credential. */\nexport function mappedCredentialHeaders(\n input: HeadersInit | undefined,\n): Headers {\n const headers = new Headers();\n if (input === undefined) {\n return headers;\n }\n const malformed = () =>\n AuthFailures.rejected({ status: 401, reason: \"MALFORMED_CREDENTIALS\" });\n if (input === null || typeof input !== \"object\") {\n throw malformed();\n }\n // Read caller-provided getters/iterators outside the conversion catch so their\n // programming errors remain errors, as do errors thrown by the mapper itself.\n const iterable = (input as { [Symbol.iterator]?: unknown })[Symbol.iterator];\n if (iterable !== undefined && typeof iterable !== \"function\") {\n throw malformed();\n }\n const entries: Iterable<unknown> =\n typeof iterable === \"function\"\n ? (input as Iterable<unknown>)\n : Object.entries(input);\n for (const entry of entries) {\n if (!Array.isArray(entry) || entry.length !== 2) {\n throw malformed();\n }\n const [name, value] = entry;\n if (\n typeof name !== \"string\" ||\n typeof value !== \"string\" ||\n /[\\r\\n\\0]/.test(value)\n ) {\n throw malformed();\n }\n try {\n headers.append(name, value);\n } catch {\n throw malformed();\n }\n }\n return headers;\n}\nexport function isSocketIo(client: unknown): client is SocketIoClientLike {\n return typeof client === \"object\" && client !== null && \"handshake\" in client;\n}\nexport function wsException(failure: AuthFailure): WsException {\n return new WsException({\n status: \"error\",\n statusCode: failure.status,\n code: failure.code,\n ...(failure.reason ? { reason: failure.reason } : {}),\n message: failure.message,\n });\n}\nexport function validateGateways(\n context: TransportValidationContext,\n coverage: WsTransportOptions<unknown>[\"gatewayCoverage\"],\n): void {\n class Probe {\n message(): void {}\n }\n WebSocketGateway()(Probe);\n SubscribeMessage(\"probe\")(\n Probe.prototype,\n \"message\",\n Object.getOwnPropertyDescriptor(Probe.prototype, \"message\")!,\n );\n if (\n Reflect.getMetadata(\"websockets:is_gateway\", Probe) !== true ||\n Reflect.getMetadata(\n \"websockets:message_mapping\",\n Probe.prototype.message,\n ) !== true\n ) {\n throw new BetterAuthConfigurationError(\n \"NEST_METADATA_KEY_CHANGED\",\n \"Nest WebSocket gateway/message metadata failed its canary.\",\n );\n }\n const scanner = new MetadataScanner();\n for (const wrapper of context.discovery.getProviders()) {\n const target = wrapper.metatype;\n if (\n !target?.prototype ||\n wrapper.isAlias ||\n !Reflect.getMetadata(\"websockets:is_gateway\", target)\n ) {\n continue;\n }\n for (const method of scanner.getAllMethodNames(target.prototype)) {\n if (\n Reflect.getMetadata(\n \"websockets:message_mapping\",\n target.prototype[method],\n )\n ) {\n context.claim(target, method, \"explicit\", {\n everyHandler: true,\n code: \"GATEWAY_UNGUARDED\",\n coverage: coverage ?? \"error\",\n hint: `Add @UseBetterAuth() to ${target.name} (or @Public() to opt out). Global guards and interceptors do not reach gateways on NestJS 11, and this check does not depend on the version.`,\n });\n }\n }\n }\n}\nexport function quotaAdvice(\n context: BootAdviceContext,\n ttl: number,\n): readonly BootAdvice[] {\n return ttl === 0 &&\n context.sources.some((source) => source.effects?.consumesQuota)\n ? [\n {\n level: \"warn\",\n code: \"W_QUOTA_PER_MESSAGE\",\n message:\n \"Quota-consuming WebSocket principals verify on every message.\",\n hint: \"Consider connection-time authentication and principalTtlMs; a positive TTL delays revocation on non-authoritative handlers.\",\n },\n ]\n : [];\n}\nexport function transportDefinition(\n transport: AuthTransport,\n): ExtensionDefinition<AuthTransport> {\n return {\n [EXTENSION_DEFINITION]: true,\n use: { useFactory: () => transport },\n providers: [\n WsConnectionAuth,\n { provide: WS_CONNECTION_AUTH, useExisting: WsConnectionAuth },\n ],\n exports: [WsConnectionAuth, WS_CONNECTION_AUTH],\n };\n}\nexport function principalTtl(value = 0): number {\n if (!Number.isFinite(value) || value < 0) {\n throw new BetterAuthConfigurationError(\n \"INVALID_WS_TTL\",\n \"principalTtlMs must be a finite non-negative number.\",\n );\n }\n return value;\n}\nexport function socketIoTransport(\n options: WsTransportOptions<SocketIoClientLike> = {},\n): ExtensionDefinition<AuthTransport> {\n const ttl = principalTtl(options.principalTtlMs);\n return transportDefinition({\n id: \"socket.io\",\n handles: (context) =>\n context.getType() === \"ws\" &&\n isSocketIo(context.switchToWs().getClient()),\n describe(context: ExecutionContext): TransportCall {\n const client = context.switchToWs().getClient<SocketIoClientLike>();\n const original = () => toWebHeaders(client.handshake.headers);\n return {\n key: context.getArgs(),\n invocation: context.getArgs(),\n connection: client,\n principalTtlMs: ttl,\n headers: () => {\n const headers = original();\n let mapped: HeadersInit | undefined;\n if (options.credentials) {\n mapped = options.credentials(client);\n } else if (!headers.has(\"authorization\")) {\n const token = client.handshake.auth?.token;\n if (token !== undefined) {\n if (typeof token !== \"string\") {\n throw AuthFailures.rejected({\n status: 401,\n reason: \"MALFORMED_CREDENTIALS\",\n });\n }\n mapped = { authorization: `Bearer ${token}` };\n }\n }\n mappedCredentialHeaders(mapped).forEach((value, name) => {\n headers.set(name, value);\n });\n return headers;\n },\n get clientIp() {\n return client.handshake.address ?? null;\n },\n cookies: null,\n get request() {\n return { method: \"GET\", url: upgradeRequestUrl(client.handshake) };\n },\n param: (name) => context.switchToWs().getData()?.[name],\n get browser() {\n return {\n enforce: true,\n key: client,\n headers: original,\n url: upgradeRequestUrl(client.handshake),\n };\n },\n };\n },\n toException: wsException,\n validate: (context) => validateGateways(context, options.gatewayCoverage),\n advise: (context) => quotaAdvice(context, ttl),\n });\n}\n","import type { IncomingHttpHeaders } from \"node:http\";\nimport type { AuthTransport, ExtensionDefinition } from \"./auth-contracts.js\";\nimport { UPGRADE_REQUEST } from \"./bridge-protocol.js\";\nimport { BetterAuthConfigurationError } from \"./auth-errors.js\";\nimport { toWebHeaders, upgradeRequestUrl } from \"./platform.js\";\nimport {\n isSocketIo,\n mappedCredentialHeaders,\n principalTtl,\n quotaAdvice,\n transportDefinition,\n validateGateways,\n wsException,\n type WsTransportOptions,\n} from \"./socket-io-transport.js\";\n\nexport { UPGRADE_REQUEST } from \"./bridge-protocol.js\";\nexport interface WsClientLike {\n readonly [UPGRADE_REQUEST]?: {\n readonly headers: Headers;\n readonly url?: string;\n readonly remoteAddress?: string;\n readonly encrypted?: boolean;\n };\n}\nexport interface WsAdapterLike {\n bindClientConnect(\n server: unknown,\n callback: (...args: any[]) => void,\n ): unknown;\n}\nexport function recordUpgradeRequest(\n client: object,\n request: {\n headers: IncomingHttpHeaders;\n url?: string;\n socket?: { remoteAddress?: string; encrypted?: boolean };\n },\n): void {\n Object.defineProperty(client, UPGRADE_REQUEST, {\n value: Object.freeze({\n headers: toWebHeaders(request.headers),\n url: request.url,\n remoteAddress: request.socket?.remoteAddress,\n encrypted: request.socket?.encrypted,\n }),\n configurable: true,\n });\n}\nexport function withUpgradeRequest<\n T extends new (\n ...args: any[]\n ) => WsAdapterLike,\n>(Base: T): T {\n return class extends Base {\n override bindClientConnect(\n server: unknown,\n callback: (...args: any[]) => void,\n ): unknown {\n return super.bindClientConnect(server, (client, request, ...rest) => {\n recordUpgradeRequest(client, request);\n callback(client, request, ...rest);\n });\n }\n };\n}\nexport function wsTransport(\n options: WsTransportOptions<WsClientLike> = {},\n): ExtensionDefinition<AuthTransport> {\n const ttl = principalTtl(options.principalTtlMs);\n return transportDefinition({\n id: \"ws\",\n handles: (context) =>\n context.getType() === \"ws\" &&\n !isSocketIo(context.switchToWs().getClient()),\n describe(context) {\n const client = context.switchToWs().getClient<WsClientLike>();\n const upgrade = () => {\n const request = client[UPGRADE_REQUEST];\n if (!request) {\n throw BetterAuthConfigurationError.atRequest(\n \"WS_UPGRADE_REQUEST_MISSING\",\n \"WebSocket authentication requires its upgrade request.\",\n {\n hint: \"app.useWebSocketAdapter(new (withUpgradeRequest(WsAdapter))(app));\",\n },\n );\n }\n return request;\n };\n const url = () => {\n const request = upgrade();\n return upgradeRequestUrl({\n headers: request.headers,\n url: request.url,\n secure: request.encrypted,\n });\n };\n return {\n key: context.getArgs(),\n invocation: context.getArgs(),\n connection: client,\n principalTtlMs: ttl,\n headers: () => {\n const headers = new Headers(upgrade().headers);\n mappedCredentialHeaders(options.credentials?.(client)).forEach(\n (value, name) => {\n headers.set(name, value);\n },\n );\n return headers;\n },\n get clientIp() {\n return upgrade().remoteAddress ?? null;\n },\n cookies: null,\n get request() {\n return { method: \"GET\", url: url() };\n },\n param: (name) => context.switchToWs().getData()?.[name],\n get browser() {\n return {\n enforce: true,\n key: client,\n headers: () => new Headers(upgrade().headers),\n url: url(),\n };\n },\n };\n },\n toException: wsException,\n validate: (context) => validateGateways(context, options.gatewayCoverage),\n advise: (context) => quotaAdvice(context, ttl),\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"websockets.cjs","names":["isConfigurationError","isInfrastructureError","readErrorProperty","Logger","BetterAuthConfigurationError","isAuthFailure","AuthFailures","Inject","INSTANCE_REGISTRY","PRINCIPAL_RESOLVER","TRANSPORT_REGISTRY","AuthFailures","WsException","BetterAuthConfigurationError","MetadataScanner","EXTENSION_DEFINITION","WS_CONNECTION_AUTH","toWebHeaders","upgradeRequestUrl","UPGRADE_REQUEST","toWebHeaders","BetterAuthConfigurationError","upgradeRequestUrl"],"sources":["../src/ws-connection-auth.ts","../src/socket-io-transport.ts","../src/ws-transport.ts"],"sourcesContent":["import {\n type ContextType,\n type ExecutionContext,\n Inject,\n Logger,\n type Type,\n} from \"@nestjs/common\";\nimport type { PrincipalResolver, PrincipalResult } from \"./auth-contracts.js\";\nimport {\n AuthFailures,\n isAuthFailure,\n isConfigurationError,\n isInfrastructureError,\n BetterAuthConfigurationError,\n type AuthFailure,\n} from \"./auth-errors.js\";\nimport {\n INSTANCE_REGISTRY,\n PRINCIPAL_RESOLVER,\n TRANSPORT_REGISTRY,\n} from \"./auth-tokens.js\";\nimport { readErrorProperty } from \"./error-redactor.js\";\nimport type { InstanceLookup } from \"./instance-registry.js\";\nimport type { TransportRegistry } from \"./transport-registry.js\";\n\nexport { WS_CONNECTION_AUTH } from \"./auth-tokens.js\";\nexport function wsCloseCodeFor(failure: AuthFailure): 4401 | 4403 | 4429 {\n return failure.status === 401 ? 4401 : failure.status === 403 ? 4403 : 4429;\n}\n\nconst STACK_FRAME = /^\\s+at .+:\\d+:\\d+\\)?$/;\n\n/**\n * Describes an unexpected connection-authentication error for the server log. Package\n * errors carry fixed messages and already-redacted causes. Application and runtime error\n * messages can quote client credentials (native Headers errors do), so only their name\n * and stack frames are kept.\n */\nexport function connectionErrorLog(error: unknown): {\n message: string;\n stack?: string;\n} {\n const text = (value: unknown) =>\n typeof value === \"string\" ? value : undefined;\n let summary: string;\n if (isConfigurationError(error)) {\n summary = `${error.code}: ${error.detail}`;\n } else if (isInfrastructureError(error)) {\n const cause = readErrorProperty(error, \"cause\");\n summary = `${error.message} (${text(readErrorProperty(cause, \"name\")) ?? \"Error\"}: ${text(readErrorProperty(cause, \"message\")) ?? \"\"})`;\n } else {\n const name = text(readErrorProperty(error, \"name\"));\n summary = `${name !== undefined && /^[\\w$.]{1,64}$/.test(name) ? name : typeof error} (message withheld)`;\n }\n const frames = (text(readErrorProperty(error, \"stack\")) ?? \"\")\n .split(/\\r?\\n/)\n .filter((line) => STACK_FRAME.test(line));\n return {\n message: `WebSocket connection authentication failed: ${summary}`,\n stack: frames.length > 0 ? [summary, ...frames].join(\"\\n\") : undefined,\n };\n}\n\n/**\n * The `ws` execution context of a connection before any gateway handler runs. Nest exports no\n * public factory for execution contexts, so this implements the public `ExecutionContext`\n * interface with the values Nest's internal host reports for the arguments `[client, undefined]`.\n */\nexport class ConnectionExecutionContext implements ExecutionContext {\n readonly #args: unknown[];\n\n constructor(client: object) {\n this.#args = [client, undefined];\n }\n\n getType<TContext extends string = ContextType>(): TContext {\n return \"ws\" as TContext;\n }\n\n /** No handler runs yet, so there is no class; Nest's host reports `null` as well. */\n getClass<T>(): Type<T> {\n return null as unknown as Type<T>;\n }\n\n /** No handler runs yet; Nest's host reports `null` as well. */\n getHandler(): ReturnType<ExecutionContext[\"getHandler\"]> {\n return null as unknown as ReturnType<ExecutionContext[\"getHandler\"]>;\n }\n\n getArgs<T extends unknown[] = unknown[]>(): T {\n return this.#args as T;\n }\n\n getArgByIndex<T>(index: number): T {\n return this.#args[index] as T;\n }\n\n switchToHttp(): ReturnType<ExecutionContext[\"switchToHttp\"]> {\n return {\n getRequest: <T>() => this.getArgByIndex<T>(0),\n getResponse: <T>() => this.getArgByIndex<T>(1),\n getNext: <T>() => this.getArgByIndex<T>(2),\n };\n }\n\n switchToRpc(): ReturnType<ExecutionContext[\"switchToRpc\"]> {\n return {\n getData: <T>() => this.getArgByIndex<T>(0),\n getContext: <T>() => this.getArgByIndex<T>(1),\n };\n }\n\n switchToWs(): ReturnType<ExecutionContext[\"switchToWs\"]> {\n return {\n getClient: <T>() => this.getArgByIndex<T>(0),\n getData: <T>() => this.getArgByIndex<T>(1),\n getPattern: () => this.getArgByIndex<string>(this.#args.length - 1),\n };\n }\n}\n\n/** Connection authentication delegates to the same origin and principal kernel as messages. */\nexport class WsConnectionAuth {\n private readonly logger = new Logger(\"BetterAuth\");\n\n constructor(\n @Inject(INSTANCE_REGISTRY) private readonly instances: InstanceLookup,\n @Inject(PRINCIPAL_RESOLVER) private readonly resolver: PrincipalResolver,\n @Inject(TRANSPORT_REGISTRY) private readonly transports: TransportRegistry,\n ) {}\n\n async authenticate(\n client: unknown,\n options: { instance?: string } = {},\n ): Promise<PrincipalResult> {\n if (typeof client !== \"object\" || client === null) {\n throw BetterAuthConfigurationError.atRequest(\n \"INVALID_WS_CLIENT\",\n \"Connection authentication requires a WebSocket client.\",\n );\n }\n const context = new ConnectionExecutionContext(client);\n const transport = this.transports.select(context);\n const call = this.transports.describe(context, transport);\n const entry = this.instances.get(options.instance ?? \"default\");\n const browser = call.browser;\n if (browser && entry.options.originCheck?.mode !== \"off\") {\n const failure = await entry.handle.checkOrigin(browser, \"cookie\");\n if (failure) {\n return { outcome: \"rejected\", failure };\n }\n }\n const accepts = new Set(\n entry.sources\n .filter((source) => source.acceptance === \"default\")\n .flatMap((source) => [...source.kinds]),\n );\n try {\n return await this.resolver.resolve(call, {\n auth: entry.handle,\n accepts,\n sourceSet: JSON.stringify(\n entry.sources.flatMap((source, index) =>\n source.kinds.some((kind) => accepts.has(kind)) ? [index] : [],\n ),\n ),\n freshness:\n entry.options.session !== false &&\n entry.options.session?.freshness === \"authoritative\"\n ? \"authoritative\"\n : \"default\",\n });\n } catch (error) {\n if (isAuthFailure(error)) {\n return { outcome: \"rejected\", failure: error };\n }\n throw error;\n }\n }\n\n socketIoMiddleware(\n options: { required?: boolean; instance?: string } = {},\n ): (socket: unknown, next: (error?: Error) => void) => void {\n return (socket, next) => {\n void this.authenticate(socket, options).then(\n (result) => {\n const failure =\n result.outcome === \"rejected\"\n ? result.failure\n : result.outcome === \"absent\" && options.required\n ? AuthFailures.unauthenticated()\n : undefined;\n if (!failure) {\n next();\n return;\n }\n next(\n Object.assign(new Error(failure.message), {\n data: {\n status: \"error\",\n statusCode: failure.status,\n code: failure.code,\n ...(failure.reason ? { reason: failure.reason } : {}),\n message: failure.message,\n },\n }),\n );\n },\n (error: unknown) => {\n const log = connectionErrorLog(error);\n this.logger.error(log.message, log.stack);\n next(\n Object.assign(new Error(\"Internal server error\"), {\n data: {\n status: \"error\",\n statusCode: 500,\n message: \"Internal server error\",\n },\n }),\n );\n },\n );\n };\n }\n}\n","import type { IncomingHttpHeaders } from \"node:http\";\nimport type { ExecutionContext } from \"@nestjs/common\";\nimport { MetadataScanner } from \"@nestjs/core\";\nimport {\n SubscribeMessage,\n WebSocketGateway,\n WsException,\n} from \"@nestjs/websockets\";\nimport {\n type AuthTransport,\n type BootAdvice,\n type BootAdviceContext,\n type ExtensionDefinition,\n type TransportCall,\n type TransportValidationContext,\n} from \"./auth-contracts.js\";\nimport {\n AuthFailures,\n BetterAuthConfigurationError,\n type AuthFailure,\n} from \"./auth-errors.js\";\nimport { EXTENSION_DEFINITION } from \"./bridge-protocol.js\";\nimport { toWebHeaders, upgradeRequestUrl } from \"./platform.js\";\nimport { WsConnectionAuth, WS_CONNECTION_AUTH } from \"./ws-connection-auth.js\";\n\nexport interface WsTransportOptions<C> {\n /** Replaces principal credentials without changing the browser handshake used for origin checks. */\n credentials?: (client: C) => HeadersInit | undefined;\n /** Defaults to zero. Positive values delay revocation for non-authoritative messages. */\n principalTtlMs?: number;\n /** Every message handler requires explicit guard and scope coverage on every Nest major. */\n gatewayCoverage?: \"error\" | \"warn\" | \"off\";\n}\nexport interface SocketIoClientLike {\n readonly handshake: {\n readonly headers: IncomingHttpHeaders;\n readonly auth?: Record<string, unknown>;\n readonly address?: string;\n readonly url?: string;\n readonly secure?: boolean;\n };\n}\n/** Convert only mapped headers here: native Headers errors can quote the credential. */\nexport function mappedCredentialHeaders(\n input: HeadersInit | undefined,\n): Headers {\n const headers = new Headers();\n if (input === undefined) {\n return headers;\n }\n const malformed = () =>\n AuthFailures.rejected({ status: 401, reason: \"MALFORMED_CREDENTIALS\" });\n if (input === null || typeof input !== \"object\") {\n throw malformed();\n }\n // Read caller-provided getters/iterators outside the conversion catch so their\n // programming errors remain errors, as do errors thrown by the mapper itself.\n const iterable = (input as { [Symbol.iterator]?: unknown })[Symbol.iterator];\n if (iterable !== undefined && typeof iterable !== \"function\") {\n throw malformed();\n }\n const entries: Iterable<unknown> =\n typeof iterable === \"function\"\n ? (input as Iterable<unknown>)\n : Object.entries(input);\n for (const entry of entries) {\n if (!Array.isArray(entry) || entry.length !== 2) {\n throw malformed();\n }\n const [name, value] = entry;\n if (\n typeof name !== \"string\" ||\n typeof value !== \"string\" ||\n /[\\r\\n\\0]/.test(value)\n ) {\n throw malformed();\n }\n try {\n headers.append(name, value);\n } catch {\n throw malformed();\n }\n }\n return headers;\n}\nexport function isSocketIo(client: unknown): client is SocketIoClientLike {\n return typeof client === \"object\" && client !== null && \"handshake\" in client;\n}\nexport function wsException(failure: AuthFailure): WsException {\n return new WsException({\n status: \"error\",\n statusCode: failure.status,\n code: failure.code,\n ...(failure.reason ? { reason: failure.reason } : {}),\n message: failure.message,\n });\n}\nexport function validateGateways(\n context: TransportValidationContext,\n coverage: WsTransportOptions<unknown>[\"gatewayCoverage\"],\n): void {\n class Probe {\n message(): void {}\n }\n WebSocketGateway()(Probe);\n SubscribeMessage(\"probe\")(\n Probe.prototype,\n \"message\",\n Object.getOwnPropertyDescriptor(Probe.prototype, \"message\")!,\n );\n if (\n Reflect.getMetadata(\"websockets:is_gateway\", Probe) !== true ||\n Reflect.getMetadata(\n \"websockets:message_mapping\",\n Probe.prototype.message,\n ) !== true\n ) {\n throw new BetterAuthConfigurationError(\n \"NEST_METADATA_KEY_CHANGED\",\n \"Nest WebSocket gateway/message metadata failed its canary.\",\n );\n }\n const scanner = new MetadataScanner();\n for (const wrapper of context.discovery.getProviders()) {\n const target = wrapper.metatype;\n if (\n !target?.prototype ||\n wrapper.isAlias ||\n !Reflect.getMetadata(\"websockets:is_gateway\", target)\n ) {\n continue;\n }\n for (const method of scanner.getAllMethodNames(target.prototype)) {\n if (\n Reflect.getMetadata(\n \"websockets:message_mapping\",\n target.prototype[method],\n )\n ) {\n context.claim(target, method, \"explicit\", {\n everyHandler: true,\n code: \"GATEWAY_UNGUARDED\",\n coverage: coverage ?? \"error\",\n hint: `Add @UseBetterAuth() to ${target.name} (or @Public() to opt out). Global guards and interceptors do not reach gateways on NestJS 11, and this check does not depend on the version.`,\n });\n }\n }\n }\n}\nexport function quotaAdvice(\n context: BootAdviceContext,\n ttl: number,\n): readonly BootAdvice[] {\n return ttl === 0 &&\n context.sources.some((source) => source.effects?.consumesQuota)\n ? [\n {\n level: \"warn\",\n code: \"W_QUOTA_PER_MESSAGE\",\n message:\n \"Quota-consuming WebSocket principals verify on every message.\",\n hint: \"Consider connection-time authentication and principalTtlMs; a positive TTL delays revocation on non-authoritative handlers.\",\n },\n ]\n : [];\n}\nexport function transportDefinition(\n transport: AuthTransport,\n): ExtensionDefinition<AuthTransport> {\n return {\n [EXTENSION_DEFINITION]: true,\n use: { useFactory: () => transport },\n providers: [\n WsConnectionAuth,\n { provide: WS_CONNECTION_AUTH, useExisting: WsConnectionAuth },\n ],\n exports: [WsConnectionAuth, WS_CONNECTION_AUTH],\n };\n}\nexport function principalTtl(value = 0): number {\n if (!Number.isFinite(value) || value < 0) {\n throw new BetterAuthConfigurationError(\n \"INVALID_WS_TTL\",\n \"principalTtlMs must be a finite non-negative number.\",\n );\n }\n return value;\n}\nexport function socketIoTransport(\n options: WsTransportOptions<SocketIoClientLike> = {},\n): ExtensionDefinition<AuthTransport> {\n const ttl = principalTtl(options.principalTtlMs);\n return transportDefinition({\n id: \"socket.io\",\n handles: (context) =>\n context.getType() === \"ws\" &&\n isSocketIo(context.switchToWs().getClient()),\n describe(context: ExecutionContext): TransportCall {\n const client = context.switchToWs().getClient<SocketIoClientLike>();\n const original = () => toWebHeaders(client.handshake.headers);\n return {\n key: context.getArgs(),\n invocation: context.getArgs(),\n connection: client,\n principalTtlMs: ttl,\n headers: () => {\n const headers = original();\n let mapped: HeadersInit | undefined;\n if (options.credentials) {\n mapped = options.credentials(client);\n } else if (!headers.has(\"authorization\")) {\n const token = client.handshake.auth?.token;\n if (token !== undefined) {\n if (typeof token !== \"string\") {\n throw AuthFailures.rejected({\n status: 401,\n reason: \"MALFORMED_CREDENTIALS\",\n });\n }\n mapped = { authorization: `Bearer ${token}` };\n }\n }\n mappedCredentialHeaders(mapped).forEach((value, name) => {\n headers.set(name, value);\n });\n return headers;\n },\n get clientIp() {\n return client.handshake.address ?? null;\n },\n cookies: null,\n get request() {\n return { method: \"GET\", url: upgradeRequestUrl(client.handshake) };\n },\n param: (name) => context.switchToWs().getData()?.[name],\n get browser() {\n return {\n enforce: true,\n key: client,\n headers: original,\n url: upgradeRequestUrl(client.handshake),\n };\n },\n };\n },\n toException: wsException,\n validate: (context) => validateGateways(context, options.gatewayCoverage),\n advise: (context) => quotaAdvice(context, ttl),\n });\n}\n","import type { IncomingHttpHeaders } from \"node:http\";\nimport type { AuthTransport, ExtensionDefinition } from \"./auth-contracts.js\";\nimport { UPGRADE_REQUEST } from \"./bridge-protocol.js\";\nimport { BetterAuthConfigurationError } from \"./auth-errors.js\";\nimport { toWebHeaders, upgradeRequestUrl } from \"./platform.js\";\nimport {\n isSocketIo,\n mappedCredentialHeaders,\n principalTtl,\n quotaAdvice,\n transportDefinition,\n validateGateways,\n wsException,\n type WsTransportOptions,\n} from \"./socket-io-transport.js\";\n\nexport { UPGRADE_REQUEST } from \"./bridge-protocol.js\";\nexport interface WsClientLike {\n readonly [UPGRADE_REQUEST]?: {\n readonly headers: Headers;\n readonly url?: string;\n readonly remoteAddress?: string;\n readonly encrypted?: boolean;\n };\n}\nexport interface WsAdapterLike {\n bindClientConnect(\n server: unknown,\n callback: (...args: any[]) => void,\n ): unknown;\n}\nexport function recordUpgradeRequest(\n client: object,\n request: {\n headers: IncomingHttpHeaders;\n url?: string;\n socket?: { remoteAddress?: string; encrypted?: boolean };\n },\n): void {\n Object.defineProperty(client, UPGRADE_REQUEST, {\n value: Object.freeze({\n headers: toWebHeaders(request.headers),\n url: request.url,\n remoteAddress: request.socket?.remoteAddress,\n encrypted: request.socket?.encrypted,\n }),\n configurable: true,\n });\n}\nexport function withUpgradeRequest<\n T extends new (...args: any[]) => WsAdapterLike,\n>(Base: T): T {\n return class extends Base {\n override bindClientConnect(\n server: unknown,\n callback: (...args: any[]) => void,\n ): unknown {\n return super.bindClientConnect(server, (client, request, ...rest) => {\n recordUpgradeRequest(client, request);\n callback(client, request, ...rest);\n });\n }\n };\n}\nexport function wsTransport(\n options: WsTransportOptions<WsClientLike> = {},\n): ExtensionDefinition<AuthTransport> {\n const ttl = principalTtl(options.principalTtlMs);\n return transportDefinition({\n id: \"ws\",\n handles: (context) =>\n context.getType() === \"ws\" &&\n !isSocketIo(context.switchToWs().getClient()),\n describe(context) {\n const client = context.switchToWs().getClient<WsClientLike>();\n const upgrade = () => {\n const request = client[UPGRADE_REQUEST];\n if (!request) {\n throw BetterAuthConfigurationError.atRequest(\n \"WS_UPGRADE_REQUEST_MISSING\",\n \"WebSocket authentication requires its upgrade request.\",\n {\n hint: \"app.useWebSocketAdapter(new (withUpgradeRequest(WsAdapter))(app));\",\n },\n );\n }\n return request;\n };\n const url = () => {\n const request = upgrade();\n return upgradeRequestUrl({\n headers: request.headers,\n url: request.url,\n secure: request.encrypted,\n });\n };\n return {\n key: context.getArgs(),\n invocation: context.getArgs(),\n connection: client,\n principalTtlMs: ttl,\n headers: () => {\n const headers = new Headers(upgrade().headers);\n mappedCredentialHeaders(options.credentials?.(client)).forEach(\n (value, name) => {\n headers.set(name, value);\n },\n );\n return headers;\n },\n get clientIp() {\n return upgrade().remoteAddress ?? null;\n },\n cookies: null,\n get request() {\n return { method: \"GET\", url: url() };\n },\n param: (name) => context.switchToWs().getData()?.[name],\n get browser() {\n return {\n enforce: true,\n key: client,\n headers: () => new Headers(upgrade().headers),\n url: url(),\n };\n },\n };\n },\n toException: wsException,\n validate: (context) => validateGateways(context, options.gatewayCoverage),\n advise: (context) => quotaAdvice(context, ttl),\n });\n}\n"],"mappings":"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"}
@@ -1,8 +1,7 @@
1
- import { Bn as WS_CONNECTION_AUTH, F as ExtensionDefinition, Mn as InstanceLookup, Pn as UPGRADE_REQUEST, c as AuthTransport, jn as TransportRegistry, nt as PrincipalResolver, qn as AuthFailure, rt as PrincipalResult } from "./auth-contracts-Brh_Qko9.cjs";
1
+ import { Bn as WS_CONNECTION_AUTH, F as ExtensionDefinition, Mn as InstanceLookup, Pn as UPGRADE_REQUEST, c as AuthTransport, jn as TransportRegistry, nt as PrincipalResolver, qn as AuthFailure, rt as PrincipalResult } from "./auth-contracts-zvt8ysoZ.cjs";
2
2
  import { IncomingHttpHeaders } from "node:http";
3
3
  import { ExecutionContext, Type } from "@nestjs/common";
4
4
  import "@nestjs/websockets";
5
- //#region src/socket-io-transport.d.ts
6
5
  interface WsTransportOptions<C> {
7
6
  /** Replaces principal credentials without changing the browser handshake used for origin checks. */
8
7
  credentials?: (client: C) => HeadersInit | undefined;
@@ -21,8 +20,6 @@ interface SocketIoClientLike {
21
20
  };
22
21
  }
23
22
  export declare function socketIoTransport(options?: WsTransportOptions<SocketIoClientLike>): ExtensionDefinition<AuthTransport>;
24
- //#endregion
25
- //#region src/ws-transport.d.ts
26
23
  interface WsClientLike {
27
24
  readonly [UPGRADE_REQUEST]?: {
28
25
  readonly headers: Headers;
@@ -44,8 +41,6 @@ export declare function recordUpgradeRequest(client: object, request: {
44
41
  }): void;
45
42
  export declare function withUpgradeRequest<T extends new (...args: any[]) => WsAdapterLike>(Base: T): T;
46
43
  export declare function wsTransport(options?: WsTransportOptions<WsClientLike>): ExtensionDefinition<AuthTransport>;
47
- //#endregion
48
- //#region src/ws-connection-auth.d.ts
49
44
  export declare function wsCloseCodeFor(failure: AuthFailure): 4401 | 4403 | 4429;
50
45
  /** Connection authentication delegates to the same origin and principal kernel as messages. */
51
46
  export declare class WsConnectionAuth {
@@ -62,6 +57,5 @@ export declare class WsConnectionAuth {
62
57
  instance?: string;
63
58
  }): (socket: unknown, next: (error?: Error) => void) => void;
64
59
  }
65
- //#endregion
66
60
  export { type SocketIoClientLike, UPGRADE_REQUEST, WS_CONNECTION_AUTH, type WsAdapterLike, type WsClientLike, type WsTransportOptions };
67
61
  //# sourceMappingURL=websockets.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"websockets.d.cts","names":[],"sources":["../src/socket-io-transport.ts","../src/ws-transport.ts","../src/ws-connection-auth.ts"],"mappings":";;;;;UAyBiB,mBAAmB;;EAElC,eAAe,QAAQ,MAAM;;EAE7B;;EAEA;;UAEe;WACN;aACE,SAAS;aACT,OAAO;aACP;aACA;aACA;;;wBAqJG,kBACd,UAAS,mBAAmB,sBAC3B,oBAAoB;;;UC7KN;YACL;aACC,SAAS;aACT;aACA;aACA;;;UAGI;EACf,kBACE,iBACA,cAAc;;wBAGF,qBACd,gBACA;EACE,SAAS;EACT;EACA;IAAW;IAAwB;;;wBAavB,mBACd,kBACK,gBACA,eACL,MAAM,IAAI;wBAaI,YACd,UAAS,mBAAmB,gBAC3B,oBAAoB;;;wBC1CP,eAAe,SAAS;;qBAgG3B;mBAImC;mBACC;mBACA;mBAL9B;EAEjB,YAC8C,WAAW,gBACV,UAAU,mBACV,YAAY;EAGrD,aACJ,iBACA;IAAW;MACV,QAAQ;EA8CX,mBACE;IAAW;IAAoB;OAC7B,iBAAiB,OAAO,QAAQ"}
1
+ {"version":3,"file":"websockets.d.cts","names":[],"sources":["../src/socket-io-transport.ts","../src/ws-transport.ts","../src/ws-connection-auth.ts"],"mappings":";;;;UAyBiB,mBAAmB;;EAElC,eAAe,QAAQ,MAAM;;EAE7B;;EAEA;;UAEe;WACN;aACE,SAAS;aACT,OAAO;aACP;aACA;aACA;;;wBAqJG,kBACd,UAAS,mBAAmB,sBAC3B,oBAAoB;UC7KN;YACL;aACC,SAAS;aACT;aACA;aACA;;;UAGI;EACf,kBACE,iBACA,cAAc;;wBAGF,qBACd,gBACA;EACE,SAAS;EACT;EACA;IAAW;IAAwB;;;wBAavB,mBACd,kBAAkB,gBAAgB,eAClC,MAAM,IAAI;wBAaI,YACd,UAAS,mBAAmB,gBAC3B,oBAAoB;wBCxCP,eAAe,SAAS;;qBAgG3B;mBAImC;mBACC;mBACA;mBAL9B;EAG6B,YAAA,WAAW,gBACV,UAAU,mBACV,YAAY;EAGrD,aACJ,iBACA;IAAW;MACV,QAAQ;EA8CX,mBACE;IAAW;IAAoB;OAC7B,iBAAiB,OAAO,QAAQ"}
@@ -1,8 +1,7 @@
1
- import { Bn as WS_CONNECTION_AUTH, F as ExtensionDefinition, Mn as InstanceLookup, Pn as UPGRADE_REQUEST, c as AuthTransport, jn as TransportRegistry, nt as PrincipalResolver, qn as AuthFailure, rt as PrincipalResult } from "./auth-contracts-Cz7C4_Ch.mjs";
1
+ import { Bn as WS_CONNECTION_AUTH, F as ExtensionDefinition, Mn as InstanceLookup, Pn as UPGRADE_REQUEST, c as AuthTransport, jn as TransportRegistry, nt as PrincipalResolver, qn as AuthFailure, rt as PrincipalResult } from "./auth-contracts-CADGyI0O.mjs";
2
2
  import { ExecutionContext, Type } from "@nestjs/common";
3
3
  import { IncomingHttpHeaders } from "node:http";
4
4
  import { WsException } from "@nestjs/websockets";
5
- //#region src/socket-io-transport.d.ts
6
5
  interface WsTransportOptions<C> {
7
6
  /** Replaces principal credentials without changing the browser handshake used for origin checks. */
8
7
  credentials?: (client: C) => HeadersInit | undefined;
@@ -21,8 +20,6 @@ interface SocketIoClientLike {
21
20
  };
22
21
  }
23
22
  export declare function socketIoTransport(options?: WsTransportOptions<SocketIoClientLike>): ExtensionDefinition<AuthTransport>;
24
- //#endregion
25
- //#region src/ws-transport.d.ts
26
23
  interface WsClientLike {
27
24
  readonly [UPGRADE_REQUEST]?: {
28
25
  readonly headers: Headers;
@@ -44,8 +41,6 @@ export declare function recordUpgradeRequest(client: object, request: {
44
41
  }): void;
45
42
  export declare function withUpgradeRequest<T extends new (...args: any[]) => WsAdapterLike>(Base: T): T;
46
43
  export declare function wsTransport(options?: WsTransportOptions<WsClientLike>): ExtensionDefinition<AuthTransport>;
47
- //#endregion
48
- //#region src/ws-connection-auth.d.ts
49
44
  export declare function wsCloseCodeFor(failure: AuthFailure): 4401 | 4403 | 4429;
50
45
  /** Connection authentication delegates to the same origin and principal kernel as messages. */
51
46
  export declare class WsConnectionAuth {
@@ -62,6 +57,5 @@ export declare class WsConnectionAuth {
62
57
  instance?: string;
63
58
  }): (socket: unknown, next: (error?: Error) => void) => void;
64
59
  }
65
- //#endregion
66
60
  export { type SocketIoClientLike, UPGRADE_REQUEST, WS_CONNECTION_AUTH, type WsAdapterLike, type WsClientLike, type WsTransportOptions };
67
61
  //# sourceMappingURL=websockets.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"websockets.d.mts","names":[],"sources":["../src/socket-io-transport.ts","../src/ws-transport.ts","../src/ws-connection-auth.ts"],"mappings":";;;;;UAyBiB,mBAAmB;;EAElC,eAAe,QAAQ,MAAM;;EAE7B;;EAEA;;UAEe;WACN;aACE,SAAS;aACT,OAAO;aACP;aACA;aACA;;;wBAqJG,kBACd,UAAS,mBAAmB,sBAC3B,oBAAoB;;;UC7KN;YACL;aACC,SAAS;aACT;aACA;aACA;;;UAGI;EACf,kBACE,iBACA,cAAc;;wBAGF,qBACd,gBACA;EACE,SAAS;EACT;EACA;IAAW;IAAwB;;;wBAavB,mBACd,kBACK,gBACA,eACL,MAAM,IAAI;wBAaI,YACd,UAAS,mBAAmB,gBAC3B,oBAAoB;;;wBC1CP,eAAe,SAAS;;qBAgG3B;mBAImC;mBACC;mBACA;mBAL9B;EAEjB,YAC8C,WAAW,gBACV,UAAU,mBACV,YAAY;EAGrD,aACJ,iBACA;IAAW;MACV,QAAQ;EA8CX,mBACE;IAAW;IAAoB;OAC7B,iBAAiB,OAAO,QAAQ"}
1
+ {"version":3,"file":"websockets.d.mts","names":[],"sources":["../src/socket-io-transport.ts","../src/ws-transport.ts","../src/ws-connection-auth.ts"],"mappings":";;;;UAyBiB,mBAAmB;;EAElC,eAAe,QAAQ,MAAM;;EAE7B;;EAEA;;UAEe;WACN;aACE,SAAS;aACT,OAAO;aACP;aACA;aACA;;;wBAqJG,kBACd,UAAS,mBAAmB,sBAC3B,oBAAoB;UC7KN;YACL;aACC,SAAS;aACT;aACA;aACA;;;UAGI;EACf,kBACE,iBACA,cAAc;;wBAGF,qBACd,gBACA;EACE,SAAS;EACT;EACA;IAAW;IAAwB;;;wBAavB,mBACd,kBAAkB,gBAAgB,eAClC,MAAM,IAAI;wBAaI,YACd,UAAS,mBAAmB,gBAC3B,oBAAoB;wBCxCP,eAAe,SAAS;;qBAgG3B;mBAImC;mBACC;mBACA;mBAL9B;EAG6B,YAAA,WAAW,gBACV,UAAU,mBACV,YAAY;EAGrD,aACJ,iBACA;IAAW;MACV,QAAQ;EA8CX,mBACE;IAAW;IAAoB;OAC7B,iBAAiB,OAAO,QAAQ"}
@@ -1,11 +1,11 @@
1
- import { c as isConfigurationError, l as isInfrastructureError, n as BetterAuthConfigurationError, p as readErrorProperty, s as isAuthFailure, t as AuthFailures } from "./auth-errors-C3rbTV9p.mjs";
2
- import { C as PRINCIPAL_RESOLVER, M as TRANSPORT_REGISTRY, P as WS_CONNECTION_AUTH, m as INSTANCE_REGISTRY, n as __decorateParam, r as __decorateMetadata, t as __decorate } from "./decorate-Dt0e9K6R.mjs";
3
- import { n as EXTENSION_DEFINITION, r as UPGRADE_REQUEST } from "./bridge-protocol-c66aEkr5.mjs";
4
- import { o as toWebHeaders, s as upgradeRequestUrl } from "./platform-CZl7TY8j.mjs";
1
+ import { c as isConfigurationError, l as isInfrastructureError, n as BetterAuthConfigurationError, p as readErrorProperty, s as isAuthFailure, t as AuthFailures } from "./auth-errors-JjxGDVSt.mjs";
2
+ import { n as EXTENSION_DEFINITION, r as UPGRADE_REQUEST } from "./bridge-protocol-CmRsff2P.mjs";
3
+ import { o as toWebHeaders, s as upgradeRequestUrl } from "./platform-BKYVzAv1.mjs";
4
+ import { C as PRINCIPAL_RESOLVER, M as TRANSPORT_REGISTRY, P as WS_CONNECTION_AUTH, m as INSTANCE_REGISTRY, n as __decorateParam, r as __decorateMetadata, t as __decorate } from "./decorate-bO-rBn-G.mjs";
5
5
  import { Inject, Logger } from "@nestjs/common";
6
6
  import { MetadataScanner } from "@nestjs/core";
7
7
  import { SubscribeMessage, WebSocketGateway, WsException } from "@nestjs/websockets";
8
- //#region src/ws-connection-auth.ts
8
+ // src/ws-connection-auth.ts
9
9
  function wsCloseCodeFor(failure) {
10
10
  return failure.status === 401 ? 4401 : failure.status === 403 ? 4403 : 4429;
11
11
  }
@@ -158,8 +158,7 @@ WsConnectionAuth = __decorate([
158
158
  Object
159
159
  ])
160
160
  ], WsConnectionAuth);
161
- //#endregion
162
- //#region src/socket-io-transport.ts
161
+ // src/socket-io-transport.ts
163
162
  /** Convert only mapped headers here: native Headers errors can quote the credential. */
164
163
  function mappedCredentialHeaders(input) {
165
164
  const headers = new Headers();
@@ -296,8 +295,7 @@ function socketIoTransport(options = {}) {
296
295
  advise: (context) => quotaAdvice(context, ttl)
297
296
  });
298
297
  }
299
- //#endregion
300
- //#region src/ws-transport.ts
298
+ // src/ws-transport.ts
301
299
  function recordUpgradeRequest(client, request) {
302
300
  Object.defineProperty(client, UPGRADE_REQUEST, {
303
301
  value: Object.freeze({
@@ -377,7 +375,6 @@ function wsTransport(options = {}) {
377
375
  advise: (context) => quotaAdvice(context, ttl)
378
376
  });
379
377
  }
380
- //#endregion
381
378
  export { UPGRADE_REQUEST, WS_CONNECTION_AUTH, WsConnectionAuth, recordUpgradeRequest, socketIoTransport, withUpgradeRequest, wsCloseCodeFor, wsTransport };
382
379
 
383
380
  //# sourceMappingURL=websockets.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"websockets.mjs","names":[],"sources":["../src/ws-connection-auth.ts","../src/socket-io-transport.ts","../src/ws-transport.ts"],"sourcesContent":["import {\n type ContextType,\n type ExecutionContext,\n Inject,\n Logger,\n type Type,\n} from \"@nestjs/common\";\nimport type { PrincipalResolver, PrincipalResult } from \"./auth-contracts.js\";\nimport {\n AuthFailures,\n isAuthFailure,\n isConfigurationError,\n isInfrastructureError,\n BetterAuthConfigurationError,\n type AuthFailure,\n} from \"./auth-errors.js\";\nimport {\n INSTANCE_REGISTRY,\n PRINCIPAL_RESOLVER,\n TRANSPORT_REGISTRY,\n} from \"./auth-tokens.js\";\nimport { readErrorProperty } from \"./error-redactor.js\";\nimport type { InstanceLookup } from \"./instance-registry.js\";\nimport type { TransportRegistry } from \"./transport-registry.js\";\n\nexport { WS_CONNECTION_AUTH } from \"./auth-tokens.js\";\nexport function wsCloseCodeFor(failure: AuthFailure): 4401 | 4403 | 4429 {\n return failure.status === 401 ? 4401 : failure.status === 403 ? 4403 : 4429;\n}\n\nconst STACK_FRAME = /^\\s+at .+:\\d+:\\d+\\)?$/;\n\n/**\n * Describes an unexpected connection-authentication error for the server log. Package\n * errors carry fixed messages and already-redacted causes. Application and runtime error\n * messages can quote client credentials (native Headers errors do), so only their name\n * and stack frames are kept.\n */\nexport function connectionErrorLog(error: unknown): {\n message: string;\n stack?: string;\n} {\n const text = (value: unknown) =>\n typeof value === \"string\" ? value : undefined;\n let summary: string;\n if (isConfigurationError(error)) {\n summary = `${error.code}: ${error.detail}`;\n } else if (isInfrastructureError(error)) {\n const cause = readErrorProperty(error, \"cause\");\n summary = `${error.message} (${text(readErrorProperty(cause, \"name\")) ?? \"Error\"}: ${text(readErrorProperty(cause, \"message\")) ?? \"\"})`;\n } else {\n const name = text(readErrorProperty(error, \"name\"));\n summary = `${name !== undefined && /^[\\w$.]{1,64}$/.test(name) ? name : typeof error} (message withheld)`;\n }\n const frames = (text(readErrorProperty(error, \"stack\")) ?? \"\")\n .split(/\\r?\\n/)\n .filter((line) => STACK_FRAME.test(line));\n return {\n message: `WebSocket connection authentication failed: ${summary}`,\n stack: frames.length > 0 ? [summary, ...frames].join(\"\\n\") : undefined,\n };\n}\n\n/**\n * The `ws` execution context of a connection before any gateway handler runs. Nest exports no\n * public factory for execution contexts, so this implements the public `ExecutionContext`\n * interface with the values Nest's internal host reports for the arguments `[client, undefined]`.\n */\nexport class ConnectionExecutionContext implements ExecutionContext {\n readonly #args: unknown[];\n\n constructor(client: object) {\n this.#args = [client, undefined];\n }\n\n getType<TContext extends string = ContextType>(): TContext {\n return \"ws\" as TContext;\n }\n\n /** No handler runs yet, so there is no class; Nest's host reports `null` as well. */\n getClass<T>(): Type<T> {\n return null as unknown as Type<T>;\n }\n\n /** No handler runs yet; Nest's host reports `null` as well. */\n getHandler(): ReturnType<ExecutionContext[\"getHandler\"]> {\n return null as unknown as ReturnType<ExecutionContext[\"getHandler\"]>;\n }\n\n getArgs<T extends unknown[] = unknown[]>(): T {\n return this.#args as T;\n }\n\n getArgByIndex<T>(index: number): T {\n return this.#args[index] as T;\n }\n\n switchToHttp(): ReturnType<ExecutionContext[\"switchToHttp\"]> {\n return {\n getRequest: <T>() => this.getArgByIndex<T>(0),\n getResponse: <T>() => this.getArgByIndex<T>(1),\n getNext: <T>() => this.getArgByIndex<T>(2),\n };\n }\n\n switchToRpc(): ReturnType<ExecutionContext[\"switchToRpc\"]> {\n return {\n getData: <T>() => this.getArgByIndex<T>(0),\n getContext: <T>() => this.getArgByIndex<T>(1),\n };\n }\n\n switchToWs(): ReturnType<ExecutionContext[\"switchToWs\"]> {\n return {\n getClient: <T>() => this.getArgByIndex<T>(0),\n getData: <T>() => this.getArgByIndex<T>(1),\n getPattern: () => this.getArgByIndex<string>(this.#args.length - 1),\n };\n }\n}\n\n/** Connection authentication delegates to the same origin and principal kernel as messages. */\nexport class WsConnectionAuth {\n private readonly logger = new Logger(\"BetterAuth\");\n\n constructor(\n @Inject(INSTANCE_REGISTRY) private readonly instances: InstanceLookup,\n @Inject(PRINCIPAL_RESOLVER) private readonly resolver: PrincipalResolver,\n @Inject(TRANSPORT_REGISTRY) private readonly transports: TransportRegistry,\n ) {}\n\n async authenticate(\n client: unknown,\n options: { instance?: string } = {},\n ): Promise<PrincipalResult> {\n if (typeof client !== \"object\" || client === null) {\n throw BetterAuthConfigurationError.atRequest(\n \"INVALID_WS_CLIENT\",\n \"Connection authentication requires a WebSocket client.\",\n );\n }\n const context = new ConnectionExecutionContext(client);\n const transport = this.transports.select(context);\n const call = this.transports.describe(context, transport);\n const entry = this.instances.get(options.instance ?? \"default\");\n const browser = call.browser;\n if (browser && entry.options.originCheck?.mode !== \"off\") {\n const failure = await entry.handle.checkOrigin(browser, \"cookie\");\n if (failure) {\n return { outcome: \"rejected\", failure };\n }\n }\n const accepts = new Set(\n entry.sources\n .filter((source) => source.acceptance === \"default\")\n .flatMap((source) => [...source.kinds]),\n );\n try {\n return await this.resolver.resolve(call, {\n auth: entry.handle,\n accepts,\n sourceSet: JSON.stringify(\n entry.sources.flatMap((source, index) =>\n source.kinds.some((kind) => accepts.has(kind)) ? [index] : [],\n ),\n ),\n freshness:\n entry.options.session !== false &&\n entry.options.session?.freshness === \"authoritative\"\n ? \"authoritative\"\n : \"default\",\n });\n } catch (error) {\n if (isAuthFailure(error)) {\n return { outcome: \"rejected\", failure: error };\n }\n throw error;\n }\n }\n\n socketIoMiddleware(\n options: { required?: boolean; instance?: string } = {},\n ): (socket: unknown, next: (error?: Error) => void) => void {\n return (socket, next) => {\n void this.authenticate(socket, options).then(\n (result) => {\n const failure =\n result.outcome === \"rejected\"\n ? result.failure\n : result.outcome === \"absent\" && options.required\n ? AuthFailures.unauthenticated()\n : undefined;\n if (!failure) {\n next();\n return;\n }\n next(\n Object.assign(new Error(failure.message), {\n data: {\n status: \"error\",\n statusCode: failure.status,\n code: failure.code,\n ...(failure.reason ? { reason: failure.reason } : {}),\n message: failure.message,\n },\n }),\n );\n },\n (error: unknown) => {\n const log = connectionErrorLog(error);\n this.logger.error(log.message, log.stack);\n next(\n Object.assign(new Error(\"Internal server error\"), {\n data: {\n status: \"error\",\n statusCode: 500,\n message: \"Internal server error\",\n },\n }),\n );\n },\n );\n };\n }\n}\n","import type { IncomingHttpHeaders } from \"node:http\";\nimport type { ExecutionContext } from \"@nestjs/common\";\nimport { MetadataScanner } from \"@nestjs/core\";\nimport {\n SubscribeMessage,\n WebSocketGateway,\n WsException,\n} from \"@nestjs/websockets\";\nimport {\n type AuthTransport,\n type BootAdvice,\n type BootAdviceContext,\n type ExtensionDefinition,\n type TransportCall,\n type TransportValidationContext,\n} from \"./auth-contracts.js\";\nimport {\n AuthFailures,\n BetterAuthConfigurationError,\n type AuthFailure,\n} from \"./auth-errors.js\";\nimport { EXTENSION_DEFINITION } from \"./bridge-protocol.js\";\nimport { toWebHeaders, upgradeRequestUrl } from \"./platform.js\";\nimport { WsConnectionAuth, WS_CONNECTION_AUTH } from \"./ws-connection-auth.js\";\n\nexport interface WsTransportOptions<C> {\n /** Replaces principal credentials without changing the browser handshake used for origin checks. */\n credentials?: (client: C) => HeadersInit | undefined;\n /** Defaults to zero. Positive values delay revocation for non-authoritative messages. */\n principalTtlMs?: number;\n /** Every message handler requires explicit guard and scope coverage on every Nest major. */\n gatewayCoverage?: \"error\" | \"warn\" | \"off\";\n}\nexport interface SocketIoClientLike {\n readonly handshake: {\n readonly headers: IncomingHttpHeaders;\n readonly auth?: Record<string, unknown>;\n readonly address?: string;\n readonly url?: string;\n readonly secure?: boolean;\n };\n}\n/** Convert only mapped headers here: native Headers errors can quote the credential. */\nexport function mappedCredentialHeaders(\n input: HeadersInit | undefined,\n): Headers {\n const headers = new Headers();\n if (input === undefined) {\n return headers;\n }\n const malformed = () =>\n AuthFailures.rejected({ status: 401, reason: \"MALFORMED_CREDENTIALS\" });\n if (input === null || typeof input !== \"object\") {\n throw malformed();\n }\n // Read caller-provided getters/iterators outside the conversion catch so their\n // programming errors remain errors, as do errors thrown by the mapper itself.\n const iterable = (input as { [Symbol.iterator]?: unknown })[Symbol.iterator];\n if (iterable !== undefined && typeof iterable !== \"function\") {\n throw malformed();\n }\n const entries: Iterable<unknown> =\n typeof iterable === \"function\"\n ? (input as Iterable<unknown>)\n : Object.entries(input);\n for (const entry of entries) {\n if (!Array.isArray(entry) || entry.length !== 2) {\n throw malformed();\n }\n const [name, value] = entry;\n if (\n typeof name !== \"string\" ||\n typeof value !== \"string\" ||\n /[\\r\\n\\0]/.test(value)\n ) {\n throw malformed();\n }\n try {\n headers.append(name, value);\n } catch {\n throw malformed();\n }\n }\n return headers;\n}\nexport function isSocketIo(client: unknown): client is SocketIoClientLike {\n return typeof client === \"object\" && client !== null && \"handshake\" in client;\n}\nexport function wsException(failure: AuthFailure): WsException {\n return new WsException({\n status: \"error\",\n statusCode: failure.status,\n code: failure.code,\n ...(failure.reason ? { reason: failure.reason } : {}),\n message: failure.message,\n });\n}\nexport function validateGateways(\n context: TransportValidationContext,\n coverage: WsTransportOptions<unknown>[\"gatewayCoverage\"],\n): void {\n class Probe {\n message(): void {}\n }\n WebSocketGateway()(Probe);\n SubscribeMessage(\"probe\")(\n Probe.prototype,\n \"message\",\n Object.getOwnPropertyDescriptor(Probe.prototype, \"message\")!,\n );\n if (\n Reflect.getMetadata(\"websockets:is_gateway\", Probe) !== true ||\n Reflect.getMetadata(\n \"websockets:message_mapping\",\n Probe.prototype.message,\n ) !== true\n ) {\n throw new BetterAuthConfigurationError(\n \"NEST_METADATA_KEY_CHANGED\",\n \"Nest WebSocket gateway/message metadata failed its canary.\",\n );\n }\n const scanner = new MetadataScanner();\n for (const wrapper of context.discovery.getProviders()) {\n const target = wrapper.metatype;\n if (\n !target?.prototype ||\n wrapper.isAlias ||\n !Reflect.getMetadata(\"websockets:is_gateway\", target)\n ) {\n continue;\n }\n for (const method of scanner.getAllMethodNames(target.prototype)) {\n if (\n Reflect.getMetadata(\n \"websockets:message_mapping\",\n target.prototype[method],\n )\n ) {\n context.claim(target, method, \"explicit\", {\n everyHandler: true,\n code: \"GATEWAY_UNGUARDED\",\n coverage: coverage ?? \"error\",\n hint: `Add @UseBetterAuth() to ${target.name} (or @Public() to opt out). Global guards and interceptors do not reach gateways on NestJS 11, and this check does not depend on the version.`,\n });\n }\n }\n }\n}\nexport function quotaAdvice(\n context: BootAdviceContext,\n ttl: number,\n): readonly BootAdvice[] {\n return ttl === 0 &&\n context.sources.some((source) => source.effects?.consumesQuota)\n ? [\n {\n level: \"warn\",\n code: \"W_QUOTA_PER_MESSAGE\",\n message:\n \"Quota-consuming WebSocket principals verify on every message.\",\n hint: \"Consider connection-time authentication and principalTtlMs; a positive TTL delays revocation on non-authoritative handlers.\",\n },\n ]\n : [];\n}\nexport function transportDefinition(\n transport: AuthTransport,\n): ExtensionDefinition<AuthTransport> {\n return {\n [EXTENSION_DEFINITION]: true,\n use: { useFactory: () => transport },\n providers: [\n WsConnectionAuth,\n { provide: WS_CONNECTION_AUTH, useExisting: WsConnectionAuth },\n ],\n exports: [WsConnectionAuth, WS_CONNECTION_AUTH],\n };\n}\nexport function principalTtl(value = 0): number {\n if (!Number.isFinite(value) || value < 0) {\n throw new BetterAuthConfigurationError(\n \"INVALID_WS_TTL\",\n \"principalTtlMs must be a finite non-negative number.\",\n );\n }\n return value;\n}\nexport function socketIoTransport(\n options: WsTransportOptions<SocketIoClientLike> = {},\n): ExtensionDefinition<AuthTransport> {\n const ttl = principalTtl(options.principalTtlMs);\n return transportDefinition({\n id: \"socket.io\",\n handles: (context) =>\n context.getType() === \"ws\" &&\n isSocketIo(context.switchToWs().getClient()),\n describe(context: ExecutionContext): TransportCall {\n const client = context.switchToWs().getClient<SocketIoClientLike>();\n const original = () => toWebHeaders(client.handshake.headers);\n return {\n key: context.getArgs(),\n invocation: context.getArgs(),\n connection: client,\n principalTtlMs: ttl,\n headers: () => {\n const headers = original();\n let mapped: HeadersInit | undefined;\n if (options.credentials) {\n mapped = options.credentials(client);\n } else if (!headers.has(\"authorization\")) {\n const token = client.handshake.auth?.token;\n if (token !== undefined) {\n if (typeof token !== \"string\") {\n throw AuthFailures.rejected({\n status: 401,\n reason: \"MALFORMED_CREDENTIALS\",\n });\n }\n mapped = { authorization: `Bearer ${token}` };\n }\n }\n mappedCredentialHeaders(mapped).forEach((value, name) => {\n headers.set(name, value);\n });\n return headers;\n },\n get clientIp() {\n return client.handshake.address ?? null;\n },\n cookies: null,\n get request() {\n return { method: \"GET\", url: upgradeRequestUrl(client.handshake) };\n },\n param: (name) => context.switchToWs().getData()?.[name],\n get browser() {\n return {\n enforce: true,\n key: client,\n headers: original,\n url: upgradeRequestUrl(client.handshake),\n };\n },\n };\n },\n toException: wsException,\n validate: (context) => validateGateways(context, options.gatewayCoverage),\n advise: (context) => quotaAdvice(context, ttl),\n });\n}\n","import type { IncomingHttpHeaders } from \"node:http\";\nimport type { AuthTransport, ExtensionDefinition } from \"./auth-contracts.js\";\nimport { UPGRADE_REQUEST } from \"./bridge-protocol.js\";\nimport { BetterAuthConfigurationError } from \"./auth-errors.js\";\nimport { toWebHeaders, upgradeRequestUrl } from \"./platform.js\";\nimport {\n isSocketIo,\n mappedCredentialHeaders,\n principalTtl,\n quotaAdvice,\n transportDefinition,\n validateGateways,\n wsException,\n type WsTransportOptions,\n} from \"./socket-io-transport.js\";\n\nexport { UPGRADE_REQUEST } from \"./bridge-protocol.js\";\nexport interface WsClientLike {\n readonly [UPGRADE_REQUEST]?: {\n readonly headers: Headers;\n readonly url?: string;\n readonly remoteAddress?: string;\n readonly encrypted?: boolean;\n };\n}\nexport interface WsAdapterLike {\n bindClientConnect(\n server: unknown,\n callback: (...args: any[]) => void,\n ): unknown;\n}\nexport function recordUpgradeRequest(\n client: object,\n request: {\n headers: IncomingHttpHeaders;\n url?: string;\n socket?: { remoteAddress?: string; encrypted?: boolean };\n },\n): void {\n Object.defineProperty(client, UPGRADE_REQUEST, {\n value: Object.freeze({\n headers: toWebHeaders(request.headers),\n url: request.url,\n remoteAddress: request.socket?.remoteAddress,\n encrypted: request.socket?.encrypted,\n }),\n configurable: true,\n });\n}\nexport function withUpgradeRequest<\n T extends new (\n ...args: any[]\n ) => WsAdapterLike,\n>(Base: T): T {\n return class extends Base {\n override bindClientConnect(\n server: unknown,\n callback: (...args: any[]) => void,\n ): unknown {\n return super.bindClientConnect(server, (client, request, ...rest) => {\n recordUpgradeRequest(client, request);\n callback(client, request, ...rest);\n });\n }\n };\n}\nexport function wsTransport(\n options: WsTransportOptions<WsClientLike> = {},\n): ExtensionDefinition<AuthTransport> {\n const ttl = principalTtl(options.principalTtlMs);\n return transportDefinition({\n id: \"ws\",\n handles: (context) =>\n context.getType() === \"ws\" &&\n !isSocketIo(context.switchToWs().getClient()),\n describe(context) {\n const client = context.switchToWs().getClient<WsClientLike>();\n const upgrade = () => {\n const request = client[UPGRADE_REQUEST];\n if (!request) {\n throw BetterAuthConfigurationError.atRequest(\n \"WS_UPGRADE_REQUEST_MISSING\",\n \"WebSocket authentication requires its upgrade request.\",\n {\n hint: \"app.useWebSocketAdapter(new (withUpgradeRequest(WsAdapter))(app));\",\n },\n );\n }\n return request;\n };\n const url = () => {\n const request = upgrade();\n return upgradeRequestUrl({\n headers: request.headers,\n url: request.url,\n secure: request.encrypted,\n });\n };\n return {\n key: context.getArgs(),\n invocation: context.getArgs(),\n connection: client,\n principalTtlMs: ttl,\n headers: () => {\n const headers = new Headers(upgrade().headers);\n mappedCredentialHeaders(options.credentials?.(client)).forEach(\n (value, name) => {\n headers.set(name, value);\n },\n );\n return headers;\n },\n get clientIp() {\n return upgrade().remoteAddress ?? null;\n },\n cookies: null,\n get request() {\n return { method: \"GET\", url: url() };\n },\n param: (name) => context.switchToWs().getData()?.[name],\n get browser() {\n return {\n enforce: true,\n key: client,\n headers: () => new Headers(upgrade().headers),\n url: url(),\n };\n },\n };\n },\n toException: wsException,\n validate: (context) => validateGateways(context, options.gatewayCoverage),\n advise: (context) => quotaAdvice(context, ttl),\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"websockets.mjs","names":[],"sources":["../src/ws-connection-auth.ts","../src/socket-io-transport.ts","../src/ws-transport.ts"],"sourcesContent":["import {\n type ContextType,\n type ExecutionContext,\n Inject,\n Logger,\n type Type,\n} from \"@nestjs/common\";\nimport type { PrincipalResolver, PrincipalResult } from \"./auth-contracts.js\";\nimport {\n AuthFailures,\n isAuthFailure,\n isConfigurationError,\n isInfrastructureError,\n BetterAuthConfigurationError,\n type AuthFailure,\n} from \"./auth-errors.js\";\nimport {\n INSTANCE_REGISTRY,\n PRINCIPAL_RESOLVER,\n TRANSPORT_REGISTRY,\n} from \"./auth-tokens.js\";\nimport { readErrorProperty } from \"./error-redactor.js\";\nimport type { InstanceLookup } from \"./instance-registry.js\";\nimport type { TransportRegistry } from \"./transport-registry.js\";\n\nexport { WS_CONNECTION_AUTH } from \"./auth-tokens.js\";\nexport function wsCloseCodeFor(failure: AuthFailure): 4401 | 4403 | 4429 {\n return failure.status === 401 ? 4401 : failure.status === 403 ? 4403 : 4429;\n}\n\nconst STACK_FRAME = /^\\s+at .+:\\d+:\\d+\\)?$/;\n\n/**\n * Describes an unexpected connection-authentication error for the server log. Package\n * errors carry fixed messages and already-redacted causes. Application and runtime error\n * messages can quote client credentials (native Headers errors do), so only their name\n * and stack frames are kept.\n */\nexport function connectionErrorLog(error: unknown): {\n message: string;\n stack?: string;\n} {\n const text = (value: unknown) =>\n typeof value === \"string\" ? value : undefined;\n let summary: string;\n if (isConfigurationError(error)) {\n summary = `${error.code}: ${error.detail}`;\n } else if (isInfrastructureError(error)) {\n const cause = readErrorProperty(error, \"cause\");\n summary = `${error.message} (${text(readErrorProperty(cause, \"name\")) ?? \"Error\"}: ${text(readErrorProperty(cause, \"message\")) ?? \"\"})`;\n } else {\n const name = text(readErrorProperty(error, \"name\"));\n summary = `${name !== undefined && /^[\\w$.]{1,64}$/.test(name) ? name : typeof error} (message withheld)`;\n }\n const frames = (text(readErrorProperty(error, \"stack\")) ?? \"\")\n .split(/\\r?\\n/)\n .filter((line) => STACK_FRAME.test(line));\n return {\n message: `WebSocket connection authentication failed: ${summary}`,\n stack: frames.length > 0 ? [summary, ...frames].join(\"\\n\") : undefined,\n };\n}\n\n/**\n * The `ws` execution context of a connection before any gateway handler runs. Nest exports no\n * public factory for execution contexts, so this implements the public `ExecutionContext`\n * interface with the values Nest's internal host reports for the arguments `[client, undefined]`.\n */\nexport class ConnectionExecutionContext implements ExecutionContext {\n readonly #args: unknown[];\n\n constructor(client: object) {\n this.#args = [client, undefined];\n }\n\n getType<TContext extends string = ContextType>(): TContext {\n return \"ws\" as TContext;\n }\n\n /** No handler runs yet, so there is no class; Nest's host reports `null` as well. */\n getClass<T>(): Type<T> {\n return null as unknown as Type<T>;\n }\n\n /** No handler runs yet; Nest's host reports `null` as well. */\n getHandler(): ReturnType<ExecutionContext[\"getHandler\"]> {\n return null as unknown as ReturnType<ExecutionContext[\"getHandler\"]>;\n }\n\n getArgs<T extends unknown[] = unknown[]>(): T {\n return this.#args as T;\n }\n\n getArgByIndex<T>(index: number): T {\n return this.#args[index] as T;\n }\n\n switchToHttp(): ReturnType<ExecutionContext[\"switchToHttp\"]> {\n return {\n getRequest: <T>() => this.getArgByIndex<T>(0),\n getResponse: <T>() => this.getArgByIndex<T>(1),\n getNext: <T>() => this.getArgByIndex<T>(2),\n };\n }\n\n switchToRpc(): ReturnType<ExecutionContext[\"switchToRpc\"]> {\n return {\n getData: <T>() => this.getArgByIndex<T>(0),\n getContext: <T>() => this.getArgByIndex<T>(1),\n };\n }\n\n switchToWs(): ReturnType<ExecutionContext[\"switchToWs\"]> {\n return {\n getClient: <T>() => this.getArgByIndex<T>(0),\n getData: <T>() => this.getArgByIndex<T>(1),\n getPattern: () => this.getArgByIndex<string>(this.#args.length - 1),\n };\n }\n}\n\n/** Connection authentication delegates to the same origin and principal kernel as messages. */\nexport class WsConnectionAuth {\n private readonly logger = new Logger(\"BetterAuth\");\n\n constructor(\n @Inject(INSTANCE_REGISTRY) private readonly instances: InstanceLookup,\n @Inject(PRINCIPAL_RESOLVER) private readonly resolver: PrincipalResolver,\n @Inject(TRANSPORT_REGISTRY) private readonly transports: TransportRegistry,\n ) {}\n\n async authenticate(\n client: unknown,\n options: { instance?: string } = {},\n ): Promise<PrincipalResult> {\n if (typeof client !== \"object\" || client === null) {\n throw BetterAuthConfigurationError.atRequest(\n \"INVALID_WS_CLIENT\",\n \"Connection authentication requires a WebSocket client.\",\n );\n }\n const context = new ConnectionExecutionContext(client);\n const transport = this.transports.select(context);\n const call = this.transports.describe(context, transport);\n const entry = this.instances.get(options.instance ?? \"default\");\n const browser = call.browser;\n if (browser && entry.options.originCheck?.mode !== \"off\") {\n const failure = await entry.handle.checkOrigin(browser, \"cookie\");\n if (failure) {\n return { outcome: \"rejected\", failure };\n }\n }\n const accepts = new Set(\n entry.sources\n .filter((source) => source.acceptance === \"default\")\n .flatMap((source) => [...source.kinds]),\n );\n try {\n return await this.resolver.resolve(call, {\n auth: entry.handle,\n accepts,\n sourceSet: JSON.stringify(\n entry.sources.flatMap((source, index) =>\n source.kinds.some((kind) => accepts.has(kind)) ? [index] : [],\n ),\n ),\n freshness:\n entry.options.session !== false &&\n entry.options.session?.freshness === \"authoritative\"\n ? \"authoritative\"\n : \"default\",\n });\n } catch (error) {\n if (isAuthFailure(error)) {\n return { outcome: \"rejected\", failure: error };\n }\n throw error;\n }\n }\n\n socketIoMiddleware(\n options: { required?: boolean; instance?: string } = {},\n ): (socket: unknown, next: (error?: Error) => void) => void {\n return (socket, next) => {\n void this.authenticate(socket, options).then(\n (result) => {\n const failure =\n result.outcome === \"rejected\"\n ? result.failure\n : result.outcome === \"absent\" && options.required\n ? AuthFailures.unauthenticated()\n : undefined;\n if (!failure) {\n next();\n return;\n }\n next(\n Object.assign(new Error(failure.message), {\n data: {\n status: \"error\",\n statusCode: failure.status,\n code: failure.code,\n ...(failure.reason ? { reason: failure.reason } : {}),\n message: failure.message,\n },\n }),\n );\n },\n (error: unknown) => {\n const log = connectionErrorLog(error);\n this.logger.error(log.message, log.stack);\n next(\n Object.assign(new Error(\"Internal server error\"), {\n data: {\n status: \"error\",\n statusCode: 500,\n message: \"Internal server error\",\n },\n }),\n );\n },\n );\n };\n }\n}\n","import type { IncomingHttpHeaders } from \"node:http\";\nimport type { ExecutionContext } from \"@nestjs/common\";\nimport { MetadataScanner } from \"@nestjs/core\";\nimport {\n SubscribeMessage,\n WebSocketGateway,\n WsException,\n} from \"@nestjs/websockets\";\nimport {\n type AuthTransport,\n type BootAdvice,\n type BootAdviceContext,\n type ExtensionDefinition,\n type TransportCall,\n type TransportValidationContext,\n} from \"./auth-contracts.js\";\nimport {\n AuthFailures,\n BetterAuthConfigurationError,\n type AuthFailure,\n} from \"./auth-errors.js\";\nimport { EXTENSION_DEFINITION } from \"./bridge-protocol.js\";\nimport { toWebHeaders, upgradeRequestUrl } from \"./platform.js\";\nimport { WsConnectionAuth, WS_CONNECTION_AUTH } from \"./ws-connection-auth.js\";\n\nexport interface WsTransportOptions<C> {\n /** Replaces principal credentials without changing the browser handshake used for origin checks. */\n credentials?: (client: C) => HeadersInit | undefined;\n /** Defaults to zero. Positive values delay revocation for non-authoritative messages. */\n principalTtlMs?: number;\n /** Every message handler requires explicit guard and scope coverage on every Nest major. */\n gatewayCoverage?: \"error\" | \"warn\" | \"off\";\n}\nexport interface SocketIoClientLike {\n readonly handshake: {\n readonly headers: IncomingHttpHeaders;\n readonly auth?: Record<string, unknown>;\n readonly address?: string;\n readonly url?: string;\n readonly secure?: boolean;\n };\n}\n/** Convert only mapped headers here: native Headers errors can quote the credential. */\nexport function mappedCredentialHeaders(\n input: HeadersInit | undefined,\n): Headers {\n const headers = new Headers();\n if (input === undefined) {\n return headers;\n }\n const malformed = () =>\n AuthFailures.rejected({ status: 401, reason: \"MALFORMED_CREDENTIALS\" });\n if (input === null || typeof input !== \"object\") {\n throw malformed();\n }\n // Read caller-provided getters/iterators outside the conversion catch so their\n // programming errors remain errors, as do errors thrown by the mapper itself.\n const iterable = (input as { [Symbol.iterator]?: unknown })[Symbol.iterator];\n if (iterable !== undefined && typeof iterable !== \"function\") {\n throw malformed();\n }\n const entries: Iterable<unknown> =\n typeof iterable === \"function\"\n ? (input as Iterable<unknown>)\n : Object.entries(input);\n for (const entry of entries) {\n if (!Array.isArray(entry) || entry.length !== 2) {\n throw malformed();\n }\n const [name, value] = entry;\n if (\n typeof name !== \"string\" ||\n typeof value !== \"string\" ||\n /[\\r\\n\\0]/.test(value)\n ) {\n throw malformed();\n }\n try {\n headers.append(name, value);\n } catch {\n throw malformed();\n }\n }\n return headers;\n}\nexport function isSocketIo(client: unknown): client is SocketIoClientLike {\n return typeof client === \"object\" && client !== null && \"handshake\" in client;\n}\nexport function wsException(failure: AuthFailure): WsException {\n return new WsException({\n status: \"error\",\n statusCode: failure.status,\n code: failure.code,\n ...(failure.reason ? { reason: failure.reason } : {}),\n message: failure.message,\n });\n}\nexport function validateGateways(\n context: TransportValidationContext,\n coverage: WsTransportOptions<unknown>[\"gatewayCoverage\"],\n): void {\n class Probe {\n message(): void {}\n }\n WebSocketGateway()(Probe);\n SubscribeMessage(\"probe\")(\n Probe.prototype,\n \"message\",\n Object.getOwnPropertyDescriptor(Probe.prototype, \"message\")!,\n );\n if (\n Reflect.getMetadata(\"websockets:is_gateway\", Probe) !== true ||\n Reflect.getMetadata(\n \"websockets:message_mapping\",\n Probe.prototype.message,\n ) !== true\n ) {\n throw new BetterAuthConfigurationError(\n \"NEST_METADATA_KEY_CHANGED\",\n \"Nest WebSocket gateway/message metadata failed its canary.\",\n );\n }\n const scanner = new MetadataScanner();\n for (const wrapper of context.discovery.getProviders()) {\n const target = wrapper.metatype;\n if (\n !target?.prototype ||\n wrapper.isAlias ||\n !Reflect.getMetadata(\"websockets:is_gateway\", target)\n ) {\n continue;\n }\n for (const method of scanner.getAllMethodNames(target.prototype)) {\n if (\n Reflect.getMetadata(\n \"websockets:message_mapping\",\n target.prototype[method],\n )\n ) {\n context.claim(target, method, \"explicit\", {\n everyHandler: true,\n code: \"GATEWAY_UNGUARDED\",\n coverage: coverage ?? \"error\",\n hint: `Add @UseBetterAuth() to ${target.name} (or @Public() to opt out). Global guards and interceptors do not reach gateways on NestJS 11, and this check does not depend on the version.`,\n });\n }\n }\n }\n}\nexport function quotaAdvice(\n context: BootAdviceContext,\n ttl: number,\n): readonly BootAdvice[] {\n return ttl === 0 &&\n context.sources.some((source) => source.effects?.consumesQuota)\n ? [\n {\n level: \"warn\",\n code: \"W_QUOTA_PER_MESSAGE\",\n message:\n \"Quota-consuming WebSocket principals verify on every message.\",\n hint: \"Consider connection-time authentication and principalTtlMs; a positive TTL delays revocation on non-authoritative handlers.\",\n },\n ]\n : [];\n}\nexport function transportDefinition(\n transport: AuthTransport,\n): ExtensionDefinition<AuthTransport> {\n return {\n [EXTENSION_DEFINITION]: true,\n use: { useFactory: () => transport },\n providers: [\n WsConnectionAuth,\n { provide: WS_CONNECTION_AUTH, useExisting: WsConnectionAuth },\n ],\n exports: [WsConnectionAuth, WS_CONNECTION_AUTH],\n };\n}\nexport function principalTtl(value = 0): number {\n if (!Number.isFinite(value) || value < 0) {\n throw new BetterAuthConfigurationError(\n \"INVALID_WS_TTL\",\n \"principalTtlMs must be a finite non-negative number.\",\n );\n }\n return value;\n}\nexport function socketIoTransport(\n options: WsTransportOptions<SocketIoClientLike> = {},\n): ExtensionDefinition<AuthTransport> {\n const ttl = principalTtl(options.principalTtlMs);\n return transportDefinition({\n id: \"socket.io\",\n handles: (context) =>\n context.getType() === \"ws\" &&\n isSocketIo(context.switchToWs().getClient()),\n describe(context: ExecutionContext): TransportCall {\n const client = context.switchToWs().getClient<SocketIoClientLike>();\n const original = () => toWebHeaders(client.handshake.headers);\n return {\n key: context.getArgs(),\n invocation: context.getArgs(),\n connection: client,\n principalTtlMs: ttl,\n headers: () => {\n const headers = original();\n let mapped: HeadersInit | undefined;\n if (options.credentials) {\n mapped = options.credentials(client);\n } else if (!headers.has(\"authorization\")) {\n const token = client.handshake.auth?.token;\n if (token !== undefined) {\n if (typeof token !== \"string\") {\n throw AuthFailures.rejected({\n status: 401,\n reason: \"MALFORMED_CREDENTIALS\",\n });\n }\n mapped = { authorization: `Bearer ${token}` };\n }\n }\n mappedCredentialHeaders(mapped).forEach((value, name) => {\n headers.set(name, value);\n });\n return headers;\n },\n get clientIp() {\n return client.handshake.address ?? null;\n },\n cookies: null,\n get request() {\n return { method: \"GET\", url: upgradeRequestUrl(client.handshake) };\n },\n param: (name) => context.switchToWs().getData()?.[name],\n get browser() {\n return {\n enforce: true,\n key: client,\n headers: original,\n url: upgradeRequestUrl(client.handshake),\n };\n },\n };\n },\n toException: wsException,\n validate: (context) => validateGateways(context, options.gatewayCoverage),\n advise: (context) => quotaAdvice(context, ttl),\n });\n}\n","import type { IncomingHttpHeaders } from \"node:http\";\nimport type { AuthTransport, ExtensionDefinition } from \"./auth-contracts.js\";\nimport { UPGRADE_REQUEST } from \"./bridge-protocol.js\";\nimport { BetterAuthConfigurationError } from \"./auth-errors.js\";\nimport { toWebHeaders, upgradeRequestUrl } from \"./platform.js\";\nimport {\n isSocketIo,\n mappedCredentialHeaders,\n principalTtl,\n quotaAdvice,\n transportDefinition,\n validateGateways,\n wsException,\n type WsTransportOptions,\n} from \"./socket-io-transport.js\";\n\nexport { UPGRADE_REQUEST } from \"./bridge-protocol.js\";\nexport interface WsClientLike {\n readonly [UPGRADE_REQUEST]?: {\n readonly headers: Headers;\n readonly url?: string;\n readonly remoteAddress?: string;\n readonly encrypted?: boolean;\n };\n}\nexport interface WsAdapterLike {\n bindClientConnect(\n server: unknown,\n callback: (...args: any[]) => void,\n ): unknown;\n}\nexport function recordUpgradeRequest(\n client: object,\n request: {\n headers: IncomingHttpHeaders;\n url?: string;\n socket?: { remoteAddress?: string; encrypted?: boolean };\n },\n): void {\n Object.defineProperty(client, UPGRADE_REQUEST, {\n value: Object.freeze({\n headers: toWebHeaders(request.headers),\n url: request.url,\n remoteAddress: request.socket?.remoteAddress,\n encrypted: request.socket?.encrypted,\n }),\n configurable: true,\n });\n}\nexport function withUpgradeRequest<\n T extends new (...args: any[]) => WsAdapterLike,\n>(Base: T): T {\n return class extends Base {\n override bindClientConnect(\n server: unknown,\n callback: (...args: any[]) => void,\n ): unknown {\n return super.bindClientConnect(server, (client, request, ...rest) => {\n recordUpgradeRequest(client, request);\n callback(client, request, ...rest);\n });\n }\n };\n}\nexport function wsTransport(\n options: WsTransportOptions<WsClientLike> = {},\n): ExtensionDefinition<AuthTransport> {\n const ttl = principalTtl(options.principalTtlMs);\n return transportDefinition({\n id: \"ws\",\n handles: (context) =>\n context.getType() === \"ws\" &&\n !isSocketIo(context.switchToWs().getClient()),\n describe(context) {\n const client = context.switchToWs().getClient<WsClientLike>();\n const upgrade = () => {\n const request = client[UPGRADE_REQUEST];\n if (!request) {\n throw BetterAuthConfigurationError.atRequest(\n \"WS_UPGRADE_REQUEST_MISSING\",\n \"WebSocket authentication requires its upgrade request.\",\n {\n hint: \"app.useWebSocketAdapter(new (withUpgradeRequest(WsAdapter))(app));\",\n },\n );\n }\n return request;\n };\n const url = () => {\n const request = upgrade();\n return upgradeRequestUrl({\n headers: request.headers,\n url: request.url,\n secure: request.encrypted,\n });\n };\n return {\n key: context.getArgs(),\n invocation: context.getArgs(),\n connection: client,\n principalTtlMs: ttl,\n headers: () => {\n const headers = new Headers(upgrade().headers);\n mappedCredentialHeaders(options.credentials?.(client)).forEach(\n (value, name) => {\n headers.set(name, value);\n },\n );\n return headers;\n },\n get clientIp() {\n return upgrade().remoteAddress ?? null;\n },\n cookies: null,\n get request() {\n return { method: \"GET\", url: url() };\n },\n param: (name) => context.switchToWs().getData()?.[name],\n get browser() {\n return {\n enforce: true,\n key: client,\n headers: () => new Headers(upgrade().headers),\n url: url(),\n };\n },\n };\n },\n toException: wsException,\n validate: (context) => validateGateways(context, options.gatewayCoverage),\n advise: (context) => quotaAdvice(context, ttl),\n });\n}\n"],"mappings":"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"}