@internxt/cli 1.6.8 → 1.6.10
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/README.md +28 -28
- package/bin/dev.js +10 -0
- package/bin/run.js +10 -0
- package/dist/commands/list.d.ts +2 -0
- package/dist/commands/move-file.d.ts +2 -0
- package/dist/commands/trash-list.d.ts +1 -2
- package/dist/commands/trash-restore-file.d.ts +2 -0
- package/dist/commands/upload-file.d.ts +2 -2
- package/dist/services/database/database.service.d.ts +6 -0
- package/dist/services/database/database.service.js +27 -0
- package/dist/services/database/drive-item/drive-item.repository.d.ts +2 -1
- package/dist/services/database/drive-item/drive-item.repository.js +10 -5
- package/dist/services/drive/drive-file.service.js +4 -6
- package/dist/services/drive/drive-folder.service.d.ts +9 -5
- package/dist/services/drive/drive-folder.service.js +48 -31
- package/dist/services/drive/drive-item.service.d.ts +1 -0
- package/dist/services/drive/drive-item.service.js +24 -14
- package/dist/services/drive/trash.service.d.ts +5 -4
- package/dist/services/drive/trash.service.js +21 -22
- package/dist/services/webdav/webdav-folder.service.d.ts +4 -0
- package/dist/services/webdav/webdav-folder.service.js +14 -1
- package/dist/types/config.types.d.ts +1 -0
- package/dist/types/drive.types.d.ts +1 -0
- package/dist/utils/cli.utils.js +2 -8
- package/dist/utils/drive.utils.d.ts +1 -0
- package/dist/utils/drive.utils.js +9 -1
- package/dist/utils/errors.utils.d.ts +35 -0
- package/dist/utils/errors.utils.js +116 -3
- package/dist/utils/network.utils.js +7 -6
- package/dist/utils/pagination.utils.d.ts +7 -0
- package/dist/utils/pagination.utils.js +20 -0
- package/dist/utils/webdav.utils.js +30 -17
- package/dist/webdav/handlers/DELETE.handler.js +0 -2
- package/dist/webdav/handlers/GET.handler.js +15 -5
- package/dist/webdav/handlers/HEAD.handler.js +17 -7
- package/dist/webdav/handlers/LOCK.handler.js +5 -1
- package/dist/webdav/handlers/MKCOL.handler.js +7 -1
- package/dist/webdav/handlers/MOVE.handler.js +13 -1
- package/dist/webdav/handlers/OPTIONS.handler.js +3 -3
- package/dist/webdav/handlers/PROPFIND.handler.js +2 -2
- package/dist/webdav/handlers/PROPPATCH.handler.d.ts +3 -1
- package/dist/webdav/handlers/PROPPATCH.handler.js +53 -3
- package/dist/webdav/handlers/PUT.handler.js +2 -7
- package/dist/webdav/index.js +3 -2
- package/dist/webdav/middewares/auth.middleware.js +3 -2
- package/dist/webdav/middewares/errors.middleware.js +10 -14
- package/oclif.manifest.json +1 -1
- package/package.json +31 -26
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DELETERequestHandler = void 0;
|
|
4
|
-
const drive_item_repository_1 = require("../../services/database/drive-item/drive-item.repository");
|
|
5
4
|
const webdav_utils_1 = require("../../utils/webdav.utils");
|
|
6
5
|
const logger_utils_1 = require("../../utils/logger.utils");
|
|
7
6
|
const errors_utils_1 = require("../../utils/errors.utils");
|
|
@@ -14,7 +13,6 @@ class DELETERequestHandler {
|
|
|
14
13
|
throw new errors_utils_1.NotFoundError(`Resource not found on Internxt Drive at ${resource.url}`);
|
|
15
14
|
}
|
|
16
15
|
await webdav_utils_1.WebDavUtils.deleteOrTrashItem(driveItem);
|
|
17
|
-
await drive_item_repository_1.DriveItemRepository.instance.delete([driveItem.uuid]);
|
|
18
16
|
res.status(204).send();
|
|
19
17
|
};
|
|
20
18
|
}
|
|
@@ -25,14 +25,24 @@ class GETRequestHandler {
|
|
|
25
25
|
const fileSize = driveFile.size ?? 0;
|
|
26
26
|
if (fileSize > 0) {
|
|
27
27
|
const range = req.headers['range'];
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
let rangeOptions;
|
|
29
|
+
try {
|
|
30
|
+
rangeOptions = network_utils_1.NetworkUtils.parseRangeHeader({
|
|
31
|
+
range,
|
|
32
|
+
totalFileSize: fileSize,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
if (error instanceof errors_utils_1.RangeNotSatisfiableError) {
|
|
37
|
+
res.header('Content-Range', `bytes */${fileSize}`);
|
|
38
|
+
}
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
32
41
|
let contentLength = fileSize;
|
|
33
42
|
if (rangeOptions) {
|
|
34
43
|
logger_utils_1.webdavLogger.info(`[GET] [${driveFile.uuid}] Range request received:`, { rangeOptions });
|
|
35
44
|
contentLength = rangeOptions.rangeSize;
|
|
45
|
+
res.header('Content-Range', `bytes ${rangeOptions.parsed.start}-${rangeOptions.parsed.end}/${fileSize}`);
|
|
36
46
|
}
|
|
37
47
|
res.header('Content-length', contentLength.toString());
|
|
38
48
|
const writable = new WritableStream({
|
|
@@ -49,7 +59,7 @@ class GETRequestHandler {
|
|
|
49
59
|
const { networkFacade, mnemonic } = await cli_utils_1.CLIUtils.prepareNetwork(user);
|
|
50
60
|
const [executeDownload] = await networkFacade.downloadToStream(driveFile.bucket, mnemonic, driveFile.fileId, contentLength, writable, rangeOptions);
|
|
51
61
|
logger_utils_1.webdavLogger.info(`[GET] [${driveFile.uuid}] Download prepared, executing...`);
|
|
52
|
-
res.status(200);
|
|
62
|
+
res.status(rangeOptions ? 206 : 200);
|
|
53
63
|
await executeDownload;
|
|
54
64
|
logger_utils_1.webdavLogger.info(`[GET] [${driveFile.uuid}] ✅ Download ready, replying to client`);
|
|
55
65
|
}
|
|
@@ -15,22 +15,32 @@ class HEADRequestHandler {
|
|
|
15
15
|
}
|
|
16
16
|
logger_utils_1.webdavLogger.info(`[HEAD] [${driveItem.uuid}] Found Drive item`);
|
|
17
17
|
res.header('ETag', webdav_utils_1.WebDavUtils.getItemETag(driveItem));
|
|
18
|
+
let rangeOptions;
|
|
18
19
|
if (driveItem.itemType === 'file') {
|
|
19
20
|
const range = req.headers['range'];
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
try {
|
|
22
|
+
rangeOptions = network_utils_1.NetworkUtils.parseRangeHeader({
|
|
23
|
+
range,
|
|
24
|
+
totalFileSize: driveItem.size,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
if (error instanceof errors_utils_1.RangeNotSatisfiableError) {
|
|
29
|
+
res.header('Content-Range', `bytes */${driveItem.size}`);
|
|
30
|
+
}
|
|
31
|
+
throw error;
|
|
32
|
+
}
|
|
24
33
|
let contentLength = driveItem.size;
|
|
34
|
+
res.header('Content-Type', 'application/octet-stream');
|
|
35
|
+
res.header('Accept-Ranges', 'bytes');
|
|
25
36
|
if (rangeOptions) {
|
|
26
37
|
logger_utils_1.webdavLogger.info(`[HEAD] [${driveItem.uuid}] Range request received:`, { rangeOptions });
|
|
27
38
|
contentLength = rangeOptions.rangeSize;
|
|
39
|
+
res.header('Content-Range', `bytes ${rangeOptions.parsed.start}-${rangeOptions.parsed.end}/${driveItem.size}`);
|
|
28
40
|
}
|
|
29
|
-
res.header('Content-Type', 'application/octet-stream');
|
|
30
|
-
res.header('Accept-Ranges', 'bytes');
|
|
31
41
|
res.header('Content-length', contentLength.toString());
|
|
32
42
|
}
|
|
33
|
-
res.status(200).send();
|
|
43
|
+
res.status(rangeOptions ? 206 : 200).send();
|
|
34
44
|
};
|
|
35
45
|
}
|
|
36
46
|
exports.HEADRequestHandler = HEADRequestHandler;
|
|
@@ -4,6 +4,7 @@ exports.LOCKRequestHandler = void 0;
|
|
|
4
4
|
const node_crypto_1 = require("node:crypto");
|
|
5
5
|
const logger_utils_1 = require("../../utils/logger.utils");
|
|
6
6
|
const xml_utils_1 = require("../../utils/xml.utils");
|
|
7
|
+
const webdav_utils_1 = require("../../utils/webdav.utils");
|
|
7
8
|
const LOCK_TIMEOUT_SECONDS = 300;
|
|
8
9
|
class LOCKRequestHandler {
|
|
9
10
|
handle = async (req, res) => {
|
|
@@ -42,9 +43,12 @@ class LOCKRequestHandler {
|
|
|
42
43
|
},
|
|
43
44
|
},
|
|
44
45
|
}, { suppressEmptyNode: true }, 'prop');
|
|
46
|
+
const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req.url);
|
|
47
|
+
const driveItem = await webdav_utils_1.WebDavUtils.getDriveItemFromResource(resource);
|
|
48
|
+
const statusCode = driveItem ? 200 : 201;
|
|
45
49
|
res.set('Lock-Token', `<${lockToken}>`);
|
|
46
50
|
res.set('Content-Type', 'application/xml; charset="utf-8"');
|
|
47
|
-
res.status(
|
|
51
|
+
res.status(statusCode).send(lockDiscoveryXml);
|
|
48
52
|
};
|
|
49
53
|
}
|
|
50
54
|
exports.LOCKRequestHandler = LOCKRequestHandler;
|
|
@@ -20,9 +20,15 @@ class MKCOLRequestHandler {
|
|
|
20
20
|
logger_utils_1.webdavLogger.info(`[MKCOL] Folder '${resource.url}' already exists, throwing 405 error`);
|
|
21
21
|
throw new errors_utils_1.MethodNotAllowed('Folder already exists');
|
|
22
22
|
}
|
|
23
|
-
const newFolder = await webdav_folder_service_1.WebDavFolderService.instance
|
|
23
|
+
const newFolder = await webdav_folder_service_1.WebDavFolderService.instance
|
|
24
|
+
.createFolder({
|
|
24
25
|
folderName: resource.path.base,
|
|
25
26
|
parentFolderUuid: parentDriveFolderItem.uuid,
|
|
27
|
+
})
|
|
28
|
+
.catch((error) => {
|
|
29
|
+
if (errors_utils_1.ErrorUtils.isAlreadyExistsError(error))
|
|
30
|
+
throw new errors_utils_1.MethodNotAllowed('Folder already exists');
|
|
31
|
+
throw error;
|
|
26
32
|
});
|
|
27
33
|
logger_utils_1.webdavLogger.info(`[MKCOL] ✅ Folder created with UUID ${newFolder.uuid}`);
|
|
28
34
|
await drive_item_repository_1.DriveItemRepository.instance.createOrUpdate([
|
|
@@ -23,6 +23,17 @@ class MOVERequestHandler {
|
|
|
23
23
|
if (!originalDriveItem) {
|
|
24
24
|
throw new errors_utils_1.NotFoundError(`Resource not found on Internxt Drive at ${resource.url}`);
|
|
25
25
|
}
|
|
26
|
+
let isOverwrite = false;
|
|
27
|
+
const destinationDriveItem = await webdav_utils_1.WebDavUtils.getDriveItemFromResource(destinationResource);
|
|
28
|
+
if (destinationDriveItem && destinationDriveItem.uuid !== originalDriveItem.uuid) {
|
|
29
|
+
const overwrite = (req.header('overwrite') ?? 'T').toUpperCase();
|
|
30
|
+
if (overwrite === 'F') {
|
|
31
|
+
throw new errors_utils_1.PreconditionFailedError(`Destination '${destinationResource.url}' already exists`);
|
|
32
|
+
}
|
|
33
|
+
isOverwrite = true;
|
|
34
|
+
logger_utils_1.webdavLogger.info(`[MOVE] Destination '${destinationResource.url}' already exists, overwriting it`);
|
|
35
|
+
await webdav_utils_1.WebDavUtils.deleteOrTrashItem(destinationDriveItem);
|
|
36
|
+
}
|
|
26
37
|
if (destinationResource.path.dir === resource.path.dir) {
|
|
27
38
|
logger_utils_1.webdavLogger.info(`[MOVE] Renaming ${originalDriveItem.itemType}
|
|
28
39
|
with UUID ${originalDriveItem.uuid} to ${destinationResource.name}`);
|
|
@@ -75,7 +86,8 @@ class MOVERequestHandler {
|
|
|
75
86
|
updatedAt: new Date(),
|
|
76
87
|
},
|
|
77
88
|
]);
|
|
78
|
-
|
|
89
|
+
const statusCode = isOverwrite ? 204 : 201;
|
|
90
|
+
res.status(statusCode).send();
|
|
79
91
|
};
|
|
80
92
|
}
|
|
81
93
|
exports.MOVERequestHandler = MOVERequestHandler;
|
|
@@ -8,21 +8,21 @@ class OPTIONSRequestHandler {
|
|
|
8
8
|
const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req.url);
|
|
9
9
|
logger_utils_1.webdavLogger.info(`[OPTIONS] Request received for item at ${resource.url}`);
|
|
10
10
|
if (resource.url === '/' || resource.url === '') {
|
|
11
|
-
const allowedMethods = 'DELETE, GET, HEAD, LOCK, MKCOL, MOVE, OPTIONS, PROPFIND, PUT, UNLOCK';
|
|
11
|
+
const allowedMethods = 'DELETE, GET, HEAD, LOCK, MKCOL, MOVE, OPTIONS, PROPFIND, PROPPATCH, PUT, UNLOCK';
|
|
12
12
|
logger_utils_1.webdavLogger.info(`[OPTIONS] Returning Allowed Options: ${allowedMethods}`);
|
|
13
13
|
res.header('Allow', allowedMethods);
|
|
14
14
|
res.header('DAV', '1, 2, ordered-collections');
|
|
15
15
|
res.status(200).send();
|
|
16
16
|
}
|
|
17
17
|
else if (resource.url.endsWith('/')) {
|
|
18
|
-
const allowedMethods = 'DELETE, HEAD, LOCK, MKCOL, MOVE, OPTIONS, PROPFIND, UNLOCK';
|
|
18
|
+
const allowedMethods = 'DELETE, HEAD, LOCK, MKCOL, MOVE, OPTIONS, PROPFIND, PROPPATCH, UNLOCK';
|
|
19
19
|
logger_utils_1.webdavLogger.info(`[OPTIONS] Returning Allowed Options: ${allowedMethods}`);
|
|
20
20
|
res.header('Allow', allowedMethods);
|
|
21
21
|
res.header('DAV', '1, 2, ordered-collections');
|
|
22
22
|
res.status(200).send();
|
|
23
23
|
}
|
|
24
24
|
else {
|
|
25
|
-
const allowedMethods = 'DELETE, GET, HEAD, LOCK, MOVE, OPTIONS, PROPFIND, PUT, UNLOCK';
|
|
25
|
+
const allowedMethods = 'DELETE, GET, HEAD, LOCK, MOVE, OPTIONS, PROPFIND, PROPPATCH, PUT, UNLOCK';
|
|
26
26
|
logger_utils_1.webdavLogger.info(`[OPTIONS] Returning Allowed Options: ${allowedMethods}`);
|
|
27
27
|
res.header('Allow', allowedMethods);
|
|
28
28
|
res.header('DAV', '1, 2, ordered-collections');
|
|
@@ -14,14 +14,14 @@ const mime_types_1 = __importDefault(require("mime-types"));
|
|
|
14
14
|
const webdav_utils_1 = require("../../utils/webdav.utils");
|
|
15
15
|
const logger_utils_1 = require("../../utils/logger.utils");
|
|
16
16
|
const usage_service_1 = require("../../services/usage.service");
|
|
17
|
+
const errors_utils_1 = require("../../utils/errors.utils");
|
|
17
18
|
class PROPFINDRequestHandler {
|
|
18
19
|
handle = async (req, res) => {
|
|
19
20
|
const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req.url);
|
|
20
21
|
logger_utils_1.webdavLogger.info(`[PROPFIND] Request received for item at ${resource.url}`);
|
|
21
22
|
const driveItem = await webdav_utils_1.WebDavUtils.getDriveItemFromResource(resource);
|
|
22
23
|
if (!driveItem) {
|
|
23
|
-
|
|
24
|
-
return;
|
|
24
|
+
throw new errors_utils_1.NotFoundError(`Resource not found on Internxt Drive at ${resource.url}`);
|
|
25
25
|
}
|
|
26
26
|
res.set('Content-Type', 'application/xml; charset="utf-8"');
|
|
27
27
|
switch (driveItem.itemType) {
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { Request, Response } from 'express';
|
|
1
2
|
import { WebDavMethodHandler } from '../../types/webdav.types';
|
|
2
3
|
export declare class PROPPATCHRequestHandler implements WebDavMethodHandler {
|
|
3
|
-
handle(
|
|
4
|
+
handle: (req: Request, res: Response) => Promise<void>;
|
|
5
|
+
private readonly getRequestedPropertyNames;
|
|
4
6
|
}
|
|
@@ -1,10 +1,60 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PROPPATCHRequestHandler = void 0;
|
|
4
|
+
const webdav_utils_1 = require("../../utils/webdav.utils");
|
|
5
|
+
const logger_utils_1 = require("../../utils/logger.utils");
|
|
6
|
+
const xml_utils_1 = require("../../utils/xml.utils");
|
|
4
7
|
const errors_utils_1 = require("../../utils/errors.utils");
|
|
5
8
|
class PROPPATCHRequestHandler {
|
|
6
|
-
async
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
handle = async (req, res) => {
|
|
10
|
+
const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req.url);
|
|
11
|
+
logger_utils_1.webdavLogger.info(`[PROPPATCH] Request received for item at ${resource.url}`);
|
|
12
|
+
const driveItem = await webdav_utils_1.WebDavUtils.getDriveItemFromResource(resource);
|
|
13
|
+
if (!driveItem) {
|
|
14
|
+
throw new errors_utils_1.NotFoundError(`Resource not found on Internxt Drive at ${resource.url}`);
|
|
15
|
+
}
|
|
16
|
+
const propertyNames = this.getRequestedPropertyNames(req.body);
|
|
17
|
+
const propNode = Object.fromEntries(propertyNames.map((name) => [name, '']));
|
|
18
|
+
const responseXML = xml_utils_1.XMLUtils.toWebDavXML({
|
|
19
|
+
[xml_utils_1.XMLUtils.addDefaultNamespace('response')]: {
|
|
20
|
+
[xml_utils_1.XMLUtils.addDefaultNamespace('href')]: xml_utils_1.XMLUtils.encodeWebDavUri(resource.url),
|
|
21
|
+
[xml_utils_1.XMLUtils.addDefaultNamespace('propstat')]: {
|
|
22
|
+
[xml_utils_1.XMLUtils.addDefaultNamespace('prop')]: propNode,
|
|
23
|
+
[xml_utils_1.XMLUtils.addDefaultNamespace('status')]: 'HTTP/1.1 403 Forbidden',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
}, { suppressEmptyNode: true });
|
|
27
|
+
res.set('Content-Type', 'application/xml; charset="utf-8"');
|
|
28
|
+
res.status(207).send(responseXML);
|
|
29
|
+
};
|
|
30
|
+
getRequestedPropertyNames = (body) => {
|
|
31
|
+
if (typeof body !== 'string' || body.trim().length === 0) {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const parsed = xml_utils_1.XMLUtils.toJSON(body, { ignoreAttributes: false });
|
|
36
|
+
const propertyUpdate = parsed?.['D:propertyupdate'] ?? parsed?.propertyupdate;
|
|
37
|
+
const sections = [
|
|
38
|
+
propertyUpdate?.['D:set'] ?? propertyUpdate?.set,
|
|
39
|
+
propertyUpdate?.['D:remove'] ?? propertyUpdate?.remove,
|
|
40
|
+
];
|
|
41
|
+
const names = new Set();
|
|
42
|
+
for (const section of sections) {
|
|
43
|
+
const prop = section?.['D:prop'] ?? section?.prop;
|
|
44
|
+
if (prop && typeof prop === 'object') {
|
|
45
|
+
for (const key of Object.keys(prop)) {
|
|
46
|
+
if (!key.startsWith('@_')) {
|
|
47
|
+
names.add(key);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return Array.from(names);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
logger_utils_1.webdavLogger.warn(`[PROPPATCH] Failed to parse request body: ${error instanceof Error ? error.message : String(error)}`);
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
};
|
|
9
59
|
}
|
|
10
60
|
exports.PROPPATCHRequestHandler = PROPPATCHRequestHandler;
|
|
@@ -83,22 +83,17 @@ class PUTRequestHandler {
|
|
|
83
83
|
encryptVersion: types_1.EncryptionVersion.Aes03,
|
|
84
84
|
};
|
|
85
85
|
let file;
|
|
86
|
-
if (driveFileItem?.itemType === 'file'
|
|
86
|
+
if (driveFileItem?.itemType === 'file') {
|
|
87
87
|
try {
|
|
88
88
|
file = await drive_file_service_1.DriveFileService.instance.replaceFile(driveFileItem.uuid, filePayload);
|
|
89
89
|
}
|
|
90
90
|
catch (error) {
|
|
91
|
-
logger_utils_1.webdavLogger.warn(`[PUT] File replace failed for '${resource.url}', falling back to delete and create: ${error instanceof Error ? error.message : String(error)}
|
|
91
|
+
logger_utils_1.webdavLogger.warn(errors_utils_1.ErrorUtils.withRequestId(`[PUT] File replace failed for '${resource.url}', falling back to delete and create: ${error instanceof Error ? error.message : String(error)}`, error));
|
|
92
92
|
await webdav_utils_1.WebDavUtils.deleteOrTrashItem(driveFileItem);
|
|
93
|
-
await drive_item_repository_1.DriveItemRepository.instance.delete([driveFileItem.uuid]);
|
|
94
93
|
file = await drive_file_service_1.DriveFileService.instance.createFile(filePayload);
|
|
95
94
|
}
|
|
96
95
|
}
|
|
97
96
|
else {
|
|
98
|
-
if (driveFileItem?.itemType === 'file') {
|
|
99
|
-
await webdav_utils_1.WebDavUtils.deleteOrTrashItem(driveFileItem);
|
|
100
|
-
await drive_item_repository_1.DriveItemRepository.instance.delete([driveFileItem.uuid]);
|
|
101
|
-
}
|
|
102
97
|
file = await drive_file_service_1.DriveFileService.instance.createFile(filePayload);
|
|
103
98
|
}
|
|
104
99
|
timings.driveUpload = driveTimer.stop();
|
package/dist/webdav/index.js
CHANGED
|
@@ -11,6 +11,7 @@ const auth_service_1 = require("../services/auth.service");
|
|
|
11
11
|
const logger_utils_1 = require("../utils/logger.utils");
|
|
12
12
|
const sdk_manager_service_1 = require("../services/sdk-manager.service");
|
|
13
13
|
const database_service_1 = require("../services/database/database.service");
|
|
14
|
+
const errors_utils_1 = require("../utils/errors.utils");
|
|
14
15
|
dotenv_1.default.config({ quiet: true });
|
|
15
16
|
const init = async () => {
|
|
16
17
|
await config_service_1.ConfigService.instance.ensureInternxtCliDataDirExists();
|
|
@@ -23,9 +24,9 @@ const init = async () => {
|
|
|
23
24
|
new webdav_server_1.WebDavServer((0, express_1.default)())
|
|
24
25
|
.start()
|
|
25
26
|
.then()
|
|
26
|
-
.catch((err) => logger_utils_1.webdavLogger.error('Failed to start WebDAV server', err));
|
|
27
|
+
.catch((err) => logger_utils_1.webdavLogger.error(errors_utils_1.ErrorUtils.withRequestId('Failed to start WebDAV server', err), err));
|
|
27
28
|
};
|
|
28
29
|
process.on('uncaughtException', (err) => {
|
|
29
|
-
logger_utils_1.webdavLogger.error('Unhandled exception:', err);
|
|
30
|
+
logger_utils_1.webdavLogger.error(errors_utils_1.ErrorUtils.withRequestId('Unhandled exception:', err), err);
|
|
30
31
|
});
|
|
31
32
|
init();
|
|
@@ -25,11 +25,12 @@ const AuthMiddleware = () => {
|
|
|
25
25
|
let message = 'Authentication required to access this resource.';
|
|
26
26
|
if (errors_utils_1.ErrorUtils.isError(error)) {
|
|
27
27
|
message = error.message;
|
|
28
|
+
const logMessage = errors_utils_1.ErrorUtils.withRequestId(message, error);
|
|
28
29
|
if (error.stack) {
|
|
29
|
-
logger_utils_1.webdavLogger.error(`Error from AuthMiddleware: ${
|
|
30
|
+
logger_utils_1.webdavLogger.error(`Error from AuthMiddleware: ${logMessage}\nStack: ${error.stack}`);
|
|
30
31
|
}
|
|
31
32
|
else {
|
|
32
|
-
logger_utils_1.webdavLogger.error(`Error from AuthMiddleware: ${
|
|
33
|
+
logger_utils_1.webdavLogger.error(`Error from AuthMiddleware: ${logMessage}`);
|
|
33
34
|
}
|
|
34
35
|
}
|
|
35
36
|
const errorBodyXML = xml_utils_1.XMLUtils.toWebDavXML({
|
|
@@ -17,34 +17,30 @@ const getErrorDetail = (err) => {
|
|
|
17
17
|
return message.join(', ');
|
|
18
18
|
return undefined;
|
|
19
19
|
};
|
|
20
|
-
const getErrorStatusCode = (err) => {
|
|
21
|
-
if (typeof err !== 'object' || err === null)
|
|
22
|
-
return undefined;
|
|
23
|
-
const { statusCode, status } = err;
|
|
24
|
-
if (typeof statusCode === 'number' && !Number.isNaN(statusCode))
|
|
25
|
-
return statusCode;
|
|
26
|
-
if (typeof status === 'number' && !Number.isNaN(status))
|
|
27
|
-
return status;
|
|
28
|
-
return undefined;
|
|
29
|
-
};
|
|
30
20
|
const ErrorHandlingMiddleware = (err, req, res, _) => {
|
|
31
21
|
let message = errors_utils_1.ErrorUtils.isError(err) ? err.message : 'Something went wrong';
|
|
32
22
|
const detail = getErrorDetail(err);
|
|
33
23
|
if (detail) {
|
|
34
24
|
message += ` [${detail}]`;
|
|
35
25
|
}
|
|
26
|
+
const logMessage = errors_utils_1.ErrorUtils.withRequestId(message, err);
|
|
36
27
|
if (errors_utils_1.ErrorUtils.isError(err) && err.stack) {
|
|
37
|
-
logger_utils_1.webdavLogger.error(`[ERROR MIDDLEWARE] [${req.method.toUpperCase()} - ${req.url}] ${
|
|
28
|
+
logger_utils_1.webdavLogger.error(`[ERROR MIDDLEWARE] [${req.method.toUpperCase()} - ${req.url}] ${logMessage}\nStack: ${err.stack}`);
|
|
38
29
|
}
|
|
39
30
|
else {
|
|
40
|
-
logger_utils_1.webdavLogger.error(`[ERROR MIDDLEWARE] [${req.method.toUpperCase()} - ${req.url}] ${
|
|
31
|
+
logger_utils_1.webdavLogger.error(`[ERROR MIDDLEWARE] [${req.method.toUpperCase()} - ${req.url}] ${logMessage}`);
|
|
41
32
|
}
|
|
42
33
|
const errorBodyXML = xml_utils_1.XMLUtils.toWebDavXML({
|
|
43
34
|
[xml_utils_1.XMLUtils.addDefaultNamespace('responsedescription')]: message,
|
|
44
35
|
}, {}, 'error');
|
|
45
|
-
const statusCode =
|
|
36
|
+
const { statusCode, retryAfter } = errors_utils_1.ErrorUtils.toWebDavStatus(err);
|
|
37
|
+
if (retryAfter !== undefined) {
|
|
38
|
+
res.set('Retry-After', String(retryAfter));
|
|
39
|
+
}
|
|
46
40
|
res.set('Content-Type', 'application/xml; charset="utf-8"');
|
|
47
41
|
res.status(statusCode).send(errorBodyXML);
|
|
48
|
-
req.
|
|
42
|
+
if (!req.complete) {
|
|
43
|
+
req.destroy();
|
|
44
|
+
}
|
|
49
45
|
};
|
|
50
46
|
exports.ErrorHandlingMiddleware = ErrorHandlingMiddleware;
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "Internxt <hello@internxt.com>",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.10",
|
|
4
4
|
"description": "Internxt CLI to manage your encrypted storage",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "npm run clean && tsc",
|
|
@@ -37,62 +37,62 @@
|
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@dashlane/pqc-kem-kyber512-node": "1.0.0",
|
|
40
|
-
"@inquirer/prompts": "8.
|
|
40
|
+
"@inquirer/prompts": "8.7.2",
|
|
41
41
|
"@internxt/inxt-js": "3.3.5",
|
|
42
42
|
"@internxt/lib": "1.5.2",
|
|
43
|
-
"@internxt/sdk": "1.
|
|
44
|
-
"@oclif/core": "
|
|
45
|
-
"@oclif/plugin-autocomplete": "
|
|
46
|
-
"axios": "1.
|
|
43
|
+
"@internxt/sdk": "1.22.0",
|
|
44
|
+
"@oclif/core": "5.0.0",
|
|
45
|
+
"@oclif/plugin-autocomplete": "4.0.2",
|
|
46
|
+
"axios": "1.20.0",
|
|
47
47
|
"better-sqlite3": "12.11.1",
|
|
48
48
|
"bip39": "3.1.0",
|
|
49
49
|
"body-parser": "2.3.0",
|
|
50
50
|
"cli-progress": "3.12.0",
|
|
51
|
-
"dayjs": "1.11.
|
|
51
|
+
"dayjs": "1.11.23",
|
|
52
52
|
"dotenv": "17.4.2",
|
|
53
53
|
"express": "5.2.1",
|
|
54
54
|
"express-async-handler": "1.2.0",
|
|
55
55
|
"fast-xml-builder": "1.3.1",
|
|
56
|
-
"fast-xml-parser": "5.
|
|
56
|
+
"fast-xml-parser": "5.11.1",
|
|
57
57
|
"hash-wasm": "4.12.0",
|
|
58
58
|
"mime-types": "3.0.2",
|
|
59
|
-
"open": "11.0.
|
|
60
|
-
"openpgp": "6.3.
|
|
61
|
-
"otpauth": "9.5.
|
|
62
|
-
"pm2": "7.0.
|
|
59
|
+
"open": "11.0.4",
|
|
60
|
+
"openpgp": "6.3.2",
|
|
61
|
+
"otpauth": "9.5.2",
|
|
62
|
+
"pm2": "7.0.4",
|
|
63
63
|
"range-parser": "1.3.0",
|
|
64
64
|
"selfsigned": "5.5.0",
|
|
65
|
-
"tty-table": "
|
|
66
|
-
"typeorm": "1.1.
|
|
67
|
-
"uuid": "14.0.
|
|
65
|
+
"tty-table": "7.0.1",
|
|
66
|
+
"typeorm": "1.1.1",
|
|
67
|
+
"uuid": "14.0.2",
|
|
68
68
|
"winston": "3.19.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
|
-
"@internxt/eslint-config-internxt": "^2.1.
|
|
71
|
+
"@internxt/eslint-config-internxt": "^2.1.1",
|
|
72
72
|
"@internxt/prettier-config": "^2.0.1",
|
|
73
73
|
"@openpgp/web-stream-tools": "^0.3.1",
|
|
74
74
|
"@types/cli-progress": "^3.11.6",
|
|
75
75
|
"@types/express": "^5.0.6",
|
|
76
76
|
"@types/mime-types": "^3.0.1",
|
|
77
|
-
"@types/node": "^26.
|
|
77
|
+
"@types/node": "^26.5.0",
|
|
78
78
|
"@types/range-parser": "^1.2.7",
|
|
79
|
-
"@vitest/coverage-istanbul": "^
|
|
80
|
-
"@vitest/spy": "^
|
|
81
|
-
"eslint": "^10.
|
|
79
|
+
"@vitest/coverage-istanbul": "^5.0.3",
|
|
80
|
+
"@vitest/spy": "^5.0.2",
|
|
81
|
+
"eslint": "^10.11.0",
|
|
82
82
|
"husky": "^9.1.7",
|
|
83
|
-
"lint-staged": "^17.
|
|
83
|
+
"lint-staged": "^17.6.0",
|
|
84
84
|
"nodemon": "^3.1.14",
|
|
85
|
-
"oclif": "^
|
|
85
|
+
"oclif": "^5.0.2",
|
|
86
86
|
"prettier": "^3.9.6",
|
|
87
87
|
"rimraf": "^6.1.3",
|
|
88
|
-
"sql.js": "^1.14.
|
|
88
|
+
"sql.js": "^1.14.2",
|
|
89
89
|
"ts-node": "^10.9.2",
|
|
90
90
|
"typescript": "^6.0.3",
|
|
91
|
-
"vitest": "^
|
|
91
|
+
"vitest": "^5.0.0",
|
|
92
92
|
"vitest-mock-express": "^2.2.0"
|
|
93
93
|
},
|
|
94
94
|
"optionalDependencies": {
|
|
95
|
-
"sharp": "0.35.
|
|
95
|
+
"sharp": "0.35.4"
|
|
96
96
|
},
|
|
97
97
|
"engines": {
|
|
98
98
|
"node": "^22.13.0 || >=24.11.0"
|
|
@@ -120,5 +120,10 @@
|
|
|
120
120
|
"*.{js,jsx,tsx,ts,cjs,mjs}": [
|
|
121
121
|
"prettier --write"
|
|
122
122
|
]
|
|
123
|
+
},
|
|
124
|
+
"overrides": {
|
|
125
|
+
"pm2": {
|
|
126
|
+
"js-yaml": "4.3.2"
|
|
127
|
+
}
|
|
123
128
|
}
|
|
124
|
-
}
|
|
129
|
+
}
|