@bgord/bun 1.23.1 → 1.23.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. package/dist/better-auth-logger.service.d.ts +1 -1
  2. package/dist/better-auth-logger.service.d.ts.map +1 -1
  3. package/dist/better-auth-logger.service.js +8 -3
  4. package/dist/better-auth-logger.service.js.map +1 -1
  5. package/dist/error-classifier-http-exception-hono.strategy.d.ts.map +1 -1
  6. package/dist/error-classifier-http-exception-hono.strategy.js +3 -2
  7. package/dist/error-classifier-http-exception-hono.strategy.js.map +1 -1
  8. package/dist/event.types.d.ts +2 -0
  9. package/dist/event.types.d.ts.map +1 -1
  10. package/dist/file-type-detector-fixed.strategy.d.ts +8 -0
  11. package/dist/file-type-detector-fixed.strategy.d.ts.map +1 -0
  12. package/dist/file-type-detector-fixed.strategy.js +10 -0
  13. package/dist/file-type-detector-fixed.strategy.js.map +1 -0
  14. package/dist/file-type-detector-magic-bytes.strategy.d.ts +6 -0
  15. package/dist/file-type-detector-magic-bytes.strategy.d.ts.map +1 -0
  16. package/dist/file-type-detector-magic-bytes.strategy.js +25 -0
  17. package/dist/file-type-detector-magic-bytes.strategy.js.map +1 -0
  18. package/dist/file-type-detector-text.strategy.d.ts +8 -0
  19. package/dist/file-type-detector-text.strategy.d.ts.map +1 -0
  20. package/dist/file-type-detector-text.strategy.js +22 -0
  21. package/dist/file-type-detector-text.strategy.js.map +1 -0
  22. package/dist/file-type-detector.strategy.d.ts +5 -0
  23. package/dist/file-type-detector.strategy.d.ts.map +1 -0
  24. package/dist/file-type-detector.strategy.js +2 -0
  25. package/dist/file-type-detector.strategy.js.map +1 -0
  26. package/dist/file-uploader-hono.middleware.d.ts +6 -1
  27. package/dist/file-uploader-hono.middleware.d.ts.map +1 -1
  28. package/dist/file-uploader-hono.middleware.js +2 -2
  29. package/dist/file-uploader-hono.middleware.js.map +1 -1
  30. package/dist/file-uploader.middleware.d.ts +7 -1
  31. package/dist/file-uploader.middleware.d.ts.map +1 -1
  32. package/dist/file-uploader.middleware.js +6 -3
  33. package/dist/file-uploader.middleware.js.map +1 -1
  34. package/dist/hcaptcha.service.d.ts +2 -1
  35. package/dist/hcaptcha.service.d.ts.map +1 -1
  36. package/dist/hcaptcha.service.js +2 -2
  37. package/dist/hcaptcha.service.js.map +1 -1
  38. package/dist/healthcheck.handler.d.ts +1 -1
  39. package/dist/healthcheck.handler.d.ts.map +1 -1
  40. package/dist/healthcheck.handler.js +1 -1
  41. package/dist/healthcheck.handler.js.map +1 -1
  42. package/dist/index.d.ts +6 -0
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +6 -0
  45. package/dist/index.js.map +1 -1
  46. package/dist/language-detector-header.strategy.d.ts.map +1 -1
  47. package/dist/language-detector-header.strategy.js +0 -1
  48. package/dist/language-detector-header.strategy.js.map +1 -1
  49. package/dist/readiness.handler.d.ts +2 -0
  50. package/dist/readiness.handler.d.ts.map +1 -1
  51. package/dist/readiness.handler.js +1 -1
  52. package/dist/readiness.handler.js.map +1 -1
  53. package/dist/remote-file-storage-disk.adapter.d.ts.map +1 -1
  54. package/dist/remote-file-storage-disk.adapter.js +4 -1
  55. package/dist/remote-file-storage-disk.adapter.js.map +1 -1
  56. package/dist/sealer-aes-gcm.adapter.d.ts.map +1 -1
  57. package/dist/sealer-aes-gcm.adapter.js +8 -3
  58. package/dist/sealer-aes-gcm.adapter.js.map +1 -1
  59. package/dist/security-rule-user-agent.strategy.d.ts.map +1 -1
  60. package/dist/security-rule-user-agent.strategy.js +4 -3
  61. package/dist/security-rule-user-agent.strategy.js.map +1 -1
  62. package/dist/security-rule-violation-threshold.strategy.d.ts +3 -0
  63. package/dist/security-rule-violation-threshold.strategy.d.ts.map +1 -1
  64. package/dist/security-rule-violation-threshold.strategy.js +3 -3
  65. package/dist/security-rule-violation-threshold.strategy.js.map +1 -1
  66. package/dist/shield-body-limit.strategy.d.ts.map +1 -1
  67. package/dist/shield-body-limit.strategy.js +3 -1
  68. package/dist/shield-body-limit.strategy.js.map +1 -1
  69. package/dist/shield-hcaptcha-hono-local.strategy.d.ts +1 -0
  70. package/dist/shield-hcaptcha-hono-local.strategy.d.ts.map +1 -1
  71. package/dist/shield-hcaptcha-hono-local.strategy.js +5 -1
  72. package/dist/shield-hcaptcha-hono-local.strategy.js.map +1 -1
  73. package/dist/shield-hcaptcha-hono.strategy.d.ts +2 -2
  74. package/dist/shield-hcaptcha-hono.strategy.d.ts.map +1 -1
  75. package/dist/shield-hcaptcha-hono.strategy.js +3 -3
  76. package/dist/shield-hcaptcha-hono.strategy.js.map +1 -1
  77. package/dist/shield-hcaptcha.strategy.d.ts +6 -2
  78. package/dist/shield-hcaptcha.strategy.d.ts.map +1 -1
  79. package/dist/shield-hcaptcha.strategy.js +9 -5
  80. package/dist/shield-hcaptcha.strategy.js.map +1 -1
  81. package/dist/shield-recaptcha.strategy.d.ts +4 -0
  82. package/dist/shield-recaptcha.strategy.d.ts.map +1 -1
  83. package/dist/shield-recaptcha.strategy.js +4 -0
  84. package/dist/shield-recaptcha.strategy.js.map +1 -1
  85. package/dist/subject-segment-remote-ip.strategy.d.ts +7 -0
  86. package/dist/subject-segment-remote-ip.strategy.d.ts.map +1 -0
  87. package/dist/subject-segment-remote-ip.strategy.js +8 -0
  88. package/dist/subject-segment-remote-ip.strategy.js.map +1 -0
  89. package/dist/subject-segment-request.strategy.d.ts +2 -2
  90. package/dist/subject-segment-request.strategy.d.ts.map +1 -1
  91. package/dist/subject-segment-request.strategy.js.map +1 -1
  92. package/dist/webhook-body-builder-signed-headers.strategy.d.ts +8 -0
  93. package/dist/webhook-body-builder-signed-headers.strategy.d.ts.map +1 -0
  94. package/dist/webhook-body-builder-signed-headers.strategy.js +11 -0
  95. package/dist/webhook-body-builder-signed-headers.strategy.js.map +1 -0
  96. package/dist/webhook-signature.vo.d.ts +2 -1
  97. package/dist/webhook-signature.vo.d.ts.map +1 -1
  98. package/dist/webhook-signature.vo.js +4 -1
  99. package/dist/webhook-signature.vo.js.map +1 -1
  100. package/dist/webhook-verifier-sha256.strategy.d.ts.map +1 -1
  101. package/dist/webhook-verifier-sha256.strategy.js +4 -3
  102. package/dist/webhook-verifier-sha256.strategy.js.map +1 -1
  103. package/dist/woodchopper.d.ts +1 -1
  104. package/dist/woodchopper.d.ts.map +1 -1
  105. package/dist/woodchopper.js +1 -3
  106. package/dist/woodchopper.js.map +1 -1
  107. package/package.json +1 -1
  108. package/readme.md +6 -0
  109. package/src/better-auth-logger.service.ts +8 -3
  110. package/src/error-classifier-http-exception-hono.strategy.ts +6 -1
  111. package/src/event.types.ts +2 -0
  112. package/src/file-type-detector-fixed.strategy.ts +10 -0
  113. package/src/file-type-detector-magic-bytes.strategy.ts +32 -0
  114. package/src/file-type-detector-text.strategy.ts +25 -0
  115. package/src/file-type-detector.strategy.ts +5 -0
  116. package/src/file-uploader-hono.middleware.ts +5 -2
  117. package/src/file-uploader.middleware.ts +10 -3
  118. package/src/hcaptcha.service.ts +3 -6
  119. package/src/healthcheck.handler.ts +2 -2
  120. package/src/index.ts +6 -0
  121. package/src/language-detector-header.strategy.ts +0 -1
  122. package/src/readiness.handler.ts +6 -2
  123. package/src/remote-file-storage-disk.adapter.ts +4 -1
  124. package/src/sealer-aes-gcm.adapter.ts +7 -3
  125. package/src/security-rule-user-agent.strategy.ts +4 -3
  126. package/src/security-rule-violation-threshold.strategy.ts +14 -8
  127. package/src/shield-body-limit.strategy.ts +3 -1
  128. package/src/shield-hcaptcha-hono-local.strategy.ts +6 -1
  129. package/src/shield-hcaptcha-hono.strategy.ts +7 -4
  130. package/src/shield-hcaptcha.strategy.ts +8 -3
  131. package/src/shield-recaptcha.strategy.ts +9 -2
  132. package/src/subject-segment-remote-ip.strategy.ts +14 -0
  133. package/src/subject-segment-request.strategy.ts +2 -0
  134. package/src/webhook-body-builder-signed-headers.strategy.ts +12 -0
  135. package/src/webhook-signature.vo.ts +5 -0
  136. package/src/webhook-verifier-sha256.strategy.ts +4 -3
  137. package/src/woodchopper.ts +2 -4
