@internxt/cli 1.5.1 → 1.5.3
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 +0 -3
- package/README.md +30 -29
- package/dist/commands/add-cert.d.ts +1 -1
- package/dist/commands/add-cert.js +23 -23
- package/dist/commands/config.js +8 -3
- package/dist/commands/create-folder.js +10 -5
- package/dist/commands/delete-permanently-file.js +8 -3
- package/dist/commands/delete-permanently-folder.js +8 -3
- package/dist/commands/download-file.js +21 -16
- package/dist/commands/list.js +8 -3
- package/dist/commands/login.js +8 -6
- package/dist/commands/logout.js +8 -5
- package/dist/commands/logs.js +8 -3
- package/dist/commands/move-file.js +8 -3
- package/dist/commands/move-folder.js +8 -3
- package/dist/commands/rename-file.js +8 -3
- package/dist/commands/rename-folder.js +8 -3
- package/dist/commands/trash-clear.js +8 -3
- package/dist/commands/trash-file.js +8 -3
- package/dist/commands/trash-folder.js +8 -3
- package/dist/commands/trash-list.js +8 -3
- package/dist/commands/trash-restore-file.js +8 -3
- package/dist/commands/trash-restore-folder.js +8 -3
- package/dist/commands/upload-file.js +15 -9
- package/dist/commands/webdav-config.d.ts +1 -0
- package/dist/commands/webdav-config.js +18 -3
- package/dist/commands/webdav.js +22 -25
- package/dist/commands/whoami.js +8 -5
- package/dist/hooks/prerun/auth_check.js +13 -7
- package/dist/services/auth.service.js +10 -2
- package/dist/services/config.service.d.ts +1 -0
- package/dist/services/config.service.js +3 -0
- package/dist/types/command.types.d.ts +1 -0
- package/dist/types/config.types.d.ts +0 -3
- package/dist/utils/cli.utils.d.ts +13 -4
- package/dist/utils/cli.utils.js +44 -10
- package/dist/utils/webdav.utils.d.ts +2 -8
- package/dist/utils/webdav.utils.js +16 -33
- package/dist/utils/xml.utils.d.ts +2 -2
- package/dist/utils/xml.utils.js +3 -3
- package/dist/webdav/handlers/DELETE.handler.d.ts +0 -2
- package/dist/webdav/handlers/DELETE.handler.js +1 -8
- package/dist/webdav/handlers/GET.handler.d.ts +0 -2
- package/dist/webdav/handlers/GET.handler.js +1 -2
- package/dist/webdav/handlers/HEAD.handler.d.ts +0 -2
- package/dist/webdav/handlers/HEAD.handler.js +24 -19
- package/dist/webdav/handlers/MKCOL.handler.d.ts +0 -2
- package/dist/webdav/handlers/MKCOL.handler.js +14 -15
- package/dist/webdav/handlers/MOVE.handler.d.ts +0 -2
- package/dist/webdav/handlers/MOVE.handler.js +1 -7
- package/dist/webdav/handlers/PROPFIND.handler.d.ts +0 -2
- package/dist/webdav/handlers/PROPFIND.handler.js +34 -38
- package/dist/webdav/handlers/PUT.handler.d.ts +0 -2
- package/dist/webdav/handlers/PUT.handler.js +3 -7
- package/dist/webdav/index.js +1 -5
- package/dist/webdav/middewares/auth.middleware.js +10 -2
- package/dist/webdav/middewares/errors.middleware.js +8 -13
- package/dist/webdav/middewares/mkcol.middleware.d.ts +2 -0
- package/dist/webdav/middewares/mkcol.middleware.js +23 -0
- package/dist/webdav/webdav-server.d.ts +3 -4
- package/dist/webdav/webdav-server.js +22 -25
- package/oclif.manifest.json +10 -1
- package/package.json +24 -30
- package/dist/database/migrations/20240402164914-create-files.d.ts +0 -1
- package/dist/database/migrations/20240402164914-create-files.js +0 -55
- package/dist/database/migrations/20240402165418-create-folders.d.ts +0 -1
- package/dist/database/migrations/20240402165418-create-folders.js +0 -37
- package/dist/database/migrations/20241018114828-add-parent-column.d.ts +0 -1
- package/dist/database/migrations/20241018114828-add-parent-column.js +0 -24
- package/dist/services/database/drive-database-manager.service.d.ts +0 -23
- package/dist/services/database/drive-database-manager.service.js +0 -93
- package/dist/services/database/drive-file/drive-file.model.d.ts +0 -18
- package/dist/services/database/drive-file/drive-file.model.js +0 -80
- package/dist/services/database/drive-file/drive-file.repository.d.ts +0 -11
- package/dist/services/database/drive-file/drive-file.repository.js +0 -40
- package/dist/services/database/drive-folder/drive-folder.model.d.ts +0 -14
- package/dist/services/database/drive-folder/drive-folder.model.js +0 -65
- package/dist/services/database/drive-folder/drive-folder.repository.d.ts +0 -11
- package/dist/services/database/drive-folder/drive-folder.repository.js +0 -40
|
@@ -17,28 +17,43 @@ class PROPFINDRequestHandler {
|
|
|
17
17
|
this.dependencies = dependencies;
|
|
18
18
|
}
|
|
19
19
|
handle = async (req, res) => {
|
|
20
|
-
const {
|
|
20
|
+
const { driveFolderService, driveFileService } = this.dependencies;
|
|
21
21
|
const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req);
|
|
22
22
|
logger_utils_1.webdavLogger.info(`[PROPFIND] Request received for ${resource.type} at ${resource.url}`);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
23
|
+
try {
|
|
24
|
+
const driveItem = await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
|
|
25
|
+
resource,
|
|
26
|
+
driveFolderService,
|
|
27
|
+
driveFileService,
|
|
28
|
+
});
|
|
29
|
+
switch (resource.type) {
|
|
30
|
+
case 'file': {
|
|
31
|
+
const fileMetaXML = await this.getFileMetaXML(resource, driveItem);
|
|
32
|
+
res.status(207).send(fileMetaXML);
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
case 'folder': {
|
|
36
|
+
const depth = req.header('depth') ?? '1';
|
|
37
|
+
const folderMetaXML = await this.getFolderContentXML(resource, driveItem, depth);
|
|
38
|
+
res.status(207).send(folderMetaXML);
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
40
41
|
}
|
|
41
42
|
}
|
|
43
|
+
catch {
|
|
44
|
+
res.status(207).send(xml_utils_1.XMLUtils.toWebDavXML({
|
|
45
|
+
[xml_utils_1.XMLUtils.addDefaultNamespace('response')]: {
|
|
46
|
+
[xml_utils_1.XMLUtils.addDefaultNamespace('href')]: xml_utils_1.XMLUtils.encodeWebDavUri(resource.url),
|
|
47
|
+
[xml_utils_1.XMLUtils.addDefaultNamespace('propstat')]: {
|
|
48
|
+
[xml_utils_1.XMLUtils.addDefaultNamespace('status')]: 'HTTP/1.1 404 Not Found',
|
|
49
|
+
[xml_utils_1.XMLUtils.addDefaultNamespace('prop')]: {},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
}, {
|
|
53
|
+
ignoreAttributes: false,
|
|
54
|
+
suppressEmptyNode: true,
|
|
55
|
+
}));
|
|
56
|
+
}
|
|
42
57
|
};
|
|
43
58
|
getFileMetaXML = async (resource, driveFileItem) => {
|
|
44
59
|
const driveFile = this.driveFileItemToXMLNode({
|
|
@@ -94,7 +109,7 @@ class PROPFINDRequestHandler {
|
|
|
94
109
|
return xml;
|
|
95
110
|
};
|
|
96
111
|
getFolderChildsXMLNode = async (relativePath, folderUuid) => {
|
|
97
|
-
const { driveFolderService
|
|
112
|
+
const { driveFolderService } = this.dependencies;
|
|
98
113
|
const folderContent = await driveFolderService.getFolderContent(folderUuid);
|
|
99
114
|
const foldersXML = folderContent.folders.map((folder) => {
|
|
100
115
|
const folderRelativePath = webdav_utils_1.WebDavUtils.joinURL(relativePath, folder.plainName, '/');
|
|
@@ -111,15 +126,6 @@ class PROPFINDRequestHandler {
|
|
|
111
126
|
parentUuid: null,
|
|
112
127
|
}, folderRelativePath);
|
|
113
128
|
});
|
|
114
|
-
await Promise.all(folderContent.folders.map((folder) => {
|
|
115
|
-
const folderRelativePath = webdav_utils_1.WebDavUtils.joinURL(relativePath, folder.plainName, '/');
|
|
116
|
-
return driveDatabaseManager.createFolder({
|
|
117
|
-
...folder,
|
|
118
|
-
name: folder.plainName,
|
|
119
|
-
encryptedName: folder.name,
|
|
120
|
-
status: folder.deleted || folder.removed ? 'TRASHED' : 'EXISTS',
|
|
121
|
-
}, folderRelativePath);
|
|
122
|
-
}));
|
|
123
129
|
const filesXML = folderContent.files.map((file) => {
|
|
124
130
|
const fileRelativePath = webdav_utils_1.WebDavUtils.joinURL(relativePath, file.type ? `${file.plainName}.${file.type}` : file.plainName);
|
|
125
131
|
return this.driveFileItemToXMLNode({
|
|
@@ -138,16 +144,6 @@ class PROPFINDRequestHandler {
|
|
|
138
144
|
size: Number(file.size),
|
|
139
145
|
}, fileRelativePath);
|
|
140
146
|
});
|
|
141
|
-
await Promise.all(folderContent.files.map((file) => {
|
|
142
|
-
const fileRelativePath = webdav_utils_1.WebDavUtils.joinURL(relativePath, file.type ? `${file.plainName}.${file.type}` : file.plainName);
|
|
143
|
-
return driveDatabaseManager.createFile({
|
|
144
|
-
...file,
|
|
145
|
-
name: file.plainName,
|
|
146
|
-
fileId: file.fileId,
|
|
147
|
-
size: Number(file.size),
|
|
148
|
-
encryptedName: file.name,
|
|
149
|
-
}, fileRelativePath);
|
|
150
|
-
}));
|
|
151
147
|
return foldersXML.concat(filesXML);
|
|
152
148
|
};
|
|
153
149
|
driveFolderRootStatsToXMLNode = async (driveFolderItem, relativePath) => {
|
|
@@ -3,7 +3,6 @@ import { DriveFileService } from '../../services/drive/drive-file.service';
|
|
|
3
3
|
import { NetworkFacade } from '../../services/network/network-facade.service';
|
|
4
4
|
import { AuthService } from '../../services/auth.service';
|
|
5
5
|
import { WebDavMethodHandler } from '../../types/webdav.types';
|
|
6
|
-
import { DriveDatabaseManager } from '../../services/database/drive-database-manager.service';
|
|
7
6
|
import { DriveFolderService } from '../../services/drive/drive-folder.service';
|
|
8
7
|
import { TrashService } from '../../services/drive/trash.service';
|
|
9
8
|
export declare class PUTRequestHandler implements WebDavMethodHandler {
|
|
@@ -11,7 +10,6 @@ export declare class PUTRequestHandler implements WebDavMethodHandler {
|
|
|
11
10
|
constructor(dependencies: {
|
|
12
11
|
driveFileService: DriveFileService;
|
|
13
12
|
driveFolderService: DriveFolderService;
|
|
14
|
-
driveDatabaseManager: DriveDatabaseManager;
|
|
15
13
|
trashService: TrashService;
|
|
16
14
|
authService: AuthService;
|
|
17
15
|
networkFacade: NetworkFacade;
|
|
@@ -16,7 +16,7 @@ class PUTRequestHandler {
|
|
|
16
16
|
this.dependencies = dependencies;
|
|
17
17
|
}
|
|
18
18
|
handle = async (req, res) => {
|
|
19
|
-
const {
|
|
19
|
+
const { authService, networkFacade, driveFileService, driveFolderService, trashService } = this.dependencies;
|
|
20
20
|
const contentLength = Number(req.headers['content-length']);
|
|
21
21
|
if (!contentLength || isNaN(contentLength) || contentLength <= 0) {
|
|
22
22
|
throw new errors_utils_1.UnsupportedMediaTypeError('Empty files are not supported');
|
|
@@ -26,21 +26,18 @@ class PUTRequestHandler {
|
|
|
26
26
|
throw new errors_utils_1.NotFoundError('Folders cannot be created with PUT. Use MKCOL instead.');
|
|
27
27
|
logger_utils_1.webdavLogger.info(`[PUT] Request received for ${resource.type} at ${resource.url}`);
|
|
28
28
|
logger_utils_1.webdavLogger.info(`[PUT] Uploading '${resource.name}' to '${resource.parentPath}'`);
|
|
29
|
-
const parentResource = await webdav_utils_1.WebDavUtils.getRequestedResource(resource.parentPath);
|
|
29
|
+
const parentResource = await webdav_utils_1.WebDavUtils.getRequestedResource(resource.parentPath, false);
|
|
30
30
|
const parentFolderItem = (await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
|
|
31
31
|
resource: parentResource,
|
|
32
|
-
driveDatabaseManager,
|
|
33
32
|
driveFolderService,
|
|
34
33
|
}));
|
|
35
34
|
try {
|
|
36
35
|
const driveFileItem = (await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
|
|
37
36
|
resource: resource,
|
|
38
|
-
driveDatabaseManager,
|
|
39
37
|
driveFileService,
|
|
40
38
|
}));
|
|
41
39
|
if (driveFileItem && driveFileItem.status === 'EXISTS') {
|
|
42
40
|
logger_utils_1.webdavLogger.info(`[PUT] File '${resource.name}' already exists in '${resource.path.dir}', trashing it...`);
|
|
43
|
-
await driveDatabaseManager.deleteFileById(driveFileItem.id);
|
|
44
41
|
await trashService.trashItems({
|
|
45
42
|
items: [{ type: resource.type, uuid: driveFileItem.uuid }],
|
|
46
43
|
});
|
|
@@ -105,8 +102,7 @@ class PUTRequestHandler {
|
|
|
105
102
|
}
|
|
106
103
|
const uploadTime = timer.stop();
|
|
107
104
|
logger_utils_1.webdavLogger.info(`[PUT] ✅ File uploaded in ${uploadTime}ms to Internxt Drive`);
|
|
108
|
-
|
|
109
|
-
res.status(200).send();
|
|
105
|
+
res.status(201).send();
|
|
110
106
|
};
|
|
111
107
|
}
|
|
112
108
|
exports.PUTRequestHandler = PUTRequestHandler;
|
package/dist/webdav/index.js
CHANGED
|
@@ -8,9 +8,6 @@ const webdav_server_1 = require("./webdav-server");
|
|
|
8
8
|
const express_1 = __importDefault(require("express"));
|
|
9
9
|
const config_service_1 = require("../services/config.service");
|
|
10
10
|
const drive_folder_service_1 = require("../services/drive/drive-folder.service");
|
|
11
|
-
const drive_database_manager_service_1 = require("../services/database/drive-database-manager.service");
|
|
12
|
-
const drive_file_repository_1 = require("../services/database/drive-file/drive-file.repository");
|
|
13
|
-
const drive_folder_repository_1 = require("../services/database/drive-folder/drive-folder.repository");
|
|
14
11
|
const drive_file_service_1 = require("../services/drive/drive-file.service");
|
|
15
12
|
const download_service_1 = require("../services/network/download.service");
|
|
16
13
|
const auth_service_1 = require("../services/auth.service");
|
|
@@ -23,13 +20,12 @@ const init = async () => {
|
|
|
23
20
|
await config_service_1.ConfigService.instance.ensureInternxtCliDataDirExists();
|
|
24
21
|
await config_service_1.ConfigService.instance.ensureWebdavCertsDirExists();
|
|
25
22
|
await config_service_1.ConfigService.instance.ensureInternxtLogsDirExists();
|
|
26
|
-
await drive_database_manager_service_1.DriveDatabaseManager.init();
|
|
27
23
|
const { token, newToken } = await auth_service_1.AuthService.instance.getAuthDetails();
|
|
28
24
|
sdk_manager_service_1.SdkManager.init({
|
|
29
25
|
token,
|
|
30
26
|
newToken,
|
|
31
27
|
});
|
|
32
|
-
new webdav_server_1.WebDavServer((0, express_1.default)(), config_service_1.ConfigService.instance, drive_file_service_1.DriveFileService.instance, drive_folder_service_1.DriveFolderService.instance,
|
|
28
|
+
new webdav_server_1.WebDavServer((0, express_1.default)(), config_service_1.ConfigService.instance, drive_file_service_1.DriveFileService.instance, drive_folder_service_1.DriveFolderService.instance, download_service_1.DownloadService.instance, auth_service_1.AuthService.instance, crypto_service_1.CryptoService.instance, trash_service_1.TrashService.instance)
|
|
33
29
|
.start()
|
|
34
30
|
.then()
|
|
35
31
|
.catch((err) => logger_utils_1.webdavLogger.error('Failed to start WebDAV server', err));
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.AuthMiddleware = void 0;
|
|
4
4
|
const sdk_manager_service_1 = require("../../services/sdk-manager.service");
|
|
5
5
|
const logger_utils_1 = require("../../utils/logger.utils");
|
|
6
|
+
const xml_utils_1 = require("../../utils/xml.utils");
|
|
6
7
|
const AuthMiddleware = (authService) => {
|
|
7
8
|
return (req, res, next) => {
|
|
8
9
|
(async () => {
|
|
@@ -19,8 +20,15 @@ const AuthMiddleware = (authService) => {
|
|
|
19
20
|
next();
|
|
20
21
|
}
|
|
21
22
|
catch (error) {
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
let message = 'Authentication required to access this resource.';
|
|
24
|
+
if ('message' in error && error.message.trim().length > 0) {
|
|
25
|
+
message = error.message;
|
|
26
|
+
}
|
|
27
|
+
logger_utils_1.webdavLogger.error('Error from AuthMiddleware: ' + message);
|
|
28
|
+
const errorBodyXML = xml_utils_1.XMLUtils.toWebDavXML({
|
|
29
|
+
[xml_utils_1.XMLUtils.addDefaultNamespace('responsedescription')]: message,
|
|
30
|
+
}, {}, 'error');
|
|
31
|
+
res.status(401).send(errorBodyXML);
|
|
24
32
|
}
|
|
25
33
|
})();
|
|
26
34
|
};
|
|
@@ -2,21 +2,16 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ErrorHandlingMiddleware = void 0;
|
|
4
4
|
const logger_utils_1 = require("../../utils/logger.utils");
|
|
5
|
+
const xml_utils_1 = require("../../utils/xml.utils");
|
|
5
6
|
const ErrorHandlingMiddleware = (err, req, res, _) => {
|
|
6
7
|
logger_utils_1.webdavLogger.error(`[ERROR MIDDLEWARE] [${req.method.toUpperCase()} - ${req.url}]`, err);
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
res.status(500).send({
|
|
16
|
-
error: {
|
|
17
|
-
message: 'message' in err ? err.message : 'Something went wrong',
|
|
18
|
-
},
|
|
19
|
-
});
|
|
8
|
+
const errorBodyXML = xml_utils_1.XMLUtils.toWebDavXML({
|
|
9
|
+
[xml_utils_1.XMLUtils.addDefaultNamespace('responsedescription')]: 'message' in err ? err.message : 'Something went wrong',
|
|
10
|
+
}, {}, 'error');
|
|
11
|
+
let statusCode = 500;
|
|
12
|
+
if ('statusCode' in err && !isNaN(err.statusCode)) {
|
|
13
|
+
statusCode = err.statusCode;
|
|
20
14
|
}
|
|
15
|
+
res.status(statusCode).send(errorBodyXML);
|
|
21
16
|
};
|
|
22
17
|
exports.ErrorHandlingMiddleware = ErrorHandlingMiddleware;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MkcolMiddleware = void 0;
|
|
4
|
+
const errors_utils_1 = require("../../utils/errors.utils");
|
|
5
|
+
const MkcolMiddleware = (req, _, next) => {
|
|
6
|
+
if (req.method === 'MKCOL') {
|
|
7
|
+
let contentType = req.headers['Content-Type'] ?? req.get('content-type');
|
|
8
|
+
if (contentType && contentType.length > 0) {
|
|
9
|
+
if (Array.isArray(contentType)) {
|
|
10
|
+
contentType = contentType[0];
|
|
11
|
+
}
|
|
12
|
+
contentType = contentType.toLowerCase().trim();
|
|
13
|
+
if (contentType !== 'application/xml' && contentType !== 'text/xml') {
|
|
14
|
+
throw new errors_utils_1.UnsupportedMediaTypeError('Unsupported Media Type');
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
if (req.body && Object.keys(req.body).length > 0) {
|
|
18
|
+
throw new errors_utils_1.UnsupportedMediaTypeError('Unsupported Media Type');
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
next();
|
|
22
|
+
};
|
|
23
|
+
exports.MkcolMiddleware = MkcolMiddleware;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Express } from 'express';
|
|
2
2
|
import { ConfigService } from '../services/config.service';
|
|
3
3
|
import { DriveFolderService } from '../services/drive/drive-folder.service';
|
|
4
|
-
import { DriveDatabaseManager } from '../services/database/drive-database-manager.service';
|
|
5
4
|
import { DriveFileService } from '../services/drive/drive-file.service';
|
|
6
5
|
import { DownloadService } from '../services/network/download.service';
|
|
7
6
|
import { AuthService } from '../services/auth.service';
|
|
@@ -12,14 +11,14 @@ export declare class WebDavServer {
|
|
|
12
11
|
private readonly configService;
|
|
13
12
|
private readonly driveFileService;
|
|
14
13
|
private readonly driveFolderService;
|
|
15
|
-
private readonly driveDatabaseManager;
|
|
16
14
|
private readonly downloadService;
|
|
17
15
|
private readonly authService;
|
|
18
16
|
private readonly cryptoService;
|
|
19
17
|
private readonly trashService;
|
|
20
|
-
constructor(app: Express, configService: ConfigService, driveFileService: DriveFileService, driveFolderService: DriveFolderService,
|
|
18
|
+
constructor(app: Express, configService: ConfigService, driveFileService: DriveFileService, driveFolderService: DriveFolderService, downloadService: DownloadService, authService: AuthService, cryptoService: CryptoService, trashService: TrashService);
|
|
21
19
|
private readonly getNetworkFacade;
|
|
22
|
-
private readonly
|
|
20
|
+
private readonly registerStartMiddlewares;
|
|
21
|
+
private readonly registerEndMiddleWares;
|
|
23
22
|
private readonly registerHandlers;
|
|
24
23
|
start: () => Promise<void>;
|
|
25
24
|
}
|
|
@@ -30,22 +30,21 @@ const PROPPATCH_handler_1 = require("./handlers/PROPPATCH.handler");
|
|
|
30
30
|
const MOVE_handler_1 = require("./handlers/MOVE.handler");
|
|
31
31
|
const COPY_handler_1 = require("./handlers/COPY.handler");
|
|
32
32
|
const inxt_js_1 = require("@internxt/inxt-js");
|
|
33
|
+
const mkcol_middleware_1 = require("./middewares/mkcol.middleware");
|
|
33
34
|
class WebDavServer {
|
|
34
35
|
app;
|
|
35
36
|
configService;
|
|
36
37
|
driveFileService;
|
|
37
38
|
driveFolderService;
|
|
38
|
-
driveDatabaseManager;
|
|
39
39
|
downloadService;
|
|
40
40
|
authService;
|
|
41
41
|
cryptoService;
|
|
42
42
|
trashService;
|
|
43
|
-
constructor(app, configService, driveFileService, driveFolderService,
|
|
43
|
+
constructor(app, configService, driveFileService, driveFolderService, downloadService, authService, cryptoService, trashService) {
|
|
44
44
|
this.app = app;
|
|
45
45
|
this.configService = configService;
|
|
46
46
|
this.driveFileService = driveFileService;
|
|
47
47
|
this.driveFolderService = driveFolderService;
|
|
48
|
-
this.driveDatabaseManager = driveDatabaseManager;
|
|
49
48
|
this.downloadService = downloadService;
|
|
50
49
|
this.authService = authService;
|
|
51
50
|
this.cryptoService = cryptoService;
|
|
@@ -68,65 +67,63 @@ class WebDavServer {
|
|
|
68
67
|
const networkFacade = new network_facade_service_1.NetworkFacade(networkModule, environment, download_service_1.DownloadService.instance, crypto_service_1.CryptoService.instance);
|
|
69
68
|
return networkFacade;
|
|
70
69
|
};
|
|
71
|
-
|
|
72
|
-
this.app.use(body_parser_1.default.text({ type: ['application/xml', 'text/xml'] }));
|
|
73
|
-
this.app.use(errors_middleware_1.ErrorHandlingMiddleware);
|
|
70
|
+
registerStartMiddlewares = () => {
|
|
74
71
|
this.app.use((0, auth_middleware_1.AuthMiddleware)(auth_service_1.AuthService.instance));
|
|
75
72
|
this.app.use((0, request_logger_middleware_1.RequestLoggerMiddleware)({
|
|
76
73
|
enable: true,
|
|
77
74
|
}));
|
|
75
|
+
this.app.use(body_parser_1.default.text({ type: ['application/xml', 'text/xml'] }));
|
|
76
|
+
this.app.use(mkcol_middleware_1.MkcolMiddleware);
|
|
77
|
+
};
|
|
78
|
+
registerEndMiddleWares = () => {
|
|
79
|
+
this.app.use(errors_middleware_1.ErrorHandlingMiddleware);
|
|
78
80
|
};
|
|
79
81
|
registerHandlers = async () => {
|
|
82
|
+
const serverListenPath = /(.*)/;
|
|
80
83
|
const networkFacade = await this.getNetworkFacade();
|
|
81
|
-
this.app.head(
|
|
84
|
+
this.app.head(serverListenPath, (0, express_async_handler_1.default)(new HEAD_handler_1.HEADRequestHandler({
|
|
82
85
|
driveFileService: this.driveFileService,
|
|
83
|
-
driveDatabaseManager: this.driveDatabaseManager,
|
|
84
86
|
}).handle));
|
|
85
|
-
this.app.get(
|
|
87
|
+
this.app.get(serverListenPath, (0, express_async_handler_1.default)(new GET_handler_1.GETRequestHandler({
|
|
86
88
|
driveFileService: this.driveFileService,
|
|
87
|
-
driveDatabaseManager: this.driveDatabaseManager,
|
|
88
89
|
downloadService: this.downloadService,
|
|
89
90
|
cryptoService: this.cryptoService,
|
|
90
91
|
authService: this.authService,
|
|
91
92
|
networkFacade: networkFacade,
|
|
92
93
|
}).handle));
|
|
93
|
-
this.app.options(
|
|
94
|
-
this.app.propfind(
|
|
94
|
+
this.app.options(serverListenPath, (0, express_async_handler_1.default)(new OPTIONS_handler_1.OPTIONSRequestHandler().handle));
|
|
95
|
+
this.app.propfind(serverListenPath, (0, express_async_handler_1.default)(new PROPFIND_handler_1.PROPFINDRequestHandler({
|
|
95
96
|
driveFileService: this.driveFileService,
|
|
96
97
|
driveFolderService: this.driveFolderService,
|
|
97
|
-
driveDatabaseManager: this.driveDatabaseManager,
|
|
98
98
|
}).handle));
|
|
99
|
-
this.app.put(
|
|
99
|
+
this.app.put(serverListenPath, (0, express_async_handler_1.default)(new PUT_handler_1.PUTRequestHandler({
|
|
100
100
|
driveFileService: this.driveFileService,
|
|
101
101
|
driveFolderService: this.driveFolderService,
|
|
102
|
-
driveDatabaseManager: this.driveDatabaseManager,
|
|
103
102
|
authService: this.authService,
|
|
104
103
|
trashService: this.trashService,
|
|
105
104
|
networkFacade: networkFacade,
|
|
106
105
|
}).handle));
|
|
107
|
-
this.app.mkcol(
|
|
108
|
-
driveDatabaseManager: this.driveDatabaseManager,
|
|
106
|
+
this.app.mkcol(serverListenPath, (0, express_async_handler_1.default)(new MKCOL_handler_1.MKCOLRequestHandler({
|
|
109
107
|
driveFolderService: this.driveFolderService,
|
|
110
108
|
}).handle));
|
|
111
|
-
this.app.delete(
|
|
112
|
-
driveDatabaseManager: this.driveDatabaseManager,
|
|
109
|
+
this.app.delete(serverListenPath, (0, express_async_handler_1.default)(new DELETE_handler_1.DELETERequestHandler({
|
|
113
110
|
trashService: this.trashService,
|
|
114
111
|
driveFileService: this.driveFileService,
|
|
115
112
|
driveFolderService: this.driveFolderService,
|
|
116
113
|
}).handle));
|
|
117
|
-
this.app.proppatch(
|
|
118
|
-
this.app.move(
|
|
119
|
-
driveDatabaseManager: this.driveDatabaseManager,
|
|
114
|
+
this.app.proppatch(serverListenPath, (0, express_async_handler_1.default)(new PROPPATCH_handler_1.PROPPATCHRequestHandler().handle));
|
|
115
|
+
this.app.move(serverListenPath, (0, express_async_handler_1.default)(new MOVE_handler_1.MOVERequestHandler({
|
|
120
116
|
driveFolderService: this.driveFolderService,
|
|
121
117
|
driveFileService: this.driveFileService,
|
|
122
118
|
}).handle));
|
|
123
|
-
this.app.copy(
|
|
119
|
+
this.app.copy(serverListenPath, (0, express_async_handler_1.default)(new COPY_handler_1.COPYRequestHandler().handle));
|
|
124
120
|
};
|
|
125
121
|
start = async () => {
|
|
126
122
|
const configs = await this.configService.readWebdavConfig();
|
|
127
123
|
this.app.disable('x-powered-by');
|
|
128
|
-
|
|
124
|
+
this.registerStartMiddlewares();
|
|
129
125
|
await this.registerHandlers();
|
|
126
|
+
this.registerEndMiddleWares();
|
|
130
127
|
const plainHttp = configs.protocol === 'http';
|
|
131
128
|
let server;
|
|
132
129
|
if (plainHttp) {
|
|
@@ -136,7 +133,7 @@ class WebDavServer {
|
|
|
136
133
|
const httpsCerts = await network_utils_1.NetworkUtils.getWebdavSSLCerts();
|
|
137
134
|
server = https_1.default.createServer(httpsCerts, this.app);
|
|
138
135
|
}
|
|
139
|
-
server.requestTimeout =
|
|
136
|
+
server.requestTimeout = configs.timeoutMinutes * 60 * 1000;
|
|
140
137
|
server.listen(configs.port, () => {
|
|
141
138
|
logger_utils_1.webdavLogger.info(`Internxt ${sdk_manager_service_1.SdkManager.getAppDetails().clientVersion} WebDav server ` +
|
|
142
139
|
`listening at ${configs.protocol}://${config_service_1.ConfigService.WEBDAV_LOCAL_URL}:${configs.port}`);
|
package/oclif.manifest.json
CHANGED
|
@@ -1163,6 +1163,15 @@
|
|
|
1163
1163
|
"required": false,
|
|
1164
1164
|
"allowNo": false,
|
|
1165
1165
|
"type": "boolean"
|
|
1166
|
+
},
|
|
1167
|
+
"timeout": {
|
|
1168
|
+
"char": "t",
|
|
1169
|
+
"description": "Configures the WebDAV server to use this timeout in minutes.",
|
|
1170
|
+
"name": "timeout",
|
|
1171
|
+
"required": false,
|
|
1172
|
+
"hasDynamicHelp": false,
|
|
1173
|
+
"multiple": false,
|
|
1174
|
+
"type": "option"
|
|
1166
1175
|
}
|
|
1167
1176
|
},
|
|
1168
1177
|
"hasDynamicHelp": false,
|
|
@@ -1257,5 +1266,5 @@
|
|
|
1257
1266
|
]
|
|
1258
1267
|
}
|
|
1259
1268
|
},
|
|
1260
|
-
"version": "1.5.
|
|
1269
|
+
"version": "1.5.3"
|
|
1261
1270
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "Internxt <hello@internxt.com>",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.3",
|
|
4
4
|
"description": "Internxt CLI to manage your encrypted storage",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "yarn clean && tsc",
|
|
@@ -16,8 +16,6 @@
|
|
|
16
16
|
"test:watch": "vitest watch",
|
|
17
17
|
"dev:webdav": "nodemon -e ts --exec ts-node src/webdav/index.ts",
|
|
18
18
|
"pack:win": "oclif pack win",
|
|
19
|
-
"migrate": "sequelize db:migrate",
|
|
20
|
-
"migrate:undo": "sequelize db:migrate:undo",
|
|
21
19
|
"publish:npm": "npm run build && npm publish --scope=@internxt --registry=https://registry.npmjs.org/ --access public",
|
|
22
20
|
"publish:github": "npm run build && npm publish --scope=@internxt --registry=https://npm.pkg.github.com",
|
|
23
21
|
"postinstall": "node ./scripts/restart-webdav.js"
|
|
@@ -37,61 +35,57 @@
|
|
|
37
35
|
"/oclif.manifest.json"
|
|
38
36
|
],
|
|
39
37
|
"dependencies": {
|
|
40
|
-
"@inquirer/prompts": "7.
|
|
38
|
+
"@inquirer/prompts": "7.5.0",
|
|
41
39
|
"@internxt/inxt-js": "2.1.0",
|
|
42
40
|
"@internxt/lib": "1.2.1",
|
|
43
41
|
"@internxt/sdk": "1.7.0",
|
|
44
|
-
"@oclif/core": "4.
|
|
45
|
-
"@types/validator": "13.
|
|
42
|
+
"@oclif/core": "4.3.0",
|
|
43
|
+
"@types/validator": "13.15.0",
|
|
46
44
|
"async": "3.2.6",
|
|
47
|
-
"axios": "1.
|
|
45
|
+
"axios": "1.9.0",
|
|
48
46
|
"bip39": "3.1.0",
|
|
49
|
-
"body-parser": "
|
|
47
|
+
"body-parser": "2.2.0",
|
|
50
48
|
"cli-progress": "3.12.0",
|
|
51
49
|
"dayjs": "1.11.13",
|
|
52
|
-
"dotenv": "16.
|
|
53
|
-
"express": "
|
|
50
|
+
"dotenv": "16.5.0",
|
|
51
|
+
"express": "5.1.0",
|
|
54
52
|
"express-async-handler": "1.2.0",
|
|
55
53
|
"express-basic-auth": "1.2.1",
|
|
56
|
-
"fast-xml-parser": "5.
|
|
57
|
-
"mime-types": "
|
|
54
|
+
"fast-xml-parser": "5.2.2",
|
|
55
|
+
"mime-types": "3.0.1",
|
|
58
56
|
"openpgp": "5.11.2",
|
|
59
|
-
"pm2": "
|
|
57
|
+
"pm2": "6.0.5",
|
|
60
58
|
"range-parser": "1.2.1",
|
|
61
59
|
"reflect-metadata": "0.2.2",
|
|
62
60
|
"selfsigned": "2.4.1",
|
|
63
|
-
"
|
|
64
|
-
"sequelize-typescript": "2.1.6",
|
|
65
|
-
"sharp": "0.33.5",
|
|
66
|
-
"sqlite3": "5.1.7",
|
|
61
|
+
"sharp": "0.34.1",
|
|
67
62
|
"tty-table": "4.2.3",
|
|
68
63
|
"winston": "3.17.0"
|
|
69
64
|
},
|
|
70
65
|
"devDependencies": {
|
|
71
66
|
"@internxt/eslint-config-internxt": "2.0.0",
|
|
72
67
|
"@internxt/prettier-config": "internxt/prettier-config#v1.0.2",
|
|
73
|
-
"@oclif/test": "4.1.
|
|
68
|
+
"@oclif/test": "4.1.12",
|
|
74
69
|
"@openpgp/web-stream-tools": "0.0.11-patch-1",
|
|
75
70
|
"@types/async": "3.2.24",
|
|
76
71
|
"@types/cli-progress": "3.11.6",
|
|
77
|
-
"@types/express": "5.0.
|
|
72
|
+
"@types/express": "5.0.1",
|
|
78
73
|
"@types/mime-types": "2.1.4",
|
|
79
|
-
"@types/node": "22.
|
|
74
|
+
"@types/node": "22.15.16",
|
|
80
75
|
"@types/range-parser": "1.2.7",
|
|
81
|
-
"@vitest/coverage-istanbul": "3.
|
|
82
|
-
"@vitest/spy": "3.
|
|
83
|
-
"eslint": "9.
|
|
76
|
+
"@vitest/coverage-istanbul": "3.1.3",
|
|
77
|
+
"@vitest/spy": "3.1.3",
|
|
78
|
+
"eslint": "9.26.0",
|
|
84
79
|
"husky": "9.1.7",
|
|
85
|
-
"lint-staged": "15.
|
|
86
|
-
"nock": "14.0.
|
|
87
|
-
"nodemon": "3.1.
|
|
88
|
-
"oclif": "4.17.
|
|
80
|
+
"lint-staged": "15.5.2",
|
|
81
|
+
"nock": "14.0.4",
|
|
82
|
+
"nodemon": "3.1.10",
|
|
83
|
+
"oclif": "4.17.46",
|
|
89
84
|
"prettier": "3.5.3",
|
|
90
85
|
"rimraf": "6.0.1",
|
|
91
|
-
"sequelize-cli": "6.6.2",
|
|
92
86
|
"ts-node": "10.9.2",
|
|
93
|
-
"typescript": "5.8.
|
|
94
|
-
"vitest": "3.
|
|
87
|
+
"typescript": "5.8.3",
|
|
88
|
+
"vitest": "3.1.3",
|
|
95
89
|
"vitest-mock-express": "2.2.0"
|
|
96
90
|
},
|
|
97
91
|
"engines": {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
module.exports = {
|
|
4
|
-
async up(queryInterface, Sequelize) {
|
|
5
|
-
await queryInterface.createTable('files', {
|
|
6
|
-
id: {
|
|
7
|
-
allowNull: false,
|
|
8
|
-
autoIncrement: true,
|
|
9
|
-
primaryKey: true,
|
|
10
|
-
type: Sequelize.INTEGER,
|
|
11
|
-
},
|
|
12
|
-
name: {
|
|
13
|
-
type: Sequelize.STRING,
|
|
14
|
-
},
|
|
15
|
-
type: {
|
|
16
|
-
type: Sequelize.STRING(24),
|
|
17
|
-
allowNull: true,
|
|
18
|
-
},
|
|
19
|
-
uuid: {
|
|
20
|
-
type: Sequelize.UUIDV4,
|
|
21
|
-
unique: true,
|
|
22
|
-
},
|
|
23
|
-
file_id: {
|
|
24
|
-
type: Sequelize.STRING(24),
|
|
25
|
-
},
|
|
26
|
-
folder_id: {
|
|
27
|
-
type: Sequelize.INTEGER,
|
|
28
|
-
},
|
|
29
|
-
bucket: {
|
|
30
|
-
type: Sequelize.STRING(24),
|
|
31
|
-
},
|
|
32
|
-
relative_path: {
|
|
33
|
-
type: Sequelize.TEXT,
|
|
34
|
-
},
|
|
35
|
-
size: {
|
|
36
|
-
type: Sequelize.BIGINT,
|
|
37
|
-
},
|
|
38
|
-
status: {
|
|
39
|
-
type: Sequelize.ENUM,
|
|
40
|
-
values: ['EXISTS', 'TRASHED', 'DELETED'],
|
|
41
|
-
defaultValue: 'EXISTS',
|
|
42
|
-
allowNull: false,
|
|
43
|
-
},
|
|
44
|
-
created_at: {
|
|
45
|
-
type: Sequelize.DATE,
|
|
46
|
-
},
|
|
47
|
-
updated_at: {
|
|
48
|
-
type: Sequelize.DATE,
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
},
|
|
52
|
-
async down(queryInterface) {
|
|
53
|
-
await queryInterface.dropTable('files');
|
|
54
|
-
},
|
|
55
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
module.exports = {
|
|
4
|
-
async up(queryInterface, Sequelize) {
|
|
5
|
-
await queryInterface.createTable('folders', {
|
|
6
|
-
id: {
|
|
7
|
-
allowNull: false,
|
|
8
|
-
autoIncrement: true,
|
|
9
|
-
primaryKey: true,
|
|
10
|
-
type: Sequelize.INTEGER,
|
|
11
|
-
},
|
|
12
|
-
name: {
|
|
13
|
-
type: Sequelize.STRING,
|
|
14
|
-
},
|
|
15
|
-
uuid: {
|
|
16
|
-
type: Sequelize.UUIDV4,
|
|
17
|
-
unique: true,
|
|
18
|
-
},
|
|
19
|
-
relative_path: {
|
|
20
|
-
type: Sequelize.TEXT,
|
|
21
|
-
},
|
|
22
|
-
parent_id: {
|
|
23
|
-
type: Sequelize.INTEGER,
|
|
24
|
-
allowNull: true,
|
|
25
|
-
},
|
|
26
|
-
created_at: {
|
|
27
|
-
type: Sequelize.DATE,
|
|
28
|
-
},
|
|
29
|
-
updated_at: {
|
|
30
|
-
type: Sequelize.DATE,
|
|
31
|
-
},
|
|
32
|
-
});
|
|
33
|
-
},
|
|
34
|
-
async down(queryInterface) {
|
|
35
|
-
await queryInterface.dropTable('folders');
|
|
36
|
-
},
|
|
37
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|