@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
@@ -6,10 +6,12 @@ export const ShieldHcaptchaStrategyError = { Rejected: "shield.hcaptcha.rejected
6
6
 
7
7
  export const ShieldHcaptchaStrategyField = "h-captcha-response";
8
8
 
9
+ export type ShieldHcaptchaConfig = { secretKey: HCaptchaSecretKeyType; hostname: string };
10
+
9
11
  export class ShieldHcaptchaStrategy {
10
12
  private readonly hcaptcha = new HCaptchaService();
11
13
 
12
- constructor(private readonly secretKey: HCaptchaSecretKeyType) {}
14
+ constructor(private readonly config: ShieldHcaptchaConfig) {}
13
15
 
14
16
  async evaluate(context: HasRequestForm & HasRequestJson): Promise<boolean> {
15
17
  try {
@@ -23,9 +25,12 @@ export class ShieldHcaptchaStrategy {
23
25
 
24
26
  if (!token) return false;
25
27
 
26
- const result = await this.hcaptcha.verify(this.secretKey, token);
28
+ const result = await this.hcaptcha.verify(this.config.secretKey, token);
29
+
30
+ if (!result.success) return false;
31
+ if (result.hostname !== this.config.hostname) return false;
27
32
 
28
- return result.success;
33
+ return true;
29
34
  } catch {
30
35
  return false;
31
36
  }
@@ -4,8 +4,13 @@ import * as v from "valibot";
4
4
  import type { RecaptchaSecretKeyType } from "./recaptcha-secret-key.vo";
5
5
  import type { HasIdentityIp, HasRequestForm, HasRequestJson } from "./request-context.port";
6
6
 
7
- export type ShieldRecaptchaConfig = { secretKey: RecaptchaSecretKeyType; threshold?: number };
8
- export type RecaptchaResult = { success: boolean; score: number };
7
+ export type ShieldRecaptchaConfig = {
8
+ secretKey: RecaptchaSecretKeyType;
9
+ hostname: string;
10
+ action?: string;
11
+ threshold?: number;
12
+ };
13
+ export type RecaptchaResult = { success: boolean; score: number; hostname?: string; action?: string };
9
14
 
10
15
  export const ShieldRecaptchaStrategyError = { Rejected: "shield.recaptcha.rejected" };
11
16
 
@@ -51,6 +56,8 @@ export class ShieldRecaptchaStrategy {
51
56
 
52
57
  if (!result.success) return false;
53
58
  if (typeof result.score !== "number" || result.score < threshold) return false;
59
+ if (result.hostname !== this.config.hostname) return false;
60
+ if (this.config.action !== undefined && result.action !== this.config.action) return false;
54
61
 
55
62
  return true;
56
63
  } catch {
@@ -0,0 +1,14 @@
1
+ import type { HasIdentityRemoteIp } from "./request-context.port";
2
+ import {
3
+ SubjectSegmentRequestEmpty,
4
+ type SubjectSegmentRequestStrategy,
5
+ type SubjectSegmentType,
6
+ } from "./subject-segment-request.strategy";
7
+
8
+ export class SubjectSegmentRemoteIpStrategy implements SubjectSegmentRequestStrategy {
9
+ readonly label = "remote-ip";
10
+
11
+ create(context: HasIdentityRemoteIp): SubjectSegmentType {
12
+ return context.identity.remoteIp() ?? SubjectSegmentRequestEmpty;
13
+ }
14
+ }
@@ -1,5 +1,6 @@
1
1
  import type {
2
2
  HasIdentityIp,
3
+ HasIdentityRemoteIp,
3
4
  HasIdentityUserId,
4
5
  HasRequestCookie,
5
6
  HasRequestHeader,
@@ -21,6 +22,7 @@ type RequestContextCapabilities = HasRequestCookie &
21
22
  HasRequestQueries &
22
23
  HasRequestParam &
23
24
  HasIdentityIp &
25
+ HasIdentityRemoteIp &
24
26
  HasIdentityUserId;
25
27
 
26
28
  export interface SubjectSegmentRequestStrategy {
@@ -0,0 +1,12 @@
1
+ import type { HasRequestHeader, HasRequestText } from "./request-context.port";
2
+ import type { WebhookBodyBuilderStrategy } from "./webhook-body-builder.strategy";
3
+
4
+ export class WebhookBodyBuilderSignedHeadersStrategy implements WebhookBodyBuilderStrategy {
5
+ constructor(private readonly headers: ReadonlyArray<string>) {}
6
+
7
+ async build(context: HasRequestHeader & HasRequestText): Promise<string> {
8
+ const headers = this.headers.map((name) => [name, context.request.header(name) ?? null]);
9
+
10
+ return JSON.stringify([headers, await context.request.text()]);
11
+ }
12
+ }
@@ -3,11 +3,16 @@ import * as v from "valibot";
3
3
  export const WebhookSignatureError = {
4
4
  Type: "webhook.signature.type",
5
5
  Empty: "webhook.signature.empty",
6
+ InvalidHex: "webhook.signature.invalid.hex",
6
7
  };
7
8
 
9
+ // Hex chars allowed
10
+ const CHARS_WHITELIST = /^[a-fA-F0-9]+$/;
11
+
8
12
  export const WebhookSignature = v.pipe(
9
13
  v.string(WebhookSignatureError.Type),
10
14
  v.nonEmpty(WebhookSignatureError.Empty),
15
+ v.regex(CHARS_WHITELIST, WebhookSignatureError.InvalidHex),
11
16
  // Stryker disable next-line StringLiteral
12
17
  v.brand("WebhookSignature"),
13
18
  );
@@ -9,9 +9,10 @@ export class WebhookVerifierSha256Strategy implements WebhookVerifierStrategy {
9
9
  constructor(private readonly config: Config) {}
10
10
 
11
11
  verify(body: string, signature: WebhookSignatureType): boolean {
12
- const digest = this.config.WebhookSignatureCreator.create(body);
12
+ const digest = Buffer.from(this.config.WebhookSignatureCreator.create(body));
13
+ const candidate = Buffer.from(signature);
13
14
 
14
- if (digest.length !== signature.length) return false;
15
- return timingSafeEqual(Buffer.from(digest), Buffer.from(signature));
15
+ if (digest.length !== candidate.length) return false;
16
+ return timingSafeEqual(digest, candidate);
16
17
  }
17
18
  }
@@ -24,7 +24,7 @@ export type WoodchopperConfig = {
24
24
  level: LogLevelEnum;
25
25
  environment: NodeEnvironmentEnum;
26
26
  dispatcher: WoodchopperDispatcher;
27
- redactor?: RedactorStrategy;
27
+ redactor: RedactorStrategy;
28
28
  diagnostics?: WoodchopperDiagnosticsStrategy;
29
29
  };
30
30
 
@@ -88,9 +88,7 @@ export class Woodchopper implements LoggerPort, LoggerStatsProviderPort {
88
88
 
89
89
  let withRedaction: LoggerEntry;
90
90
  try {
91
- withRedaction = this.config.redactor
92
- ? this.config.redactor.redact(withInjectedFields)
93
- : withInjectedFields;
91
+ withRedaction = this.config.redactor.redact(withInjectedFields);
94
92
  } catch (error) {
95
93
  this.stats.recordDropped();
96
94
  this.config.diagnostics?.handle({ kind: "redaction", error });