@@ -0,0 +1,8 @@
1
+ import type { HasRequestHeader, HasRequestText } from "./request-context.port";
2
+ import type { WebhookBodyBuilderStrategy } from "./webhook-body-builder.strategy";
3
+ export declare class WebhookBodyBuilderSignedHeadersStrategy implements WebhookBodyBuilderStrategy {
4
+ private readonly headers;
5
+ constructor(headers: ReadonlyArray<string>);
6
+ build(context: HasRequestHeader & HasRequestText): Promise<string>;
7
+ }
8
+ //# sourceMappingURL=webhook-body-builder-signed-headers.strategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-body-builder-signed-headers.strategy.d.ts","sourceRoot":"","sources":["../src/webhook-body-builder-signed-headers.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAC/E,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,iCAAiC,CAAC;AAElF,qBAAa,uCAAwC,YAAW,0BAA0B;IAC5E,OAAO,CAAC,QAAQ,CAAC,OAAO;IAApC,YAA6B,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAAI;IAEzD,KAAK,CAAC,OAAO,EAAE,gBAAgB,GAAG,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAIvE;CACF"}
@@ -0,0 +1,11 @@
1
+ export class WebhookBodyBuilderSignedHeadersStrategy {
2
+ headers;
3
+ constructor(headers) {
4
+ this.headers = headers;
5
+ }
6
+ async build(context) {
7
+ const headers = this.headers.map((name) => [name, context.request.header(name) ?? null]);
8
+ return JSON.stringify([headers, await context.request.text()]);
9
+ }
10
+ }
11
+ //# sourceMappingURL=webhook-body-builder-signed-headers.strategy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-body-builder-signed-headers.strategy.js","sourceRoot":"","sources":["../src/webhook-body-builder-signed-headers.strategy.ts"],"names":[],"mappings":"AAGA,MAAM,OAAO,uCAAuC;IACrB,OAAO;IAApC,YAA6B,OAA8B;uBAA9B,OAAO;IAA0B,CAAC;IAE/D,KAAK,CAAC,KAAK,CAAC,OAA0C;QACpD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC;QAEzF,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACjE,CAAC;CACF"}
@@ -2,7 +2,8 @@ import * as v from "valibot";
2
2
  export declare const WebhookSignatureError: {
3
3
  Type: string;
4
4
  Empty: string;
5
+ InvalidHex: string;
5
6
  };
