@muhgholy/next-drive 4.23.2 → 4.23.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.
@@ -7,9 +7,9 @@ var os2 = require('os');
7
7
  var crypto2 = require('crypto');
8
8
  var mongoose = require('mongoose');
9
9
  var sharp2 = require('sharp');
10
- var zod = require('zod');
11
10
  var ffmpeg = require('fluent-ffmpeg');
12
11
  var googleapis = require('googleapis');
12
+ var zod = require('zod');
13
13
 
14
14
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
15
 
@@ -337,35 +337,6 @@ var getDriveInformation = async (input) => {
337
337
  }
338
338
  return config.information(input);
339
339
  };
340
- var StorageAccountSchema = new mongoose.Schema(
341
- {
342
- owner: { type: mongoose.Schema.Types.Mixed, default: null },
343
- name: { type: String, required: true },
344
- metadata: {
345
- provider: { type: String, enum: ["GOOGLE"], required: true },
346
- google: {
347
- email: { type: String, required: true },
348
- credentials: { type: mongoose.Schema.Types.Mixed, required: true }
349
- }
350
- },
351
- createdAt: { type: Date, default: Date.now }
352
- },
353
- { minimize: false }
354
- );
355
- StorageAccountSchema.index({ owner: 1, "metadata.provider": 1 });
356
- StorageAccountSchema.index({ owner: 1, "metadata.google.email": 1 });
357
- StorageAccountSchema.method("toClient", async function() {
358
- const data = this.toJSON();
359
- return {
360
- id: String(data._id),
361
- owner: data.owner,
362
- name: data.name,
363
- metadata: data.metadata,
364
- createdAt: data.createdAt
365
- };
366
- });
367
- var StorageAccount = mongoose__default.default.models.StorageAccount || mongoose__default.default.model("StorageAccount", StorageAccountSchema);
368
- var account_default = StorageAccount;
369
340
  var validateMimeType = (mime, allowedTypes) => {
370
341
  if (allowedTypes.includes("*/*")) return true;
371
342
  return allowedTypes.some((pattern) => {
@@ -529,97 +500,6 @@ var getImageSettings = (fileSizeInBytes, qualityPreset, display, size, fit, posi
529
500
  ...resolvedPosition && { position: resolvedPosition }
530
501
  };
531
502
  };
532
- var objectIdSchema = zod.z.string().refine((val) => mongoose.isValidObjectId(val), {
533
- message: "Invalid ObjectId format"
534
- });
535
- var sanitizeFilename = (name) => {
536
- return name.replace(/[<>:"|?*\x00-\x1F]/g, "").replace(/^\.+/, "").replace(/\.+$/, "").replace(/\\/g, "/").replace(/\/+/g, "/").replace(/\.\.\//g, "").replace(/\.\.+/g, "").split("/").pop() || "".trim().slice(0, 255);
537
- };
538
- var sanitizeRegexInput = (input) => {
539
- return input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").slice(0, 100);
540
- };
541
- var nameSchema = zod.z.string().min(1, "Name is required").max(255, "Name too long").transform(sanitizeFilename).refine((val) => val.length > 0, { message: "Invalid name after sanitization" });
542
- var uploadChunkSchema = zod.z.object({
543
- chunkIndex: zod.z.number().int().min(0).max(1e4),
544
- totalChunks: zod.z.number().int().min(1).max(1e4),
545
- driveId: zod.z.string().optional(),
546
- fileName: nameSchema,
547
- fileSize: zod.z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),
548
- fileType: zod.z.string().min(1).max(255),
549
- folderId: zod.z.string().optional()
550
- }).refine((data) => data.chunkIndex < data.totalChunks, {
551
- message: "Chunk index must be less than total chunks"
552
- });
553
- var listQuerySchema = zod.z.object({
554
- folderId: zod.z.union([zod.z.literal("root"), objectIdSchema, zod.z.undefined()]),
555
- limit: zod.z.string().optional().transform((val) => {
556
- const num = parseInt(val || "50", 10);
557
- return Math.min(Math.max(1, num), 100);
558
- }),
559
- afterId: objectIdSchema.optional()
560
- });
561
- zod.z.object({
562
- id: objectIdSchema,
563
- token: zod.z.string().optional()
564
- });
565
- zod.z.object({
566
- id: objectIdSchema,
567
- size: zod.z.enum(["small", "medium", "large"]).optional().default("medium"),
568
- token: zod.z.string().optional()
569
- });
570
- var renameBodySchema = zod.z.object({
571
- id: objectIdSchema,
572
- newName: nameSchema
573
- });
574
- var deleteQuerySchema = zod.z.object({
575
- id: objectIdSchema
576
- });
577
- zod.z.object({
578
- ids: zod.z.array(objectIdSchema).min(1).max(1e3)
579
- });
580
- var createFolderBodySchema = zod.z.object({
581
- name: nameSchema,
582
- parentId: zod.z.union([zod.z.literal("root"), objectIdSchema, zod.z.string().length(0), zod.z.undefined()]).optional()
583
- });
584
- var moveBodySchema = zod.z.object({
585
- ids: zod.z.array(objectIdSchema).min(1).max(1e3),
586
- targetFolderId: zod.z.union([zod.z.literal("root"), objectIdSchema, zod.z.undefined()]).optional()
587
- });
588
- zod.z.object({
589
- ids: zod.z.array(objectIdSchema).min(1).max(1e3)
590
- });
591
- var searchQuerySchema = zod.z.object({
592
- q: zod.z.string().min(1).max(100).transform(sanitizeRegexInput),
593
- folderId: zod.z.union([zod.z.literal("root"), objectIdSchema, zod.z.undefined()]).optional(),
594
- limit: zod.z.string().optional().transform((val) => {
595
- const num = parseInt(val || "50", 10);
596
- return Math.min(Math.max(1, num), 100);
597
- }),
598
- trashed: zod.z.string().optional().transform((val) => val === "true")
599
- });
600
- zod.z.object({
601
- id: objectIdSchema
602
- });
603
- var cancelQuerySchema = zod.z.object({
604
- id: zod.z.string().uuid()
605
- });
606
- zod.z.object({
607
- days: zod.z.number().int().min(1).max(365).optional()
608
- });
609
- var driveFileSchemaZod = zod.z.object({
610
- id: zod.z.string(),
611
- file: zod.z.object({
612
- name: zod.z.string(),
613
- mime: zod.z.string(),
614
- size: zod.z.number()
615
- })
616
- });
617
-
618
- // src/server/security/cryptoUtils.ts
619
- function sanitizeContentDispositionFilename(filename) {
620
- const basename = filename.replace(/^.*[\\\/]/, "");
621
- return basename.replace(/["\r\n]/g, "").replace(/[^\x20-\x7E]/g, "").slice(0, 255);
622
- }
623
503
  var generatePlaceholderThumbnail = async (outputPath, mimeType) => {
624
504
  const typeParts = mimeType.split("/");
625
505
  const subtype = typeParts[1] || "file";
@@ -816,6 +696,37 @@ var LocalStorageProvider = {
816
696
  revokeToken: async (owner, accountId) => {
817
697
  }
818
698
  };
699
+ var StorageAccountSchema = new mongoose.Schema(
700
+ {
701
+ owner: { type: mongoose.Schema.Types.Mixed, default: null },
702
+ name: { type: String, required: true },
703
+ metadata: {
704
+ provider: { type: String, enum: ["GOOGLE"], required: true },
705
+ google: {
706
+ email: { type: String, required: true },
707
+ credentials: { type: mongoose.Schema.Types.Mixed, required: true }
708
+ }
709
+ },
710
+ createdAt: { type: Date, default: Date.now }
711
+ },
712
+ { minimize: false }
713
+ );
714
+ StorageAccountSchema.index({ owner: 1, "metadata.provider": 1 });
715
+ StorageAccountSchema.index({ owner: 1, "metadata.google.email": 1 });
716
+ StorageAccountSchema.method("toClient", async function() {
717
+ const data = this.toJSON();
718
+ return {
719
+ id: String(data._id),
720
+ owner: data.owner,
721
+ name: data.name,
722
+ metadata: data.metadata,
723
+ createdAt: data.createdAt
724
+ };
725
+ });
726
+ var StorageAccount = mongoose__default.default.models.StorageAccount || mongoose__default.default.model("StorageAccount", StorageAccountSchema);
727
+ var account_default = StorageAccount;
728
+
729
+ // src/server/providers/google.ts
819
730
  var createAuthClient = async (owner, accountId) => {
820
731
  const query = { owner, "metadata.provider": "GOOGLE" };
821
732
  if (accountId) query._id = accountId;
@@ -1282,6 +1193,8 @@ var GoogleDriveProvider = {
1282
1193
  }
1283
1194
  }
1284
1195
  };
1196
+
1197
+ // src/server/controllers/drive.ts
1285
1198
  var getNextOrderValue = async (owner) => {
1286
1199
  const lastItem = await drive_default.findOne({ owner }, {}, { sort: { order: -1 } });
1287
1200
  return lastItem ? lastItem.order + 1 : 0;
@@ -1302,7 +1215,22 @@ var driveGetUrl = (fileId, options) => {
1302
1215
  }
1303
1216
  const signature = crypto2__default.default.createHmac("sha256", secret).update(`${fileId}:${expiryTimestamp}`).digest("hex");
1304
1217
  const token = Buffer.from(`${expiryTimestamp}:${signature}`).toString("base64url");
1305
- return `/api/drive?action=serve&id=${fileId}&token=${token}`;
1218
+ return `${config.apiUrl || "/api/drive"}?action=serve&id=${fileId}&token=${token}`;
1219
+ };
1220
+ var driveAddSignedUrlToken = (item, config) => {
1221
+ let token;
1222
+ if (config.security?.signedUrls?.enabled && config.security.signedUrls.secret) {
1223
+ const { secret, expiresIn } = config.security.signedUrls;
1224
+ const expiryTimestamp = Math.floor(Date.now() / 1e3) + expiresIn;
1225
+ const signature = crypto2__default.default.createHmac("sha256", secret).update(`${item.id}:${expiryTimestamp}`).digest("hex");
1226
+ token = Buffer.from(`${expiryTimestamp}:${signature}`).toString("base64url");
1227
+ }
1228
+ const apiUrl = config.apiUrl || "/api/drive";
1229
+ const url = `${apiUrl}?action=serve&id=${item.id}${token ? `&token=${token}` : ""}`;
1230
+ return { ...item, token, url };
1231
+ };
1232
+ var driveAddSignedUrlTokens = (items, config) => {
1233
+ return items.map((item) => driveAddSignedUrlToken(item, config));
1306
1234
  };
1307
1235
  var driveReadFile = async (file) => {
1308
1236
  let drive;
@@ -1462,7 +1390,8 @@ var driveList = async (options) => {
1462
1390
  query._id = { $lt: afterId };
1463
1391
  }
1464
1392
  const items = await drive_default.find(query, {}, { sort: { order: 1, _id: -1 }, limit });
1465
- return await Promise.all(items.map((item) => item.toClient()));
1393
+ const config = getDriveConfig();
1394
+ return driveAddSignedUrlTokens(await Promise.all(items.map((item) => item.toClient())), config);
1466
1395
  };
1467
1396
  var driveListFiles = async (options) => {
1468
1397
  const { key, folderId, accountId } = options;
@@ -1498,8 +1427,9 @@ var driveListFiles = async (options) => {
1498
1427
  drive_default.find(query, {}, { sort: { createdAt: -1 }, skip, limit })
1499
1428
  ]);
1500
1429
  const totalPages = Math.ceil(totalCount / limit);
1430
+ const config = getDriveConfig();
1501
1431
  return {
1502
- items: await Promise.all(items.map((item) => item.toClient())),
1432
+ items: driveAddSignedUrlTokens(await Promise.all(items.map((item) => item.toClient())), config),
1503
1433
  pagination: {
1504
1434
  page,
1505
1435
  limit,
@@ -1791,8 +1721,97 @@ var driveCleanup = async () => {
1791
1721
  }
1792
1722
  return { removed, totalFreedInBytes };
1793
1723
  };
1724
+ var objectIdSchema = zod.z.string().refine((val) => mongoose.isValidObjectId(val), {
1725
+ message: "Invalid ObjectId format"
1726
+ });
1727
+ var sanitizeFilename = (name) => {
1728
+ return name.replace(/[<>:"|?*\x00-\x1F]/g, "").replace(/^\.+/, "").replace(/\.+$/, "").replace(/\\/g, "/").replace(/\/+/g, "/").replace(/\.\.\//g, "").replace(/\.\.+/g, "").split("/").pop() || "".trim().slice(0, 255);
1729
+ };
1730
+ var sanitizeRegexInput = (input) => {
1731
+ return input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").slice(0, 100);
1732
+ };
1733
+ var nameSchema = zod.z.string().min(1, "Name is required").max(255, "Name too long").transform(sanitizeFilename).refine((val) => val.length > 0, { message: "Invalid name after sanitization" });
1734
+ var uploadChunkSchema = zod.z.object({
1735
+ chunkIndex: zod.z.number().int().min(0).max(1e4),
1736
+ totalChunks: zod.z.number().int().min(1).max(1e4),
1737
+ driveId: zod.z.string().optional(),
1738
+ fileName: nameSchema,
1739
+ fileSize: zod.z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),
1740
+ fileType: zod.z.string().min(1).max(255),
1741
+ folderId: zod.z.string().optional()
1742
+ }).refine((data) => data.chunkIndex < data.totalChunks, {
1743
+ message: "Chunk index must be less than total chunks"
1744
+ });
1745
+ var listQuerySchema = zod.z.object({
1746
+ folderId: zod.z.union([zod.z.literal("root"), objectIdSchema, zod.z.undefined()]),
1747
+ limit: zod.z.string().optional().transform((val) => {
1748
+ const num = parseInt(val || "50", 10);
1749
+ return Math.min(Math.max(1, num), 100);
1750
+ }),
1751
+ afterId: objectIdSchema.optional()
1752
+ });
1753
+ zod.z.object({
1754
+ id: objectIdSchema,
1755
+ token: zod.z.string().optional()
1756
+ });
1757
+ zod.z.object({
1758
+ id: objectIdSchema,
1759
+ size: zod.z.enum(["small", "medium", "large"]).optional().default("medium"),
1760
+ token: zod.z.string().optional()
1761
+ });
1762
+ var renameBodySchema = zod.z.object({
1763
+ id: objectIdSchema,
1764
+ newName: nameSchema
1765
+ });
1766
+ var deleteQuerySchema = zod.z.object({
1767
+ id: objectIdSchema
1768
+ });
1769
+ zod.z.object({
1770
+ ids: zod.z.array(objectIdSchema).min(1).max(1e3)
1771
+ });
1772
+ var createFolderBodySchema = zod.z.object({
1773
+ name: nameSchema,
1774
+ parentId: zod.z.union([zod.z.literal("root"), objectIdSchema, zod.z.string().length(0), zod.z.undefined()]).optional()
1775
+ });
1776
+ var moveBodySchema = zod.z.object({
1777
+ ids: zod.z.array(objectIdSchema).min(1).max(1e3),
1778
+ targetFolderId: zod.z.union([zod.z.literal("root"), objectIdSchema, zod.z.undefined()]).optional()
1779
+ });
1780
+ zod.z.object({
1781
+ ids: zod.z.array(objectIdSchema).min(1).max(1e3)
1782
+ });
1783
+ var searchQuerySchema = zod.z.object({
1784
+ q: zod.z.string().min(1).max(100).transform(sanitizeRegexInput),
1785
+ folderId: zod.z.union([zod.z.literal("root"), objectIdSchema, zod.z.undefined()]).optional(),
1786
+ limit: zod.z.string().optional().transform((val) => {
1787
+ const num = parseInt(val || "50", 10);
1788
+ return Math.min(Math.max(1, num), 100);
1789
+ }),
1790
+ trashed: zod.z.string().optional().transform((val) => val === "true")
1791
+ });
1792
+ zod.z.object({
1793
+ id: objectIdSchema
1794
+ });
1795
+ var cancelQuerySchema = zod.z.object({
1796
+ id: zod.z.string().uuid()
1797
+ });
1798
+ zod.z.object({
1799
+ days: zod.z.number().int().min(1).max(365).optional()
1800
+ });
1801
+ var driveFileSchemaZod = zod.z.object({
1802
+ id: zod.z.string(),
1803
+ file: zod.z.object({
1804
+ name: zod.z.string(),
1805
+ mime: zod.z.string(),
1806
+ size: zod.z.number()
1807
+ })
1808
+ });
1794
1809
 
1795
- // src/server/index.ts
1810
+ // src/server/security/cryptoUtils.ts
1811
+ function sanitizeContentDispositionFilename(filename) {
1812
+ const basename = filename.replace(/^.*[\\\/]/, "");
1813
+ return basename.replace(/["\r\n]/g, "").replace(/[^\x20-\x7E]/g, "").slice(0, 255);
1814
+ }
1796
1815
  var getProvider = async (req, owner) => {
1797
1816
  const accountId = req.headers["x-drive-account"];
1798
1817
  if (!accountId || accountId === "LOCAL") {
@@ -1806,19 +1825,10 @@ var getProvider = async (req, owner) => {
1806
1825
  return { provider: LocalStorageProvider };
1807
1826
  };
1808
1827
  var addSignedUrlToken = (item, config) => {
1809
- if (!config.security?.signedUrls?.enabled || !config.security.signedUrls.secret) {
1810
- return item;
1811
- }
1812
- const { secret, expiresIn } = config.security.signedUrls;
1813
- const expiryTimestamp = Math.floor(Date.now() / 1e3) + expiresIn;
1814
- const signature = crypto2__default.default.createHmac("sha256", secret).update(`${item.id}:${expiryTimestamp}`).digest("hex");
1815
- return { ...item, token: Buffer.from(`${expiryTimestamp}:${signature}`).toString("base64url") };
1828
+ return driveAddSignedUrlToken(item, config);
1816
1829
  };
1817
1830
  var addSignedUrlTokens = (items, config) => {
1818
- if (!config.security?.signedUrls?.enabled || !config.security.signedUrls.secret) {
1819
- return items;
1820
- }
1821
- return items.map((item) => addSignedUrlToken(item, config));
1831
+ return driveAddSignedUrlTokens(items, config);
1822
1832
  };
1823
1833
  var applyCorsHeaders = (req, res, config) => {
1824
1834
  const cors = config.cors;
@@ -2552,5 +2562,5 @@ exports.driveUpload = driveUpload;
2552
2562
  exports.drive_default = drive_default;
2553
2563
  exports.getDriveConfig = getDriveConfig;
2554
2564
  exports.getDriveInformation = getDriveInformation;
2555
- //# sourceMappingURL=chunk-RBLDH7CP.cjs.map
2556
- //# sourceMappingURL=chunk-RBLDH7CP.cjs.map
2565
+ //# sourceMappingURL=chunk-VIB7R4JN.cjs.map
2566
+ //# sourceMappingURL=chunk-VIB7R4JN.cjs.map