@cedarjs/uploads 7.0.1-next.333 → 7.0.1-next.467

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 (47) hide show
  1. package/README.md +11 -0
  2. package/dist/authenticator.d.ts +2 -2
  3. package/dist/authenticator.d.ts.map +1 -1
  4. package/dist/cleanupStaleUploads.d.ts +4 -3
  5. package/dist/cleanupStaleUploads.d.ts.map +1 -1
  6. package/dist/cleanupStaleUploads.js +8 -2
  7. package/dist/contentTypes.d.ts +74 -0
  8. package/dist/contentTypes.d.ts.map +1 -0
  9. package/dist/contentTypes.js +78 -0
  10. package/dist/deleteFile.d.ts +19 -4
  11. package/dist/deleteFile.d.ts.map +1 -1
  12. package/dist/deleteFile.js +49 -8
  13. package/dist/detectContentType.d.ts +168 -0
  14. package/dist/detectContentType.d.ts.map +1 -0
  15. package/dist/detectContentType.js +443 -0
  16. package/dist/errors.d.ts +1 -1
  17. package/dist/errors.d.ts.map +1 -1
  18. package/dist/errors.js +2 -1
  19. package/dist/fastify/plugin.d.ts +30 -2
  20. package/dist/fastify/plugin.d.ts.map +1 -1
  21. package/dist/fastify/plugin.js +38 -10
  22. package/dist/index.d.ts +6 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +35 -0
  25. package/dist/keys.d.ts +3 -1
  26. package/dist/keys.d.ts.map +1 -1
  27. package/dist/keys.js +2 -1
  28. package/dist/profiles.d.ts +8 -2
  29. package/dist/profiles.d.ts.map +1 -1
  30. package/dist/profiles.js +5 -4
  31. package/dist/providers/s3.d.ts.map +1 -1
  32. package/dist/providers/s3.js +16 -0
  33. package/dist/services.d.ts +24 -6
  34. package/dist/services.d.ts.map +1 -1
  35. package/dist/services.js +45 -10
  36. package/dist/types.d.ts +116 -0
  37. package/dist/types.d.ts.map +1 -1
  38. package/dist/variants.d.ts +207 -0
  39. package/dist/variants.d.ts.map +1 -0
  40. package/dist/variants.js +498 -0
  41. package/dist/verifyStoredContentType.d.ts +19 -0
  42. package/dist/verifyStoredContentType.d.ts.map +1 -0
  43. package/dist/verifyStoredContentType.js +41 -0
  44. package/dist/webhooks/s3.d.ts +17 -8
  45. package/dist/webhooks/s3.d.ts.map +1 -1
  46. package/dist/webhooks/s3.js +22 -3
  47. package/package.json +18 -18
package/dist/index.js CHANGED
@@ -8,11 +8,30 @@ import {
8
8
  isMimeTypeAllowed,
9
9
  resolveProfile
10
10
  } from "./profiles.js";
11
+ import {
12
+ acceptedContentType,
13
+ DETECT_CONTENT_TYPE_BYTES,
14
+ DETECT_CONTENT_TYPE_TAIL_BYTES,
15
+ DETECTABLE_CONTENT_TYPES,
16
+ detectContentType,
17
+ findZipCentralDirectory,
18
+ isClaimedContentTypeAllowed,
19
+ MAX_ZIP_DIRECTORY_BYTES
20
+ } from "./detectContentType.js";
21
+ import {
22
+ canonicalContentType,
23
+ CONTENT_TYPE_ALIASES,
24
+ isExplicitOnlyContentType,
25
+ isScriptableContentType,
26
+ MACRO_CONTENT_TYPES,
27
+ SCRIPTABLE_CONTENT_TYPES
28
+ } from "./contentTypes.js";
11
29
  import { createFsProvider } from "./providers/fs.js";
12
30
  import { createDbProvider } from "./providers/db.js";
13
31
  import { generateStorageKey } from "./keys.js";
14
32
  import { storeFile } from "./storeFile.js";
15
33
  import { deleteFile } from "./deleteFile.js";
34
+ import { defineUploadVariants, deleteVariants } from "./variants.js";
16
35
  import { cleanupStaleUploads } from "./cleanupStaleUploads.js";
