@internxt/cli 1.5.0 → 1.5.2
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 +32 -31
- package/dist/commands/login.js +0 -3
- package/dist/commands/logout.js +0 -2
- package/dist/commands/webdav-config.d.ts +1 -0
- package/dist/commands/webdav-config.js +10 -0
- package/dist/commands/webdav.js +0 -3
- package/dist/commands/whoami.js +0 -2
- 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/webdav.utils.d.ts +2 -8
- package/dist/utils/webdav.utils.js +16 -33
- package/dist/utils/xml.utils.d.ts +1 -1
- 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 +23 -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/mkcol.middleware.d.ts +2 -0
- package/dist/webdav/middewares/mkcol.middleware.js +23 -0
- package/dist/webdav/webdav-server.d.ts +1 -3
- package/dist/webdav/webdav-server.js +16 -22
- package/oclif.manifest.json +10 -1
- package/package.json +27 -33
- 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
|
@@ -11,7 +11,7 @@ class GETRequestHandler {
|
|
|
11
11
|
this.dependencies = dependencies;
|
|
12
12
|
}
|
|
13
13
|
handle = async (req, res) => {
|
|
14
|
-
const {
|
|
14
|
+
const { driveFileService, authService, networkFacade } = this.dependencies;
|
|
15
15
|
const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req);
|
|
16
16
|
if (resource.name.startsWith('._'))
|
|
17
17
|
throw new errors_utils_1.NotFoundError('File not found');
|
|
@@ -20,7 +20,6 @@ class GETRequestHandler {
|
|
|
20
20
|
logger_utils_1.webdavLogger.info(`[GET] Request received for ${resource.type} at ${resource.url}`);
|
|
21
21
|
const driveFile = (await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
|
|
22
22
|
resource,
|
|
23
|
-
driveDatabaseManager,
|
|
24
23
|
driveFileService,
|
|
25
24
|
}));
|
|
26
25
|
logger_utils_1.webdavLogger.info(`[GET] [${driveFile.uuid}] Found Drive File`);
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { Request, Response } from 'express';
|
|
2
2
|
import { WebDavMethodHandler } from '../../types/webdav.types';
|
|
3
3
|
import { DriveFileService } from '../../services/drive/drive-file.service';
|
|
4
|
-
import { DriveDatabaseManager } from '../../services/database/drive-database-manager.service';
|
|
5
4
|
export declare class HEADRequestHandler implements WebDavMethodHandler {
|
|
6
5
|
private readonly dependencies;
|
|
7
6
|
constructor(dependencies: {
|
|
8
7
|
driveFileService: DriveFileService;
|
|
9
|
-
driveDatabaseManager: DriveDatabaseManager;
|
|
10
8
|
});
|
|
11
9
|
handle: (req: Request, res: Response) => Promise<void>;
|
|
12
10
|
}
|
|
@@ -10,32 +10,37 @@ class HEADRequestHandler {
|
|
|
10
10
|
this.dependencies = dependencies;
|
|
11
11
|
}
|
|
12
12
|
handle = async (req, res) => {
|
|
13
|
-
const {
|
|
13
|
+
const { driveFileService } = this.dependencies;
|
|
14
14
|
const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req);
|
|
15
15
|
if (resource.type === 'folder') {
|
|
16
16
|
res.status(200).send();
|
|
17
17
|
return;
|
|
18
18
|
}
|
|
19
19
|
logger_utils_1.webdavLogger.info(`[HEAD] Request received for ${resource.type} at ${resource.url}`);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
20
|
+
try {
|
|
21
|
+
const driveFile = (await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
|
|
22
|
+
resource,
|
|
23
|
+
driveFileService,
|
|
24
|
+
}));
|
|
25
|
+
logger_utils_1.webdavLogger.info(`[HEAD] [${driveFile.uuid}] Found Drive File`);
|
|
26
|
+
const range = req.headers['range'];
|
|
27
|
+
const rangeOptions = network_utils_1.NetworkUtils.parseRangeHeader({
|
|
28
|
+
range,
|
|
29
|
+
totalFileSize: driveFile.size,
|
|
30
|
+
});
|
|
31
|
+
let contentLength = driveFile.size;
|
|
32
|
+
if (rangeOptions) {
|
|
33
|
+
logger_utils_1.webdavLogger.info(`[HEAD] [${driveFile.uuid}] Range request received:`, { rangeOptions });
|
|
34
|
+
contentLength = rangeOptions.rangeSize;
|
|
35
|
+
}
|
|
36
|
+
res.header('Content-Type', 'application/octet-stream');
|
|
37
|
+
res.header('Content-length', contentLength.toString());
|
|
38
|
+
res.status(200).send();
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
res.header('Content-Type', 'application/octet-stream');
|
|
42
|
+
res.status(200).send();
|
|
35
43
|
}
|
|
36
|
-
res.header('Content-Type', 'application/octet-stream');
|
|
37
|
-
res.header('Content-length', contentLength.toString());
|
|
38
|
-
res.status(200).send();
|
|
39
44
|
};
|
|
40
45
|
}
|
|
41
46
|
exports.HEADRequestHandler = HEADRequestHandler;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
import { DriveDatabaseManager } from '../../services/database/drive-database-manager.service';
|
|
2
1
|
import { WebDavMethodHandler } from '../../types/webdav.types';
|
|
3
2
|
import { Request, Response } from 'express';
|
|
4
3
|
import { DriveFolderService } from '../../services/drive/drive-folder.service';
|
|
5
4
|
export declare class MKCOLRequestHandler implements WebDavMethodHandler {
|
|
6
5
|
private readonly dependencies;
|
|
7
6
|
constructor(dependencies: {
|
|
8
|
-
driveDatabaseManager: DriveDatabaseManager;
|
|
9
7
|
driveFolderService: DriveFolderService;
|
|
10
8
|
});
|
|
11
9
|
handle: (req: Request, res: Response) => Promise<void>;
|
|
@@ -5,39 +5,38 @@ const webdav_utils_1 = require("../../utils/webdav.utils");
|
|
|
5
5
|
const logger_utils_1 = require("../../utils/logger.utils");
|
|
6
6
|
const xml_utils_1 = require("../../utils/xml.utils");
|
|
7
7
|
const async_utils_1 = require("../../utils/async.utils");
|
|
8
|
+
const errors_utils_1 = require("../../utils/errors.utils");
|
|
8
9
|
class MKCOLRequestHandler {
|
|
9
10
|
dependencies;
|
|
10
11
|
constructor(dependencies) {
|
|
11
12
|
this.dependencies = dependencies;
|
|
12
13
|
}
|
|
13
14
|
handle = async (req, res) => {
|
|
14
|
-
const {
|
|
15
|
+
const { driveFolderService } = this.dependencies;
|
|
15
16
|
const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req);
|
|
16
17
|
logger_utils_1.webdavLogger.info(`[MKCOL] Request received for ${resource.type} at ${resource.url}`);
|
|
17
|
-
const parentResource = await webdav_utils_1.WebDavUtils.getRequestedResource(resource.parentPath);
|
|
18
|
+
const parentResource = await webdav_utils_1.WebDavUtils.getRequestedResource(resource.parentPath, false);
|
|
18
19
|
const parentFolderItem = (await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
|
|
19
20
|
resource: parentResource,
|
|
20
|
-
driveDatabaseManager,
|
|
21
21
|
driveFolderService,
|
|
22
22
|
}));
|
|
23
|
+
let folderAlreadyExists = true;
|
|
24
|
+
try {
|
|
25
|
+
await driveFolderService.getFolderMetadataByPath(resource.url);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
folderAlreadyExists = false;
|
|
29
|
+
}
|
|
30
|
+
if (folderAlreadyExists) {
|
|
31
|
+
logger_utils_1.webdavLogger.info(`[MKCOL] ❌ Folder '${resource.url}' already exists`);
|
|
32
|
+
throw new errors_utils_1.MethodNotAllowed('Folder already exists');
|
|
33
|
+
}
|
|
23
34
|
const [createFolder] = driveFolderService.createFolder({
|
|
24
35
|
plainName: resource.path.base,
|
|
25
36
|
parentFolderUuid: parentFolderItem.uuid,
|
|
26
37
|
});
|
|
27
38
|
const newFolder = await createFolder;
|
|
28
39
|
logger_utils_1.webdavLogger.info(`[MKCOL] ✅ Folder created with UUID ${newFolder.uuid}`);
|
|
29
|
-
await driveDatabaseManager.createFolder({
|
|
30
|
-
name: newFolder.plainName,
|
|
31
|
-
status: 'EXISTS',
|
|
32
|
-
encryptedName: newFolder.name,
|
|
33
|
-
bucket: newFolder.bucket,
|
|
34
|
-
id: newFolder.id,
|
|
35
|
-
parentId: newFolder.parentId,
|
|
36
|
-
parentUuid: newFolder.parentUuid,
|
|
37
|
-
uuid: newFolder.uuid,
|
|
38
|
-
createdAt: new Date(newFolder.createdAt),
|
|
39
|
-
updatedAt: new Date(newFolder.updatedAt),
|
|
40
|
-
}, resource.url);
|
|
41
40
|
await async_utils_1.AsyncUtils.sleep(500);
|
|
42
41
|
res.status(201).send(xml_utils_1.XMLUtils.toWebDavXML({}, {}));
|
|
43
42
|
};
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import { Request, Response } from 'express';
|
|
2
|
-
import { DriveDatabaseManager } from '../../services/database/drive-database-manager.service';
|
|
3
2
|
import { DriveFileService } from '../../services/drive/drive-file.service';
|
|
4
3
|
import { DriveFolderService } from '../../services/drive/drive-folder.service';
|
|
5
4
|
import { WebDavMethodHandler } from '../../types/webdav.types';
|
|
6
5
|
export declare class MOVERequestHandler implements WebDavMethodHandler {
|
|
7
6
|
private readonly dependencies;
|
|
8
7
|
constructor(dependencies: {
|
|
9
|
-
driveDatabaseManager: DriveDatabaseManager;
|
|
10
8
|
driveFolderService: DriveFolderService;
|
|
11
9
|
driveFileService: DriveFileService;
|
|
12
10
|
});
|
|
@@ -10,7 +10,7 @@ class MOVERequestHandler {
|
|
|
10
10
|
this.dependencies = dependencies;
|
|
11
11
|
}
|
|
12
12
|
handle = async (req, res) => {
|
|
13
|
-
const {
|
|
13
|
+
const { driveFolderService, driveFileService } = this.dependencies;
|
|
14
14
|
const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req);
|
|
15
15
|
logger_utils_1.webdavLogger.info(`[MOVE] Request received for ${resource.type} at ${resource.url}`);
|
|
16
16
|
const destinationUrl = req.header('destination');
|
|
@@ -22,7 +22,6 @@ class MOVERequestHandler {
|
|
|
22
22
|
logger_utils_1.webdavLogger.info('[MOVE] Destination resource found', { destinationResource });
|
|
23
23
|
const originalDriveItem = await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
|
|
24
24
|
resource,
|
|
25
|
-
driveDatabaseManager,
|
|
26
25
|
driveFolderService,
|
|
27
26
|
driveFileService,
|
|
28
27
|
});
|
|
@@ -35,7 +34,6 @@ class MOVERequestHandler {
|
|
|
35
34
|
folderUuid: folder.uuid,
|
|
36
35
|
name: newName,
|
|
37
36
|
});
|
|
38
|
-
await driveDatabaseManager.createFolder(folder, destinationResource.url);
|
|
39
37
|
}
|
|
40
38
|
else if (resource.type === 'file') {
|
|
41
39
|
const newType = destinationResource.path.ext.replace('.', '');
|
|
@@ -44,7 +42,6 @@ class MOVERequestHandler {
|
|
|
44
42
|
plainName: newName,
|
|
45
43
|
type: newType,
|
|
46
44
|
});
|
|
47
|
-
await driveDatabaseManager.createFile(file, destinationResource.url);
|
|
48
45
|
}
|
|
49
46
|
}
|
|
50
47
|
else {
|
|
@@ -52,7 +49,6 @@ class MOVERequestHandler {
|
|
|
52
49
|
const destinationFolderResource = await webdav_utils_1.WebDavUtils.getRequestedResource(destinationResource.parentPath);
|
|
53
50
|
const destinationFolderItem = (await webdav_utils_1.WebDavUtils.getAndSearchItemFromResource({
|
|
54
51
|
resource: destinationFolderResource,
|
|
55
|
-
driveDatabaseManager,
|
|
56
52
|
driveFolderService,
|
|
57
53
|
}));
|
|
58
54
|
if (resource.type === 'folder') {
|
|
@@ -61,7 +57,6 @@ class MOVERequestHandler {
|
|
|
61
57
|
folderUuid: folder.uuid,
|
|
62
58
|
destinationFolderUuid: destinationFolderItem.uuid,
|
|
63
59
|
});
|
|
64
|
-
await driveDatabaseManager.createFolder(folder, destinationPath);
|
|
65
60
|
}
|
|
66
61
|
else if (resource.type === 'file') {
|
|
67
62
|
const file = originalDriveItem;
|
|
@@ -69,7 +64,6 @@ class MOVERequestHandler {
|
|
|
69
64
|
fileUuid: file.uuid,
|
|
70
65
|
destinationFolderUuid: destinationFolderItem.uuid,
|
|
71
66
|
});
|
|
72
|
-
await driveDatabaseManager.createFile(file, destinationPath);
|
|
73
67
|
}
|
|
74
68
|
}
|
|
75
69
|
res.status(204).send();
|
|
@@ -2,13 +2,11 @@ import { WebDavMethodHandler } from '../../types/webdav.types';
|
|
|
2
2
|
import { DriveFolderService } from '../../services/drive/drive-folder.service';
|
|
3
3
|
import { DriveFileService } from '../../services/drive/drive-file.service';
|
|
4
4
|
import { Request, Response } from 'express';
|
|
5
|
-
import { DriveDatabaseManager } from '../../services/database/drive-database-manager.service';
|
|
6
5
|
export declare class PROPFINDRequestHandler implements WebDavMethodHandler {
|
|
7
6
|
private readonly dependencies;
|
|
8
7
|
constructor(dependencies: {
|
|
9
8
|
driveFolderService: DriveFolderService;
|
|
10
9
|
driveFileService: DriveFileService;
|
|
11
|
-
driveDatabaseManager: DriveDatabaseManager;
|
|
12
10
|
});
|
|
13
11
|
handle: (req: Request, res: Response) => Promise<void>;
|
|
14
12
|
private readonly getFileMetaXML;
|
|
@@ -17,28 +17,32 @@ 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();
|
|
45
|
+
}
|
|
42
46
|
};
|
|
43
47
|
getFileMetaXML = async (resource, driveFileItem) => {
|
|
44
48
|
const driveFile = this.driveFileItemToXMLNode({
|
|
@@ -94,7 +98,7 @@ class PROPFINDRequestHandler {
|
|
|
94
98
|
return xml;
|
|
95
99
|
};
|
|
96
100
|
getFolderChildsXMLNode = async (relativePath, folderUuid) => {
|
|
97
|
-
const { driveFolderService
|
|
101
|
+
const { driveFolderService } = this.dependencies;
|
|
98
102
|
const folderContent = await driveFolderService.getFolderContent(folderUuid);
|
|
99
103
|
const foldersXML = folderContent.folders.map((folder) => {
|
|
100
104
|
const folderRelativePath = webdav_utils_1.WebDavUtils.joinURL(relativePath, folder.plainName, '/');
|
|
@@ -111,15 +115,6 @@ class PROPFINDRequestHandler {
|
|
|
111
115
|
parentUuid: null,
|
|
112
116
|
}, folderRelativePath);
|
|
113
117
|
});
|
|
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
118
|
const filesXML = folderContent.files.map((file) => {
|
|
124
119
|
const fileRelativePath = webdav_utils_1.WebDavUtils.joinURL(relativePath, file.type ? `${file.plainName}.${file.type}` : file.plainName);
|
|
125
120
|
return this.driveFileItemToXMLNode({
|
|
@@ -138,16 +133,6 @@ class PROPFINDRequestHandler {
|
|
|
138
133
|
size: Number(file.size),
|
|
139
134
|
}, fileRelativePath);
|
|
140
135
|
});
|
|
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
136
|
return foldersXML.concat(filesXML);
|
|
152
137
|
};
|
|
153
138
|
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));
|
|
@@ -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,12 +11,11 @@ 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
20
|
private readonly registerMiddlewares;
|
|
23
21
|
private readonly registerHandlers;
|
|
@@ -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;
|
|
@@ -69,58 +68,53 @@ class WebDavServer {
|
|
|
69
68
|
return networkFacade;
|
|
70
69
|
};
|
|
71
70
|
registerMiddlewares = async () => {
|
|
72
|
-
this.app.use(body_parser_1.default.text({ type: ['application/xml', 'text/xml'] }));
|
|
73
71
|
this.app.use(errors_middleware_1.ErrorHandlingMiddleware);
|
|
74
72
|
this.app.use((0, auth_middleware_1.AuthMiddleware)(auth_service_1.AuthService.instance));
|
|
75
73
|
this.app.use((0, request_logger_middleware_1.RequestLoggerMiddleware)({
|
|
76
74
|
enable: true,
|
|
77
75
|
}));
|
|
76
|
+
this.app.use(body_parser_1.default.text({ type: ['application/xml', 'text/xml'] }));
|
|
77
|
+
this.app.use(mkcol_middleware_1.MkcolMiddleware);
|
|
78
78
|
};
|
|
79
79
|
registerHandlers = async () => {
|
|
80
|
+
const serverListenPath = /(.*)/;
|
|
80
81
|
const networkFacade = await this.getNetworkFacade();
|
|
81
|
-
this.app.head(
|
|
82
|
+
this.app.head(serverListenPath, (0, express_async_handler_1.default)(new HEAD_handler_1.HEADRequestHandler({
|
|
82
83
|
driveFileService: this.driveFileService,
|
|
83
|
-
driveDatabaseManager: this.driveDatabaseManager,
|
|
84
84
|
}).handle));
|
|
85
|
-
this.app.get(
|
|
85
|
+
this.app.get(serverListenPath, (0, express_async_handler_1.default)(new GET_handler_1.GETRequestHandler({
|
|
86
86
|
driveFileService: this.driveFileService,
|
|
87
|
-
driveDatabaseManager: this.driveDatabaseManager,
|
|
88
87
|
downloadService: this.downloadService,
|
|
89
88
|
cryptoService: this.cryptoService,
|
|
90
89
|
authService: this.authService,
|
|
91
90
|
networkFacade: networkFacade,
|
|
92
91
|
}).handle));
|
|
93
|
-
this.app.options(
|
|
94
|
-
this.app.propfind(
|
|
92
|
+
this.app.options(serverListenPath, (0, express_async_handler_1.default)(new OPTIONS_handler_1.OPTIONSRequestHandler().handle));
|
|
93
|
+
this.app.propfind(serverListenPath, (0, express_async_handler_1.default)(new PROPFIND_handler_1.PROPFINDRequestHandler({
|
|
95
94
|
driveFileService: this.driveFileService,
|
|
96
95
|
driveFolderService: this.driveFolderService,
|
|
97
|
-
driveDatabaseManager: this.driveDatabaseManager,
|
|
98
96
|
}).handle));
|
|
99
|
-
this.app.put(
|
|
97
|
+
this.app.put(serverListenPath, (0, express_async_handler_1.default)(new PUT_handler_1.PUTRequestHandler({
|
|
100
98
|
driveFileService: this.driveFileService,
|
|
101
99
|
driveFolderService: this.driveFolderService,
|
|
102
|
-
driveDatabaseManager: this.driveDatabaseManager,
|
|
103
100
|
authService: this.authService,
|
|
104
101
|
trashService: this.trashService,
|
|
105
102
|
networkFacade: networkFacade,
|
|
106
103
|
}).handle));
|
|
107
|
-
this.app.mkcol(
|
|
108
|
-
driveDatabaseManager: this.driveDatabaseManager,
|
|
104
|
+
this.app.mkcol(serverListenPath, (0, express_async_handler_1.default)(new MKCOL_handler_1.MKCOLRequestHandler({
|
|
109
105
|
driveFolderService: this.driveFolderService,
|
|
110
106
|
}).handle));
|
|
111
|
-
this.app.delete(
|
|
112
|
-
driveDatabaseManager: this.driveDatabaseManager,
|
|
107
|
+
this.app.delete(serverListenPath, (0, express_async_handler_1.default)(new DELETE_handler_1.DELETERequestHandler({
|
|
113
108
|
trashService: this.trashService,
|
|
114
109
|
driveFileService: this.driveFileService,
|
|
115
110
|
driveFolderService: this.driveFolderService,
|
|
116
111
|
}).handle));
|
|
117
|
-
this.app.proppatch(
|
|
118
|
-
this.app.move(
|
|
119
|
-
driveDatabaseManager: this.driveDatabaseManager,
|
|
112
|
+
this.app.proppatch(serverListenPath, (0, express_async_handler_1.default)(new PROPPATCH_handler_1.PROPPATCHRequestHandler().handle));
|
|
113
|
+
this.app.move(serverListenPath, (0, express_async_handler_1.default)(new MOVE_handler_1.MOVERequestHandler({
|
|
120
114
|
driveFolderService: this.driveFolderService,
|
|
121
115
|
driveFileService: this.driveFileService,
|
|
122
116
|
}).handle));
|
|
123
|
-
this.app.copy(
|
|
117
|
+
this.app.copy(serverListenPath, (0, express_async_handler_1.default)(new COPY_handler_1.COPYRequestHandler().handle));
|
|
124
118
|
};
|
|
125
119
|
start = async () => {
|
|
126
120
|
const configs = await this.configService.readWebdavConfig();
|
|
@@ -136,7 +130,7 @@ class WebDavServer {
|
|
|
136
130
|
const httpsCerts = await network_utils_1.NetworkUtils.getWebdavSSLCerts();
|
|
137
131
|
server = https_1.default.createServer(httpsCerts, this.app);
|
|
138
132
|
}
|
|
139
|
-
server.requestTimeout =
|
|
133
|
+
server.requestTimeout = configs.timeoutMinutes * 60 * 1000;
|
|
140
134
|
server.listen(configs.port, () => {
|
|
141
135
|
logger_utils_1.webdavLogger.info(`Internxt ${sdk_manager_service_1.SdkManager.getAppDetails().clientVersion} WebDav server ` +
|
|
142
136
|
`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.2"
|
|
1261
1270
|
}
|