6
- export declare const WebhookSignature: v.SchemaWithPipe<readonly [v.StringSchema<string>, v.NonEmptyAction<string, string>, v.BrandAction<string, "WebhookSignature">]>;
7
+ export declare const WebhookSignature: v.SchemaWithPipe<readonly [v.StringSchema<string>, v.NonEmptyAction<string, string>, v.RegexAction<string, string>, v.BrandAction<string, "WebhookSignature">]>;
7
8
  export type WebhookSignatureType = v.InferOutput<typeof WebhookSignature>;
8
9
  //# sourceMappingURL=webhook-signature.vo.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"webhook-signature.vo.d.ts","sourceRoot":"","sources":["../src/webhook-signature.vo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAE7B,eAAO,MAAM,qBAAqB;IAChC,IAAI;IACJ,KAAK;CACN,CAAC;AAEF,eAAO,MAAM,gBAAgB,kIAK5B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
1
+ {"version":3,"file":"webhook-signature.vo.d.ts","sourceRoot":"","sources":["../src/webhook-signature.vo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAE7B,eAAO,MAAM,qBAAqB;IAChC,IAAI;IACJ,KAAK;IACL,UAAU;CACX,CAAC;AAKF,eAAO,MAAM,gBAAgB,iKAM5B,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,gBAAgB,CAAC,CAAC"}
@@ -2,8 +2,11 @@ import * as v from "valibot";
2
2
  export const WebhookSignatureError = {
3
3
  Type: "webhook.signature.type",
4
4
  Empty: "webhook.signature.empty",
5
+ InvalidHex: "webhook.signature.invalid.hex",
5
6
  };
6
- export const WebhookSignature = v.pipe(v.string(WebhookSignatureError.Type), v.nonEmpty(WebhookSignatureError.Empty),
7
+ // Hex chars allowed
8
+ const CHARS_WHITELIST = /^[a-fA-F0-9]+$/;
9
+ export const WebhookSignature = v.pipe(v.string(WebhookSignatureError.Type), v.nonEmpty(WebhookSignatureError.Empty), v.regex(CHARS_WHITELIST, WebhookSignatureError.InvalidHex),
7
10
  // Stryker disable next-line StringLiteral
8
11
  v.brand("WebhookSignature"));
9
12
  //# sourceMappingURL=webhook-signature.vo.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"webhook-signature.vo.js","sourceRoot":"","sources":["../src/webhook-signature.vo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAE7B,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,IAAI,EAAE,wBAAwB;IAC9B,KAAK,EAAE,yBAAyB;CACjC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CACpC,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,EACpC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,KAAK,CAAC;AACvC,0CAA0C;AAC1C,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAC5B,CAAC"}
1
+ {"version":3,"file":"webhook-signature.vo.js","sourceRoot":"","sources":["../src/webhook-signature.vo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAE7B,MAAM,CAAC,MAAM,qBAAqB,GAAG;IACnC,IAAI,EAAE,wBAAwB;IAC9B,KAAK,EAAE,yBAAyB;IAChC,UAAU,EAAE,+BAA+B;CAC5C,CAAC;AAEF,oBAAoB;AACpB,MAAM,eAAe,GAAG,gBAAgB,CAAC;AAEzC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CACpC,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,IAAI,CAAC,EACpC,CAAC,CAAC,QAAQ,CAAC,qBAAqB,CAAC,KAAK,CAAC,EACvC,CAAC,CAAC,KAAK,CAAC,eAAe,EAAE,qBAAqB,CAAC,UAAU,CAAC;AAC1D,0CAA0C;AAC1C,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAC5B,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"webhook-verifier-sha256.strategy.d.ts","sourceRoot":"","sources":["../src/webhook-verifier-sha256.strategy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,sCAAsC,CAAC;AAC5F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAE3E,KAAK,MAAM,GAAG;IAAE,uBAAuB,EAAE,+BAA+B,CAAA;CAAE,CAAC;AAE3E,qBAAa,6BAA8B,YAAW,uBAAuB;IAC/D,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAnC,YAA6B,MAAM,EAAE,MAAM,EAAI;IAE/C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,oBAAoB,GAAG,OAAO,CAK7D;CACF"}
1
+ {"version":3,"file":"webhook-verifier-sha256.strategy.d.ts","sourceRoot":"","sources":["../src/webhook-verifier-sha256.strategy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,sCAAsC,CAAC;AAC5F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAE3E,KAAK,MAAM,GAAG;IAAE,uBAAuB,EAAE,+BAA+B,CAAA;CAAE,CAAC;AAE3E,qBAAa,6BAA8B,YAAW,uBAAuB;IAC/D,OAAO,CAAC,QAAQ,CAAC,MAAM;IAAnC,YAA6B,MAAM,EAAE,MAAM,EAAI;IAE/C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,oBAAoB,GAAG,OAAO,CAM7D;CACF"}
@@ -5,10 +5,11 @@ export class WebhookVerifierSha256Strategy {
5
5
  this.config = config;
6
6
  }
7
7
  verify(body, signature) {
8
- const digest = this.config.WebhookSignatureCreator.create(body);
9
- if (digest.length !== signature.length)
8
+ const digest = Buffer.from(this.config.WebhookSignatureCreator.create(body));
9
+ const candidate = Buffer.from(signature);
10
+ if (digest.length !== candidate.length)
10
11
  return false;
11
- return timingSafeEqual(Buffer.from(digest), Buffer.from(signature));
12
+ return timingSafeEqual(digest, candidate);
12
13
  }
13
14
  }
14
15
  //# sourceMappingURL=webhook-verifier-sha256.strategy.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"webhook-verifier-sha256.strategy.js","sourceRoot":"","sources":["../src/webhook-verifier-sha256.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAO9C,MAAM,OAAO,6BAA6B;IACX,MAAM;IAAnC,YAA6B,MAAc;sBAAd,MAAM;IAAW,CAAC;IAE/C,MAAM,CAAC,IAAY,EAAE,SAA+B;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAEhE,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QACrD,OAAO,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACtE,CAAC;CACF"}
1
+ {"version":3,"file":"webhook-verifier-sha256.strategy.js","sourceRoot":"","sources":["../src/webhook-verifier-sha256.strategy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAO9C,MAAM,OAAO,6BAA6B;IACX,MAAM;IAAnC,YAA6B,MAAc;sBAAd,MAAM;IAAW,CAAC;IAE/C,MAAM,CAAC,IAAY,EAAE,SAA+B;QAClD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,uBAAuB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7E,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEzC,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QACrD,OAAO,eAAe,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC5C,CAAC;CACF"}
@@ -10,7 +10,7 @@ export type WoodchopperConfig = {
10
10
  level: LogLevelEnum;
11
11
  environment: NodeEnvironmentEnum;
12
12
  dispatcher: WoodchopperDispatcher;
13
- redactor?: RedactorStrategy;
13
+ redactor: RedactorStrategy;
14
14
  diagnostics?: WoodchopperDiagnosticsStrategy;
15
15
  };
16
16
  type Dependencies = {
@@ -1 +1 @@
1
- {"version":3,"file":"woodchopper.d.ts","sourceRoot":"","sources":["../src/woodchopper.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EACL,KAAK,aAAa,EAIlB,KAAK,UAAU,EACf,YAAY,EACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAEL,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACzB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,oCAAoC,CAAC;AACzF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAG/E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,aAAa,CAAC;IACnB,KAAK,EAAE,YAAY,CAAC;IACpB,WAAW,EAAE,mBAAmB,CAAC;IACjC,UAAU,EAAE,qBAAqB,CAAC;IAClC,QAAQ,CAAC,EAAE,gBAAgB,CAAC;IAC5B,WAAW,CAAC,EAAE,8BAA8B,CAAC;CAC9C,CAAC;AAEF,KAAK,YAAY,GAAG;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAYzC,qBAAa,WAAY,YAAW,UAAU,EAAE,uBAAuB;IAKnE,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IALvB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0B;IAEhD,YACmB,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,YAAY,EAQpC;IAED,OAAO,CAAC,GAAG;IA4CX,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAkD;IAC5E,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAiD;IACzE,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAiD;IACzE,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAiD;IACzE,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,CAAoD;IAClF,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAkD;IAC5E,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAkD;IAE5E,KAAK,SAKJ;IAED,QAAQ,IAAI,mBAAmB,CAE9B;CACF"}
1
+ {"version":3,"file":"woodchopper.d.ts","sourceRoot":"","sources":["../src/woodchopper.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EACL,KAAK,aAAa,EAIlB,KAAK,UAAU,EACf,YAAY,EACb,MAAM,eAAe,CAAC;AACvB,OAAO,EAEL,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACzB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,oCAAoC,CAAC;AACzF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAG/E,MAAM,MAAM,iBAAiB,GAAG;IAC9B,GAAG,EAAE,aAAa,CAAC;IACnB,KAAK,EAAE,YAAY,CAAC;IACpB,WAAW,EAAE,mBAAmB,CAAC;IACjC,UAAU,EAAE,qBAAqB,CAAC;IAClC,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,WAAW,CAAC,EAAE,8BAA8B,CAAC;CAC9C,CAAC;AAEF,KAAK,YAAY,GAAG;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AAYzC,qBAAa,WAAY,YAAW,UAAU,EAAE,uBAAuB;IAKnE,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IALvB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA0B;IAEhD,YACmB,MAAM,EAAE,iBAAiB,EACzB,IAAI,EAAE,YAAY,EAQpC;IAED,OAAO,CAAC,GAAG;IA0CX,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAkD;IAC5E,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAiD;IACzE,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAiD;IACzE,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,CAAiD;IACzE,OAAO,EAAE,UAAU,CAAC,SAAS,CAAC,CAAoD;IAClF,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAkD;IAC5E,KAAK,EAAE,UAAU,CAAC,OAAO,CAAC,CAAkD;IAE5E,KAAK,SAKJ;IAED,QAAQ,IAAI,mBAAmB,CAE9B;CACF"}
@@ -58,9 +58,7 @@ export class Woodchopper {
58
58
  }
59
59
  let withRedaction;
60
60
  try {
61
- withRedaction = this.config.redactor
62
- ? this.config.redactor.redact(withInjectedFields)
63
- : withInjectedFields;
61
+ withRedaction = this.config.redactor.redact(withInjectedFields);
64
62
  }
65
63
  catch (error) {
66
64
  this.stats.recordDropped();
@@ -1 +1 @@
1
- {"version":3,"file":"woodchopper.js","sourceRoot":"","sources":["../src/woodchopper.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"woodchopper.js","sourceRoot":"","sources":["../src/woodchopper.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bgord/bun",
3
- "version": "1.23.1",
3
+ "version": "1.23.3",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "author": "Bartosz Gordon",
package/readme.md CHANGED
@@ -207,6 +207,10 @@ src/
207
207
  ├── file-renamer-node.adapter.ts
208
208
  ├── file-renamer-noop.adapter.ts
209
209
  ├── file-renamer.port.ts
210
+ ├── file-type-detector-fixed.strategy.ts
211
+ ├── file-type-detector-magic-bytes.strategy.ts
212
+ ├── file-type-detector-text.strategy.ts
213
+ ├── file-type-detector.strategy.ts
210
214
  ├── file-uploader-hono.middleware.ts
211
215
  ├── file-uploader.middleware.ts
212
216
  ├── file-writer-forgiving.adapter.ts
@@ -615,6 +619,7 @@ src/
615
619
  ├── subject-segment-param.strategy.ts
616
620
  ├── subject-segment-path.strategy.ts
617
621
  ├── subject-segment-query.strategy.ts
622
+ ├── subject-segment-remote-ip.strategy.ts
618
623
  ├── subject-segment-request.strategy.ts
619
624
  ├── subject-segment-user.strategy.ts
620
625
  ├── temporary-file-absolute.adapter.ts
@@ -653,6 +658,7 @@ src/
653
658
  ├── weak-etag-extractor-param.strategy.ts
654
659
  ├── weak-etag-extractor.middleware.ts
655
660
  ├── weak-etag-extractor.strategy.ts
661
+ ├── webhook-body-builder-signed-headers.strategy.ts
656
662
  ├── webhook-body-builder-text.strategy.ts
657
663
  ├── webhook-body-builder.strategy.ts
658
664
  ├── webhook-id-extractor-header.strategy.ts
@@ -11,13 +11,18 @@ export class BetterAuthLogger {
11
11
  return {
12
12
  disabled: false,
13
13
  level: "debug",
14
- log: (level: LogLevel | undefined, message: string, ...args: ReadonlyArray<unknown>) => {
15
- const entry = { component: "infra", operation: "better-auth", message, metadata: { args } } as const;
14
+ log: (level: LogLevel | undefined, message: string, ...params: ReadonlyArray<unknown>) => {
15
+ const entry = {
16
+ component: "infra",
17
+ operation: "better-auth",
18
+ message,
19
+ metadata: { params },
20
+ } as const;
16
21
 
17
22
  if (level === "error") {
18
23
  this.deps.Logger.error({
19
24
  ...entry,
20
- error: args.find((arg) => arg instanceof Error) ?? new Error(message),
25
+ error: params.find((param) => param instanceof Error) ?? new Error(message),
21
26
  });
22
27
  } else if (level === "warn") {
23
28
  this.deps.Logger.warn(entry);
@@ -15,7 +15,12 @@ export class ErrorClassifierHttpExceptionHonoStrategy implements ErrorClassifier
15
15
  classify(error: unknown): Response | null {
16
16
  if (!(error instanceof HTTPException)) return null;
17
17
 
18
- if (!this.errors.has(error.message)) return error.getResponse();
18
+ if (!this.errors.has(error.message)) {
19
+ return Response.json(
20
+ { message: "general.unknown" },
21
+ { status: error.status, headers: error.res?.headers },
22
+ );
23
+ }
19
24
 
20
25
  return Response.json({ message: error.message }, { status: error.status, headers: error.res?.headers });
21
26
  }
@@ -1,4 +1,5 @@
1
1
  import type * as tools from "@bgord/tools";
2
+ import type { CommitShaValueType } from "./commit-sha-value.vo";
2
3
  import type { CorrelationIdType } from "./correlation-id.vo";
3
4
  import type { EventStreamType } from "./event-stream.vo";
4
5
  import type { UUIDType } from "./uuid.vo";
@@ -9,6 +10,7 @@ export type GenericEvent = {
9
10
  createdAt: number;
10
11
  stream: EventStreamType;
11
12
  revision?: tools.RevisionValueType;
13
+ commit: CommitShaValueType;
12
14
  name: string;
13
15
  version: number;
14
16
  payload: Record<string, unknown>;
@@ -0,0 +1,10 @@
1
+ import type * as tools from "@bgord/tools";
2
+ import type { FileTypeDetectorStrategy } from "./file-type-detector.strategy";
3
+
4
+ export class FileTypeDetectorFixedStrategy implements FileTypeDetectorStrategy {
5
+ constructor(private readonly mime: tools.Mime | null) {}
6
+
7
+ async detect(_file: File): Promise<tools.Mime | null> {
8
+ return this.mime;
9
+ }
10
+ }
@@ -0,0 +1,32 @@
1
+ // cSpell:ignore ftyp
2
+ import * as tools from "@bgord/tools";
3
+ import type { FileTypeDetectorStrategy } from "./file-type-detector.strategy";
4
+
5
+ type Signature = { mime: tools.Mime; offset: number; bytes: ReadonlyArray<number> };
6
+
7
+ const ASCII = (value: string): ReadonlyArray<number> => [...value].map((char) => char.charCodeAt(0));
8
+
9
+ const SIGNATURES: ReadonlyArray<Signature> = [
10
+ { mime: tools.Mimes.png.mime, offset: 0, bytes: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a] },
11
+ { mime: tools.Mimes.webp.mime, offset: 8, bytes: ASCII("WEBP") },
12
+ { mime: tools.Mimes.wav.mime, offset: 8, bytes: ASCII("WAVE") },
13
+ { mime: tools.Mimes.mp4.mime, offset: 4, bytes: ASCII("ftyp") },
14
+ { mime: tools.Mimes.pdf.mime, offset: 0, bytes: ASCII("%PDF-") },
15
+ { mime: tools.Mimes.zip.mime, offset: 0, bytes: [0x50, 0x4b, 0x03, 0x04] },
16
+ { mime: tools.Mimes.jpg.mime, offset: 0, bytes: [0xff, 0xd8, 0xff] },
17
+ { mime: tools.Mimes.tar.mime, offset: 0, bytes: [0x1f, 0x8b] },
18
+ ];
19
+
20
+ export class FileTypeDetectorMagicBytesStrategy implements FileTypeDetectorStrategy {
21
+ async detect(file: File): Promise<tools.Mime | null> {
22
+ const bytes = new Uint8Array(await file.slice(0, 12).arrayBuffer());
23
+
24
+ for (const signature of SIGNATURES) {
25
+ if (signature.bytes.every((byte, index) => bytes[signature.offset + index] === byte)) {
26
+ return signature.mime;
27
+ }
28
+ }
29
+
30
+ return null;
31
+ }
32
+ }
@@ -0,0 +1,25 @@
1
+ import type * as tools from "@bgord/tools";
2
+ import type { FileTypeDetectorStrategy } from "./file-type-detector.strategy";
3
+
4
+ const ALLOWED_CONTROL_BYTES = [0x09, 0x0a, 0x0c, 0x0d];
5
+
6
+ const isControlByte = (byte: number) =>
7
+ (byte < 0x20 && !ALLOWED_CONTROL_BYTES.includes(byte)) || byte === 0x7f;
8
+
9
+ export class FileTypeDetectorTextStrategy implements FileTypeDetectorStrategy {
10
+ constructor(private readonly mime: tools.Mime) {}
11
+
12
+ async detect(file: File): Promise<tools.Mime | null> {
13
+ const bytes = new Uint8Array(await file.slice(0, 1445).arrayBuffer());
14
+
15
+ if (bytes.length === 0) return null;
16
+ if (bytes.some(isControlByte)) return null;
17
+
18
+ const text = new TextDecoder().decode(bytes);
19
+
20
+ if (text.includes("\ufffd")) return null;
21
+ if (text.trimStart().startsWith("<")) return null;
22
+
23
+ return this.mime;
24
+ }
25
+ }
@@ -0,0 +1,5 @@
1
+ import type * as tools from "@bgord/tools";
2
+
3
+ export interface FileTypeDetectorStrategy {
4
+ detect(file: File): Promise<tools.Mime | null>;
5
+ }
@@ -1,14 +1,17 @@
1
1
  import { createMiddleware } from "hono/factory";
2
2
  import { HTTPException } from "hono/http-exception";
3
+ import type { FileTypeDetectorStrategy } from "./file-type-detector.strategy";
3
4
  import { type FileUploaderConfig, FileUploaderMiddleware } from "./file-uploader.middleware";
4
5
  import type { MiddlewareHonoPort } from "./middleware-hono.port";
5
6
  import { RequestContextHonoAdapter } from "./request-context-hono.adapter";
6
7
 
8
+ type Dependencies = { FileTypeDetector: FileTypeDetectorStrategy };
9
+
7
10
  export class FileUploaderHonoMiddleware implements MiddlewareHonoPort {
8
11
  private readonly middleware: FileUploaderMiddleware;
9
12
 
10
- constructor(config: FileUploaderConfig) {
11
- this.middleware = new FileUploaderMiddleware(config);
13
+ constructor(config: FileUploaderConfig, deps: Dependencies) {
14
+ this.middleware = new FileUploaderMiddleware(config, deps);
12
15
  }
13
16
 
14
17
  handle() {
@@ -1,8 +1,11 @@
1
1
  import * as tools from "@bgord/tools";
2
+ import type { FileTypeDetectorStrategy } from "./file-type-detector.strategy";
2
3
  import type { HasRequestForm } from "./request-context.port";
3
4
 
4
5
  export type FileUploaderConfig = { MimeRegistry: tools.MimeRegistry; maxSize: tools.Size; field: string };
5
6
 
7
+ type Dependencies = { FileTypeDetector: FileTypeDetectorStrategy };
8
+
6
9
  export const FileUploaderError = {
7
10
  MissingFile: "file.uploader.missing.file",
8
11
  EmptyFile: "file.uploader.empty.file",
@@ -15,7 +18,10 @@ export type FileValidationError = (typeof FileUploaderError)[keyof typeof FileUp
15
18
  export type FileValidationResult = { valid: true } | { valid: false; error: FileValidationError };
16
19
 
17
20
  export class FileUploaderMiddleware {
18
- constructor(private readonly config: FileUploaderConfig) {}
21
+ constructor(
22
+ private readonly config: FileUploaderConfig,
23
+ private readonly deps: Dependencies,
24
+ ) {}
19
25
 
20
26
  async validate(context: HasRequestForm): Promise<FileValidationResult> {
21
27
  const form = await context.request.form();
@@ -28,8 +34,9 @@ export class FileUploaderMiddleware {
28
34
 
29
35
  if (size.isGreaterThan(this.config.maxSize)) return { valid: false, error: FileUploaderError.SizeLimit };
30
36
 
31
- // TODO: MIME spoofing possible by reading client-supplied file.type
32
- const mime = tools.Mime.fromString(file.type);
37
+ const mime = await this.deps.FileTypeDetector.detect(file);
38
+
39
+ if (!mime) return { valid: false, error: FileUploaderError.InvalidMime };
33
40
 
34
41
  if (!this.config.MimeRegistry.hasMime(mime)) {
35
42
  return { valid: false, error: FileUploaderError.InvalidMime };
@@ -4,14 +4,11 @@ export const HCaptchaServiceError = { Error: "hcaptcha.service.error" };
4
4
 
5
5
  type HcaptchaTokenType = string;
6
6
 
7
- export type HCaptchaVerificationResult = { success: boolean };
7
+ export type HCaptchaVerificationResult = { success: boolean; hostname?: string };
8
8
 
9
9
  export class HCaptchaService {
10
- async verify(
11
- secretKey: HCaptchaSecretKeyType,
12
- token: HcaptchaTokenType,
13
- ): Promise<HCaptchaVerificationResult> {
14
- const body = new URLSearchParams({ secret: secretKey, response: token });
10
+ async verify(secret: HCaptchaSecretKeyType, token: HcaptchaTokenType): Promise<HCaptchaVerificationResult> {
11
+ const body = new URLSearchParams({ secret, response: token });
15
12
 
16
13
  const response = await fetch("https://hcaptcha.com/siteverify", {
17
14
  method: "POST",
@@ -37,7 +37,7 @@ export type HealthcheckDependencies = {
37
37
  export type HealthcheckConfig = {
38
38
  Env: NodeEnvironmentEnum;
39
39
  prerequisites: ReadonlyArray<Prerequisite>;
40
- redactor?: RedactorStrategy;
40
+ redactor: RedactorStrategy;
41
41
  };
42
42
 
43
43
  const self = new Prerequisite("self", new PrerequisiteVerifierSelfAdapter());
@@ -111,7 +111,7 @@ export class HealthcheckHandler {
111
111
 
112
112
  return {
113
113
  label: prerequisite.label,
114
- outcome: this.config.redactor ? this.config.redactor.redact(outcome) : outcome,
114
+ outcome: this.config.redactor.redact(outcome),
115
115
  ms: stopwatch.stop().ms,
116
116
  };
117
117
  }),
package/src/index.ts CHANGED
@@ -180,6 +180,10 @@ export * from "./file-renamer.port";
180
180
  export * from "./file-renamer-node.adapter";
181
181
  export * from "./file-renamer-node-forgiving.adapter";
182
182
  export * from "./file-renamer-noop.adapter";
183
+ export * from "./file-type-detector.strategy";
184
+ export * from "./file-type-detector-fixed.strategy";
185
+ export * from "./file-type-detector-magic-bytes.strategy";
186
+ export * from "./file-type-detector-text.strategy";
183
187
  export * from "./file-uploader.middleware";
184
188
  export * from "./file-uploader-hono.middleware";
185
189
  export * from "./file-writer.adapter";
@@ -537,6 +541,7 @@ export * from "./subject-segment-method.strategy";
537
541
  export * from "./subject-segment-param.strategy";
538
542
  export * from "./subject-segment-path.strategy";
539
543
  export * from "./subject-segment-query.strategy";
544
+ export * from "./subject-segment-remote-ip.strategy";
540
545
  export * from "./subject-segment-request.strategy";
541
546
  export * from "./subject-segment-user.strategy";
542
547
  export * from "./temporary-file.port";
@@ -576,6 +581,7 @@ export * from "./weak-etag-extractor-header.strategy";
576
581
  export * from "./weak-etag-extractor-hono.middleware";
577
582
  export * from "./weak-etag-extractor-param.strategy";
578
583
  export * from "./webhook-body-builder.strategy";
584
+ export * from "./webhook-body-builder-signed-headers.strategy";
579
585
  export * from "./webhook-body-builder-text.strategy";
580
586
  export * from "./webhook-id.vo";
581
587
  export * from "./webhook-id-extractor.strategy";
@@ -23,7 +23,6 @@ export class LanguageDetectorHeaderStrategy<T extends tools.LanguageType>
23
23
  quality: Number(quality.replace("q=", "")),
24
24
  };
25
25
  })
26
- // Quality of 0 means the language is explicitly not acceptable
27
26
  .filter((candidate) => candidate.quality > 0)
28
27
  .sort((first, second) => second.quality - first.quality)
29
28
  .map((candidate) => candidate.language);
@@ -3,8 +3,12 @@ import {
3
3
  PrerequisiteVerificationOutcome,
4
4
  type PrerequisiteVerificationResult,
5
5
  } from "./prerequisite-verifier.port";
6
+ import type { RedactorStrategy } from "./redactor.strategy";
6
7
 
7
- export type ReadinessConfig = { prerequisites: ReadonlyArray<Prerequisite> };
8
+ export type ReadinessConfig = {
9
+ prerequisites: ReadonlyArray<Prerequisite>;
10
+ redactor: RedactorStrategy;
11
+ };
8
12
 
9
13
  export enum ReadinessStatusCode {
10
14
  Ready = 200,
@@ -28,7 +32,7 @@ export class ReadinessHandler {
28
32
  const details = await Promise.all(
29
33
  prerequisites.map(async (prerequisite) => ({
30
34
  label: prerequisite.label,
31
- outcome: await prerequisite.build().verify(),
35
+ outcome: this.config.redactor.redact(await prerequisite.build().verify()),
32
36
  })),
33
37
  );
34
38
 
@@ -37,7 +37,10 @@ export class RemoteFileStorageDiskAdapter implements RemoteFileStoragePort {
37
37
  const parts = key.split("/");
38
38
  const filename = tools.Filename.fromString(parts.pop() as string);
39
39
 
40
- const directory = v.parse(tools.DirectoryPathAbsoluteSchema, `${this.config.root}/${parts.join("/")}`);
40
+ if (parts.length === 0) return tools.FilePathAbsolute.fromPartsSafe(this.config.root, filename);
41
+
42
+ const base = this.config.root === "/" ? "" : this.config.root;
43
+ const directory = v.parse(tools.DirectoryPathAbsoluteSchema, `${base}/${parts.join("/")}`);
41
44
 
42
45
  return tools.FilePathAbsolute.fromPartsSafe(directory, filename);
43
46
  }
@@ -34,9 +34,13 @@ export class SealerAesGcmAdapter implements SealerPort {
34
34
 
35
35
  const key = await this.deps.CryptoKeyProvider.get();
36
36
 
37
- const encrypted = Uint8Array.fromBase64(value.slice(SealerAesGcmAdapter.PREFIX.length));
38
- const plaintext = await CryptoAesGcm.decrypt(key, encrypted);
37
+ try {
38
+ const encrypted = Uint8Array.fromBase64(value.slice(SealerAesGcmAdapter.PREFIX.length));
39
+ const plaintext = await CryptoAesGcm.decrypt(key, encrypted);
39
40
 
40
- return JSON.parse(new TextDecoder().decode(plaintext));
41
+ return JSON.parse(new TextDecoder().decode(plaintext));
42
+ } catch {
43
+ throw new Error(SealerAesGcmAdapterError.InvalidPayload);
44
+ }
41
45
  }
42
46
  }
@@ -1,6 +1,5 @@
1
1
  import * as v from "valibot";
2
2
  import { ALL_BOTS } from "./bots.vo";
3
- import { Client } from "./client.vo";
4
3
  import type { RequestContext } from "./request-context.port";
5
4
  import type { SecurityRuleStrategy } from "./security-rule.strategy";
6
5
  import { SecurityRuleName, type SecurityRuleNameType } from "./security-rule-name.vo";
@@ -9,9 +8,11 @@ export class SecurityRuleUserAgentStrategy implements SecurityRuleStrategy {
9
8
  constructor(private readonly blacklist: ReadonlyArray<string> = ALL_BOTS) {}
10
9
 
11
10
  async isViolated(context: RequestContext): Promise<boolean> {
12
- const client = Client.fromParts(context.identity.ip(), context.identity.ua());
11
+ const ua = context.identity.ua()?.toLowerCase();
13
12
 
14
- return this.blacklist.some((bot) => client.hasSameUa(Client.fromParts(undefined, bot)));
13
+ if (!ua) return false;
14
+
15
+ return this.blacklist.some((bot) => ua.includes(bot.toLowerCase()));
15
16
  }
16
17
 
17
18
  get name(): SecurityRuleNameType {
@@ -7,25 +7,31 @@ import type { SecurityRuleStrategy } from "./security-rule.strategy";
7
7
  import { SecurityRuleName, type SecurityRuleNameType } from "./security-rule-name.vo";
8
8
  import { SubjectRequestResolver } from "./subject-request-resolver.vo";
9
9
  import { SubjectSegmentFixedStrategy } from "./subject-segment-fixed.strategy";
10
- import { SubjectSegmentIpStrategy } from "./subject-segment-ip.strategy";
10
+ import type { SubjectSegmentRequestStrategy } from "./subject-segment-request.strategy";
11
11
 
12
12
  type Dependencies = { CacheRepository: CacheRepositoryPort; HashContent: HashContentStrategy };
13
- type Config = { threshold: tools.IntegerPositiveType };
13
+ type Config = {
14
+ threshold: tools.IntegerPositiveType;
15
+ segments: ReadonlyArray<SubjectSegmentRequestStrategy>;
16
+ };
14
17
 
15
18
  export class SecurityRuleViolationThresholdStrategy implements SecurityRuleStrategy {
19
+ private readonly resolver: SubjectRequestResolver;
20
+
16
21
  constructor(
17
22
  private readonly rule: SecurityRuleStrategy,
18
23
  private readonly config: Config,
19
24
  private readonly deps: Dependencies,
20
- ) {}
25
+ ) {
26
+ this.resolver = new SubjectRequestResolver(
27
+ [new SubjectSegmentFixedStrategy(this.name), ...this.config.segments],
28
+ this.deps,
29
+ );
30
+ }
21
31
 
22
32
  // Best-effort increment, occasional lost increments are acceptable for concurrent requests.
23
33
  async isViolated(context: RequestContext): Promise<boolean> {
24
- const resolver = new SubjectRequestResolver(
25
- [new SubjectSegmentFixedStrategy(this.name), new SubjectSegmentIpStrategy()],
26
- this.deps,
27
- );
28
- const subject = await resolver.resolve(context);
34
+ const subject = await this.resolver.resolve(context);
29
35
 
30
36
  const violated = await this.rule.isViolated(context);
31
37
 
@@ -12,9 +12,11 @@ export class ShieldBodyLimitStrategy {
12
12
  evaluate(context: HasRequestHeader): boolean {
13
13
  const header = context.request.header("content-length");
14
14
 
15
+ if (header === undefined) return true;
16
+
15
17
  const contentLength = v.safeParse(tools.SizeBytes, Number(header));
16
18
 
17
- if (!contentLength.success) return true;
19
+ if (!contentLength.success) return false;
18
20
 
19
21
  const size = tools.Size.fromBytes(contentLength.output);
20
22
 
@@ -18,8 +18,13 @@ export class ShieldHcaptchaLocalHonoStrategy implements MiddlewareHonoPort {
18
18
 
19
19
  private static readonly TOKEN_LOCAL = "10000000-aaaa-bbbb-cccc-000000000001";
20
20
 
21
+ private static readonly HOSTNAME_LOCAL = "local-pass";
22
+
21
23
  constructor() {
22
- this.strategy = new ShieldHcaptchaStrategy(ShieldHcaptchaLocalHonoStrategy.SECRET_KEY_LOCAL);
24
+ this.strategy = new ShieldHcaptchaStrategy({
25
+ secretKey: ShieldHcaptchaLocalHonoStrategy.SECRET_KEY_LOCAL,
26
+ hostname: ShieldHcaptchaLocalHonoStrategy.HOSTNAME_LOCAL,
27
+ });
23
28
  }
24
29
 
25
30
  handle(): MiddlewareHandler {
@@ -1,15 +1,18 @@
1
1
  import type { MiddlewareHandler } from "hono";
2
2
  import { HTTPException } from "hono/http-exception";
3
- import type { HCaptchaSecretKeyType } from "./hcaptcha-secret-key.vo";
4
3
  import type { MiddlewareHonoPort } from "./middleware-hono.port";
5
4
  import { RequestContextHonoAdapter } from "./request-context-hono.adapter";
6
- import { ShieldHcaptchaStrategy, ShieldHcaptchaStrategyError } from "./shield-hcaptcha.strategy";
5
+ import {
6
+ type ShieldHcaptchaConfig,
7
+ ShieldHcaptchaStrategy,
8
+ ShieldHcaptchaStrategyError,
9
+ } from "./shield-hcaptcha.strategy";
7
10
 
8
11
  export class ShieldHcaptchaHonoStrategy implements MiddlewareHonoPort {
9
12
  private readonly strategy: ShieldHcaptchaStrategy;
10
13
 
11
- constructor(secretKey: HCaptchaSecretKeyType) {
12
- this.strategy = new ShieldHcaptchaStrategy(secretKey);
14
+ constructor(config: ShieldHcaptchaConfig) {
15
+ this.strategy = new ShieldHcaptchaStrategy(config);
13
16
  }
14
17
 
15
18
  handle(): MiddlewareHandler {