mbkbucket 4.0.0 → 4.1.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/.env.example +16 -15
- package/README.md +613 -561
- package/index.js +36 -33
- package/lib/cli.js +239 -239
- package/lib/public/bucketadmin.css +2042 -2042
- package/lib/public/bucketadmin.js +1844 -1622
- package/lib/public/mbkbucket-helper-demo.html +0 -58
- package/lib/public/mbkbucket-helper.js +1 -9
- package/lib/src/config/validation.js +91 -86
- package/lib/src/controllers/api.controller.js +486 -459
- package/lib/src/controllers/dashboard.controller.js +69 -69
- package/lib/src/controllers/info.controller.js +13 -13
- package/lib/src/controllers/view.controller.js +234 -233
- package/lib/src/core/metrics.js +134 -0
- package/lib/src/core/storage/capabilities.js +58 -0
- package/lib/src/core/storage/errors.js +0 -5
- package/lib/src/core/storage/gdrive-auth.js +0 -36
- package/lib/src/core/storage/gdrive-provider.js +101 -43
- package/lib/src/core/storage/index.js +4 -1
- package/lib/src/core/storage/local-provider.js +507 -0
- package/lib/src/core/storage/models.js +90 -50
- package/lib/src/core/storage/path-strategy.js +14 -1
- package/lib/src/core/storage/s3-provider.js +17 -37
- package/lib/src/core/storage/storage-manager.js +70 -50
- package/lib/src/core/storage/storage-provider.js +49 -120
- package/lib/src/middleware/bucket-resolver.js +37 -37
- package/lib/src/routes/api.routes.js +4 -1
- package/lib/src/routes/index.js +60 -60
- package/lib/src/routes/view.routes.js +28 -28
- package/lib/src/services/s3.service.js +42 -42
- package/lib/src/services/storage.service.js +311 -213
- package/lib/src/utils/cleanup-scheduler.js +91 -0
- package/lib/src/utils/errors.js +56 -56
- package/lib/src/utils/helpers.js +6 -6
- package/package.json +3 -5
- package/views/bucket.hbs +0 -5
- package/views/bucketadmin_move_modal.hbs +35 -35
- package/views/bucketadmin_preview_modal.hbs +108 -108
- package/views/bucketadmincontent.hbs +193 -193
- package/views/mbkbucket_info.hbs +134 -134
|
@@ -2,7 +2,7 @@ import express from "express";
|
|
|
2
2
|
import { sessRole } from "mbkauthe";
|
|
3
3
|
import multer from "multer";
|
|
4
4
|
import { requireBucketApi } from "../middleware/bucket-resolver.js";
|
|
5
|
-
import { cleanupUploads, listIncompleteUploads, listFiles, uploadSingleFile, initiateMultipartUpload, uploadChunk, completeUpload, abortUpload, createFolder, deleteItems, downloadFileHandler, moveItem, copyItem, getHealthStatus, getFileInfo } from "../controllers/api.controller.js";
|
|
5
|
+
import { cleanupUploads, listIncompleteUploads, listFiles, uploadSingleFile, initiateMultipartUpload, uploadChunk, completeUpload, abortUpload, createFolder, deleteItems, downloadFileHandler, moveItem, copyItem, getHealthStatus, getFileInfo, getMetricsHandler } from "../controllers/api.controller.js";
|
|
6
6
|
|
|
7
7
|
const MAX_CHUNK_SIZE = 50 * 1024 * 1024; // 50 MB
|
|
8
8
|
const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: MAX_CHUNK_SIZE } });
|
|
@@ -38,6 +38,8 @@ export function createApiRoutes({
|
|
|
38
38
|
apiRouter.get('/api/files', viewAuth, listFiles);
|
|
39
39
|
apiRouter.get('/api/health', viewAuth, getHealthStatus);
|
|
40
40
|
apiRouter.get('/api/file-info/*key', viewAuth, getFileInfo);
|
|
41
|
+
apiRouter.get('/api/metrics', viewAuth, getMetricsHandler);
|
|
42
|
+
apiRouter.get('/metrics', viewAuth, getMetricsHandler);
|
|
41
43
|
apiRouter.post('/upload', uploadAuth, upload.single('file'), uploadSingleFile);
|
|
42
44
|
apiRouter.post('/upload-init', uploadAuth, initiateMultipartUpload);
|
|
43
45
|
apiRouter.post('/upload-chunk', uploadAuth, uploadChunkMiddleware, uploadChunk);
|
|
@@ -52,6 +54,7 @@ export function createApiRoutes({
|
|
|
52
54
|
return apiRouter;
|
|
53
55
|
}
|
|
54
56
|
|
|
57
|
+
|
|
55
58
|
const router = createApiRoutes();
|
|
56
59
|
|
|
57
60
|
export default router;
|
package/lib/src/routes/index.js
CHANGED
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MBKBucket
|
|
3
|
-
* Copyright (c) 2026 Muhammad Bin Khalid, MBKTech.org and contributors
|
|
4
|
-
* Licensed under the MIT License.
|
|
5
|
-
* Source: https://github.com/MIbnEKhalid/mbkbucket
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import express from "express";
|
|
9
|
-
import { sessRole } from "mbkauthe";
|
|
10
|
-
import path from "path";
|
|
11
|
-
import { fileURLToPath } from "url";
|
|
12
|
-
import { bucketResolver } from "../middleware/bucket-resolver.js";
|
|
13
|
-
import { renderBucketDashboard } from "../controllers/dashboard.controller.js";
|
|
14
|
-
import infoRoutes from "./info.routes.js";
|
|
15
|
-
import { createViewRoutes } from "./view.routes.js";
|
|
16
|
-
import { createApiRoutes } from "./api.routes.js";
|
|
17
|
-
|
|
18
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
19
|
-
const __dirname = path.dirname(__filename);
|
|
20
|
-
const publicDir = path.resolve(__dirname, "..", "..", "public");
|
|
21
|
-
|
|
22
|
-
const serveAsset = (filename) => (_req, res) => {
|
|
23
|
-
res.set("Cache-Control", "public, max-age=300, must-revalidate");
|
|
24
|
-
res.sendFile(path.join(publicDir, filename), (err) => {
|
|
25
|
-
if (err) res.status(err.status || 404).end();
|
|
26
|
-
});
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export function createBucketRouter({ authorization, publiViewEnabled } = {}) {
|
|
30
|
-
const router = express.Router();
|
|
31
|
-
const defaultAuth = sessRole('superadmin');
|
|
32
|
-
const auths = typeof authorization === 'function'
|
|
33
|
-
? { view: authorization, upload: authorization, delete: authorization }
|
|
34
|
-
: authorization ?? {};
|
|
35
|
-
const viewAuth = auths.view ?? defaultAuth;
|
|
36
|
-
const uploadAuth = auths.upload ?? defaultAuth;
|
|
37
|
-
const deleteAuth = auths.delete ?? defaultAuth;
|
|
38
|
-
|
|
39
|
-
// Static dashboard & helper assets
|
|
40
|
-
router.get('/mbkbucket/bucketadmin.css', serveAsset('bucketadmin.css'));
|
|
41
|
-
router.get('/mbkbucket/bucketadmin.js', serveAsset('bucketadmin.js'));
|
|
42
|
-
router.get('/mbkbucket/mbkbucket-helper.css', serveAsset('mbkbucket-helper.css'));
|
|
43
|
-
router.get('/mbkbucket/mbkbucket-helper.js', serveAsset('mbkbucket-helper.js'));
|
|
44
|
-
router.get('/mbkbucket/helper-demo', serveAsset('mbkbucket-helper-demo.html'));
|
|
45
|
-
|
|
46
|
-
router.get('/mbkbucket', viewAuth, renderBucketDashboard);
|
|
47
|
-
router.use(
|
|
48
|
-
'/mbkbucket',
|
|
49
|
-
bucketResolver,
|
|
50
|
-
infoRoutes,
|
|
51
|
-
createViewRoutes({ authorization: viewAuth, publiViewEnabled }),
|
|
52
|
-
createApiRoutes({ viewAuthorization: viewAuth, uploadAuthorization: uploadAuth, deleteAuthorization: deleteAuth })
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
return router;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const router = createBucketRouter();
|
|
59
|
-
|
|
60
|
-
export default router;
|
|
1
|
+
/**
|
|
2
|
+
* MBKBucket
|
|
3
|
+
* Copyright (c) 2026 Muhammad Bin Khalid, MBKTech.org and contributors
|
|
4
|
+
* Licensed under the MIT License.
|
|
5
|
+
* Source: https://github.com/MIbnEKhalid/mbkbucket
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import express from "express";
|
|
9
|
+
import { sessRole } from "mbkauthe";
|
|
10
|
+
import path from "path";
|
|
11
|
+
import { fileURLToPath } from "url";
|
|
12
|
+
import { bucketResolver } from "../middleware/bucket-resolver.js";
|
|
13
|
+
import { renderBucketDashboard } from "../controllers/dashboard.controller.js";
|
|
14
|
+
import infoRoutes from "./info.routes.js";
|
|
15
|
+
import { createViewRoutes } from "./view.routes.js";
|
|
16
|
+
import { createApiRoutes } from "./api.routes.js";
|
|
17
|
+
|
|
18
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
19
|
+
const __dirname = path.dirname(__filename);
|
|
20
|
+
const publicDir = path.resolve(__dirname, "..", "..", "public");
|
|
21
|
+
|
|
22
|
+
const serveAsset = (filename) => (_req, res) => {
|
|
23
|
+
res.set("Cache-Control", "public, max-age=300, must-revalidate");
|
|
24
|
+
res.sendFile(path.join(publicDir, filename), (err) => {
|
|
25
|
+
if (err) res.status(err.status || 404).end();
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export function createBucketRouter({ authorization, publiViewEnabled } = {}) {
|
|
30
|
+
const router = express.Router();
|
|
31
|
+
const defaultAuth = sessRole('superadmin');
|
|
32
|
+
const auths = typeof authorization === 'function'
|
|
33
|
+
? { view: authorization, upload: authorization, delete: authorization }
|
|
34
|
+
: authorization ?? {};
|
|
35
|
+
const viewAuth = auths.view ?? defaultAuth;
|
|
36
|
+
const uploadAuth = auths.upload ?? defaultAuth;
|
|
37
|
+
const deleteAuth = auths.delete ?? defaultAuth;
|
|
38
|
+
|
|
39
|
+
// Static dashboard & helper assets
|
|
40
|
+
router.get('/mbkbucket/bucketadmin.css', serveAsset('bucketadmin.css'));
|
|
41
|
+
router.get('/mbkbucket/bucketadmin.js', serveAsset('bucketadmin.js'));
|
|
42
|
+
router.get('/mbkbucket/mbkbucket-helper.css', serveAsset('mbkbucket-helper.css'));
|
|
43
|
+
router.get('/mbkbucket/mbkbucket-helper.js', serveAsset('mbkbucket-helper.js'));
|
|
44
|
+
router.get('/mbkbucket/helper-demo', serveAsset('mbkbucket-helper-demo.html'));
|
|
45
|
+
|
|
46
|
+
router.get('/mbkbucket', viewAuth, renderBucketDashboard);
|
|
47
|
+
router.use(
|
|
48
|
+
'/mbkbucket',
|
|
49
|
+
bucketResolver,
|
|
50
|
+
infoRoutes,
|
|
51
|
+
createViewRoutes({ authorization: viewAuth, publiViewEnabled }),
|
|
52
|
+
createApiRoutes({ viewAuthorization: viewAuth, uploadAuthorization: uploadAuth, deleteAuthorization: deleteAuth })
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
return router;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const router = createBucketRouter();
|
|
59
|
+
|
|
60
|
+
export default router;
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import express from "express";
|
|
2
|
-
import { sessRole } from "mbkauthe";
|
|
3
|
-
import { mbkbucketVar } from "../config/index.js";
|
|
4
|
-
import { requireBucketView } from "../middleware/bucket-resolver.js";
|
|
5
|
-
import { pviewRateLimit } from "../middleware/rate-limiter.js";
|
|
6
|
-
import { pviewSecurity } from "../middleware/security.js";
|
|
7
|
-
import { viewFile, playerPage, publicView } from "../controllers/view.controller.js";
|
|
8
|
-
|
|
9
|
-
export function createViewRoutes({
|
|
10
|
-
authorization = sessRole('superadmin'),
|
|
11
|
-
publiViewEnabled = mbkbucketVar?.publiView_enabled
|
|
12
|
-
} = {}) {
|
|
13
|
-
const viewRouter = express.Router();
|
|
14
|
-
|
|
15
|
-
viewRouter.use(requireBucketView);
|
|
16
|
-
viewRouter.get('/player/*key', authorization, playerPage);
|
|
17
|
-
viewRouter.get('/view/*key', authorization, viewFile);
|
|
18
|
-
|
|
19
|
-
if (publiViewEnabled ?? mbkbucketVar?.publiView_enabled) {
|
|
20
|
-
viewRouter.get('/p_view/*key', pviewRateLimit, pviewSecurity, publicView);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return viewRouter;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const router = createViewRoutes();
|
|
27
|
-
|
|
28
|
-
export default router;
|
|
1
|
+
import express from "express";
|
|
2
|
+
import { sessRole } from "mbkauthe";
|
|
3
|
+
import { mbkbucketVar } from "../config/index.js";
|
|
4
|
+
import { requireBucketView } from "../middleware/bucket-resolver.js";
|
|
5
|
+
import { pviewRateLimit } from "../middleware/rate-limiter.js";
|
|
6
|
+
import { pviewSecurity } from "../middleware/security.js";
|
|
7
|
+
import { viewFile, playerPage, publicView } from "../controllers/view.controller.js";
|
|
8
|
+
|
|
9
|
+
export function createViewRoutes({
|
|
10
|
+
authorization = sessRole('superadmin'),
|
|
11
|
+
publiViewEnabled = mbkbucketVar?.publiView_enabled
|
|
12
|
+
} = {}) {
|
|
13
|
+
const viewRouter = express.Router();
|
|
14
|
+
|
|
15
|
+
viewRouter.use(requireBucketView);
|
|
16
|
+
viewRouter.get('/player/*key', authorization, playerPage);
|
|
17
|
+
viewRouter.get('/view/*key', authorization, viewFile);
|
|
18
|
+
|
|
19
|
+
if (publiViewEnabled ?? mbkbucketVar?.publiView_enabled) {
|
|
20
|
+
viewRouter.get('/p_view/*key', pviewRateLimit, pviewSecurity, publicView);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return viewRouter;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const router = createViewRoutes();
|
|
27
|
+
|
|
28
|
+
export default router;
|
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MBKBucket - S3 Service Compatibility Layer
|
|
3
|
-
* Copyright (c) 2026 Muhammad Bin Khalid, MBKTech.org and contributors
|
|
4
|
-
* Licensed under the MIT License.
|
|
5
|
-
*
|
|
6
|
-
* Provides backwards-compatible S3 APIs delegating to the unified storage layer.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import { storageManager } from "../core/storage/storage-manager.js";
|
|
10
|
-
import { getAvailableBucketNames, resolveBucketName, getAppName, ensureKeyHasAppPrefix, ensurePrefix, uploadFile, downloadFile, deleteFile, deleteFiles, deleteFolder, listfiles, getFileMetadata, fileExists, getFileSize,
|
|
11
|
-
|
|
12
|
-
export { getAvailableBucketNames, resolveBucketName, getAppName, ensureKeyHasAppPrefix, ensurePrefix, uploadFile, downloadFile, deleteFile, deleteFiles, deleteFolder, listfiles, getFileMetadata, fileExists, getFileSize,
|
|
13
|
-
|
|
14
|
-
export function getBucketConfig(bucketName) {
|
|
15
|
-
return storageManager.getConnectionConfig(bucketName);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export function getBucketClient(bucketName) {
|
|
19
|
-
const provider = storageManager.getProvider(bucketName);
|
|
20
|
-
if (provider.client) {
|
|
21
|
-
return provider.client;
|
|
22
|
-
}
|
|
23
|
-
throw new Error(`Connection '${provider.name}' is of type '${provider.type}' and does not use an S3Client.`);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function getBucketClientAndConfig(bucketName) {
|
|
27
|
-
const resolved = resolveBucketName(bucketName);
|
|
28
|
-
return {
|
|
29
|
-
client: getBucketClient(resolved),
|
|
30
|
-
config: getBucketConfig(resolved),
|
|
31
|
-
bucketName: resolved
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
let _defaultClient = null;
|
|
36
|
-
export const bucketClient = new Proxy({}, {
|
|
37
|
-
get(_, prop) {
|
|
38
|
-
_defaultClient ??= getBucketClient();
|
|
39
|
-
const val = _defaultClient[prop];
|
|
40
|
-
return typeof val === 'function' ? val.bind(_defaultClient) : val;
|
|
41
|
-
}
|
|
42
|
-
});
|
|
1
|
+
/**
|
|
2
|
+
* MBKBucket - S3 Service Compatibility Layer
|
|
3
|
+
* Copyright (c) 2026 Muhammad Bin Khalid, MBKTech.org and contributors
|
|
4
|
+
* Licensed under the MIT License.
|
|
5
|
+
*
|
|
6
|
+
* Provides backwards-compatible S3 APIs delegating to the unified storage layer.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { storageManager } from "../core/storage/storage-manager.js";
|
|
10
|
+
import { getAvailableBucketNames, resolveBucketName, getAppName, ensureKeyHasAppPrefix, ensurePrefix, uploadFile, downloadFile, deleteFile, deleteFiles, deleteFolder, listfiles, getFileMetadata, fileExists, getFileSize, createMultipartUpload, uploadPart, completeMultipartUpload, abortMultipartUpload, listIncompleteMultipartUploads, cleanupIncompleteMultipartUploads, checkHealth, runHealthCheck } from "./storage.service.js";
|
|
11
|
+
|
|
12
|
+
export { getAvailableBucketNames, resolveBucketName, getAppName, ensureKeyHasAppPrefix, ensurePrefix, uploadFile, downloadFile, deleteFile, deleteFiles, deleteFolder, listfiles, getFileMetadata, fileExists, getFileSize, createMultipartUpload, uploadPart, completeMultipartUpload, abortMultipartUpload, listIncompleteMultipartUploads, cleanupIncompleteMultipartUploads, checkHealth, runHealthCheck };
|
|
13
|
+
|
|
14
|
+
export function getBucketConfig(bucketName) {
|
|
15
|
+
return storageManager.getConnectionConfig(bucketName);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function getBucketClient(bucketName) {
|
|
19
|
+
const provider = storageManager.getProvider(bucketName);
|
|
20
|
+
if (provider.client) {
|
|
21
|
+
return provider.client;
|
|
22
|
+
}
|
|
23
|
+
throw new Error(`Connection '${provider.name}' is of type '${provider.type}' and does not use an S3Client.`);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function getBucketClientAndConfig(bucketName) {
|
|
27
|
+
const resolved = resolveBucketName(bucketName);
|
|
28
|
+
return {
|
|
29
|
+
client: getBucketClient(resolved),
|
|
30
|
+
config: getBucketConfig(resolved),
|
|
31
|
+
bucketName: resolved
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
let _defaultClient = null;
|
|
36
|
+
export const bucketClient = new Proxy({}, {
|
|
37
|
+
get(_, prop) {
|
|
38
|
+
_defaultClient ??= getBucketClient();
|
|
39
|
+
const val = _defaultClient[prop];
|
|
40
|
+
return typeof val === 'function' ? val.bind(_defaultClient) : val;
|
|
41
|
+
}
|
|
42
|
+
});
|