@internxt/cli 1.5.4 → 1.5.6
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 -3
- package/README.md +65 -30
- package/dist/commands/create-folder.js +2 -0
- package/dist/commands/download-file.d.ts +1 -1
- package/dist/commands/download-file.js +9 -2
- package/dist/commands/list.d.ts +40 -2
- package/dist/commands/login.d.ts +1 -0
- package/dist/commands/login.js +58 -8
- package/dist/commands/move-file.d.ts +19 -1
- package/dist/commands/move-file.js +1 -1
- package/dist/commands/move-folder.js +3 -1
- package/dist/commands/rename-file.d.ts +1 -0
- package/dist/commands/rename-file.js +11 -4
- package/dist/commands/trash-file.js +1 -1
- package/dist/commands/trash-folder.js +1 -1
- package/dist/commands/trash-list.d.ts +40 -2
- package/dist/commands/trash-restore-file.d.ts +19 -1
- package/dist/commands/trash-restore-file.js +1 -1
- package/dist/commands/trash-restore-folder.js +3 -1
- package/dist/commands/upload-file.d.ts +17 -1
- package/dist/commands/upload-file.js +17 -11
- package/dist/commands/webdav-config.d.ts +1 -0
- package/dist/commands/webdav-config.js +9 -0
- package/dist/commands/webdav.js +2 -2
- package/dist/commands/whoami.js +14 -8
- package/dist/hooks/prerun/auth_check.js +2 -5
- package/dist/services/auth.service.d.ts +2 -1
- package/dist/services/auth.service.js +32 -37
- package/dist/services/config.service.d.ts +1 -1
- package/dist/services/config.service.js +4 -7
- package/dist/services/database/drive-file/drive-file.attributes.d.ts +3 -1
- package/dist/services/database/drive-file/drive-file.domain.d.ts +4 -2
- package/dist/services/database/drive-file/drive-file.domain.js +9 -2
- package/dist/services/drive/drive-file.service.d.ts +1 -1
- package/dist/services/drive/drive-file.service.js +5 -4
- package/dist/services/drive/drive-folder.service.d.ts +41 -4
- package/dist/services/drive/drive-folder.service.js +2 -2
- package/dist/services/drive/trash.service.d.ts +40 -2
- package/dist/services/keys.service.d.ts +0 -3
- package/dist/services/keys.service.js +1 -60
- package/dist/services/sdk-manager.service.d.ts +1 -3
- package/dist/services/sdk-manager.service.js +6 -15
- package/dist/services/thumbnail.service.js +59 -15
- package/dist/types/command.types.d.ts +27 -3
- package/dist/types/config.types.d.ts +1 -0
- package/dist/types/drive.types.d.ts +5 -4
- package/dist/types/keys.types.d.ts +0 -12
- package/dist/types/keys.types.js +0 -29
- package/dist/utils/drive.utils.js +4 -3
- package/dist/utils/network.utils.d.ts +4 -3
- package/dist/utils/network.utils.js +8 -8
- package/dist/webdav/handlers/DELETE.handler.js +1 -1
- package/dist/webdav/handlers/MOVE.handler.js +9 -7
- package/dist/webdav/handlers/PROPFIND.handler.js +8 -5
- package/dist/webdav/handlers/PUT.handler.js +5 -6
- package/dist/webdav/index.js +2 -5
- package/dist/webdav/middewares/auth.middleware.js +3 -10
- package/dist/webdav/webdav-server.js +4 -3
- package/oclif.manifest.json +27 -3
- package/package.json +27 -28
|
@@ -11,8 +11,46 @@ export default class TrashList extends Command {
|
|
|
11
11
|
run: () => Promise<{
|
|
12
12
|
success: boolean;
|
|
13
13
|
list: {
|
|
14
|
-
folders:
|
|
15
|
-
|
|
14
|
+
folders: {
|
|
15
|
+
type: string;
|
|
16
|
+
id: number;
|
|
17
|
+
parentId: number;
|
|
18
|
+
parentUuid: string;
|
|
19
|
+
name: string;
|
|
20
|
+
parent: import("@internxt/sdk/dist/schema").components["schemas"]["Folder"];
|
|
21
|
+
bucket: string;
|
|
22
|
+
userId: number;
|
|
23
|
+
encryptVersion: string;
|
|
24
|
+
createdAt: string;
|
|
25
|
+
updatedAt: string;
|
|
26
|
+
uuid: string;
|
|
27
|
+
plainName: string;
|
|
28
|
+
size: number;
|
|
29
|
+
creationTime: string;
|
|
30
|
+
modificationTime: string;
|
|
31
|
+
status: "EXISTS" | "TRASHED" | "DELETED";
|
|
32
|
+
removed: boolean;
|
|
33
|
+
deleted: boolean;
|
|
34
|
+
}[];
|
|
35
|
+
files: {
|
|
36
|
+
id: number;
|
|
37
|
+
uuid: string;
|
|
38
|
+
fileId: string;
|
|
39
|
+
name: string;
|
|
40
|
+
type: string;
|
|
41
|
+
size: string;
|
|
42
|
+
bucket: string;
|
|
43
|
+
folderId: number;
|
|
44
|
+
folderUuid: string;
|
|
45
|
+
encryptVersion: string;
|
|
46
|
+
userId: number;
|
|
47
|
+
creationTime: string;
|
|
48
|
+
modificationTime: string;
|
|
49
|
+
createdAt: string;
|
|
50
|
+
updatedAt: string;
|
|
51
|
+
plainName: string;
|
|
52
|
+
status: "EXISTS" | "TRASHED" | "DELETED";
|
|
53
|
+
}[];
|
|
16
54
|
};
|
|
17
55
|
}>;
|
|
18
56
|
catch: (error: Error) => Promise<never>;
|
|
@@ -13,7 +13,25 @@ export default class TrashRestoreFile extends Command {
|
|
|
13
13
|
run: () => Promise<{
|
|
14
14
|
success: boolean;
|
|
15
15
|
message: string;
|
|
16
|
-
file:
|
|
16
|
+
file: {
|
|
17
|
+
id: number;
|
|
18
|
+
uuid: string;
|
|
19
|
+
fileId: string;
|
|
20
|
+
name: string;
|
|
21
|
+
type: string;
|
|
22
|
+
size: string;
|
|
23
|
+
bucket: string;
|
|
24
|
+
folderId: number;
|
|
25
|
+
folderUuid: string;
|
|
26
|
+
encryptVersion: string;
|
|
27
|
+
userId: number;
|
|
28
|
+
creationTime: string;
|
|
29
|
+
modificationTime: string;
|
|
30
|
+
createdAt: string;
|
|
31
|
+
updatedAt: string;
|
|
32
|
+
plainName: string;
|
|
33
|
+
status: "EXISTS" | "TRASHED" | "DELETED";
|
|
34
|
+
};
|
|
17
35
|
}>;
|
|
18
36
|
catch: (error: Error) => Promise<never>;
|
|
19
37
|
private getFileUuid;
|
|
@@ -37,7 +37,7 @@ class TrashRestoreFile extends core_1.Command {
|
|
|
37
37
|
if (destinationFolderUuid.trim().length === 0) {
|
|
38
38
|
destinationFolderUuid = userCredentials.user.rootFolderId;
|
|
39
39
|
}
|
|
40
|
-
const file = await drive_file_service_1.DriveFileService.instance.moveFile(
|
|
40
|
+
const file = await drive_file_service_1.DriveFileService.instance.moveFile(fileUuid, { destinationFolder: destinationFolderUuid });
|
|
41
41
|
const message = `File restored successfully to: ${destinationFolderUuid}`;
|
|
42
42
|
cli_utils_1.CLIUtils.success(this.log.bind(this), message);
|
|
43
43
|
return { success: true, message, file };
|
|
@@ -37,7 +37,9 @@ class TrashRestoreFolder extends core_1.Command {
|
|
|
37
37
|
if (destinationFolderUuid.trim().length === 0) {
|
|
38
38
|
destinationFolderUuid = userCredentials.user.rootFolderId;
|
|
39
39
|
}
|
|
40
|
-
const folder = await drive_folder_service_1.DriveFolderService.instance.moveFolder(
|
|
40
|
+
const folder = await drive_folder_service_1.DriveFolderService.instance.moveFolder(folderUuid, {
|
|
41
|
+
destinationFolder: destinationFolderUuid,
|
|
42
|
+
});
|
|
41
43
|
const message = `Folder restored successfully to: ${destinationFolderUuid}`;
|
|
42
44
|
cli_utils_1.CLIUtils.success(this.log.bind(this), message);
|
|
43
45
|
return { success: true, message, folder };
|
|
@@ -13,7 +13,23 @@ export default class UploadFile extends Command {
|
|
|
13
13
|
run: () => Promise<{
|
|
14
14
|
success: boolean;
|
|
15
15
|
message: string;
|
|
16
|
-
file:
|
|
16
|
+
file: {
|
|
17
|
+
plainName: string;
|
|
18
|
+
name: string;
|
|
19
|
+
id: number;
|
|
20
|
+
bucket: string;
|
|
21
|
+
uuid: string;
|
|
22
|
+
folderUuid: string;
|
|
23
|
+
folderId: number;
|
|
24
|
+
status: "EXISTS" | "TRASHED" | "DELETED";
|
|
25
|
+
fileId: string;
|
|
26
|
+
size: number;
|
|
27
|
+
createdAt: Date;
|
|
28
|
+
updatedAt: Date;
|
|
29
|
+
creationTime: Date;
|
|
30
|
+
modificationTime: Date;
|
|
31
|
+
type?: string | null;
|
|
32
|
+
};
|
|
17
33
|
}>;
|
|
18
34
|
catch: (error: Error) => Promise<never>;
|
|
19
35
|
private getDestinationFolderUuid;
|
|
@@ -46,9 +46,7 @@ class UploadFile extends core_1.Command {
|
|
|
46
46
|
run = async () => {
|
|
47
47
|
const { flags } = await this.parse(UploadFile);
|
|
48
48
|
const nonInteractive = flags['non-interactive'];
|
|
49
|
-
const
|
|
50
|
-
if (!userCredentials)
|
|
51
|
-
throw new command_types_1.MissingCredentialsError();
|
|
49
|
+
const { user } = await auth_service_1.AuthService.instance.getAuthDetails();
|
|
52
50
|
const filePath = await this.getFilePath(flags['file'], nonInteractive);
|
|
53
51
|
const stats = await (0, promises_1.stat)(filePath);
|
|
54
52
|
if (!stats.size) {
|
|
@@ -58,10 +56,9 @@ class UploadFile extends core_1.Command {
|
|
|
58
56
|
const fileType = fileInfo.ext.replaceAll('.', '');
|
|
59
57
|
let destinationFolderUuid = await this.getDestinationFolderUuid(flags['destination'], nonInteractive);
|
|
60
58
|
if (destinationFolderUuid.trim().length === 0) {
|
|
61
|
-
destinationFolderUuid =
|
|
59
|
+
destinationFolderUuid = user.rootFolderId;
|
|
62
60
|
}
|
|
63
61
|
cli_utils_1.CLIUtils.doing('Preparing Network', flags['json']);
|
|
64
|
-
const { user } = await auth_service_1.AuthService.instance.getAuthDetails();
|
|
65
62
|
const networkModule = sdk_manager_service_1.SdkManager.instance.getNetwork({
|
|
66
63
|
user: user.bridgeUser,
|
|
67
64
|
pass: user.userId,
|
|
@@ -71,6 +68,7 @@ class UploadFile extends core_1.Command {
|
|
|
71
68
|
bridgePass: user.userId,
|
|
72
69
|
bridgeUrl: config_service_1.ConfigService.instance.get('NETWORK_URL'),
|
|
73
70
|
encryptionKey: user.mnemonic,
|
|
71
|
+
appDetails: sdk_manager_service_1.SdkManager.getAppDetails(),
|
|
74
72
|
});
|
|
75
73
|
const networkFacade = new network_facade_service_1.NetworkFacade(networkModule, environment, download_service_1.DownloadService.instance, crypto_service_1.CryptoService.instance);
|
|
76
74
|
cli_utils_1.CLIUtils.done(flags['json']);
|
|
@@ -104,14 +102,15 @@ class UploadFile extends core_1.Command {
|
|
|
104
102
|
});
|
|
105
103
|
});
|
|
106
104
|
const createdDriveFile = await drive_file_service_1.DriveFileService.instance.createFile({
|
|
107
|
-
|
|
105
|
+
plainName: fileInfo.name,
|
|
108
106
|
type: fileType,
|
|
109
107
|
size: stats.size,
|
|
110
|
-
|
|
111
|
-
|
|
108
|
+
folderUuid: destinationFolderUuid,
|
|
109
|
+
fileId: fileId,
|
|
112
110
|
bucket: user.bucket,
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
encryptVersion: types_1.EncryptionVersion.Aes03,
|
|
112
|
+
creationTime: stats.birthtime?.toISOString(),
|
|
113
|
+
modificationTime: stats.mtime?.toISOString(),
|
|
115
114
|
});
|
|
116
115
|
try {
|
|
117
116
|
if (isThumbnailable && bufferStream) {
|
|
@@ -130,7 +129,14 @@ class UploadFile extends core_1.Command {
|
|
|
130
129
|
this.log('\n');
|
|
131
130
|
const message = `File uploaded in ${uploadTime}ms, view it at ${config_service_1.ConfigService.instance.get('DRIVE_WEB_URL')}/file/${createdDriveFile.uuid}`;
|
|
132
131
|
cli_utils_1.CLIUtils.success(this.log.bind(this), message);
|
|
133
|
-
return {
|
|
132
|
+
return {
|
|
133
|
+
success: true,
|
|
134
|
+
message,
|
|
135
|
+
file: {
|
|
136
|
+
...createdDriveFile,
|
|
137
|
+
plainName: fileInfo.name,
|
|
138
|
+
},
|
|
139
|
+
};
|
|
134
140
|
};
|
|
135
141
|
catch = async (error) => {
|
|
136
142
|
const { flags } = await this.parse(UploadFile);
|
|
@@ -5,6 +5,7 @@ export default class WebDAVConfig extends Command {
|
|
|
5
5
|
static readonly aliases: never[];
|
|
6
6
|
static readonly examples: string[];
|
|
7
7
|
static readonly flags: {
|
|
8
|
+
host: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
9
|
port: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
10
|
https: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
11
|
http: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
@@ -11,6 +11,11 @@ class WebDAVConfig extends core_1.Command {
|
|
|
11
11
|
static aliases = [];
|
|
12
12
|
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
13
13
|
static flags = {
|
|
14
|
+
host: core_1.Flags.string({
|
|
15
|
+
char: 'l',
|
|
16
|
+
description: 'The listening host for the WebDAV server.',
|
|
17
|
+
required: false,
|
|
18
|
+
}),
|
|
14
19
|
port: core_1.Flags.string({
|
|
15
20
|
char: 'p',
|
|
16
21
|
description: 'The new port for the WebDAV server.',
|
|
@@ -39,6 +44,10 @@ class WebDAVConfig extends core_1.Command {
|
|
|
39
44
|
run = async () => {
|
|
40
45
|
const { flags } = await this.parse(WebDAVConfig);
|
|
41
46
|
const webdavConfig = await config_service_1.ConfigService.instance.readWebdavConfig();
|
|
47
|
+
const host = flags['host'];
|
|
48
|
+
if (host) {
|
|
49
|
+
webdavConfig['host'] = host;
|
|
50
|
+
}
|
|
42
51
|
const port = flags['port'];
|
|
43
52
|
if (port) {
|
|
44
53
|
if (validation_service_1.ValidationService.instance.validateTCPIntegerPort(port)) {
|
package/dist/commands/webdav.js
CHANGED
|
@@ -75,10 +75,10 @@ class Webdav extends core_1.Command {
|
|
|
75
75
|
const { status } = await pm2_utils_1.PM2Utils.webdavServerStatus();
|
|
76
76
|
const webdavConfigs = await config_service_1.ConfigService.instance.readWebdavConfig();
|
|
77
77
|
if (status === 'online') {
|
|
78
|
-
const message =
|
|
78
|
+
const message = 'Internxt WebDav server started successfully at ' +
|
|
79
|
+
`${webdavConfigs.protocol}://${webdavConfigs.host}:${webdavConfigs.port}`;
|
|
79
80
|
cli_utils_1.CLIUtils.log(this.log.bind(this), `\nWebDav server status: ${core_1.ux.colorize('green', 'online')}\n`);
|
|
80
81
|
cli_utils_1.CLIUtils.success(this.log.bind(this), message);
|
|
81
|
-
cli_utils_1.CLIUtils.log(this.log.bind(this), `\n[If the above URL is not working, the WebDAV server can be accessed directly via your localhost IP at: ${webdavConfigs.protocol}://127.0.0.1:${webdavConfigs.port} ]\n`);
|
|
82
82
|
return message;
|
|
83
83
|
}
|
|
84
84
|
else {
|
package/dist/commands/whoami.js
CHANGED
|
@@ -4,6 +4,7 @@ const core_1 = require("@oclif/core");
|
|
|
4
4
|
const cli_utils_1 = require("../utils/cli.utils");
|
|
5
5
|
const config_service_1 = require("../services/config.service");
|
|
6
6
|
const validation_service_1 = require("../services/validation.service");
|
|
7
|
+
const auth_service_1 = require("../services/auth.service");
|
|
7
8
|
class Whoami extends core_1.Command {
|
|
8
9
|
static args = {};
|
|
9
10
|
static description = 'Display the current user logged into the Internxt CLI.';
|
|
@@ -20,13 +21,20 @@ class Whoami extends core_1.Command {
|
|
|
20
21
|
}
|
|
21
22
|
else {
|
|
22
23
|
const validCreds = this.checkUserAndTokens(userCredentials);
|
|
23
|
-
if (!validCreds) {
|
|
24
|
+
if (!validCreds.valid) {
|
|
24
25
|
const message = 'Your session has expired. You have been logged out. Please log in again.';
|
|
25
26
|
await config_service_1.ConfigService.instance.clearUser();
|
|
26
27
|
cli_utils_1.CLIUtils.error(this.log.bind(this), message);
|
|
27
28
|
return { success: false, message };
|
|
28
29
|
}
|
|
29
30
|
else {
|
|
31
|
+
if (validCreds.refreshRequired) {
|
|
32
|
+
try {
|
|
33
|
+
await auth_service_1.AuthService.instance.refreshUserToken(userCredentials);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
}
|
|
37
|
+
}
|
|
30
38
|
const message = `You are logged in as: ${userCredentials.user.email}.`;
|
|
31
39
|
cli_utils_1.CLIUtils.success(this.log.bind(this), message);
|
|
32
40
|
return { success: true, message, login: userCredentials };
|
|
@@ -45,15 +53,13 @@ class Whoami extends core_1.Command {
|
|
|
45
53
|
this.exit(1);
|
|
46
54
|
};
|
|
47
55
|
checkUserAndTokens = (loginCreds) => {
|
|
48
|
-
if (!(loginCreds?.
|
|
49
|
-
return false;
|
|
56
|
+
if (!(loginCreds?.token && loginCreds?.user?.mnemonic)) {
|
|
57
|
+
return { valid: false, refreshRequired: false };
|
|
50
58
|
}
|
|
51
|
-
const
|
|
52
|
-
const newTokenDetails = validation_service_1.ValidationService.instance.validateTokenAndCheckExpiration(loginCreds.newToken);
|
|
59
|
+
const tokenDetails = validation_service_1.ValidationService.instance.validateTokenAndCheckExpiration(loginCreds.token);
|
|
53
60
|
const goodMnemonic = validation_service_1.ValidationService.instance.validateMnemonic(loginCreds.user.mnemonic);
|
|
54
|
-
const goodToken =
|
|
55
|
-
|
|
56
|
-
return goodToken && goodNewToken && goodMnemonic;
|
|
61
|
+
const goodToken = tokenDetails.isValid && !tokenDetails.expiration.expired;
|
|
62
|
+
return { valid: goodToken && goodMnemonic, refreshRequired: tokenDetails.expiration.refreshRequired };
|
|
57
63
|
};
|
|
58
64
|
}
|
|
59
65
|
exports.default = Whoami;
|
|
@@ -19,11 +19,8 @@ const hook = async function (opts) {
|
|
|
19
19
|
if (!CommandsToSkip.map((command) => command.name).includes(Command.name)) {
|
|
20
20
|
cli_utils_1.CLIUtils.doing('Checking credentials', jsonFlag);
|
|
21
21
|
try {
|
|
22
|
-
const { token
|
|
23
|
-
sdk_manager_service_1.SdkManager.init({
|
|
24
|
-
token,
|
|
25
|
-
newToken,
|
|
26
|
-
});
|
|
22
|
+
const { token } = await auth_service_1.AuthService.instance.getAuthDetails();
|
|
23
|
+
sdk_manager_service_1.SdkManager.init({ token });
|
|
27
24
|
cli_utils_1.CLIUtils.done(jsonFlag);
|
|
28
25
|
cli_utils_1.CLIUtils.clearPreviousLine(jsonFlag);
|
|
29
26
|
}
|
|
@@ -4,6 +4,7 @@ export declare class AuthService {
|
|
|
4
4
|
doLogin: (email: string, password: string, twoFactorCode?: string) => Promise<LoginCredentials>;
|
|
5
5
|
is2FANeeded: (email: string) => Promise<boolean>;
|
|
6
6
|
getAuthDetails: () => Promise<LoginCredentials>;
|
|
7
|
-
|
|
7
|
+
refreshUserDetails: (oldCreds: LoginCredentials) => Promise<LoginCredentials>;
|
|
8
|
+
refreshUserToken: (oldCreds: LoginCredentials) => Promise<LoginCredentials>;
|
|
8
9
|
logout: () => Promise<void>;
|
|
9
10
|
}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AuthService = void 0;
|
|
4
4
|
const sdk_manager_service_1 = require("./sdk-manager.service");
|
|
5
|
-
const keys_service_1 = require("./keys.service");
|
|
6
5
|
const crypto_service_1 = require("./crypto.service");
|
|
7
6
|
const config_service_1 = require("./config.service");
|
|
8
7
|
const command_types_1 = require("../types/command.types");
|
|
@@ -16,26 +15,16 @@ class AuthService {
|
|
|
16
15
|
password: password,
|
|
17
16
|
tfaCode: twoFactorCode,
|
|
18
17
|
};
|
|
19
|
-
const data = await authClient.
|
|
20
|
-
const { user,
|
|
21
|
-
const { privateKey, publicKey } = user;
|
|
22
|
-
const plainPrivateKeyInBase64 = privateKey
|
|
23
|
-
? Buffer.from(keys_service_1.KeysService.instance.decryptPrivateKey(privateKey, password)).toString('base64')
|
|
24
|
-
: '';
|
|
25
|
-
if (privateKey) {
|
|
26
|
-
await keys_service_1.KeysService.instance.assertPrivateKeyIsValid(privateKey, password);
|
|
27
|
-
await keys_service_1.KeysService.instance.assertValidateKeys(Buffer.from(plainPrivateKeyInBase64, 'base64').toString(), Buffer.from(publicKey, 'base64').toString());
|
|
28
|
-
}
|
|
18
|
+
const data = await authClient.loginAccess(loginDetails, crypto_service_1.CryptoService.cryptoProvider);
|
|
19
|
+
const { user, newToken } = data;
|
|
29
20
|
const clearMnemonic = crypto_service_1.CryptoService.instance.decryptTextWithKey(user.mnemonic, password);
|
|
30
21
|
const clearUser = {
|
|
31
22
|
...user,
|
|
32
23
|
mnemonic: clearMnemonic,
|
|
33
|
-
privateKey: plainPrivateKeyInBase64,
|
|
34
24
|
};
|
|
35
25
|
return {
|
|
36
26
|
user: clearUser,
|
|
37
|
-
token:
|
|
38
|
-
newToken: newToken,
|
|
27
|
+
token: newToken,
|
|
39
28
|
lastLoggedInAt: new Date().toISOString(),
|
|
40
29
|
lastTokenRefreshAt: new Date().toISOString(),
|
|
41
30
|
};
|
|
@@ -49,57 +38,63 @@ class AuthService {
|
|
|
49
38
|
};
|
|
50
39
|
getAuthDetails = async () => {
|
|
51
40
|
let loginCreds = await config_service_1.ConfigService.instance.readUser();
|
|
52
|
-
if (!loginCreds?.
|
|
41
|
+
if (!loginCreds?.token || !loginCreds?.user?.mnemonic) {
|
|
53
42
|
throw new command_types_1.MissingCredentialsError();
|
|
54
43
|
}
|
|
55
|
-
const
|
|
56
|
-
const newTokenDetails = validation_service_1.ValidationService.instance.validateTokenAndCheckExpiration(loginCreds.newToken);
|
|
44
|
+
const tokenDetails = validation_service_1.ValidationService.instance.validateTokenAndCheckExpiration(loginCreds.token);
|
|
57
45
|
const isValidMnemonic = validation_service_1.ValidationService.instance.validateMnemonic(loginCreds.user.mnemonic);
|
|
58
|
-
if (!
|
|
46
|
+
if (!tokenDetails.isValid || !isValidMnemonic) {
|
|
59
47
|
throw new command_types_1.InvalidCredentialsError();
|
|
60
48
|
}
|
|
61
|
-
if (
|
|
49
|
+
if (tokenDetails.expiration.expired) {
|
|
62
50
|
throw new command_types_1.ExpiredCredentialsError();
|
|
63
51
|
}
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
loginCreds = await this.refreshUserTokens(loginCreds);
|
|
52
|
+
const refreshToken = tokenDetails.expiration.refreshRequired;
|
|
53
|
+
if (refreshToken) {
|
|
54
|
+
loginCreds = await this.refreshUserToken(loginCreds);
|
|
68
55
|
}
|
|
69
56
|
return loginCreds;
|
|
70
57
|
};
|
|
71
|
-
|
|
72
|
-
sdk_manager_service_1.SdkManager.init({
|
|
73
|
-
token: oldCreds.token,
|
|
74
|
-
newToken: oldCreds.newToken,
|
|
75
|
-
});
|
|
58
|
+
refreshUserDetails = async (oldCreds) => {
|
|
59
|
+
sdk_manager_service_1.SdkManager.init({ token: oldCreds.token });
|
|
76
60
|
const usersClient = sdk_manager_service_1.SdkManager.instance.getUsers();
|
|
77
61
|
const newCreds = await usersClient.getUserData({ userUuid: oldCreds.user.uuid });
|
|
78
62
|
const loginCreds = {
|
|
79
63
|
user: {
|
|
80
64
|
...newCreds.user,
|
|
81
65
|
mnemonic: oldCreds.user.mnemonic,
|
|
82
|
-
|
|
66
|
+
createdAt: new Date(newCreds.user.createdAt).toISOString(),
|
|
83
67
|
},
|
|
84
|
-
token: newCreds.
|
|
85
|
-
newToken: newCreds.newToken,
|
|
68
|
+
token: newCreds.newToken,
|
|
86
69
|
lastLoggedInAt: oldCreds.lastLoggedInAt,
|
|
87
70
|
lastTokenRefreshAt: new Date().toISOString(),
|
|
88
71
|
};
|
|
89
|
-
sdk_manager_service_1.SdkManager.init({
|
|
90
|
-
|
|
91
|
-
newToken: newCreds.newToken,
|
|
92
|
-
});
|
|
72
|
+
sdk_manager_service_1.SdkManager.init({ token: newCreds.newToken });
|
|
73
|
+
await config_service_1.ConfigService.instance.saveUser(loginCreds);
|
|
93
74
|
return loginCreds;
|
|
94
75
|
};
|
|
76
|
+
refreshUserToken = async (oldCreds) => {
|
|
77
|
+
sdk_manager_service_1.SdkManager.init({ token: oldCreds.token });
|
|
78
|
+
const usersClient = sdk_manager_service_1.SdkManager.instance.getUsers();
|
|
79
|
+
const newCreds = await usersClient.refreshUser();
|
|
80
|
+
sdk_manager_service_1.SdkManager.init({ token: newCreds.newToken });
|
|
81
|
+
const newLoginCreds = {
|
|
82
|
+
...oldCreds,
|
|
83
|
+
token: newCreds.newToken,
|
|
84
|
+
lastLoggedInAt: oldCreds.lastLoggedInAt,
|
|
85
|
+
lastTokenRefreshAt: new Date().toISOString(),
|
|
86
|
+
};
|
|
87
|
+
await config_service_1.ConfigService.instance.saveUser(newLoginCreds);
|
|
88
|
+
return newLoginCreds;
|
|
89
|
+
};
|
|
95
90
|
logout = async () => {
|
|
96
91
|
try {
|
|
97
92
|
const user = await config_service_1.ConfigService.instance.readUser();
|
|
98
|
-
if (!user || !user.
|
|
93
|
+
if (!user || !user.token) {
|
|
99
94
|
return;
|
|
100
95
|
}
|
|
101
96
|
const authClient = sdk_manager_service_1.SdkManager.instance.getAuth();
|
|
102
|
-
return authClient.logout(user.
|
|
97
|
+
return authClient.logout(user.token);
|
|
103
98
|
}
|
|
104
99
|
catch {
|
|
105
100
|
}
|
|
@@ -8,7 +8,7 @@ export declare class ConfigService {
|
|
|
8
8
|
static readonly DRIVE_SQLITE_FILE: string;
|
|
9
9
|
static readonly WEBDAV_SSL_CERTS_DIR: string;
|
|
10
10
|
static readonly WEBDAV_CONFIGS_FILE: string;
|
|
11
|
-
static readonly
|
|
11
|
+
static readonly WEBDAV_DEFAULT_HOST = "127.0.0.1";
|
|
12
12
|
static readonly WEBDAV_DEFAULT_PORT = "3005";
|
|
13
13
|
static readonly WEBDAV_DEFAULT_PROTOCOL = "https";
|
|
14
14
|
static readonly WEBDAV_DEFAULT_TIMEOUT = 0;
|
|
@@ -16,7 +16,7 @@ class ConfigService {
|
|
|
16
16
|
static DRIVE_SQLITE_FILE = node_path_1.default.join(this.INTERNXT_CLI_DATA_DIR, 'internxt-cli-drive.sqlite');
|
|
17
17
|
static WEBDAV_SSL_CERTS_DIR = node_path_1.default.join(this.INTERNXT_CLI_DATA_DIR, 'certs');
|
|
18
18
|
static WEBDAV_CONFIGS_FILE = node_path_1.default.join(this.INTERNXT_CLI_DATA_DIR, 'config.webdav.inxt');
|
|
19
|
-
static
|
|
19
|
+
static WEBDAV_DEFAULT_HOST = '127.0.0.1';
|
|
20
20
|
static WEBDAV_DEFAULT_PORT = '3005';
|
|
21
21
|
static WEBDAV_DEFAULT_PROTOCOL = 'https';
|
|
22
22
|
static WEBDAV_DEFAULT_TIMEOUT = 0;
|
|
@@ -43,12 +43,7 @@ class ConfigService {
|
|
|
43
43
|
try {
|
|
44
44
|
const encryptedCredentials = await promises_1.default.readFile(ConfigService.CREDENTIALS_FILE, 'utf8');
|
|
45
45
|
const credentialsString = crypto_service_1.CryptoService.instance.decryptText(encryptedCredentials);
|
|
46
|
-
const loginCredentials = JSON.parse(credentialsString
|
|
47
|
-
if (typeof value === 'string' && key === 'createdAt') {
|
|
48
|
-
return new Date(value);
|
|
49
|
-
}
|
|
50
|
-
return value;
|
|
51
|
-
});
|
|
46
|
+
const loginCredentials = JSON.parse(credentialsString);
|
|
52
47
|
return loginCredentials;
|
|
53
48
|
}
|
|
54
49
|
catch {
|
|
@@ -65,6 +60,7 @@ class ConfigService {
|
|
|
65
60
|
const configsData = await promises_1.default.readFile(ConfigService.WEBDAV_CONFIGS_FILE, 'utf8');
|
|
66
61
|
const configs = JSON.parse(configsData);
|
|
67
62
|
return {
|
|
63
|
+
host: configs?.host ?? ConfigService.WEBDAV_DEFAULT_HOST,
|
|
68
64
|
port: configs?.port ?? ConfigService.WEBDAV_DEFAULT_PORT,
|
|
69
65
|
protocol: configs?.protocol ?? ConfigService.WEBDAV_DEFAULT_PROTOCOL,
|
|
70
66
|
timeoutMinutes: configs?.timeoutMinutes ?? ConfigService.WEBDAV_DEFAULT_TIMEOUT,
|
|
@@ -72,6 +68,7 @@ class ConfigService {
|
|
|
72
68
|
}
|
|
73
69
|
catch {
|
|
74
70
|
return {
|
|
71
|
+
host: ConfigService.WEBDAV_DEFAULT_HOST,
|
|
75
72
|
port: ConfigService.WEBDAV_DEFAULT_PORT,
|
|
76
73
|
protocol: ConfigService.WEBDAV_DEFAULT_PROTOCOL,
|
|
77
74
|
timeoutMinutes: ConfigService.WEBDAV_DEFAULT_TIMEOUT,
|
|
@@ -13,8 +13,10 @@ export declare class DriveFile implements DriveFileAttributes {
|
|
|
13
13
|
createdAt: Date;
|
|
14
14
|
updatedAt: Date;
|
|
15
15
|
size: number;
|
|
16
|
-
status:
|
|
17
|
-
|
|
16
|
+
status: 'EXISTS' | 'TRASHED' | 'DELETED';
|
|
17
|
+
creationTime: Date;
|
|
18
|
+
modificationTime: Date;
|
|
19
|
+
constructor({ id, name, type, uuid, fileId, folderId, folderUuid, bucket, relativePath, createdAt, updatedAt, size, status, creationTime, modificationTime, }: DriveFileAttributes);
|
|
18
20
|
static build(file: DriveFileAttributes): DriveFile;
|
|
19
21
|
toJSON(): DriveFileAttributes;
|
|
20
22
|
toItem(): DriveFileItem;
|
|
@@ -15,7 +15,9 @@ class DriveFile {
|
|
|
15
15
|
updatedAt;
|
|
16
16
|
size;
|
|
17
17
|
status;
|
|
18
|
-
|
|
18
|
+
creationTime;
|
|
19
|
+
modificationTime;
|
|
20
|
+
constructor({ id, name, type, uuid, fileId, folderId, folderUuid, bucket, relativePath, createdAt, updatedAt, size, status, creationTime, modificationTime, }) {
|
|
19
21
|
this.id = id;
|
|
20
22
|
this.name = name;
|
|
21
23
|
this.type = type;
|
|
@@ -29,6 +31,8 @@ class DriveFile {
|
|
|
29
31
|
this.updatedAt = updatedAt;
|
|
30
32
|
this.size = size;
|
|
31
33
|
this.status = status;
|
|
34
|
+
this.creationTime = creationTime;
|
|
35
|
+
this.modificationTime = modificationTime;
|
|
32
36
|
}
|
|
33
37
|
static build(file) {
|
|
34
38
|
return new DriveFile(file);
|
|
@@ -48,6 +52,8 @@ class DriveFile {
|
|
|
48
52
|
updatedAt: this.updatedAt,
|
|
49
53
|
size: this.size,
|
|
50
54
|
status: this.status,
|
|
55
|
+
creationTime: this.creationTime,
|
|
56
|
+
modificationTime: this.modificationTime,
|
|
51
57
|
};
|
|
52
58
|
}
|
|
53
59
|
toItem() {
|
|
@@ -64,7 +70,8 @@ class DriveFile {
|
|
|
64
70
|
updatedAt: this.updatedAt,
|
|
65
71
|
size: this.size,
|
|
66
72
|
status: this.status,
|
|
67
|
-
|
|
73
|
+
creationTime: this.creationTime,
|
|
74
|
+
modificationTime: this.modificationTime,
|
|
68
75
|
};
|
|
69
76
|
}
|
|
70
77
|
}
|
|
@@ -4,7 +4,7 @@ export declare class DriveFileService {
|
|
|
4
4
|
static readonly instance: DriveFileService;
|
|
5
5
|
createFile: (payload: StorageTypes.FileEntryByUuid) => Promise<DriveFileItem>;
|
|
6
6
|
getFileMetadata: (uuid: string) => Promise<DriveFileItem>;
|
|
7
|
-
moveFile: (payload: StorageTypes.MoveFileUuidPayload) => Promise<StorageTypes.FileMeta>;
|
|
7
|
+
moveFile: (uuid: string, payload: StorageTypes.MoveFileUuidPayload) => Promise<StorageTypes.FileMeta>;
|
|
8
8
|
renameFile: (fileUuid: string, payload: {
|
|
9
9
|
plainName?: string;
|
|
10
10
|
type?: string | null;
|
|
@@ -9,8 +9,7 @@ class DriveFileService {
|
|
|
9
9
|
const storageClient = sdk_manager_service_1.SdkManager.instance.getStorage();
|
|
10
10
|
const driveFile = await storageClient.createFileEntryByUuid(payload);
|
|
11
11
|
return {
|
|
12
|
-
name: payload.
|
|
13
|
-
encryptedName: driveFile.name,
|
|
12
|
+
name: payload.plainName,
|
|
14
13
|
id: driveFile.id,
|
|
15
14
|
uuid: driveFile.uuid,
|
|
16
15
|
size: driveFile.size,
|
|
@@ -22,6 +21,8 @@ class DriveFileService {
|
|
|
22
21
|
status: driveFile.status,
|
|
23
22
|
folderId: driveFile.folderId,
|
|
24
23
|
folderUuid: driveFile.folderUuid,
|
|
24
|
+
creationTime: new Date(driveFile.creationTime ?? driveFile.createdAt),
|
|
25
|
+
modificationTime: new Date(driveFile.modificationTime ?? driveFile.updatedAt),
|
|
25
26
|
};
|
|
26
27
|
};
|
|
27
28
|
getFileMetadata = async (uuid) => {
|
|
@@ -30,9 +31,9 @@ class DriveFileService {
|
|
|
30
31
|
const fileMetadata = await getFileMetadata;
|
|
31
32
|
return drive_utils_1.DriveUtils.driveFileMetaToItem(fileMetadata);
|
|
32
33
|
};
|
|
33
|
-
moveFile = (payload) => {
|
|
34
|
+
moveFile = (uuid, payload) => {
|
|
34
35
|
const storageClient = sdk_manager_service_1.SdkManager.instance.getStorage();
|
|
35
|
-
return storageClient.moveFileByUuid(payload);
|
|
36
|
+
return storageClient.moveFileByUuid(uuid, payload);
|
|
36
37
|
};
|
|
37
38
|
renameFile = (fileUuid, payload) => {
|
|
38
39
|
const storageClient = sdk_manager_service_1.SdkManager.instance.getStorage();
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { FetchPaginatedFile, FetchPaginatedFolder } from '@internxt/sdk/dist/drive/storage/types';
|
|
2
1
|
import { StorageTypes } from '@internxt/sdk/dist/drive';
|
|
3
2
|
import { DriveFolderItem } from '../../types/drive.types';
|
|
4
3
|
import { RequestCanceler } from '@internxt/sdk/dist/shared/http/types';
|
|
@@ -7,12 +6,50 @@ export declare class DriveFolderService {
|
|
|
7
6
|
getFolderMetaByUuid: (uuid: string) => Promise<DriveFolderItem>;
|
|
8
7
|
getFolderMetaById: (id: number) => Promise<DriveFolderItem>;
|
|
9
8
|
getFolderContent: (folderUuid: string) => Promise<{
|
|
10
|
-
folders:
|
|
11
|
-
|
|
9
|
+
folders: {
|
|
10
|
+
type: string;
|
|
11
|
+
id: number;
|
|
12
|
+
parentId: number;
|
|
13
|
+
parentUuid: string;
|
|
14
|
+
name: string;
|
|
15
|
+
parent: import("@internxt/sdk/dist/schema").components["schemas"]["Folder"];
|
|
16
|
+
bucket: string;
|
|
17
|
+
userId: number;
|
|
18
|
+
encryptVersion: string;
|
|
19
|
+
createdAt: string;
|
|
20
|
+
updatedAt: string;
|
|
21
|
+
uuid: string;
|
|
22
|
+
plainName: string;
|
|
23
|
+
size: number;
|
|
24
|
+
creationTime: string;
|
|
25
|
+
modificationTime: string;
|
|
26
|
+
status: "EXISTS" | "TRASHED" | "DELETED";
|
|
27
|
+
removed: boolean;
|
|
28
|
+
deleted: boolean;
|
|
29
|
+
}[];
|
|
30
|
+
files: {
|
|
31
|
+
id: number;
|
|
32
|
+
uuid: string;
|
|
33
|
+
fileId: string;
|
|
34
|
+
name: string;
|
|
35
|
+
type: string;
|
|
36
|
+
size: string;
|
|
37
|
+
bucket: string;
|
|
38
|
+
folderId: number;
|
|
39
|
+
folderUuid: string;
|
|
40
|
+
encryptVersion: string;
|
|
41
|
+
userId: number;
|
|
42
|
+
creationTime: string;
|
|
43
|
+
modificationTime: string;
|
|
44
|
+
createdAt: string;
|
|
45
|
+
updatedAt: string;
|
|
46
|
+
plainName: string;
|
|
47
|
+
status: "EXISTS" | "TRASHED" | "DELETED";
|
|
48
|
+
}[];
|
|
12
49
|
}>;
|
|
13
50
|
private readonly getAllSubfolders;
|
|
14
51
|
private readonly getAllSubfiles;
|
|
15
|
-
moveFolder: (payload: StorageTypes.MoveFolderUuidPayload) => Promise<StorageTypes.FolderMeta>;
|
|
52
|
+
moveFolder: (uuid: string, payload: StorageTypes.MoveFolderUuidPayload) => Promise<StorageTypes.FolderMeta>;
|
|
16
53
|
createFolder(payload: StorageTypes.CreateFolderByUuidPayload): [Promise<StorageTypes.CreateFolderResponse>, RequestCanceler];
|
|
17
54
|
renameFolder: (payload: {
|
|
18
55
|
folderUuid: string;
|