@muhgholy/next-drive 3.9.0 → 3.10.0
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/dist/{chunk-WPX4ZQ4V.js → chunk-32UNO3KE.js} +101 -46
- package/dist/chunk-32UNO3KE.js.map +1 -0
- package/dist/{chunk-RL3P26H3.cjs → chunk-UCSCXKC2.cjs} +101 -46
- package/dist/chunk-UCSCXKC2.cjs.map +1 -0
- package/dist/server/config.d.ts.map +1 -1
- package/dist/server/controllers/drive.d.ts.map +1 -1
- package/dist/server/express.cjs +11 -11
- package/dist/server/express.js +2 -2
- package/dist/server/index.cjs +13 -13
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/providers/google.d.ts.map +1 -1
- package/dist/server/providers/local.d.ts.map +1 -1
- package/dist/types/server/config.d.ts +14 -3
- package/dist/types/server/config.d.ts.map +1 -1
- package/dist/types/server/express.d.ts +40 -15
- package/dist/types/server/express.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-RL3P26H3.cjs.map +0 -1
- package/dist/chunk-WPX4ZQ4V.js.map +0 -1
|
@@ -15,25 +15,35 @@ var driveConfiguration = (config) => {
|
|
|
15
15
|
if (mongoose2.connection.readyState !== 1) {
|
|
16
16
|
throw new Error("Database not connected. Please connect to Mongoose before initializing next-drive.");
|
|
17
17
|
}
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
18
|
+
const mode = config.mode || "NORMAL";
|
|
19
|
+
if (mode === "ROOT") {
|
|
20
|
+
globalConfig = {
|
|
21
|
+
...config,
|
|
22
|
+
mode: "ROOT",
|
|
23
|
+
security: config.security || {
|
|
24
|
+
maxUploadSizeInBytes: 1024 * 1024 * 1024 * 10,
|
|
25
|
+
// 10GB default for ROOT
|
|
26
|
+
allowedMimeTypes: ["*/*"]
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
return globalConfig;
|
|
30
|
+
} else {
|
|
31
|
+
if (!config.information) {
|
|
32
|
+
throw new Error("information callback is required in NORMAL mode");
|
|
33
|
+
}
|
|
34
|
+
globalConfig = {
|
|
35
|
+
...config,
|
|
36
|
+
mode: "NORMAL",
|
|
37
|
+
security: {
|
|
38
|
+
maxUploadSizeInBytes: config.security?.maxUploadSizeInBytes ?? 10 * 1024 * 1024,
|
|
39
|
+
allowedMimeTypes: config.security?.allowedMimeTypes ?? ["*/*"],
|
|
40
|
+
signedUrls: config.security?.signedUrls,
|
|
41
|
+
trash: config.security?.trash
|
|
42
|
+
},
|
|
43
|
+
information: config.information
|
|
44
|
+
};
|
|
45
|
+
return globalConfig;
|
|
46
|
+
}
|
|
37
47
|
};
|
|
38
48
|
var getDriveConfig = () => {
|
|
39
49
|
if (!globalConfig) throw new Error("Drive configuration not initialized");
|
|
@@ -41,6 +51,16 @@ var getDriveConfig = () => {
|
|
|
41
51
|
};
|
|
42
52
|
var getDriveInformation = async (req) => {
|
|
43
53
|
const config = getDriveConfig();
|
|
54
|
+
if (config.mode === "ROOT") {
|
|
55
|
+
if (!config.information) {
|
|
56
|
+
return {
|
|
57
|
+
key: null,
|
|
58
|
+
storage: { quotaInBytes: Number.MAX_SAFE_INTEGER }
|
|
59
|
+
// Unlimited quota in ROOT mode
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return config.information(req);
|
|
63
|
+
}
|
|
44
64
|
return config.information(req);
|
|
45
65
|
};
|
|
46
66
|
var informationSchema = new Schema({
|
|
@@ -252,19 +272,25 @@ var LocalStorageProvider = {
|
|
|
252
272
|
search: async (query, owner, accountId) => {
|
|
253
273
|
},
|
|
254
274
|
getQuota: async (owner, accountId, configuredQuotaInBytes) => {
|
|
275
|
+
const config = getDriveConfig();
|
|
276
|
+
const isRootMode = config.mode === "ROOT";
|
|
277
|
+
const match = {
|
|
278
|
+
"information.type": "FILE",
|
|
279
|
+
trashedAt: null,
|
|
280
|
+
"provider.type": "LOCAL",
|
|
281
|
+
storageAccountId: accountId || null
|
|
282
|
+
};
|
|
283
|
+
if (!isRootMode) {
|
|
284
|
+
match.owner = owner;
|
|
285
|
+
}
|
|
255
286
|
const result = await drive_default.aggregate([
|
|
256
|
-
{
|
|
257
|
-
$match: {
|
|
258
|
-
owner,
|
|
259
|
-
"information.type": "FILE",
|
|
260
|
-
trashedAt: null,
|
|
261
|
-
"provider.type": "LOCAL",
|
|
262
|
-
storageAccountId: accountId || null
|
|
263
|
-
}
|
|
264
|
-
},
|
|
287
|
+
{ $match: match },
|
|
265
288
|
{ $group: { _id: null, total: { $sum: "$information.sizeInBytes" } } }
|
|
266
289
|
]);
|
|
267
290
|
const usedInBytes = result[0]?.total || 0;
|
|
291
|
+
if (isRootMode) {
|
|
292
|
+
return { usedInBytes, quotaInBytes: Number.MAX_SAFE_INTEGER };
|
|
293
|
+
}
|
|
268
294
|
return { usedInBytes, quotaInBytes: configuredQuotaInBytes ?? 0 };
|
|
269
295
|
},
|
|
270
296
|
openStream: async (item, accountId) => {
|
|
@@ -606,6 +632,23 @@ var GoogleDriveProvider = {
|
|
|
606
632
|
}
|
|
607
633
|
},
|
|
608
634
|
getQuota: async (owner, accountId, _configuredQuotaInBytes) => {
|
|
635
|
+
const config = getDriveConfig();
|
|
636
|
+
const isRootMode = config.mode === "ROOT";
|
|
637
|
+
if (isRootMode) {
|
|
638
|
+
const result = await drive_default.aggregate([
|
|
639
|
+
{
|
|
640
|
+
$match: {
|
|
641
|
+
"information.type": "FILE",
|
|
642
|
+
trashedAt: null,
|
|
643
|
+
"provider.type": "GOOGLE",
|
|
644
|
+
storageAccountId: accountId || null
|
|
645
|
+
}
|
|
646
|
+
},
|
|
647
|
+
{ $group: { _id: null, total: { $sum: "$information.sizeInBytes" } } }
|
|
648
|
+
]);
|
|
649
|
+
const usedInBytes = result[0]?.total || 0;
|
|
650
|
+
return { usedInBytes, quotaInBytes: Number.MAX_SAFE_INTEGER };
|
|
651
|
+
}
|
|
609
652
|
try {
|
|
610
653
|
const { client } = await createAuthClient(owner, accountId);
|
|
611
654
|
const drive = google.drive({ version: "v3", auth: client });
|
|
@@ -832,7 +875,7 @@ var getNextOrderValue = async (owner) => {
|
|
|
832
875
|
};
|
|
833
876
|
var driveGetUrl = (fileId, options) => {
|
|
834
877
|
const config = getDriveConfig();
|
|
835
|
-
if (!config.security
|
|
878
|
+
if (!config.security?.signedUrls?.enabled) {
|
|
836
879
|
return `/api/drive?action=serve&id=${fileId}`;
|
|
837
880
|
}
|
|
838
881
|
const { secret, expiresIn } = config.security.signedUrls;
|
|
@@ -1119,13 +1162,14 @@ var driveUpload = async (source, key, options) => {
|
|
|
1119
1162
|
};
|
|
1120
1163
|
mimeType = mimeTypes[ext] || "application/octet-stream";
|
|
1121
1164
|
}
|
|
1122
|
-
if (!validateMimeType(mimeType, config.security.allowedMimeTypes)) {
|
|
1165
|
+
if (config.security && !validateMimeType(mimeType, config.security.allowedMimeTypes)) {
|
|
1123
1166
|
throw new Error(`File type ${mimeType} not allowed`);
|
|
1124
1167
|
}
|
|
1125
|
-
if (fileSize > config.security.maxUploadSizeInBytes) {
|
|
1168
|
+
if (config.security && fileSize > config.security.maxUploadSizeInBytes) {
|
|
1126
1169
|
throw new Error(`File size ${fileSize} exceeds maximum allowed size ${config.security.maxUploadSizeInBytes}`);
|
|
1127
1170
|
}
|
|
1128
|
-
|
|
1171
|
+
const isRootMode = config.mode === "ROOT";
|
|
1172
|
+
if (!options.enforce && !isRootMode) {
|
|
1129
1173
|
const quota = await provider.getQuota(key, accountId, void 0);
|
|
1130
1174
|
if (quota.usedInBytes + fileSize > quota.quotaInBytes) {
|
|
1131
1175
|
throw new Error("Storage quota exceeded");
|
|
@@ -1251,7 +1295,7 @@ var driveAPIHandler = async (req, res) => {
|
|
|
1251
1295
|
}
|
|
1252
1296
|
const drive = await drive_default.findById(id);
|
|
1253
1297
|
if (!drive) return res.status(404).json({ status: 404, message: "File not found" });
|
|
1254
|
-
if (config.security
|
|
1298
|
+
if (config.security?.signedUrls?.enabled) {
|
|
1255
1299
|
if (!token || typeof token !== "string") {
|
|
1256
1300
|
return res.status(401).json({ status: 401, message: "Missing or invalid token" });
|
|
1257
1301
|
}
|
|
@@ -1303,9 +1347,11 @@ var driveAPIHandler = async (req, res) => {
|
|
|
1303
1347
|
}
|
|
1304
1348
|
}
|
|
1305
1349
|
try {
|
|
1350
|
+
const mode = config.mode || "NORMAL";
|
|
1306
1351
|
const information = await getDriveInformation(req);
|
|
1307
1352
|
const { key: owner } = information;
|
|
1308
1353
|
const STORAGE_PATH = config.storage.path;
|
|
1354
|
+
const isRootMode = mode === "ROOT";
|
|
1309
1355
|
if (action === "information") {
|
|
1310
1356
|
const { clientId, clientSecret, redirectUri } = config.storage?.google || {};
|
|
1311
1357
|
const googleConfigured = !!(clientId && clientSecret && redirectUri);
|
|
@@ -1315,7 +1361,8 @@ var driveAPIHandler = async (req, res) => {
|
|
|
1315
1361
|
data: {
|
|
1316
1362
|
providers: {
|
|
1317
1363
|
google: googleConfigured
|
|
1318
|
-
}
|
|
1364
|
+
},
|
|
1365
|
+
mode
|
|
1319
1366
|
}
|
|
1320
1367
|
});
|
|
1321
1368
|
}
|
|
@@ -1448,12 +1495,14 @@ var driveAPIHandler = async (req, res) => {
|
|
|
1448
1495
|
console.error("Sync failed", e);
|
|
1449
1496
|
}
|
|
1450
1497
|
const query = {
|
|
1451
|
-
owner,
|
|
1452
1498
|
"provider.type": provider.name,
|
|
1453
1499
|
storageAccountId: accountId || null,
|
|
1454
1500
|
parentId: folderId === "root" || !folderId ? null : folderId,
|
|
1455
1501
|
trashedAt: null
|
|
1456
1502
|
};
|
|
1503
|
+
if (!isRootMode) {
|
|
1504
|
+
query.owner = owner;
|
|
1505
|
+
}
|
|
1457
1506
|
if (afterId) query._id = { $lt: afterId };
|
|
1458
1507
|
const items = await drive_default.find(query, {}, { sort: { order: 1, _id: -1 }, limit });
|
|
1459
1508
|
const plainItems = await Promise.all(items.map((item) => item.toClient()));
|
|
@@ -1473,12 +1522,14 @@ var driveAPIHandler = async (req, res) => {
|
|
|
1473
1522
|
}
|
|
1474
1523
|
}
|
|
1475
1524
|
const query = {
|
|
1476
|
-
owner,
|
|
1477
1525
|
"provider.type": provider.name,
|
|
1478
1526
|
storageAccountId: accountId || null,
|
|
1479
1527
|
trashedAt: trashed ? { $ne: null } : null,
|
|
1480
1528
|
name: { $regex: q, $options: "i" }
|
|
1481
1529
|
};
|
|
1530
|
+
if (!isRootMode) {
|
|
1531
|
+
query.owner = owner;
|
|
1532
|
+
}
|
|
1482
1533
|
if (folderId && folderId !== "root") query.parentId = folderId;
|
|
1483
1534
|
const items = await drive_default.find(query, {}, { limit, sort: { createdAt: -1 } });
|
|
1484
1535
|
const plainItems = await Promise.all(items.map((i) => i.toClient()));
|
|
@@ -1491,7 +1542,7 @@ var driveAPIHandler = async (req, res) => {
|
|
|
1491
1542
|
if (!fs4.existsSync(systemTmpDir)) fs4.mkdirSync(systemTmpDir, { recursive: true });
|
|
1492
1543
|
const form = formidable({
|
|
1493
1544
|
multiples: false,
|
|
1494
|
-
maxFileSize: config.security
|
|
1545
|
+
maxFileSize: (config.security?.maxUploadSizeInBytes ?? 1024 * 1024 * 1024) * 2,
|
|
1495
1546
|
uploadDir: systemTmpDir,
|
|
1496
1547
|
keepExtensions: true
|
|
1497
1548
|
});
|
|
@@ -1526,14 +1577,18 @@ var driveAPIHandler = async (req, res) => {
|
|
|
1526
1577
|
const tempBaseDir = path3.join(os2.tmpdir(), "next-drive-uploads");
|
|
1527
1578
|
if (!currentUploadId) {
|
|
1528
1579
|
if (chunkIndex !== 0) return res.status(400).json({ message: "Missing upload ID for non-zero chunk" });
|
|
1529
|
-
if (fileType &&
|
|
1530
|
-
|
|
1531
|
-
|
|
1580
|
+
if (fileType && config.security) {
|
|
1581
|
+
if (!validateMimeType(fileType, config.security.allowedMimeTypes)) {
|
|
1582
|
+
cleanupTempFiles(files);
|
|
1583
|
+
return res.status(400).json({ status: 400, message: `File type ${fileType} not allowed` });
|
|
1584
|
+
}
|
|
1532
1585
|
}
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1586
|
+
if (!isRootMode) {
|
|
1587
|
+
const quota = await provider.getQuota(owner, accountId, information.storage.quotaInBytes);
|
|
1588
|
+
if (quota.usedInBytes + fileSizeInBytes > quota.quotaInBytes) {
|
|
1589
|
+
cleanupTempFiles(files);
|
|
1590
|
+
return res.status(413).json({ status: 413, message: "Storage quota exceeded" });
|
|
1591
|
+
}
|
|
1537
1592
|
}
|
|
1538
1593
|
currentUploadId = crypto2.randomUUID();
|
|
1539
1594
|
const uploadDir = path3.join(tempBaseDir, currentUploadId);
|
|
@@ -1798,5 +1853,5 @@ var driveAPIHandler = async (req, res) => {
|
|
|
1798
1853
|
};
|
|
1799
1854
|
|
|
1800
1855
|
export { driveAPIHandler, driveConfiguration, driveDelete, driveFilePath, driveFileSchemaZod, driveGetUrl, driveInfo, driveList, driveReadFile, driveUpload, getDriveConfig, getDriveInformation };
|
|
1801
|
-
//# sourceMappingURL=chunk-
|
|
1802
|
-
//# sourceMappingURL=chunk-
|
|
1856
|
+
//# sourceMappingURL=chunk-32UNO3KE.js.map
|
|
1857
|
+
//# sourceMappingURL=chunk-32UNO3KE.js.map
|