@internxt/cli 1.5.3 → 1.5.5
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 +4 -7
- package/README.md +78 -26
- package/bin/dev.js +1 -1
- package/bin/run.js +1 -1
- package/dist/commands/create-folder.js +1 -1
- package/dist/commands/delete-permanently-file.js +1 -1
- package/dist/commands/delete-permanently-folder.js +1 -1
- package/dist/commands/download-file.js +2 -1
- package/dist/commands/logout.js +2 -0
- package/dist/commands/upload-file.js +3 -2
- package/dist/services/auth.service.d.ts +1 -0
- package/dist/services/auth.service.js +14 -1
- package/dist/services/crypto.service.d.ts +1 -1
- package/dist/services/crypto.service.js +2 -2
- package/dist/services/drive/drive-file.service.d.ts +1 -1
- package/dist/services/drive/drive-file.service.js +7 -7
- package/dist/services/drive/drive-folder.service.js +7 -7
- package/dist/services/drive/trash.service.d.ts +6 -4
- package/dist/services/drive/trash.service.js +6 -6
- package/dist/services/keys.service.js +1 -1
- package/dist/services/sdk-manager.service.d.ts +3 -5
- package/dist/services/sdk-manager.service.js +15 -34
- package/dist/services/thumbnail.service.d.ts +2 -2
- package/dist/services/thumbnail.service.js +6 -6
- package/dist/services/usage.service.d.ts +2 -2
- package/dist/services/usage.service.js +2 -2
- package/dist/services/validation.service.js +2 -2
- package/dist/types/config.types.d.ts +2 -4
- package/dist/utils/pm2.utils.d.ts +1 -1
- package/dist/utils/thumbnail.utils.js +3 -3
- package/dist/utils/webdav.utils.d.ts +2 -3
- package/dist/utils/webdav.utils.js +6 -18
- package/dist/webdav/handlers/DELETE.handler.js +5 -1
- package/dist/webdav/handlers/GET.handler.js +6 -2
- package/dist/webdav/handlers/HEAD.handler.js +7 -2
- package/dist/webdav/handlers/MKCOL.handler.js +10 -8
- package/dist/webdav/handlers/MOVE.handler.js +10 -3
- package/dist/webdav/handlers/OPTIONS.handler.js +2 -5
- package/dist/webdav/handlers/PROPFIND.handler.js +20 -21
- package/dist/webdav/handlers/PUT.handler.js +8 -4
- package/dist/webdav/index.js +1 -1
- package/dist/webdav/webdav-server.js +1 -0
- package/oclif.manifest.json +1 -1
- package/package.json +35 -38
- package/scripts/restart-webdav.js +2 -1
|
@@ -12,11 +12,9 @@ export declare class SdkManager {
|
|
|
12
12
|
throwErrorOnMissingCredentials: boolean;
|
|
13
13
|
}) => SdkManagerApiSecurity;
|
|
14
14
|
static readonly getAppDetails: () => AppDetails;
|
|
15
|
-
getAuth(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
getReferrals(): Drive.Referrals;
|
|
19
|
-
getStorage(useNewApi?: boolean): Drive.Storage;
|
|
15
|
+
getAuth(): Auth;
|
|
16
|
+
getUsers(): Drive.Users;
|
|
17
|
+
getStorage(): Drive.Storage;
|
|
20
18
|
getTrash(): Drive.Trash;
|
|
21
19
|
getShare(): Drive.Share;
|
|
22
20
|
getNetwork(credentials: {
|
|
@@ -25,68 +25,49 @@ class SdkManager {
|
|
|
25
25
|
};
|
|
26
26
|
static getAppDetails = () => {
|
|
27
27
|
return {
|
|
28
|
-
clientName: package_json_1.default.
|
|
28
|
+
clientName: package_json_1.default.clientName,
|
|
29
29
|
clientVersion: package_json_1.default.version,
|
|
30
|
+
desktopHeader: config_service_1.ConfigService.instance.get('DESKTOP_HEADER'),
|
|
30
31
|
};
|
|
31
32
|
};
|
|
32
|
-
getAuth(
|
|
33
|
-
const DRIVE_API_URL =
|
|
34
|
-
? config_service_1.ConfigService.instance.get('DRIVE_NEW_API_URL')
|
|
35
|
-
: config_service_1.ConfigService.instance.get('DRIVE_API_URL');
|
|
33
|
+
getAuth() {
|
|
34
|
+
const DRIVE_API_URL = config_service_1.ConfigService.instance.get('DRIVE_NEW_API_URL');
|
|
36
35
|
const apiSecurity = SdkManager.getApiSecurity({ throwErrorOnMissingCredentials: false });
|
|
37
36
|
const appDetails = SdkManager.getAppDetails();
|
|
38
37
|
return sdk_1.Auth.client(DRIVE_API_URL, appDetails, {
|
|
39
|
-
token:
|
|
38
|
+
token: apiSecurity?.newToken,
|
|
40
39
|
});
|
|
41
40
|
}
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
const newToken = SdkManager.getApiSecurity().newToken;
|
|
45
|
-
const appDetails = SdkManager.getAppDetails();
|
|
46
|
-
return sdk_1.Drive.Payments.client(PAYMENTS_API_URL, appDetails, {
|
|
47
|
-
token: newToken,
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
getUsers(useNewApi = false) {
|
|
51
|
-
const DRIVE_API_URL = useNewApi
|
|
52
|
-
? config_service_1.ConfigService.instance.get('DRIVE_NEW_API_URL')
|
|
53
|
-
: config_service_1.ConfigService.instance.get('DRIVE_API_URL');
|
|
41
|
+
getUsers() {
|
|
42
|
+
const DRIVE_API_URL = config_service_1.ConfigService.instance.get('DRIVE_NEW_API_URL');
|
|
54
43
|
const apiSecurity = SdkManager.getApiSecurity({ throwErrorOnMissingCredentials: false });
|
|
55
44
|
const appDetails = SdkManager.getAppDetails();
|
|
56
45
|
return sdk_1.Drive.Users.client(DRIVE_API_URL, appDetails, {
|
|
57
|
-
token:
|
|
46
|
+
token: apiSecurity.newToken,
|
|
58
47
|
});
|
|
59
48
|
}
|
|
60
|
-
|
|
61
|
-
const DRIVE_API_URL = config_service_1.ConfigService.instance.get('
|
|
62
|
-
const apiSecurity = SdkManager.getApiSecurity();
|
|
63
|
-
const appDetails = SdkManager.getAppDetails();
|
|
64
|
-
return sdk_1.Drive.Referrals.client(DRIVE_API_URL, appDetails, apiSecurity);
|
|
65
|
-
}
|
|
66
|
-
getStorage(useNewApi = false) {
|
|
67
|
-
const DRIVE_API_URL = useNewApi
|
|
68
|
-
? config_service_1.ConfigService.instance.get('DRIVE_NEW_API_URL')
|
|
69
|
-
: config_service_1.ConfigService.instance.get('DRIVE_API_URL');
|
|
49
|
+
getStorage() {
|
|
50
|
+
const DRIVE_API_URL = config_service_1.ConfigService.instance.get('DRIVE_NEW_API_URL');
|
|
70
51
|
const apiSecurity = SdkManager.getApiSecurity();
|
|
71
52
|
const appDetails = SdkManager.getAppDetails();
|
|
72
53
|
return sdk_1.Drive.Storage.client(DRIVE_API_URL, appDetails, {
|
|
73
|
-
token:
|
|
54
|
+
token: apiSecurity.newToken,
|
|
74
55
|
});
|
|
75
56
|
}
|
|
76
57
|
getTrash() {
|
|
77
58
|
const DRIVE_NEW_API_URL = config_service_1.ConfigService.instance.get('DRIVE_NEW_API_URL');
|
|
78
|
-
const
|
|
59
|
+
const apiSecurity = SdkManager.getApiSecurity();
|
|
79
60
|
const appDetails = SdkManager.getAppDetails();
|
|
80
61
|
return drive_1.Trash.client(DRIVE_NEW_API_URL, appDetails, {
|
|
81
|
-
token: newToken,
|
|
62
|
+
token: apiSecurity.newToken,
|
|
82
63
|
});
|
|
83
64
|
}
|
|
84
65
|
getShare() {
|
|
85
66
|
const DRIVE_NEW_API_URL = config_service_1.ConfigService.instance.get('DRIVE_NEW_API_URL');
|
|
86
|
-
const
|
|
67
|
+
const apiSecurity = SdkManager.getApiSecurity();
|
|
87
68
|
const appDetails = SdkManager.getAppDetails();
|
|
88
69
|
return sdk_1.Drive.Share.client(DRIVE_NEW_API_URL, appDetails, {
|
|
89
|
-
token: newToken,
|
|
70
|
+
token: apiSecurity.newToken,
|
|
90
71
|
});
|
|
91
72
|
}
|
|
92
73
|
getNetwork(credentials) {
|
|
@@ -2,6 +2,6 @@ import { StorageTypes } from '@internxt/sdk/dist/drive';
|
|
|
2
2
|
import { NetworkFacade } from './network/network-facade.service';
|
|
3
3
|
export declare class ThumbnailService {
|
|
4
4
|
static readonly instance: ThumbnailService;
|
|
5
|
-
uploadThumbnail: (fileContent: Buffer, fileType: string, userBucket: string, file_id:
|
|
6
|
-
private getThumbnailFromImageBuffer;
|
|
5
|
+
uploadThumbnail: (fileContent: Buffer, fileType: string, userBucket: string, file_id: string, networkFacade: NetworkFacade) => Promise<StorageTypes.Thumbnail | undefined>;
|
|
6
|
+
private readonly getThumbnailFromImageBuffer;
|
|
7
7
|
}
|
|
@@ -27,14 +27,14 @@ class ThumbnailService {
|
|
|
27
27
|
}, () => { });
|
|
28
28
|
});
|
|
29
29
|
const createdThumbnailFile = await drive_file_service_1.DriveFileService.instance.createThumbnail({
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
fileUuid: file_id,
|
|
31
|
+
maxWidth: thumbnail_utils_1.ThumbnailConfig.MaxWidth,
|
|
32
|
+
maxHeight: thumbnail_utils_1.ThumbnailConfig.MaxHeight,
|
|
33
33
|
type: thumbnail_utils_1.ThumbnailConfig.Type,
|
|
34
34
|
size: size,
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
bucketId: userBucket,
|
|
36
|
+
bucketFile: fileId,
|
|
37
|
+
encryptVersion: drive_1.StorageTypes.EncryptionVersion.Aes03,
|
|
38
38
|
});
|
|
39
39
|
return createdThumbnailFile;
|
|
40
40
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { UsageResponseV2 } from '@internxt/sdk/dist/drive/storage/types';
|
|
2
2
|
export declare class UsageService {
|
|
3
3
|
static readonly instance: UsageService;
|
|
4
4
|
static readonly INFINITE_LIMIT: number;
|
|
5
|
-
fetchUsage: () => Promise<
|
|
5
|
+
fetchUsage: () => Promise<UsageResponseV2>;
|
|
6
6
|
fetchSpaceLimit: () => Promise<number>;
|
|
7
7
|
}
|
|
@@ -7,12 +7,12 @@ class UsageService {
|
|
|
7
7
|
static INFINITE_LIMIT = 99 * Math.pow(1024, 4);
|
|
8
8
|
fetchUsage = async () => {
|
|
9
9
|
const storageClient = sdk_manager_service_1.SdkManager.instance.getStorage();
|
|
10
|
-
const driveUsage = await storageClient.
|
|
10
|
+
const driveUsage = await storageClient.spaceUsageV2();
|
|
11
11
|
return driveUsage;
|
|
12
12
|
};
|
|
13
13
|
fetchSpaceLimit = async () => {
|
|
14
14
|
const storageClient = sdk_manager_service_1.SdkManager.instance.getStorage();
|
|
15
|
-
const spaceLimit = await storageClient.
|
|
15
|
+
const spaceLimit = await storageClient.spaceLimitV2();
|
|
16
16
|
return spaceLimit.maxSpaceBytes;
|
|
17
17
|
};
|
|
18
18
|
}
|
|
@@ -52,10 +52,10 @@ class ValidationService {
|
|
|
52
52
|
return { isValid: false, expiration: { expired: true, refreshRequired: false } };
|
|
53
53
|
}
|
|
54
54
|
const currentTime = Math.floor(Date.now() / 1000);
|
|
55
|
-
const
|
|
55
|
+
const oneDayInSeconds = 1 * 24 * 60 * 60;
|
|
56
56
|
const remainingSeconds = payload.exp - currentTime;
|
|
57
57
|
const expired = remainingSeconds <= 0;
|
|
58
|
-
const refreshRequired = remainingSeconds > 0 && remainingSeconds <=
|
|
58
|
+
const refreshRequired = remainingSeconds > 0 && remainingSeconds <= oneDayInSeconds;
|
|
59
59
|
return { isValid: true, expiration: { expired, refreshRequired } };
|
|
60
60
|
}
|
|
61
61
|
catch {
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
export interface ConfigKeys {
|
|
2
|
-
readonly
|
|
3
|
-
readonly DRIVE_API_URL: string;
|
|
2
|
+
readonly DRIVE_WEB_URL: string;
|
|
4
3
|
readonly DRIVE_NEW_API_URL: string;
|
|
5
|
-
readonly PAYMENTS_API_URL: string;
|
|
6
4
|
readonly APP_CRYPTO_SECRET: string;
|
|
7
|
-
readonly APP_CRYPTO_SECRET2: string;
|
|
8
5
|
readonly APP_MAGIC_IV: string;
|
|
9
6
|
readonly APP_MAGIC_SALT: string;
|
|
10
7
|
readonly NETWORK_URL: string;
|
|
8
|
+
readonly DESKTOP_HEADER: string;
|
|
11
9
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import pm2 from 'pm2';
|
|
2
2
|
export type WebDavProcessStatus = 'online' | 'stopping' | 'stopped' | 'launching' | 'errored' | 'one-launch-status' | 'offline' | 'unknown';
|
|
3
3
|
export declare class PM2Utils {
|
|
4
|
-
private static WEBDAV_APP_NAME;
|
|
4
|
+
private static readonly WEBDAV_APP_NAME;
|
|
5
5
|
static connect(): Promise<void>;
|
|
6
6
|
static disconnect(): void;
|
|
7
7
|
static clean(): Promise<void>;
|
|
@@ -31,14 +31,14 @@ const thumbnailableImageExtension = [
|
|
|
31
31
|
const thumbnailablePdfExtension = pdfExtensions['pdf'];
|
|
32
32
|
const thumbnailableExtension = [...thumbnailableImageExtension];
|
|
33
33
|
const isFileThumbnailable = (fileType) => {
|
|
34
|
-
return fileType.trim().length > 0 && thumbnailableExtension.includes(fileType);
|
|
34
|
+
return fileType.trim().length > 0 && thumbnailableExtension.includes(fileType.trim().toLowerCase());
|
|
35
35
|
};
|
|
36
36
|
exports.isFileThumbnailable = isFileThumbnailable;
|
|
37
37
|
const isPDFThumbnailable = (fileType) => {
|
|
38
|
-
return fileType.trim().length > 0 && thumbnailablePdfExtension.includes(fileType);
|
|
38
|
+
return fileType.trim().length > 0 && thumbnailablePdfExtension.includes(fileType.trim().toLowerCase());
|
|
39
39
|
};
|
|
40
40
|
exports.isPDFThumbnailable = isPDFThumbnailable;
|
|
41
41
|
const isImageThumbnailable = (fileType) => {
|
|
42
|
-
return fileType.trim().length > 0 && thumbnailableImageExtension.includes(fileType);
|
|
42
|
+
return fileType.trim().length > 0 && thumbnailableImageExtension.includes(fileType.trim().toLowerCase());
|
|
43
43
|
};
|
|
44
44
|
exports.isImageThumbnailable = isImageThumbnailable;
|
|
@@ -7,10 +7,9 @@ export declare class WebDavUtils {
|
|
|
7
7
|
static joinURL(...pathComponents: string[]): string;
|
|
8
8
|
static removeHostFromURL(completeURL: string): string;
|
|
9
9
|
static getRequestedResource(urlObject: string | Request, decodeUri?: boolean): Promise<WebDavRequestedResource>;
|
|
10
|
-
static getDriveItemFromResource(resource
|
|
11
|
-
static getAndSearchItemFromResource({ resource, driveFolderService, driveFileService, }: {
|
|
10
|
+
static getDriveItemFromResource({ resource, driveFolderService, driveFileService, }: {
|
|
12
11
|
resource: WebDavRequestedResource;
|
|
13
12
|
driveFolderService?: DriveFolderService;
|
|
14
13
|
driveFileService?: DriveFileService;
|
|
15
|
-
}): Promise<DriveFileItem | DriveFolderItem>;
|
|
14
|
+
}): Promise<DriveFileItem | DriveFolderItem | undefined>;
|
|
16
15
|
}
|
|
@@ -5,7 +5,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.WebDavUtils = void 0;
|
|
7
7
|
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
-
const errors_utils_1 = require("./errors.utils");
|
|
9
8
|
class WebDavUtils {
|
|
10
9
|
static joinURL(...pathComponents) {
|
|
11
10
|
return node_path_1.default.posix.join(...pathComponents);
|
|
@@ -55,30 +54,19 @@ class WebDavUtils {
|
|
|
55
54
|
};
|
|
56
55
|
}
|
|
57
56
|
}
|
|
58
|
-
static async getDriveItemFromResource(resource, driveFolderService, driveFileService) {
|
|
57
|
+
static async getDriveItemFromResource({ resource, driveFolderService, driveFileService, }) {
|
|
59
58
|
let item = undefined;
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
try {
|
|
60
|
+
if (resource.type === 'folder') {
|
|
62
61
|
item = await driveFolderService?.getFolderMetadataByPath(resource.url);
|
|
63
62
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
throw new errors_utils_1.ConflictError(`Resource not found on Internxt Drive at ${resource.url}`);
|
|
67
|
-
}
|
|
68
|
-
throw error;
|
|
63
|
+
if (resource.type === 'file') {
|
|
64
|
+
item = await driveFileService?.getFileMetadataByPath(resource.url);
|
|
69
65
|
}
|
|
70
66
|
}
|
|
71
|
-
|
|
72
|
-
item = await driveFileService?.getFileMetadataByPath(resource.url);
|
|
67
|
+
catch {
|
|
73
68
|
}
|
|
74
69
|
return item;
|
|
75
70
|
}
|
|
76
|
-
static async getAndSearchItemFromResource({ resource, driveFolderService, driveFileService, }) {
|
|
77
|
-
const driveItem = await this.getDriveItemFromResource(resource, driveFolderService, driveFileService);
|
|
78
|
-
if (!driveItem) {
|
|
79
|
-
throw new errors_utils_1.NotFoundError(`Resource not found on Internxt Drive at ${resource.url}`);
|
|
80
|
-
}
|
|
81
|
-
return driveItem;
|
|
82
|
-
}
|
|
83
71
|
}
|
|
84
72
|
exports.WebDavUtils = WebDavUtils;
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.DELETERequestHandler = void 0;
|
|
4
4
|
const webdav_utils_1 = require("../../utils/webdav.utils");
|
|
5
5
|
const logger_utils_1 = require("../../utils/logger.utils");
|
|
6
|
+
const errors_utils_1 = require("../../utils/errors.utils");
|
|
6
7
|
class DELETERequestHandler {
|
|
7
8
|
dependencies;
|
|
8
9
|
constructor(dependencies) {
|
|
@@ -12,11 +13,14 @@ class DELETERequestHandler {
|
|
|
12
13
|
const { driveFileService, driveFolderService, trashService } = this.dependencies;
|
|
13
14
|
const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req);
|
|
14
15
|
logger_utils_1.webdavLogger.info(`[DELETE] Request received for ${resource.type} at ${resource.url}`);
|
|
15
|
-
const driveItem = await webdav_utils_1.WebDavUtils.
|
|
16
|
+
const driveItem = await webdav_utils_1.WebDavUtils.getDriveItemFromResource({
|
|
16
17
|
resource,
|
|
17
18
|
driveFolderService,
|
|
18
19
|
driveFileService: driveFileService,
|
|
19
20
|
});
|
|
21
|
+
if (!driveItem) {
|
|
22
|
+
throw new errors_utils_1.NotFoundError(`Resource not found on Internxt Drive at ${resource.url}`);
|
|
23
|
+
}
|
|
20
24
|
logger_utils_1.webdavLogger.info(`[DELETE] [${driveItem.uuid}] Trashing ${resource.type}`);
|
|
21
25
|
await trashService.trashItems({
|
|
22
26
|
items: [{ type: resource.type, uuid: driveItem.uuid }],
|
|
@@ -18,10 +18,14 @@ class GETRequestHandler {
|
|
|
18
18
|
if (resource.type === 'folder')
|
|
19
19
|
throw new errors_utils_1.NotFoundError('Folders cannot be listed with GET. Use PROPFIND instead.');
|
|
20
20
|
logger_utils_1.webdavLogger.info(`[GET] Request received for ${resource.type} at ${resource.url}`);
|
|
21
|
-
const
|
|
21
|
+
const driveItem = await webdav_utils_1.WebDavUtils.getDriveItemFromResource({
|
|
22
22
|
resource,
|
|
23
23
|
driveFileService,
|
|
24
|
-
})
|
|
24
|
+
});
|
|
25
|
+
if (!driveItem) {
|
|
26
|
+
throw new errors_utils_1.NotFoundError(`Resource not found on Internxt Drive at ${resource.url}`);
|
|
27
|
+
}
|
|
28
|
+
const driveFile = driveItem;
|
|
25
29
|
logger_utils_1.webdavLogger.info(`[GET] [${driveFile.uuid}] Found Drive File`);
|
|
26
30
|
const { user } = await authService.getAuthDetails();
|
|
27
31
|
logger_utils_1.webdavLogger.info(`[GET] [${driveFile.uuid}] Network ready for download`);
|
|
@@ -4,6 +4,7 @@ exports.HEADRequestHandler = void 0;
|
|
|
4
4
|
const webdav_utils_1 = require("../../utils/webdav.utils");
|
|
5
5
|
const logger_utils_1 = require("../../utils/logger.utils");
|
|
6
6
|
const network_utils_1 = require("../../utils/network.utils");
|
|
7
|
+
const errors_utils_1 = require("../../utils/errors.utils");
|
|
7
8
|
class HEADRequestHandler {
|
|
8
9
|
dependencies;
|
|
9
10
|
constructor(dependencies) {
|
|
@@ -18,10 +19,14 @@ class HEADRequestHandler {
|
|
|
18
19
|
}
|
|
19
20
|
logger_utils_1.webdavLogger.info(`[HEAD] Request received for ${resource.type} at ${resource.url}`);
|
|
20
21
|
try {
|
|
21
|
-
const
|
|
22
|
+
const driveItem = await webdav_utils_1.WebDavUtils.getDriveItemFromResource({
|
|
22
23
|
resource,
|
|
23
24
|
driveFileService,
|
|
24
|
-
})
|
|
25
|
+
});
|
|
26
|
+
if (!driveItem) {
|
|
27
|
+
throw new errors_utils_1.NotFoundError(`Resource not found on Internxt Drive at ${resource.url}`);
|
|
28
|
+
}
|
|
29
|
+
const driveFile = driveItem;
|
|
25
30
|
logger_utils_1.webdavLogger.info(`[HEAD] [${driveFile.uuid}] Found Drive File`);
|
|
26
31
|
const range = req.headers['range'];
|
|
27
32
|
const rangeOptions = network_utils_1.NetworkUtils.parseRangeHeader({
|
|
@@ -16,17 +16,19 @@ class MKCOLRequestHandler {
|
|
|
16
16
|
const resource = await webdav_utils_1.WebDavUtils.getRequestedResource(req);
|
|
17
17
|
logger_utils_1.webdavLogger.info(`[MKCOL] Request received for ${resource.type} at ${resource.url}`);
|
|
18
18
|
const parentResource = await webdav_utils_1.WebDavUtils.getRequestedResource(resource.parentPath, false);
|
|
19
|
-
const
|
|
19
|
+
const parentDriveItem = await webdav_utils_1.WebDavUtils.getDriveItemFromResource({
|
|
20
20
|
resource: parentResource,
|
|
21
21
|
driveFolderService,
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
await driveFolderService.getFolderMetadataByPath(resource.url);
|
|
26
|
-
}
|
|
27
|
-
catch {
|
|
28
|
-
folderAlreadyExists = false;
|
|
22
|
+
});
|
|
23
|
+
if (!parentDriveItem) {
|
|
24
|
+
throw new errors_utils_1.ConflictError(`Parent folders not found on Internxt Drive at ${resource.url}`);
|
|
29
25
|
}
|
|
26
|
+
const parentFolderItem = parentDriveItem;
|
|
27
|
+
const driveFolderItem = await webdav_utils_1.WebDavUtils.getDriveItemFromResource({
|
|
28
|
+
resource,
|
|
29
|
+
driveFolderService,
|
|
30
|
+
});
|
|
31
|
+
const folderAlreadyExists = !!driveFolderItem;
|
|
30
32
|
if (folderAlreadyExists) {
|
|
31
33
|
logger_utils_1.webdavLogger.info(`[MKCOL] ❌ Folder '${resource.url}' already exists`);
|
|
32
34
|
throw new errors_utils_1.MethodNotAllowed('Folder already exists');
|
|
@@ -20,11 +20,14 @@ class MOVERequestHandler {
|
|
|
20
20
|
const destinationPath = webdav_utils_1.WebDavUtils.removeHostFromURL(destinationUrl);
|
|
21
21
|
const destinationResource = await webdav_utils_1.WebDavUtils.getRequestedResource(destinationPath);
|
|
22
22
|
logger_utils_1.webdavLogger.info('[MOVE] Destination resource found', { destinationResource });
|
|
23
|
-
const originalDriveItem = await webdav_utils_1.WebDavUtils.
|
|
23
|
+
const originalDriveItem = await webdav_utils_1.WebDavUtils.getDriveItemFromResource({
|
|
24
24
|
resource,
|
|
25
25
|
driveFolderService,
|
|
26
26
|
driveFileService,
|
|
27
27
|
});
|
|
28
|
+
if (!originalDriveItem) {
|
|
29
|
+
throw new errors_utils_1.NotFoundError(`Resource not found on Internxt Drive at ${resource.url}`);
|
|
30
|
+
}
|
|
28
31
|
if (destinationResource.path.dir === resource.path.dir) {
|
|
29
32
|
logger_utils_1.webdavLogger.info(`[MOVE] Renaming ${resource.type} with UUID ${originalDriveItem.uuid} to ${destinationResource.name}`);
|
|
30
33
|
const newName = destinationResource.name;
|
|
@@ -47,10 +50,14 @@ class MOVERequestHandler {
|
|
|
47
50
|
else {
|
|
48
51
|
logger_utils_1.webdavLogger.info(`[MOVE] Moving ${resource.type} with UUID ${originalDriveItem.uuid} to ${destinationPath}`);
|
|
49
52
|
const destinationFolderResource = await webdav_utils_1.WebDavUtils.getRequestedResource(destinationResource.parentPath);
|
|
50
|
-
const
|
|
53
|
+
const destinationDriveFolderItem = await webdav_utils_1.WebDavUtils.getDriveItemFromResource({
|
|
51
54
|
resource: destinationFolderResource,
|
|
52
55
|
driveFolderService,
|
|
53
|
-
})
|
|
56
|
+
});
|
|
57
|
+
if (!destinationDriveFolderItem) {
|
|
58
|
+
throw new errors_utils_1.NotFoundError(`Resource not found on Internxt Drive at ${resource.url}`);
|
|
59
|
+
}
|
|
60
|
+
const destinationFolderItem = destinationDriveFolderItem;
|
|
54
61
|
if (resource.type === 'folder') {
|
|
55
62
|
const folder = originalDriveItem;
|
|
56
63
|
await driveFolderService.moveFolder({
|
|
@@ -13,23 +13,20 @@ class OPTIONSRequestHandler {
|
|
|
13
13
|
res.header('Allow', 'DELETE, GET, HEAD, MKCOL, MOVE, OPTIONS, PROPFIND, PUT');
|
|
14
14
|
res.header('DAV', '1, 2, ordered-collections');
|
|
15
15
|
res.status(200).send();
|
|
16
|
-
return;
|
|
17
16
|
}
|
|
18
|
-
if (resource.type === 'folder') {
|
|
17
|
+
else if (resource.type === 'folder') {
|
|
19
18
|
const allowedMethods = 'DELETE, HEAD, MKCOL, MOVE, OPTIONS, PROPFIND';
|
|
20
19
|
logger_utils_1.webdavLogger.info(`[OPTIONS] Returning Allowed Options: ${allowedMethods}`);
|
|
21
20
|
res.header('Allow', allowedMethods);
|
|
22
21
|
res.header('DAV', '1, 2, ordered-collections');
|
|
23
22
|
res.status(200).send();
|
|
24
|
-
return;
|
|
25
23
|
}
|
|
26
|
-
|
|
24
|
+
else {
|
|
27
25
|
const allowedMethods = 'DELETE, GET, HEAD, MOVE, OPTIONS, PROPFIND, PUT';
|
|
28
26
|
logger_utils_1.webdavLogger.info(`[OPTIONS] Returning Allowed Options: ${allowedMethods}`);
|
|
29
27
|
res.header('Allow', allowedMethods);
|
|
30
28
|
res.header('DAV', '1, 2, ordered-collections');
|
|
31
29
|
res.status(200).send();
|
|
32
|
-
return;
|
|
33
30
|
}
|
|
34
31
|
};
|
|
35
32
|
}
|
|
@@ -20,27 +20,12 @@ class PROPFINDRequestHandler {
|
|
|
20
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
|
-
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
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
catch {
|
|
23
|
+
const driveItem = await webdav_utils_1.WebDavUtils.getDriveItemFromResource({
|
|
24
|
+
resource,
|
|
25
|
+
driveFolderService,
|
|
26
|
+
driveFileService,
|
|
27
|
+
});
|
|
28
|
+
if (!driveItem) {
|
|
44
29
|
res.status(207).send(xml_utils_1.XMLUtils.toWebDavXML({
|
|
45
30
|
[xml_utils_1.XMLUtils.addDefaultNamespace('response')]: {
|
|
46
31
|
[xml_utils_1.XMLUtils.addDefaultNamespace('href')]: xml_utils_1.XMLUtils.encodeWebDavUri(resource.url),
|
|
@@ -53,6 +38,20 @@ class PROPFINDRequestHandler {
|
|
|
53
38
|
ignoreAttributes: false,
|
|
54
39
|
suppressEmptyNode: true,
|
|
55
40
|
}));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
switch (resource.type) {
|
|
44
|
+
case 'file': {
|
|
45
|
+
const fileMetaXML = await this.getFileMetaXML(resource, driveItem);
|
|
46
|
+
res.status(207).send(fileMetaXML);
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
case 'folder': {
|
|
50
|
+
const depth = req.header('depth') ?? '1';
|
|
51
|
+
const folderMetaXML = await this.getFolderContentXML(resource, driveItem, depth);
|
|
52
|
+
res.status(207).send(folderMetaXML);
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
56
55
|
}
|
|
57
56
|
};
|
|
58
57
|
getFileMetaXML = async (resource, driveFileItem) => {
|
|
@@ -27,12 +27,16 @@ class PUTRequestHandler {
|
|
|
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
29
|
const parentResource = await webdav_utils_1.WebDavUtils.getRequestedResource(resource.parentPath, false);
|
|
30
|
-
const
|
|
30
|
+
const parentDriveFolderItem = await webdav_utils_1.WebDavUtils.getDriveItemFromResource({
|
|
31
31
|
resource: parentResource,
|
|
32
32
|
driveFolderService,
|
|
33
|
-
})
|
|
33
|
+
});
|
|
34
|
+
if (!parentDriveFolderItem) {
|
|
35
|
+
throw new errors_utils_1.ConflictError(`Parent folders not found on Internxt Drive at ${resource.url}`);
|
|
36
|
+
}
|
|
37
|
+
const parentFolderItem = parentDriveFolderItem;
|
|
34
38
|
try {
|
|
35
|
-
const driveFileItem = (await webdav_utils_1.WebDavUtils.
|
|
39
|
+
const driveFileItem = (await webdav_utils_1.WebDavUtils.getDriveItemFromResource({
|
|
36
40
|
resource: resource,
|
|
37
41
|
driveFileService,
|
|
38
42
|
}));
|
|
@@ -93,7 +97,7 @@ class PUTRequestHandler {
|
|
|
93
97
|
if (isThumbnailable && bufferStream) {
|
|
94
98
|
const thumbnailBuffer = bufferStream.getBuffer();
|
|
95
99
|
if (thumbnailBuffer) {
|
|
96
|
-
await thumbnail_service_1.ThumbnailService.instance.uploadThumbnail(thumbnailBuffer, fileType, user.bucket, file.
|
|
100
|
+
await thumbnail_service_1.ThumbnailService.instance.uploadThumbnail(thumbnailBuffer, fileType, user.bucket, file.uuid, networkFacade);
|
|
97
101
|
}
|
|
98
102
|
}
|
|
99
103
|
}
|
package/dist/webdav/index.js
CHANGED
|
@@ -15,7 +15,7 @@ const crypto_service_1 = require("../services/crypto.service");
|
|
|
15
15
|
const trash_service_1 = require("../services/drive/trash.service");
|
|
16
16
|
const logger_utils_1 = require("../utils/logger.utils");
|
|
17
17
|
const sdk_manager_service_1 = require("../services/sdk-manager.service");
|
|
18
|
-
dotenv_1.default.config();
|
|
18
|
+
dotenv_1.default.config({ quiet: true });
|
|
19
19
|
const init = async () => {
|
|
20
20
|
await config_service_1.ConfigService.instance.ensureInternxtCliDataDirExists();
|
|
21
21
|
await config_service_1.ConfigService.instance.ensureWebdavCertsDirExists();
|
|
@@ -63,6 +63,7 @@ class WebDavServer {
|
|
|
63
63
|
bridgePass: credentials.user.userId,
|
|
64
64
|
bridgeUrl: config_service_1.ConfigService.instance.get('NETWORK_URL'),
|
|
65
65
|
encryptionKey: credentials.user.mnemonic,
|
|
66
|
+
appDetails: sdk_manager_service_1.SdkManager.getAppDetails(),
|
|
66
67
|
});
|
|
67
68
|
const networkFacade = new network_facade_service_1.NetworkFacade(networkModule, environment, download_service_1.DownloadService.instance, crypto_service_1.CryptoService.instance);
|
|
68
69
|
return networkFacade;
|
package/oclif.manifest.json
CHANGED