17
36
  import {
18
37
  createUploadToken,
@@ -46,13 +65,22 @@ import { cedarUploadsPlugin } from "./fastify/plugin.js";
46
65
  import { handleS3Webhook, processS3EventRecord } from "./webhooks/s3.js";
47
66
  import { verifySnsMessage } from "./webhooks/sns.js";
48
67
  export {
68
+ CONTENT_TYPE_ALIASES,
49
69
  DB_MAX_FILE_SIZE,
50
70
  DEFAULT_UPLOAD_TOKEN_EXPIRES_IN,
71
+ DETECTABLE_CONTENT_TYPES,
72
+ DETECT_CONTENT_TYPE_BYTES,
73
+ DETECT_CONTENT_TYPE_TAIL_BYTES,
74
+ MACRO_CONTENT_TYPES,
75
+ MAX_ZIP_DIRECTORY_BYTES,
76
+ SCRIPTABLE_CONTENT_TYPES,
51
77
  SERVE_TOKEN_PURPOSE,
52
78
  UPLOAD_TOKEN_CONTEXT_KEY,
53
79
  UPLOAD_TOKEN_HEADER,
54
80
  UPLOAD_TOKEN_PURPOSE,
55
81
  UploadError,
82
+ acceptedContentType,
83
+ canonicalContentType,
56
84
  cedarUploadsPlugin,
57
85
  cleanupStaleUploads,
58
86
  confirmUpload,
@@ -67,11 +95,18 @@ export {
67
95
  createWithSignedUrlDirective,
68
96
  defineStorageTargets,
69
97
  defineUploadProfiles,
98
+ defineUploadVariants,
70
99
  deleteFile,
100
+ deleteVariants,
101
+ detectContentType,
102
+ findZipCentralDirectory,
71
103
  generateStorageKey,
72
104
  getUploadTokenPayload,
73
105
  handleS3Webhook,
106
+ isClaimedContentTypeAllowed,
107
+ isExplicitOnlyContentType,
74
108
  isMimeTypeAllowed,
109
+ isScriptableContentType,
75
110
  issueUploadToken,
76
111
  processS3EventRecord,
77
112
  requireUploadTokenSchema,
package/dist/keys.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  /**
2
2
  * A fresh storage key: a random id plus the extension that matches
3
3
  * `mimeType`, when one is known. Keys never derive from the client's
4
- * filename.
4
+ * filename. Aliased types are looked up under every spelling, so the
5
+ * registered `video/matroska` gets the `.mkv` the database only knows for
6
+ * `video/x-matroska`.
5
7
  */
6
8
  export declare function generateStorageKey(mimeType: string): string;
7
9
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAI3D;AAID;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,QAIxC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQzD"}
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"AAOA;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAM3D;AAID;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,QAIxC;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQzD"}
package/dist/keys.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import mime from "mime-types";
3
+ import { canonicalContentType, contentTypeSpellings } from "./contentTypes.js";
3
4
  import { UploadError } from "./errors.js";
4
5
  function generateStorageKey(mimeType) {
5
- const ext = mime.extension(mimeType.split(";")[0].trim());
6
+ const ext = contentTypeSpellings(canonicalContentType(mimeType)).map((type) => mime.extension(type)).find(Boolean);
6
7
  return ext ? `${randomUUID()}.${ext}` : randomUUID();
7
8
  }
8
9
  const SAFE_KEY = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
@@ -15,7 +15,11 @@ export interface UploadProfile {
15
15
  target: string;
16
16
  /**
17
17
  * MIME types the profile accepts. Exact types (`image/png`) and wildcard
18
- * subtypes (`image/*`) are supported.
18
+ * subtypes (`image/*`) are supported, and either spelling of an aliased
19
+ * type (`image/jpeg` or `image/jpg`) matches both. When files are checked
20
+ * by their bytes (`verifyContentType`, on by default), types that can carry
21
+ * script, such as `image/svg+xml` or `text/html`, are only accepted when
22
+ * listed exactly; see `SCRIPTABLE_CONTENT_TYPES`.
19
23
  */
20
24
  allowedMimeTypes: string[];
21
25
  /** Largest file the profile accepts, in bytes. */
@@ -43,7 +47,9 @@ export declare function resolveProfile(profiles: UploadProfiles, name: string):
43
47
  /**
44
48
  * Whether `mimeType` matches one of `allowed`. Matching is case-insensitive
45
49
  * and ignores parameters such as `; charset=utf-8`. An entry of `image/*`
46
- * matches every `image/` subtype.
50
+ * matches every `image/` subtype. Aliases in `CONTENT_TYPE_ALIASES` are the
51
+ * same type, so `image/jpg` matches an entry of `image/jpeg` and the other
52
+ * way round.
47
53
  */
48
54
  export declare function isMimeTypeAllowed(allowed: string[], mimeType: string): boolean;
49
55
  //# sourceMappingURL=profiles.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../src/profiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAIxD;;;GAGG;AACH,eAAO,MAAM,gBAAgB,QAAc,CAAA;AAE3C,2CAA2C;AAC3C,eAAO,MAAM,+BAA+B,EAAE,oBAA2B,CAAA;AAEzE;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAA;IACnB,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAA;IAChB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,oBAAoB,CAAA;CACjC;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;AAE1D,MAAM,WAAW,qBAAsB,SAAQ,aAAa;IAC1D,IAAI,EAAE,MAAM,CAAA;CACb;AAiCD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,cAAc,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAM7E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,MAAM,GACX,qBAAqB,CAavB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,WAoBpE"}
1
+ {"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../src/profiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAA;AAKxD;;;GAGG;AACH,eAAO,MAAM,gBAAgB,QAAc,CAAA;AAE3C,2CAA2C;AAC3C,eAAO,MAAM,+BAA+B,EAAE,oBAA2B,CAAA;AAEzE;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAA;IACd;;;;;;;OAOG;IACH,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAA;IACnB,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAA;IAChB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,oBAAoB,CAAA;CACjC;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;AAE1D,MAAM,WAAW,qBAAsB,SAAQ,aAAa;IAC1D,IAAI,EAAE,MAAM,CAAA;CACb;AAiCD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,cAAc,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAM7E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,MAAM,GACX,qBAAqB,CAavB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,WAoBpE"}
package/dist/profiles.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { canonicalContentType } from "./contentTypes.js";
1
2
  import { UploadError } from "./errors.js";
2
3
  const DB_MAX_FILE_SIZE = 1024 * 1024;
3
4
  const DEFAULT_UPLOAD_TOKEN_EXPIRES_IN = "5m";
@@ -44,8 +45,8 @@ function resolveProfile(profiles, name) {
44
45
  return { ...profile, name };
45
46
  }
46
47
  function isMimeTypeAllowed(allowed, mimeType) {
47
- const normalized = mimeType.split(";")[0].trim().toLowerCase();
48
- if (!normalized) {
48
+ const type = canonicalContentType(mimeType);
49
+ if (!type) {
49
50
  return false;
50
51
  }
51
52
  return allowed.some((entry) => {
@@ -54,9 +55,9 @@ function isMimeTypeAllowed(allowed, mimeType) {
54
55
  return true;
55
56
  }
56
57
  if (pattern.endsWith("/*")) {
57
- return normalized.startsWith(pattern.slice(0, -1));
58
+ return type.startsWith(pattern.slice(0, -1));
58
59
  }
59
- return pattern === normalized;
60
+ return canonicalContentType(pattern) === type;
60
61
  });
61
62
  }
62
63
  export {
@@ -1 +1 @@
1
- {"version":3,"file":"s3.d.ts","sourceRoot":"","sources":["../../src/providers/s3.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAGlD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD,MAAM,WAAW,iBAAiB;IAChC,8EAA8E;IAC9E,MAAM,EAAE,QAAQ,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,sEAAsE;IACtE,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAmBD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,eAAe,CAwHzE"}
1
+ {"version":3,"file":"s3.d.ts","sourceRoot":"","sources":["../../src/providers/s3.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAGlD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD,MAAM,WAAW,iBAAiB;IAChC,8EAA8E;IAC9E,MAAM,EAAE,QAAQ,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,sEAAsE;IACtE,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,kEAAkE;IAClE,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAmBD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,iBAAiB,GAAG,eAAe,CA4IzE"}
@@ -45,6 +45,22 @@ function createS3Provider(opts) {
45
45
  }
46
46
  return Buffer.from(await res.Body.transformToByteArray());
47
47
  },
48
+ async readRange(key, { offset, length }) {
49
+ if (length <= 0) {
50
+ return Buffer.alloc(0);
51
+ }
52
+ const res = await client.send(
53
+ new GetObjectCommand({
54
+ Bucket: bucket,
55
+ Key: fullKey(key),
56
+ Range: `bytes=${offset}-${offset + length - 1}`
57
+ })
58
+ );
59
+ if (!res.Body) {
60
+ return Buffer.alloc(0);
61
+ }
62
+ return Buffer.from(await res.Body.transformToByteArray());
63
+ },
48
64
  async readStream(key) {
49
65
  const res = await client.send(
50
66
  new GetObjectCommand({ Bucket: bucket, Key: fullKey(key) })
@@ -40,6 +40,16 @@ export interface CreatePresignedUploadOptions {
40
40
  /** The validated token, as attached to context by `@requireUploadToken`. */
41
41
  tokenPayload: UploadTokenPayload;
42
42
  input: CreatePresignedUploadInput;
43
+ /**
44
+ * Holds the declared type to the rules `acceptedContentType()` applies to
45
+ * a type it can't check by bytes: no wildcard types, and types that can
46
+ * carry script (`SCRIPTABLE_CONTENT_TYPES`) only when the profile lists
47
+ * them exactly. Pair it with `verifyContentType` on `confirmUpload` (and
48
+ * the S3 webhook), which checks the bytes against the declared type.
49
+ * Defaults to `true`; `false` checks the declared type with
50
+ * `isMimeTypeAllowed()` only.
51
+ */
52
+ verifyContentType?: boolean;
43
53
  }
44
54
  export interface PresignedUploadResponse {
45
55
  uploadId: string;
@@ -52,19 +62,27 @@ export interface PresignedUploadResponse {
52
62
  * a presigned URL the client PUTs the bytes to. This is what the generated
53
63
  * `createPresignedUploadUrl` resolver calls.
54
64
  */
55
- export declare function createPresignedUpload({ db, targets, tokenPayload, input, }: CreatePresignedUploadOptions): Promise<PresignedUploadResponse>;
65
+ export declare function createPresignedUpload({ db, targets, tokenPayload, input, verifyContentType, }: CreatePresignedUploadOptions): Promise<PresignedUploadResponse>;
56
66
  export interface ConfirmUploadOptions {
57
67
  db: UploadDatabase;
58
68
  targets: StorageTargets;
59
69
  uploadId: string;
60
70
  currentUser: UploadActor | null | undefined;
71
+ /**
72
+ * Checks the object's bytes against the type the client declared for it
73
+ * when it asked for the upload URL, with a ranged read of its head (and of
74
+ * its tail for ZIPs), and records the canonical spelling of that type. A
75
+ * mismatch fails the row and deletes the object. Defaults to `true`.
76
+ */
77
+ verifyContentType?: boolean;
61
78
  }
62
79
  /**
63
80
  * Client-side confirmation of a direct upload. Verifies that the object
64
- * exists in storage and that its size matches what the token authorized,
65
- * then flips the row `pending` to `completed`. On a size mismatch the row is
66
- * claimed `failed` and the object deleted. Only the user (and organization)
67
- * the upload was issued to can confirm it.
81
+ * exists in storage, that its size matches what the token authorized, and
82
+ * (with `verifyContentType`, the default) that its bytes are the type the
83
+ * client declared, then flips the row `pending` to `completed`. On a
84
+ * mismatch the row is claimed `failed` and the object deleted. Only the user
85
+ * (and organization) the upload was issued to can confirm it.
68
86
  */
69
- export declare function confirmUpload({ db, targets, uploadId, currentUser, }: ConfirmUploadOptions): Promise<UploadRecord>;
87
+ export declare function confirmUpload({ db, targets, uploadId, currentUser, verifyContentType, }: ConfirmUploadOptions): Promise<UploadRecord>;
70
88
  //# sourceMappingURL=services.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../src/services.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAEnD,OAAO,KAAK,EAEV,cAAc,EACd,cAAc,EACd,YAAY,EACb,MAAM,YAAY,CAAA;AAEnB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAE1D,yCAAyC;AACzC,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,cAAc,CAAA;IACxB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,8DAA8D;IAC9D,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,CAAA;IAC3C,mEAAmE;IACnE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,OAAO,EAAE,WAAW,EACpB,MAAM,EACN,WAAW,EACX,cAAc,GACf,EAAE,uBAAuB,GAAG,mBAAmB,CA+B/C;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;CAC/B;AAED,MAAM,WAAW,4BAA4B;IAC3C,EAAE,EAAE,cAAc,CAAA;IAClB,OAAO,EAAE,cAAc,CAAA;IACvB,4EAA4E;IAC5E,YAAY,EAAE,kBAAkB,CAAA;IAChC,KAAK,EAAE,0BAA0B,CAAA;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC;AAUD;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,EAC1C,EAAE,EACF,OAAO,EACP,YAAY,EACZ,KAAK,GACN,EAAE,4BAA4B,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAkCjE;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,cAAc,CAAA;IAClB,OAAO,EAAE,cAAc,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,CAAA;CAC5C;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,EAClC,EAAE,EACF,OAAO,EACP,QAAQ,EACR,WAAW,GACZ,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CAoE9C"}
1
+ {"version":3,"file":"services.d.ts","sourceRoot":"","sources":["../src/services.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAEnD,OAAO,KAAK,EAGV,cAAc,EACd,cAAc,EACd,YAAY,EACb,MAAM,YAAY,CAAA;AAEnB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAG1D,yCAAyC;AACzC,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,cAAc,CAAA;IACxB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,8DAA8D;IAC9D,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,CAAA;IAC3C,mEAAmE;IACnE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;IACb,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,QAAQ,EACR,OAAO,EAAE,WAAW,EACpB,MAAM,EACN,WAAW,EACX,cAAc,GACf,EAAE,uBAAuB,GAAG,mBAAmB,CA+B/C;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;CAC/B;AAED,MAAM,WAAW,4BAA4B;IAC3C,EAAE,EAAE,cAAc,CAAA;IAClB,OAAO,EAAE,cAAc,CAAA;IACvB,4EAA4E;IAC5E,YAAY,EAAE,kBAAkB,CAAA;IAChC,KAAK,EAAE,0BAA0B,CAAA;IACjC;;;;;;;;OAQG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAChC;AAUD;;;;GAIG;AACH,wBAAsB,qBAAqB,CAAC,EAC1C,EAAE,EACF,OAAO,EACP,YAAY,EACZ,KAAK,EACL,iBAAwB,GACzB,EAAE,4BAA4B,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAiDjE;AAED,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,cAAc,CAAA;IAClB,OAAO,EAAE,cAAc,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,CAAA;IAC3C;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAqBD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,EAClC,EAAE,EACF,OAAO,EACP,QAAQ,EACR,WAAW,EACX,iBAAwB,GACzB,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CA4F9C"}
package/dist/services.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { isClaimedContentTypeAllowed } from "./detectContentType.js";
1
2
  import { UploadError } from "./errors.js";
2
3
  import { generateStorageKey } from "./keys.js";
3
4
  import {
@@ -8,6 +9,7 @@ import {
8
9
  import { resolveProfile } from "./profiles.js";
9
10
  import { resolveTarget } from "./targets.js";
10
11
  import { createUploadToken } from "./uploadToken.js";
12
+ import { verifyStoredContentType } from "./verifyStoredContentType.js";
11
13
  function issueUploadToken({
12
14
  profiles,
13
15
  profile: profileName,
@@ -54,10 +56,20 @@ async function createPresignedUpload({
54
56
  db,
55
57
  targets,
56
58
  tokenPayload,
57
- input
59
+ input,
60
+ verifyContentType = true
58
61
  }) {
59
62
  const size = toBigInt(input.size, "file size");
60
63
  assertTokenAllowsFile(tokenPayload, { contentType: input.contentType, size });
64
+ if (verifyContentType && !isClaimedContentTypeAllowed(
65
+ tokenPayload.allowedMimeTypes,
66
+ input.contentType
67
+ )) {
68
+ throw new UploadError(
69
+ "MIME_TYPE_NOT_ALLOWED",
70
+ `File type '${input.contentType}' is not allowed for upload profile '${tokenPayload.profile}'. Types that can carry script must be listed exactly, not through a wildcard.`
71
+ );
72
+ }
61
73
  const target = resolveTarget(targets, tokenPayload.target);
62
74
  const storageKey = generateStorageKey(input.contentType);
63
75
  const upload = await createPendingUpload({
@@ -80,11 +92,21 @@ async function createPresignedUpload({
80
92
  }
81
93
  return { uploadId: upload.id, ...presigned };
82
94
  }
95
+ async function failUpload(db, target, upload) {
96
+ const { count } = await db.upload.updateMany({
97
+ where: { id: upload.id, status: "pending" },
98
+ data: { status: "failed" }
99
+ });
100
+ if (count === 1) {
101
+ await target.delete(upload.storageKey);
102
+ }
103
+ }
83
104
  async function confirmUpload({
84
105
  db,
85
106
  targets,
86
107
  uploadId,
87
- currentUser
108
+ currentUser,
109
+ verifyContentType = true
88
110
  }) {
89
111
  const upload = await db.upload.findFirst({
90
112
  where: { id: uploadId },
@@ -102,22 +124,35 @@ async function confirmUpload({
102
124
  throw new UploadError("NOT_IN_STORAGE", "Upload not found in storage.");
103
125
  }
104
126
  const actualSize = await target.getObjectSize(upload.storageKey);
127
+ const storedUpload = { ...upload, storageKey: upload.storageKey };
105
128
  if (actualSize === null || BigInt(actualSize) !== upload.size) {
106
- const { count: count2 } = await db.upload.updateMany({
107
- where: { id: uploadId, status: "pending" },
108
- data: { status: "failed" }
109
- });
110
- if (count2 === 1) {
111
- await target.delete(upload.storageKey);
112
- }
129
+ await failUpload(db, target, storedUpload);
113
130
  throw new UploadError(
114
131
  "SIZE_MISMATCH",
115
132
  `Uploaded object is ${actualSize ?? "of unknown"} bytes but ${upload.size} bytes were authorized.`
116
133
  );
117
134
  }
135
+ let mimeType = upload.mimeType;
136
+ if (verifyContentType) {
137
+ const verified = await verifyStoredContentType(target, upload.storageKey, {
138
+ size: actualSize,
139
+ declaredType: upload.mimeType
140
+ });
141
+ if (!verified) {
142
+ await failUpload(db, target, storedUpload);
143
+ throw new UploadError(
144
+ "MIME_TYPE_NOT_ALLOWED",
145
+ `Uploaded file is not of the type '${upload.mimeType}' it was declared as, so it was deleted.`
146
+ );
147
+ }
148
+ mimeType = verified;
149
+ }
118
150
  const { count } = await db.upload.updateMany({
119
151
  where: { id: uploadId, status: "pending" },
120
- data: { status: "completed" }
152
+ data: {
153
+ status: "completed",
154
+ ...mimeType !== upload.mimeType ? { mimeType } : {}
155
+ }
121
156
  });
122
157
  const confirmed = await db.upload.findFirst({
123
158
  where: { id: uploadId },
package/dist/types.d.ts CHANGED
@@ -43,6 +43,11 @@ export interface UploadWhere {
43
43
  id?: string | {
44
44
  in: string[];
45
45
  };
46
+ /**
47
+ * Only exists when the `Upload` model has the variant columns. A query
48
+ * that uses it must handle the error Prisma raises without them.
49
+ */
50
+ sourceId?: string;
46
51
  target?: string;
47
52
  status?: string | {
48
53
  in: string[];
@@ -63,6 +68,7 @@ export interface UploadWhere {
63
68
  export interface UploadUpdateData {
64
69
  status?: UploadStatus;
65
70
  size?: bigint;
71
+ mimeType?: string;
66
72
  storageKey?: string | null;
67
73
  }
68
74
  /**
@@ -157,6 +163,15 @@ export interface StorageProvider {
157
163
  }): Promise<void>;
158
164
  /** Read the whole object into memory. */
159
165
  read(key: string): Promise<Buffer>;
166
+ /**
167
+ * Read `length` bytes starting at `offset` (fewer when the object ends
168
+ * first). Optional; checking a direct upload's content type falls back to
169
+ * `read()` when a provider does not implement it.
170
+ */
171
+ readRange?(key: string, range: {
172
+ offset: number;
173
+ length: number;
174
+ }): Promise<Buffer>;
160
175
  /**
161
176
  * Stream the object. Optional; the serve route falls back to `read()` when
162
177
  * a provider does not implement it.
@@ -209,4 +224,105 @@ export interface SerializedUpload {
209
224
  createdAt: string;
210
225
  updatedAt: string;
211
226
  }
227
+ /**
228
+ * An `Upload` row in a schema that has the two variant columns, `sourceId`
229
+ * and `variant`. A derived file (a thumbnail, a preview, a video's poster
230
+ * frame) is an `Upload` row of its own whose `sourceId` points at the file
231
+ * it was made from and whose `variant` names what it is (`'thumb-164'`,
232
+ * `'preview'`). Original files have both set to `null`.
233
+ */
234
+ export interface UploadVariantRecord extends UploadRecord {
235
+ sourceId: string | null;
236
+ variant: string | null;
237
+ }
238
+ export interface UploadVariantWhere {
239
+ id?: string | {
240
+ in?: string[];
241
+ notIn?: string[];
242
+ };
243
+ sourceId?: string | null | {
244
+ in: string[];
245
+ };
246
+ variant?: string | null;
247
+ status?: string;
248
+ tokenId?: string | null;
249
+ storageKey?: string | null;
250
+ createdAt?: {
251
+ lt?: Date;
252
+ lte?: Date;
253
+ };
254
+ updatedAt?: {
255
+ lt?: Date;
256
+ };
257
+ }
258
+ export interface UploadVariantCreateData extends UploadCreateData {
259
+ sourceId: string;
260
+ variant: string;
261
+ }
262
+ export interface UploadVariantUpdateData {
263
+ status?: UploadStatus;
264
+ target?: string;
265
+ size?: bigint;
266
+ storageKey?: string | null;
267
+ filename?: string;
268
+ mimeType?: string;
269
+ data?: Uint8Array<ArrayBuffer> | null;
270
+ tokenId?: string | null;
271
+ }
272
+ /**
273
+ * The subset of Prisma's generated `Upload` delegate that derived files
274
+ * (variants) need. A generated client satisfies it once the `Upload` model
275
+ * has the `sourceId` and `variant` columns described in the uploads docs.
276
+ */
277
+ export interface UploadVariantDelegate {
278
+ create(args: {
279
+ data: UploadVariantCreateData;
280
+ }): Promise<UploadVariantRecord>;
281
+ findUnique(args: {
282
+ where: {
283
+ id: string;
284
+ };
285
+ omit?: {
286
+ data?: boolean;
287
+ };
288
+ }): Promise<UploadVariantRecord | null>;
289
+ findFirst(args: {
290
+ where: UploadVariantWhere;
291
+ omit?: {
292
+ data?: boolean;
293
+ };
294
+ orderBy?: {
295
+ createdAt: 'asc' | 'desc';
296
+ };
297
+ }): Promise<UploadVariantRecord | null>;
298
+ findMany(args: {
299
+ where: UploadVariantWhere;
300
+ omit?: {
301
+ data?: boolean;
302
+ };
303
+ orderBy?: {
304
+ createdAt: 'asc' | 'desc';
305
+ };
306
+ take?: number;
307
+ }): Promise<UploadVariantRecord[]>;
308
+ updateMany(args: {
309
+ where: UploadVariantWhere;
310
+ data: UploadVariantUpdateData;
311
+ }): Promise<{
312
+ count: number;
313
+ }>;
314
+ deleteMany(args: {
315
+ where: UploadVariantWhere;
316
+ }): Promise<{
317
+ count: number;
318
+ }>;
319
+ }
320
+ /**
321
+ * The subset of a Prisma client that derived files (variants) need. Any
322
+ * generated client whose `Upload` model has the `sourceId` and `variant`
323
+ * columns satisfies it.
324
+ */
325
+ export interface UploadVariantDatabase {
326
+ upload: UploadVariantDelegate;
327
+ }
212
328
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}