@exabugs/dynamodb-client 1.5.3 → 1.6.1

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 (43) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/server/handler.cjs +3 -3
  3. package/dist/server/media/magicBytes.d.ts.map +1 -1
  4. package/dist/server/media/magicBytes.js +17 -14
  5. package/dist/server/media/magicBytes.js.map +1 -1
  6. package/dist/server/media/media-handler.d.ts.map +1 -1
  7. package/dist/server/media/media-handler.js +38 -4
  8. package/dist/server/media/media-handler.js.map +1 -1
  9. package/dist/server/media/metadata.d.ts +29 -0
  10. package/dist/server/media/metadata.d.ts.map +1 -0
  11. package/dist/server/media/metadata.js +57 -0
  12. package/dist/server/media/metadata.js.map +1 -0
  13. package/dist/server/media/presign.d.ts.map +1 -1
  14. package/dist/server/media/presign.js +18 -1
  15. package/dist/server/media/presign.js.map +1 -1
  16. package/dist/server/media/process-handler-dlq.d.ts +0 -13
  17. package/dist/server/media/process-handler-dlq.d.ts.map +1 -1
  18. package/dist/server/media/process-handler-dlq.js +49 -7
  19. package/dist/server/media/process-handler-dlq.js.map +1 -1
  20. package/dist/server/media/process-handler.d.ts.map +1 -1
  21. package/dist/server/media/process-handler.js +40 -25
  22. package/dist/server/media/process-handler.js.map +1 -1
  23. package/dist/server/media/types.d.ts +1 -1
  24. package/dist/server/media/types.d.ts.map +1 -1
  25. package/dist/server/media/upload-handler.d.ts +50 -0
  26. package/dist/server/media/upload-handler.d.ts.map +1 -0
  27. package/dist/server/media/upload-handler.js +115 -0
  28. package/dist/server/media/upload-handler.js.map +1 -0
  29. package/dist/server/media-handler.cjs +27 -3
  30. package/dist/server/media-handler.cjs.map +2 -2
  31. package/dist/server/media-process-handler-dlq.cjs +25496 -13553
  32. package/dist/server/media-process-handler-dlq.cjs.map +4 -4
  33. package/dist/server/media-process-handler.cjs +648 -536
  34. package/dist/server/media-process-handler.cjs.map +4 -4
  35. package/dist/sharp-layer.zip +0 -0
  36. package/package.json +5 -1
  37. package/terraform/main.tf +2 -0
  38. package/terraform/media/README.md +4 -1
  39. package/terraform/media/main.tf +86 -13
  40. package/terraform/media/variables.tf +33 -0
  41. package/terraform/modules/parameter-store/README.md +2 -0
  42. package/terraform/modules/parameter-store/main.tf +9 -1
  43. package/terraform/modules/parameter-store/variables.tf +6 -0
package/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.6.1] - 2026-10-11
11
+
12
+ ### Fixed
13
+
14
+ - `terraform/modules/parameter-store`: **新規環境への初回デプロイで `terraform plan` が `Invalid count argument` で失敗する不具合を修正**(1.5.3〜1.6.0 が対象)。IAM認証URLのパラメータの個数を、同じ apply で作成する Function URL の属性(初回は未確定)の有無で決めていたため。確定している真偽値の変数 `create_records_iam_url_parameter` を追加し、トップの `terraform/main.tf` は `true` を渡す。変数を渡さない既存の呼び出し元は従来どおりの動作
15
+
10
16
  ## [1.5.3] - 2026-10-04
11
17
 
12
18
  ### Fixed
@@ -1,5 +1,5 @@
1
- // @exabugs/dynamodb-client v1.5.3
2
- // Built: 2026-10-04T14:32:33.468Z
1
+ // @exabugs/dynamodb-client v1.6.1
2
+ // Built: 2026-10-11T12:45:55.244Z
3
3
  "use strict";
4
4
  var __create = Object.create;
5
5
  var __defProp = Object.defineProperty;
@@ -38701,7 +38701,7 @@ async function handler(event) {
38701
38701
  return createCorsResponse(HTTP_STATUS.OK);
38702
38702
  }
38703
38703
  if (event.requestContext.http.method === "GET" && event.requestContext.http.path === "/version") {
38704
- const version = "1.5.3";
38704
+ const version = "1.6.1";
38705
38705
  return createSuccessResponse({ version, timestamp: (/* @__PURE__ */ new Date()).toISOString() }, requestId);
38706
38706
  }
