@bgord/bun 1.8.2 → 1.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bgord/bun",
3
- "version": "1.8.2",
3
+ "version": "1.8.4",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "author": "Bartosz Gordon",
package/readme.md CHANGED
@@ -233,6 +233,10 @@ src/
233
233
  │   ├── passage-of-time-hourly.service.ts
234
234
  │   └── passage-of-time-minute.service.ts
235
235
  ├── node-env.vo.ts
236
+ ├── nonce-provider-crypto.adapter.ts
237
+ ├── nonce-provider-noop.adapter.ts
238
+ ├── nonce-provider.port.ts
239
+ ├── nonce-value.vo.ts
236
240
  ├── pdf-generator-noop.adapter.ts
237
241
  ├── pdf-generator.port.ts
238
242
  ├── port.vo.ts
package/src/index.ts CHANGED
@@ -168,6 +168,10 @@ export * as History from "./modules/history";
168
168
  export * as Preferences from "./modules/preferences";
169
169
  export * as System from "./modules/system";
170
170
  export * from "./node-env.vo";
171
+ export * from "./nonce-provider.port";
172
+ export * from "./nonce-provider-crypto.adapter";
173
+ export * from "./nonce-provider-noop.adapter";
174
+ export * from "./nonce-value.vo";
171
175
  export * from "./pdf-generator.port";
172
176
  export * from "./pdf-generator-noop.adapter";
173
177
  export * from "./port.vo";
@@ -0,0 +1,16 @@
1
+ import type { NonceProviderPort } from "./nonce-provider.port";
2
+ import { NonceValue } from "./nonce-value.vo";
3
+
4
+ export class NonceProviderCryptoAdapter implements NonceProviderPort {
5
+ generate() {
6
+ const buffer = new Uint8Array(8);
7
+
8
+ crypto.getRandomValues(buffer);
9
+
10
+ const nonce = Array.from(buffer)
11
+ .map((byte) => byte.toString(16).padStart(2, "0"))
12
+ .join("");
13
+
14
+ return NonceValue.parse(nonce);
15
+ }
16
+ }
@@ -0,0 +1,8 @@
1
+ import type { NonceProviderPort } from "./nonce-provider.port";
2
+ import { NonceValue } from "./nonce-value.vo";
3
+
4
+ export class NonceProviderNoopAdapter implements NonceProviderPort {
5
+ generate() {
6
+ return NonceValue.parse("0000000000000000");
7
+ }
8
+ }
@@ -0,0 +1,5 @@
1
+ import type { NonceValueType } from "./nonce-value.vo";
2
+
3
+ export interface NonceProviderPort {
4
+ generate(): NonceValueType;
5
+ }
@@ -0,0 +1,18 @@
1
+ import { z } from "zod/v4";
2
+
3
+ export const NonceValueError = {
4
+ Type: "nonce.value.type",
5
+ InvalidHex: "nonce.value.invalid.hex",
6
+ };
7
+
8
+ // 16 hex chars allowed
9
+ const CHARS_WHITELIST = /^[a-fA-F0-9]{16}$/;
10
+
11
+ // Stryker disable all
12
+ export const NonceValue = z
13
+ // Stryker restore all
14
+ .string(NonceValueError.Type)
15
+ .regex(CHARS_WHITELIST, NonceValueError.InvalidHex)
16
+ .brand("NonceValue");
17
+
18
+ export type NonceValueType = z.infer<typeof NonceValue>;
@@ -42,16 +42,31 @@ export class Setup {
42
42
  MaintenanceMode.build(overrides?.maintenanceMode),
43
43
  secureHeaders({
44
44
  crossOriginResourcePolicy: "same-origin",
45
- contentSecurityPolicy: {
46
- defaultSrc: ["'none'"],
47
- scriptSrc: ["'self'"],
48
- styleSrc: ["'self'"],
49
- imgSrc: ["'self'"],
50
- },
45
+ crossOriginOpenerPolicy: "same-origin",
46
+ crossOriginEmbedderPolicy: "require-corp",
47
+ referrerPolicy: "no-referrer",
48
+ xContentTypeOptions: "nosniff",
49
+ strictTransportSecurity: `max-age=${tools.Duration.Days(180).seconds}; includeSubDomains`,
51
50
  }),
52
51
  bodyLimit({ maxSize: BODY_LIMIT_MAX_SIZE.toBytes() }),
53
52
  ApiVersion.build({ Clock: deps.Clock, FileReaderJson: deps.FileReaderJson }),
54
- cors(overrides?.cors),
53
+ cors({
54
+ // Stryker disable all
55
+ origin: (origin, c) => {
56
+ // server-to-server, curl, same-origin navigation
57
+ if (!origin) return undefined;
58
+
59
+ // same-origin fetch
60
+ if (origin === new URL(c.req.url).origin) return origin;
61
+
62
+ // deny cross-origin
63
+ return null;
64
+ },
65
+ // Stryker restore all
66
+ credentials: false,
67
+ maxAge: tools.Duration.Minutes(10).seconds,
68
+ ...overrides?.cors,
69
+ }),
55
70
  languageDetector({
56
71
  supportedLanguages: Object.keys(deps.I18n.supportedLanguages),
57
72
  fallbackLanguage: deps.I18n.defaultLanguage,