38707
38707
  if (event.requestContext.http.method !== "POST") {
@@ -1 +1 @@
1
- {"version":3,"file":"magicBytes.d.ts","sourceRoot":"","sources":["../../../src/server/media/magicBytes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAiBH;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAW7E;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAE/D"}
1
+ {"version":3,"file":"magicBytes.d.ts","sourceRoot":"","sources":["../../../src/server/media/magicBytes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAmCH;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAO7E;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAE/D"}
@@ -9,17 +9,25 @@
9
9
  * 別の対策で守るため、ここでは照合不要(常に一致扱い)とする。
10
10
  */
11
11
  const SIGNATURES = {
12
- 'image/jpeg': [{ bytes: [0xff, 0xd8, 0xff] }],
13
- 'image/png': [{ bytes: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a] }],
12
+ 'image/jpeg': [[{ bytes: [0xff, 0xd8, 0xff] }]],
13
+ 'image/png': [[{ bytes: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a] }]],
14
14
  'image/gif': [
15
- { bytes: [0x47, 0x49, 0x46, 0x38, 0x37, 0x61] },
16
- { bytes: [0x47, 0x49, 0x46, 0x38, 0x39, 0x61] },
15
+ [{ bytes: [0x47, 0x49, 0x46, 0x38, 0x37, 0x61] }], // GIF87a
16
+ [{ bytes: [0x47, 0x49, 0x46, 0x38, 0x39, 0x61] }], // GIF89a
17
17
  ],
18
18
  'image/webp': [
19
- { bytes: [0x52, 0x49, 0x46, 0x46] }, // "RIFF"
20
- { bytes: [0x57, 0x45, 0x42, 0x50], offset: 8 }, // "WEBP"
19
+ [
20
+ { bytes: [0x52, 0x49, 0x46, 0x46] }, // "RIFF"
21
+ { bytes: [0x57, 0x45, 0x42, 0x50], offset: 8 }, // "WEBP"
22
+ ],
21
23
  ],
22
24
  };
25
+ function matchesCondition(sig, buffer) {
26
+ const offset = sig.offset ?? 0;
27
+ if (buffer.length < offset + sig.bytes.length)
28
+ return false;
29
+ return sig.bytes.every((byte, i) => buffer[offset + i] === byte);
30
+ }
23
31
  /**
24
32
  * 申告されたcontentTypeと実バイト列が一致するか検証する。
25
33
  *
@@ -27,16 +35,11 @@ const SIGNATURES = {
27
35
  * (画像として処理されないため)常に一致扱いとする。
28
36
  */
29
37
  export function verifyMagicBytes(contentType, buffer) {
30
- const signatures = SIGNATURES[contentType];
31
- if (!signatures) {
38
+ const candidates = SIGNATURES[contentType];
39
+ if (!candidates) {
32
40
  return true;
33
41
  }
34
- return signatures.every((sig) => {
35
- const offset = sig.offset ?? 0;
36
- if (buffer.length < offset + sig.bytes.length)
37
- return false;
38
- return sig.bytes.every((byte, i) => buffer[offset + i] === byte);
39
- });
42
+ return candidates.some((conditions) => conditions.every((sig) => matchesCondition(sig, buffer)));
40
43
  }
41
44
  /**
42
45
  * sharpで処理してよい「画像」として扱うかどうか。
@@ -1 +1 @@
1
- {"version":3,"file":"magicBytes.js","sourceRoot":"","sources":["../../../src/server/media/magicBytes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,MAAM,UAAU,GAAqC;IACnD,YAAY,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;IAC7C,WAAW,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;IAC1E,WAAW,EAAE;QACX,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;QAC/C,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;KAChD;IACD,YAAY,EAAE;QACZ,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS;QAC9C,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,SAAS;KAC1D;CACF,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAmB,EAAE,MAAc;IAClE,MAAM,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAC3C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QAC9B,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;QAC/B,IAAI,MAAM,CAAC,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO,KAAK,CAAC;QAC5D,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB;IACpD,OAAO,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,WAAW,KAAK,eAAe,CAAC;AAC7E,CAAC"}
1
+ {"version":3,"file":"magicBytes.js","sourceRoot":"","sources":["../../../src/server/media/magicBytes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAcH,MAAM,UAAU,GAAyC;IACvD,YAAY,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/C,WAAW,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5E,WAAW,EAAE;QACX,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,SAAS;QAC5D,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,SAAS;KAC7D;IACD,YAAY,EAAE;QACZ;YACE,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS;YAC9C,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,SAAS;SAC1D;KACF;CACF,CAAC;AAEF,SAAS,gBAAgB,CAAC,GAAmB,EAAE,MAAc;IAC3D,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC;IAC/B,IAAI,MAAM,CAAC,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC5D,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;AACnE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,WAAmB,EAAE,MAAc;IAClE,MAAM,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAC3C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AACnG,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,WAAmB;IACpD,OAAO,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,WAAW,KAAK,eAAe,CAAC;AAC7E,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"media-handler.d.ts","sourceRoot":"","sources":["../../../src/server/media/media-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,sBAAsB,EAAE,iCAAiC,EAAE,MAAM,YAAY,CAAC;AAoF5F,wBAAsB,OAAO,CAC3B,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,iCAAiC,CAAC,CAkF5C"}
1
+ {"version":3,"file":"media-handler.d.ts","sourceRoot":"","sources":["../../../src/server/media/media-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,sBAAsB,EAAE,iCAAiC,EAAE,MAAM,YAAY,CAAC;AAsG5F,wBAAsB,OAAO,CAC3B,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,iCAAiC,CAAC,CAqG5C"}
@@ -9,6 +9,22 @@ const ssmClient = new SSMClient({ region: process.env.AWS_REGION });
9
9
  const MAX_INPUT_PIXELS = 100_000_000;
10
10
  const CACHE_CONTROL_IMMUTABLE = 'public, max-age=31536000, immutable';
11
11
  const CACHE_CONTROL_NO_STORE = 'no-store';
12
+ /**
13
+ * Lambda Function URLのバッファ型応答上限(約6MB、base64化を考慮すると実質
14
+ * 約4.4MB)に対する安全マージン。これを超えると502になり、しかも一度
15
+ * cache/{fileId}/{width}に書き込まれると自動削除(S3 Lifecycle)されるまで
16
+ * 同じリクエストが502であり続けるため、キャッシュに書き込む前に検査する
17
+ * (詳細: docs/media-design.md「リサイズのサイズ設計」)。
18
+ */
19
+ const MAX_RESPONSE_BYTES = 4 * 1024 * 1024;
20
+ const QUALITY_FALLBACK_STEPS = [80, 60, 40];
21
+ function payloadTooLargeResponse(message) {
22
+ return {
23
+ statusCode: 413,
24
+ headers: { 'Cache-Control': CACHE_CONTROL_NO_STORE, 'Content-Type': 'text/plain' },
25
+ body: message,
26
+ };
27
+ }
12
28
  function notFoundResponse(message) {
13
29
  return {
14
30
  statusCode: 404,
@@ -116,12 +132,22 @@ export async function handler(event) {
116
132
  // image/jpeg)にのみ適用できる。非画像ファイル・SVGのmasterはオリジナル
117
133
  // バイト列のまま保存されており、sharpで処理すると例外(PDF等)や意図しない
118
134
  // ラスタライズ(SVG)を起こすため、ここで明示的に拒否する。
135
+ //
136
+ // JPEG品質フォールバック: 応答サイズがLambda Function URLの上限を超える
137
+ // 場合、品質を段階的に下げて再エンコードする。最低品質でも閾値を超える
138
+ // 場合はキャッシュに書き込まず413を返す(詳細: docs/media-design.md)。
119
139
  let resized;
120
140
  try {
121
- resized = await sharp(master, { limitInputPixels: MAX_INPUT_PIXELS })
122
- .resize(width, width, { fit: 'inside', withoutEnlargement: true })
123
- .jpeg()
124
- .toBuffer();
141
+ for (const quality of QUALITY_FALLBACK_STEPS) {
142
+ const buffer = await sharp(master, { limitInputPixels: MAX_INPUT_PIXELS })
143
+ .resize(width, width, { fit: 'inside', withoutEnlargement: true })
144
+ .jpeg({ quality })
145
+ .toBuffer();
146
+ if (buffer.length <= MAX_RESPONSE_BYTES) {
147
+ resized = buffer;
148
+ break;
149
+ }
150
+ }
125
151
  }
126
152
  catch (error) {
127
153
  logger.warn('Resize not applicable (master is not a processable raster image)', {
@@ -131,6 +157,14 @@ export async function handler(event) {
131
157
  });
132
158
  return badRequestResponse('Resize is not applicable to this file');
133
159
  }
160
+ if (!resized) {
161
+ logger.warn('Resized output exceeds response size limit even at minimum quality', {
162
+ requestId,
163
+ fileId,
164
+ width,
165
+ });
166
+ return payloadTooLargeResponse('Resized output is too large to return');
167
+ }
134
168
  await s3Client.send(new PutObjectCommand({
135
169
  Bucket: bucket,
136
170
  Key: cacheKey,
@@ -1 +1 @@
1
- {"version":3,"file":"media-handler.js","sourceRoot":"","sources":["../../../src/server/media/media-handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"media-handler.js","sourceRoot":"","sources":["../../../src/server/media/media-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * S3オブジェクトメタデータの共通処理(process-handler・process-handler-dlqで共有)
3
+ *
4
+ * メタデータの契約の詳細: docs/media-design.md「メタデータの契約」参照
5
+ */
6
+ /**
7
+ * S3オブジェクトメタデータ(x-amz-meta-プレフィックスを除いた小文字キー)から、
8
+ * アプリ固有の追加フィールドのみを抽出する。
9
+ */
10
+ export declare function extractAppMetadata(metadata: Record<string, string>): Record<string, string>;
11
+ /**
12
+ * S3メタデータの値はUS-ASCIIのみ有効なため、呼び出し側は非ASCIIの
13
+ * originalFilename(日本語ファイル名等)をpercent-encodingして渡す契約になっている
14
+ * (詳細: docs/media-design.md「メタデータの契約」)。ここでデコードし、
15
+ * MediaRecordには人間が読める実際のファイル名を保存する。
16
+ *
17
+ * 不正なpercent-encodingの場合は、デコードを諦めて元の文字列をそのまま返す
18
+ * (安全側: 例外で処理全体を失敗させない)。
19
+ */
20
+ export declare function decodeOriginalFilename(raw: string | undefined): string | undefined;
21
+ /**
22
+ * 非画像ファイルのContent-Dispositionヘッダー値を構築する。
23
+ *
24
+ * 日本語等の非ASCIIファイル名は、RFC 6266の`filename*=UTF-8''...`拡張パラメータ
25
+ * (RFC 5987のpercent-encoding)で埋め込む。あわせて、拡張パラメータに対応しない
26
+ * 古いクライアント向けに、ASCII専用の`filename=`フォールバックも含める。
27
+ */
28
+ export declare function buildContentDisposition(decodedFilename: string | undefined): string;
29
+ //# sourceMappingURL=metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.d.ts","sourceRoot":"","sources":["../../../src/server/media/metadata.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQ3F;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAOlF;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAUnF"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * S3オブジェクトメタデータの共通処理(process-handler・process-handler-dlqで共有)
3
+ *
4
+ * メタデータの契約の詳細: docs/media-design.md「メタデータの契約」参照
5
+ */
6
+ /** メディアレコードに持ち込まないS3メタデータキー(original-filenameは専用フィールドとして扱う) */
7
+ const RESERVED_METADATA_KEYS = new Set(['original-filename']);
8
+ /**
9
+ * S3オブジェクトメタデータ(x-amz-meta-プレフィックスを除いた小文字キー)から、
10
+ * アプリ固有の追加フィールドのみを抽出する。
11
+ */
12
+ export function extractAppMetadata(metadata) {
13
+ const result = {};
14
+ for (const [key, value] of Object.entries(metadata)) {
15
+ if (!RESERVED_METADATA_KEYS.has(key)) {
16
+ result[key] = value;
17
+ }
18
+ }
19
+ return result;
20
+ }
21
+ /**
22
+ * S3メタデータの値はUS-ASCIIのみ有効なため、呼び出し側は非ASCIIの
23
+ * originalFilename(日本語ファイル名等)をpercent-encodingして渡す契約になっている
24
+ * (詳細: docs/media-design.md「メタデータの契約」)。ここでデコードし、
25
+ * MediaRecordには人間が読める実際のファイル名を保存する。
26
+ *
27
+ * 不正なpercent-encodingの場合は、デコードを諦めて元の文字列をそのまま返す
28
+ * (安全側: 例外で処理全体を失敗させない)。
29
+ */
30
+ export function decodeOriginalFilename(raw) {
31
+ if (!raw)
32
+ return undefined;
33
+ try {
34
+ return decodeURIComponent(raw);
35
+ }
36
+ catch {
37
+ return raw;
38
+ }
39
+ }
40
+ /**
41
+ * 非画像ファイルのContent-Dispositionヘッダー値を構築する。
42
+ *
43
+ * 日本語等の非ASCIIファイル名は、RFC 6266の`filename*=UTF-8''...`拡張パラメータ
44
+ * (RFC 5987のpercent-encoding)で埋め込む。あわせて、拡張パラメータに対応しない
45
+ * 古いクライアント向けに、ASCII専用の`filename=`フォールバックも含める。
46
+ */
47
+ export function buildContentDisposition(decodedFilename) {
48
+ if (!decodedFilename)
49
+ return 'attachment';
50
+ // 改行・ダブルクォートを除去(ヘッダーインジェクション対策)
51
+ const sanitized = decodedFilename.replace(/["\r\n]/g, '');
52
+ // ASCII専用フォールバック: 非ASCII文字を取り除いた簡易版(空ならdownloadにする)
53
+ const asciiFallback = sanitized.replace(/[^\x20-\x7e]/g, '').trim() || 'download';
54
+ const encoded = encodeURIComponent(sanitized);
55
+ return `attachment; filename="${asciiFallback}"; filename*=UTF-8''${encoded}`;
56
+ }
57
+ //# sourceMappingURL=metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"metadata.js","sourceRoot":"","sources":["../../../src/server/media/metadata.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,+DAA+D;AAC/D,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;AAE9D;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgC;IACjE,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpD,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACrC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAuB;IAC5D,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,IAAI,CAAC;QACH,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,uBAAuB,CAAC,eAAmC;IACzE,IAAI,CAAC,eAAe;QAAE,OAAO,YAAY,CAAC;IAE1C,gCAAgC;IAChC,MAAM,SAAS,GAAG,eAAe,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC1D,oDAAoD;IACpD,MAAM,aAAa,GAAG,SAAS,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,UAAU,CAAC;IAClF,MAAM,OAAO,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAE9C,OAAO,yBAAyB,aAAa,uBAAuB,OAAO,EAAE,CAAC;AAChF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"presign.d.ts","sourceRoot":"","sources":["../../../src/server/media/presign.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AA4B/E;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CAwDhC"}
1
+ {"version":3,"file":"presign.d.ts","sourceRoot":"","sources":["../../../src/server/media/presign.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AA+C/E;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CAwDhC"}
@@ -7,7 +7,24 @@
7
7
  */
8
8
  import { ulid } from 'ulid';
9
9
  import { createPresignedPost } from '@aws-sdk/s3-presigned-post';
10
- const DEFAULT_EXPIRES_IN_SECONDS = 300;
10
+ /**
11
+ * presignは「呼び出し側がアップロードを開始する直前」に発行する設計を前提とする
12
+ * (事前に先回りして取得・保持しておくものではない)。そのためTTLがカバえるべきは
13
+ * 「presignを受け取ってからS3へのPOSTを開始するまでの間隔」(ネットワーク往復・
14
+ * 悪条件下でのTCP/TLSハンドシェイク等)であり、ファイル転送そのものの所要時間では
15
+ * ない(S3は presigned POST のpolicy expirationをリクエスト開始時点で判定し、
16
+ * 転送開始後に期限が切れても転送自体は継続する。AWS公式ドキュメントで
17
+ * presigned URL(GET/PUT)について明記されている挙動 -
18
+ * https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-presigned-url.html
19
+ * 。POSTについても同様の挙動と推定されるが、本番投入前に実機で確認すること)。
20
+ * 悪条件のモバイル回線(DNS・TCP/TLSハンドシェイクのSYN再送込み)を想定しても
21
+ * 数秒〜10秒程度に収まるため、30秒は十分な余裕を持った値とする。
22
+ *
23
+ * 失敗時(ネットワークエラー・期限切れ等いずれの場合も)は、同じpresignで
24
+ * 再試行せず、必ず新しいpresignを取り直すこと。これによりTTLの長さを
25
+ * リトライ回数・間隔から独立させ、設計をシンプルに保てる。
26
+ */
27
+ const DEFAULT_EXPIRES_IN_SECONDS = 30;
11
28
  /**
12
29
  * S3はユーザー定義メタデータのキーを常に小文字で保存する(AWS仕様)。
13
30
  * ここで大文字混じりのキーを許可すると、アップロード時に指定したキー名と
@@ -1 +1 @@
1
- {"version":3,"file":"presign.js","sourceRoot":"","sources":["../../../src/server/media/presign.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAIjE,MAAM,0BAA0B,GAAG,GAAG,CAAC;AAMvC;;;;;;GAMG;AACH,MAAM,oBAAoB,GAAG,cAAc,CAAC;AAE5C,SAAS,oBAAoB,CAAC,QAAgC;IAC5D,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CACb,yBAAyB,GAAG,0DAA0D;gBACpF,4EAA4E,CAC/E,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,MAA6B;IAE7B,MAAM,EACJ,QAAQ,EACR,MAAM,EACN,WAAW,EACX,gBAAgB,EAChB,QAAQ,EACR,mBAAmB,EACnB,aAAa,EACb,QAAQ,EACR,gBAAgB,GACjB,GAAG,MAAM,CAAC;IAEX,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,6BAA6B,WAAW,EAAE,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,QAAQ,IAAI,CAAC,IAAI,QAAQ,GAAG,aAAa,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,2BAA2B,QAAQ,UAAU,aAAa,GAAG,CAAC,CAAC;IACjF,CAAC;IACD,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAE/B,MAAM,MAAM,GAAG,IAAI,EAAE,CAAC;IACtB,MAAM,GAAG,GAAG,OAAO,MAAM,EAAE,CAAC;IAE5B,MAAM,UAAU,GAAuB;QACrC,CAAC,sBAAsB,EAAE,CAAC,EAAE,aAAa,CAAC;QAC1C,EAAE,cAAc,EAAE,WAAW,EAAE;KAChC,CAAC;IACF,MAAM,MAAM,GAA2B;QACrC,cAAc,EAAE,WAAW;KAC5B,CAAC;IAEF,KAAK,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5D,MAAM,SAAS,GAAG,cAAc,OAAO,EAAE,CAAC;QAC1C,MAAM,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;QAC9B,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,gBAAgB,EAAE,CAAC;QACrB,MAAM,CAAC,8BAA8B,CAAC,GAAG,gBAAgB,CAAC;QAC1D,UAAU,CAAC,IAAI,CAAC,EAAE,8BAA8B,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,mBAAmB,CAAC,QAAQ,EAAE;QAC3E,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,GAAG;QACR,UAAU,EAAE,UAAU;QACtB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,gBAAgB,IAAI,0BAA0B;KACxD,CAAC,CAAC;IAEH,OAAO;QACL,MAAM;QACN,SAAS,EAAE,GAAG;QACd,MAAM,EAAE,eAAe;KACxB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"presign.js","sourceRoot":"","sources":["../../../src/server/media/presign.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAIjE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,0BAA0B,GAAG,EAAE,CAAC;AAQtC;;;;;;GAMG;AACH,MAAM,oBAAoB,GAAG,cAAc,CAAC;AAE5C,SAAS,oBAAoB,CAAC,QAAgC;IAC5D,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxC,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CACb,yBAAyB,GAAG,0DAA0D;gBACpF,4EAA4E,CAC/E,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,MAA6B;IAE7B,MAAM,EACJ,QAAQ,EACR,MAAM,EACN,WAAW,EACX,gBAAgB,EAChB,QAAQ,EACR,mBAAmB,EACnB,aAAa,EACb,QAAQ,EACR,gBAAgB,GACjB,GAAG,MAAM,CAAC;IAEX,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,6BAA6B,WAAW,EAAE,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,QAAQ,IAAI,CAAC,IAAI,QAAQ,GAAG,aAAa,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,2BAA2B,QAAQ,UAAU,aAAa,GAAG,CAAC,CAAC;IACjF,CAAC;IACD,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAE/B,MAAM,MAAM,GAAG,IAAI,EAAE,CAAC;IACtB,MAAM,GAAG,GAAG,OAAO,MAAM,EAAE,CAAC;IAE5B,MAAM,UAAU,GAAuB;QACrC,CAAC,sBAAsB,EAAE,CAAC,EAAE,aAAa,CAAC;QAC1C,EAAE,cAAc,EAAE,WAAW,EAAE;KAChC,CAAC;IACF,MAAM,MAAM,GAA2B;QACrC,cAAc,EAAE,WAAW;KAC5B,CAAC;IAEF,KAAK,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5D,MAAM,SAAS,GAAG,cAAc,OAAO,EAAE,CAAC;QAC1C,MAAM,CAAC,SAAS,CAAC,GAAG,SAAS,CAAC;QAC9B,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,gBAAgB,EAAE,CAAC;QACrB,MAAM,CAAC,8BAA8B,CAAC,GAAG,gBAAgB,CAAC;QAC1D,UAAU,CAAC,IAAI,CAAC,EAAE,8BAA8B,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,mBAAmB,CAAC,QAAQ,EAAE;QAC3E,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,GAAG;QACR,UAAU,EAAE,UAAU;QACtB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,gBAAgB,IAAI,0BAA0B;KACxD,CAAC,CAAC;IAEH,OAAO;QACL,MAAM;QACN,SAAS,EAAE,GAAG;QACd,MAAM,EAAE,eAAe;KACxB,CAAC;AACJ,CAAC"}
@@ -1,16 +1,3 @@
1
- /**
2
- * process-handler の失敗(Lambda非同期呼び出しのリトライが尽きた場合)を
3
- * 受け取るDLQ(SQS)ハンドラー
4
- *
5
- * process-handler本体が例外を投げ続けてLambdaのリトライが尽きると、
6
- * on-failure宛先として設定したこのSQSキューにメッセージが送られる。
7
- * ここでは呼び出し側に「処理が永久に終わらない」状態(クライアントが
8
- * 無限ポーリングし続ける)を解消するため、status:'failed'レコードを書き込む。
9
- *
10
- * 上書き防止: S3イベントの重複配信により、process-handler本体が先に
11
- * completedを書き込んだ後にDLQ経由の古いリトライがfailedで上書きする
12
- * 可能性があるため、書き込み前に既存レコードを確認する。
13
- */
14
1
  import type { SQSHandler } from 'aws-lambda';
15
2
  export declare const handler: SQSHandler;
16
3
  //# sourceMappingURL=process-handler-dlq.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"process-handler-dlq.d.ts","sourceRoot":"","sources":["../../../src/server/media/process-handler-dlq.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAY,UAAU,EAAE,MAAM,YAAY,CAAC;AAwEvD,eAAO,MAAM,OAAO,EAAE,UAIrB,CAAC"}
1
+ {"version":3,"file":"process-handler-dlq.d.ts","sourceRoot":"","sources":["../../../src/server/media/process-handler-dlq.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAY,UAAU,EAAE,MAAM,YAAY,CAAC;AA2GvD,eAAO,MAAM,OAAO,EAAE,UAIrB,CAAC"}
@@ -1,12 +1,31 @@
1
+ /**
2
+ * process-handler の失敗(Lambda非同期呼び出しのリトライが尽きた場合)を
3
+ * 受け取るDLQ(SQS)ハンドラー
4
+ *
5
+ * process-handler本体が例外を投げ続けてLambdaのリトライが尽きると、
6
+ * on-failure宛先として設定したこのSQSキューにメッセージが送られる。
7
+ * ここでは呼び出し側に「処理が永久に終わらない」状態(クライアントが
8
+ * 無限ポーリングし続ける)を解消するため、status:'failed'レコードを書き込む。
9
+ *
10
+ * 上書き防止: S3イベントの重複配信により、process-handler本体が先に
11
+ * completedを書き込んだ後にDLQ経由の古いリトライがfailedで上書きする
12
+ * 可能性があるため、書き込み前に既存レコードを確認する。
13
+ */
14
+ import { HeadObjectCommand, S3Client } from '@aws-sdk/client-s3';
1
15
  import { createLogger } from '../../shared/index.js';
16
+ import { extractAppMetadata, decodeOriginalFilename } from './metadata.js';
2
17
  import { handleFindMany } from '../operations/findMany.js';
3
18
  import { handleUpdateOne } from '../operations/updateOne.js';
4
19
  const logger = createLogger({ service: 'media-process-handler-dlq' });
5
- function extractFileId(envelope) {
6
- const key = envelope.requestPayload?.Records?.[0]?.s3?.object?.key;
7
- if (!key)
20
+ const s3Client = new S3Client({ region: process.env.AWS_REGION });
21
+ function extractS3Ref(envelope) {
22
+ const record = envelope.requestPayload?.Records?.[0];
23
+ const bucket = record?.s3?.bucket?.name;
24
+ const rawKey = record?.s3?.object?.key;
25
+ if (!bucket || !rawKey)
8
26
  return undefined;
9
- return decodeURIComponent(key.replace(/\+/g, ' ')).replace(/^raw\//, '');
27
+ const key = decodeURIComponent(rawKey.replace(/\+/g, ' '));
28
+ return { bucket, key, fileId: key.replace(/^raw\//, '') };
10
29
  }
11
30
  async function processMessage(body) {
12
31
  let envelope;
@@ -17,11 +36,12 @@ async function processMessage(body) {
17
36
  logger.error('DLQ message is not valid JSON', { body });
18
37
  return;
19
38
  }
20
- const fileId = extractFileId(envelope);
21
- if (!fileId) {
22
- logger.error('Could not extract fileId from DLQ message', { envelope });
39
+ const ref = extractS3Ref(envelope);
40
+ if (!ref) {
41
+ logger.error('Could not extract S3 reference from DLQ message', { envelope });
23
42
  return;
24
43
  }
44
+ const { bucket, key, fileId } = ref;
25
45
  const requestId = `dlq-${fileId}`;
26
46
  const existing = await handleFindMany('media', { ids: [fileId] }, requestId);
27
47
  const existingRecord = existing[0];
@@ -29,6 +49,26 @@ async function processMessage(body) {
29
49
  logger.info('Media already completed, skipping DLQ failure write', { requestId, fileId });
30
50
  return;
31
51
  }
52
+ // 呼び出し側のアプリ固有メタデータ(ownerId等)を再取得する。これが無いと、
53
+ // 呼び出し側が権限スコープ付きのポーリングでこのfailedレコードを読めず、
54
+ // クライアントが無限ポーリングし続けることになる(詳細: docs/adr/0002-media-design.md)。
55
+ // raw/{fileId}が既に削除されている等でHeadObjectが失敗しても、処理全体は
56
+ // 失敗させず、メタデータ無しでfailedレコードを書き込む(fail-soft)。
57
+ let appMetadata = {};
58
+ let originalFilename;
59
+ try {
60
+ const head = await s3Client.send(new HeadObjectCommand({ Bucket: bucket, Key: key }));
61
+ const metadata = head.Metadata || {};
62
+ appMetadata = extractAppMetadata(metadata);
63
+ originalFilename = decodeOriginalFilename(metadata['original-filename']);
64
+ }
65
+ catch (error) {
66
+ logger.warn('Failed to re-fetch metadata for DLQ failure record', {
67
+ requestId,
68
+ fileId,
69
+ error: error instanceof Error ? error.message : String(error),
70
+ });
71
+ }
32
72
  const now = new Date().toISOString();
33
73
  await handleUpdateOne('media', {
34
74
  id: fileId,
@@ -37,6 +77,8 @@ async function processMessage(body) {
37
77
  status: 'failed',
38
78
  error: 'Processing failed after exhausting retries',
39
79
  updatedAt: now,
80
+ ...(originalFilename ? { originalFilename } : {}),
81
+ ...appMetadata,
40
82
  },
41
83
  $setOnInsert: { createdAt: now },
42
84
  },
@@ -1 +1 @@
1
- {"version":3,"file":"process-handler-dlq.js","sourceRoot":"","sources":["../../../src/server/media/process-handler-dlq.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAG7D,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,OAAO,EAAE,2BAA2B,EAAE,CAAC,CAAC;AActE,SAAS,aAAa,CAAC,QAAwC;IAC7D,MAAM,GAAG,GAAG,QAAQ,CAAC,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC;IACnE,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,OAAO,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAC3E,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,IAAY;IACxC,IAAI,QAAwC,CAAC;IAC7C,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,CAAC,KAAK,CAAC,2CAA2C,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxE,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,MAAM,EAAE,CAAC;IAElC,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IAC7E,MAAM,cAAc,GAAG,QAAQ,CAAC,CAAC,CAA4B,CAAC;IAC9D,IAAI,cAAc,EAAE,MAAM,KAAK,WAAW,EAAE,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,qDAAqD,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1F,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,eAAe,CACnB,OAAO,EACP;QACE,EAAE,EAAE,MAAM;QACV,IAAI,EAAE;YACJ,IAAI,EAAE;gBACJ,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,4CAA4C;gBACnD,SAAS,EAAE,GAAG;aACf;YACD,YAAY,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE;SACjC;QACD,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;KAC1B,EACD,SAAS,CACV,CAAC;IAEF,MAAM,CAAC,IAAI,CAAC,gCAAgC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAe,KAAK,EAAE,KAAe,EAAiB,EAAE;IAC1E,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACnC,MAAM,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;AACH,CAAC,CAAC"}
1
+ {"version":3,"file":"process-handler-dlq.js","sourceRoot":"","sources":["../../../src/server/media/process-handler-dlq.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGjE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAG7D,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,OAAO,EAAE,2BAA2B,EAAE,CAAC,CAAC;AAEtE,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;AAoBlE,SAAS,YAAY,CAAC,QAAwC;IAC5D,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC;IACvC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,GAAG,GAAG,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3D,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,CAAC;AAC5D,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,IAAY;IACxC,IAAI,QAAwC,CAAC;IAC7C,IAAI,CAAC;QACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,CAAC,KAAK,CAAC,iDAAiD,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC9E,OAAO;IACT,CAAC;IACD,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IAEpC,MAAM,SAAS,GAAG,OAAO,MAAM,EAAE,CAAC;IAElC,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IAC7E,MAAM,cAAc,GAAG,QAAQ,CAAC,CAAC,CAA4B,CAAC;IAC9D,IAAI,cAAc,EAAE,MAAM,KAAK,WAAW,EAAE,CAAC;QAC3C,MAAM,CAAC,IAAI,CAAC,qDAAqD,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1F,OAAO;IACT,CAAC;IAED,2CAA2C;IAC3C,yCAAyC;IACzC,8DAA8D;IAC9D,iDAAiD;IACjD,4CAA4C;IAC5C,IAAI,WAAW,GAA2B,EAAE,CAAC;IAC7C,IAAI,gBAAoC,CAAC;IACzC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACtF,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;QACrC,WAAW,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAC3C,gBAAgB,GAAG,sBAAsB,CAAC,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAC;IAC3E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,IAAI,CAAC,oDAAoD,EAAE;YAChE,SAAS;YACT,MAAM;YACN,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC,CAAC;IACL,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,eAAe,CACnB,OAAO,EACP;QACE,EAAE,EAAE,MAAM;QACV,IAAI,EAAE;YACJ,IAAI,EAAE;gBACJ,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,4CAA4C;gBACnD,SAAS,EAAE,GAAG;gBACd,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjD,GAAG,WAAW;aACf;YACD,YAAY,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE;SACjC;QACD,OAAO,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;KAC1B,EACD,SAAS,CACV,CAAC;IAEF,MAAM,CAAC,IAAI,CAAC,gCAAgC,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAe,KAAK,EAAE,KAAe,EAAiB,EAAE;IAC1E,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QACnC,MAAM,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;AACH,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"process-handler.d.ts","sourceRoot":"","sources":["../../../src/server/media/process-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAW,SAAS,EAAE,MAAM,YAAY,CAAC;AA8KrD,eAAO,MAAM,OAAO,EAAE,SAgBrB,CAAC"}
1
+ {"version":3,"file":"process-handler.d.ts","sourceRoot":"","sources":["../../../src/server/media/process-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAW,SAAS,EAAE,MAAM,YAAY,CAAC;AAiMrD,eAAO,MAAM,OAAO,EAAE,SAgBrB,CAAC"}
@@ -2,37 +2,36 @@ import sharp from 'sharp';
2
2
  import { CopyObjectCommand, GetObjectCommand, HeadObjectCommand, PutObjectCommand, S3Client, } from '@aws-sdk/client-s3';
3
3
  import { SSMClient } from '@aws-sdk/client-ssm';
4
4
  import { createLogger } from '../../shared/index.js';
5
+ import { handleFindMany } from '../operations/findMany.js';
5
6
  import { handleUpdateOne } from '../operations/updateOne.js';
6
7
  import { isProcessableImage, verifyMagicBytes } from './magicBytes.js';
8
+ import { buildContentDisposition, decodeOriginalFilename, extractAppMetadata } from './metadata.js';
7
9
  import { getImagePolicy } from './ssmParams.js';
8
10
  const logger = createLogger({ service: 'media-process-handler' });
9
11
  const s3Client = new S3Client({ region: process.env.AWS_REGION });
10
12
  const ssmClient = new SSMClient({ region: process.env.AWS_REGION });
11
13
  /** sharp のDoS対策(極端に大きい画素数の画像を拒否) */
12
14
  const MAX_INPUT_PIXELS = 100_000_000;
13
- /** メディアレコードに持ち込まないS3メタデータキー(original-filenameは専用フィールドとして扱う) */
14
- const RESERVED_METADATA_KEYS = new Set(['original-filename']);
15
15
  /**
16
- * S3オブジェクトメタデータ(x-amz-meta-プレフィックスを除いた小文字キー)から、
17
- * アプリ固有の追加フィールドのみを抽出する。
16
+ * マジックナンバー照合に必要な先頭バイト数。現状の照合表(magicBytes.ts)は
17
+ * 最大12バイト程度までしか見ないが、将来の形式追加を見込んで余裕を持たせる。
18
18
  */
19
- function extractAppMetadata(metadata) {
20
- const result = {};
21
- for (const [key, value] of Object.entries(metadata)) {
22
- if (!RESERVED_METADATA_KEYS.has(key)) {
23
- result[key] = value;
24
- }
25
- }
26
- return result;
27
- }
28
- /** Content-Dispositionのfilenameパラメータに安全に埋め込めるよう制御文字・ダブルクォートを除去する */
29
- function sanitizeFilenameForHeader(filename) {
30
- return filename.replace(/["\r\n]/g, '');
31
- }
19
+ const MAGIC_BYTES_CHECK_RANGE = 255;
32
20
  async function streamToBuffer(body) {
33
21
  const bytes = await body.transformToByteArray();
34
22
  return Buffer.from(bytes);
35
23
  }
24
+ /**
25
+ * マジックナンバー照合用に、先頭の一部バイトだけを取得する。
26
+ *
27
+ * 非画像ファイル(CopyObjectで足りる)は、これ以上ファイル全体をメモリに
28
+ * 読み込む必要が無い。大きな動画・PDF等でも、この先頭バイトの取得だけで
29
+ * 検証が完結し、Lambdaのメモリを無駄に消費しない(詳細: docs/adr/0002-media-design.md)。
30
+ */
31
+ async function getHeadBytes(bucket, key) {
32
+ const result = await s3Client.send(new GetObjectCommand({ Bucket: bucket, Key: key, Range: `bytes=0-${MAGIC_BYTES_CHECK_RANGE}` }));
33
+ return streamToBuffer(result.Body);
34
+ }
36
35
  async function writeMediaRecord(fileId, fields, requestId) {
37
36
  const now = new Date().toISOString();
38
37
  await handleUpdateOne('media', {
@@ -48,13 +47,28 @@ async function processRecord(bucket, rawKey) {
48
47
  const key = decodeURIComponent(rawKey.replace(/\+/g, ' '));
49
48
  const fileId = key.replace(/^raw\//, '');
50
49
  const requestId = `s3-event-${fileId}`;
50
+ // fileId→内容の不変性を保証する: 同じpresignのTTL内(既定30秒)に2回目のPOSTが
51
+ // 行われた場合、raw/{fileId}への2回目のPutObjectイベントが発火しうる。既にこの
52
+ // fileIdがcompletedとして処理済みなら、再処理してmasterを上書きしない
53
+ // (process-handler-dlq.tsの重複配信対策と同じガード。詳細: docs/media-design.md
54
+ // 「presigned POSTの再利用・master不変性について」)
55
+ const existing = await handleFindMany('media', { ids: [fileId] }, requestId);
56
+ const existingRecord = existing[0];
57
+ if (existingRecord?.status === 'completed') {
58
+ logger.warn('Media already completed, ignoring re-upload to the same fileId', {
59
+ requestId,
60
+ fileId,
61
+ });
62
+ return;
63
+ }
51
64
  const head = await s3Client.send(new HeadObjectCommand({ Bucket: bucket, Key: key }));
52
65
  const contentType = head.ContentType || 'application/octet-stream';
53
66
  const metadata = head.Metadata || {};
54
- const originalFilename = metadata['original-filename'];
55
- const getResult = await s3Client.send(new GetObjectCommand({ Bucket: bucket, Key: key }));
56
- const buffer = await streamToBuffer(getResult.Body);
57
- if (!verifyMagicBytes(contentType, buffer)) {
67
+ const originalFilename = decodeOriginalFilename(metadata['original-filename']);
68
+ // マジックナンバー照合は先頭バイトのみで完結する。非画像(CopyObjectで足りる)
69
+ // の場合、このあとファイル全体を読み込む必要が無い
70
+ const headBytes = await getHeadBytes(bucket, key);
71
+ if (!verifyMagicBytes(contentType, headBytes)) {
58
72
  logger.warn('Content type does not match file signature', { requestId, fileId, contentType });
59
73
  await writeMediaRecord(fileId, {
60
74
  status: 'failed',
@@ -71,6 +85,9 @@ async function processRecord(bucket, rawKey) {
71
85
  throw new Error('IMAGE_POLICY_PARAM environment variable is not set');
72
86
  }
73
87
  const imagePolicy = await getImagePolicy(ssmClient, imagePolicyParam);
88
+ // 画像処理にはファイル全体が必要なため、ここで改めて全量を取得する
89
+ const getResult = await s3Client.send(new GetObjectCommand({ Bucket: bucket, Key: key }));
90
+ const buffer = await streamToBuffer(getResult.Body);
74
91
  const image = sharp(buffer, { limitInputPixels: MAX_INPUT_PIXELS }).rotate();
75
92
  const inputMeta = await image.metadata();
76
93
  const maxDim = imagePolicy.masterMaxDimension;
@@ -102,15 +119,13 @@ async function processRecord(bucket, rawKey) {
102
119
  CopySource: `${bucket}/${key}`,
103
120
  MetadataDirective: 'REPLACE',
104
121
  ContentType: contentType,
105
- ContentDisposition: originalFilename
106
- ? `attachment; filename="${sanitizeFilenameForHeader(originalFilename)}"`
107
- : 'attachment',
122
+ ContentDisposition: buildContentDisposition(originalFilename),
108
123
  }));
109
124
  await writeMediaRecord(fileId, {
110
125
  status: 'completed',
111
126
  contentType,
112
127
  outputContentType: contentType,
113
- size: head.ContentLength ?? buffer.length,
128
+ size: head.ContentLength ?? 0,
114
129
  ...(originalFilename ? { originalFilename } : {}),
115
130
  ...appMetadata,
116
131
  }, requestId);
@@ -1 +1 @@
1
- {"version":3,"file":"process-handler.js","sourceRoot":"","sources":["../../../src/server/media/process-handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"process-handler.js","sourceRoot":"","sources":["../../../src/server/media/process-handler.ts"],"names":[],"mappings":"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"}