@lemoncat7/dsh-ssh 1.2.0 → 1.3.0
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/ARCHITECTURE.md +18 -3
- package/README.md +16 -3
- package/lib/api.d.ts +8 -0
- package/lib/api.d.ts.map +1 -1
- package/lib/api.js +218 -13
- package/lib/api.js.map +1 -1
- package/lib/client-api.d.ts +66 -0
- package/lib/client-api.d.ts.map +1 -1
- package/lib/client-api.js +14 -0
- package/lib/client-api.js.map +1 -1
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +467 -97
- package/lib/client.js.map +4 -4
- package/lib/connector.js +2 -2
- package/lib/connector.js.map +1 -1
- package/lib/credentials.d.ts +9 -0
- package/lib/credentials.d.ts.map +1 -1
- package/lib/credentials.js +16 -0
- package/lib/credentials.js.map +1 -1
- package/lib/domain.d.ts +42 -1
- package/lib/domain.d.ts.map +1 -1
- package/lib/domain.js +32 -0
- package/lib/domain.js.map +1 -1
- package/lib/endpoint-session-manager.d.ts +16 -0
- package/lib/endpoint-session-manager.d.ts.map +1 -0
- package/lib/endpoint-session-manager.js +70 -0
- package/lib/endpoint-session-manager.js.map +1 -0
- package/lib/file-transfer-manager.d.ts +50 -0
- package/lib/file-transfer-manager.d.ts.map +1 -0
- package/lib/file-transfer-manager.js +257 -0
- package/lib/file-transfer-manager.js.map +1 -0
- package/lib/file-transfer-tools.d.ts +6 -0
- package/lib/file-transfer-tools.d.ts.map +1 -0
- package/lib/file-transfer-tools.js +143 -0
- package/lib/file-transfer-tools.js.map +1 -0
- package/lib/file-transfer-workspace.d.ts +10 -0
- package/lib/file-transfer-workspace.d.ts.map +1 -0
- package/lib/file-transfer-workspace.js +299 -0
- package/lib/file-transfer-workspace.js.map +1 -0
- package/lib/ftp-adapter.d.ts +18 -0
- package/lib/ftp-adapter.d.ts.map +1 -0
- package/lib/ftp-adapter.js +240 -0
- package/lib/ftp-adapter.js.map +1 -0
- package/lib/ftp-profile-editor.d.ts +9 -0
- package/lib/ftp-profile-editor.d.ts.map +1 -0
- package/lib/ftp-profile-editor.js +89 -0
- package/lib/ftp-profile-editor.js.map +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +17 -2
- package/lib/index.js.map +1 -1
- package/lib/network-dialer.d.ts +12 -0
- package/lib/network-dialer.d.ts.map +1 -0
- package/lib/network-dialer.js +27 -0
- package/lib/network-dialer.js.map +1 -0
- package/lib/proxy.d.ts +3 -3
- package/lib/proxy.d.ts.map +1 -1
- package/lib/proxy.js +11 -7
- package/lib/proxy.js.map +1 -1
- package/lib/remote-file-systems.d.ts +9 -0
- package/lib/remote-file-systems.d.ts.map +1 -0
- package/lib/remote-file-systems.js +23 -0
- package/lib/remote-file-systems.js.map +1 -0
- package/lib/remote-files.d.ts +51 -0
- package/lib/remote-files.d.ts.map +1 -0
- package/lib/remote-files.js +36 -0
- package/lib/remote-files.js.map +1 -0
- package/lib/remote-workspace-tree.d.ts.map +1 -1
- package/lib/remote-workspace-tree.js +5 -15
- package/lib/remote-workspace-tree.js.map +1 -1
- package/lib/session-access.d.ts +3 -0
- package/lib/session-access.d.ts.map +1 -1
- package/lib/session-access.js +4 -1
- package/lib/session-access.js.map +1 -1
- package/lib/sftp-adapter.d.ts +13 -0
- package/lib/sftp-adapter.d.ts.map +1 -0
- package/lib/sftp-adapter.js +28 -0
- package/lib/sftp-adapter.js.map +1 -0
- package/lib/sftp.d.ts +7 -0
- package/lib/sftp.d.ts.map +1 -1
- package/lib/sftp.js +215 -6
- package/lib/sftp.js.map +1 -1
- package/lib/store.d.ts +3 -1
- package/lib/store.d.ts.map +1 -1
- package/lib/store.js +51 -3
- package/lib/store.js.map +1 -1
- package/lib/tools.d.ts +3 -1
- package/lib/tools.d.ts.map +1 -1
- package/lib/tools.js +4 -1
- package/lib/tools.js.map +1 -1
- package/package.json +7 -2
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import net from 'node:net';
|
|
2
|
+
import tls from 'node:tls';
|
|
3
|
+
import { Client, FTPError } from 'basic-ftp';
|
|
4
|
+
import { endpointId, remoteJoin, remoteName, remoteParent, sortRemoteEntries } from './remote-files.js';
|
|
5
|
+
export class FtpFileSystemAdapter {
|
|
6
|
+
store;
|
|
7
|
+
credentials;
|
|
8
|
+
dialer;
|
|
9
|
+
kind = 'ftp';
|
|
10
|
+
constructor(store, credentials, dialer) {
|
|
11
|
+
this.store = store;
|
|
12
|
+
this.credentials = credentials;
|
|
13
|
+
this.dialer = dialer;
|
|
14
|
+
}
|
|
15
|
+
endpoint(id) {
|
|
16
|
+
const profile = this.store.ftpProfile(id);
|
|
17
|
+
return profile === undefined ? undefined : ftpEndpoint(this.resolveProfile(profile));
|
|
18
|
+
}
|
|
19
|
+
endpoints() { return this.store.ftpProfiles().map(profile => ftpEndpoint(this.resolveProfile(profile))); }
|
|
20
|
+
async connect(id, signal) {
|
|
21
|
+
const profile = this.store.ftpProfile(id);
|
|
22
|
+
if (profile === undefined)
|
|
23
|
+
throw Object.assign(new Error(`FTP endpoint ${id} was not found`), { status: 404 });
|
|
24
|
+
const entry = profile.credentialId === undefined ? undefined : this.store.credentialEntry(profile.credentialId);
|
|
25
|
+
if (profile.credentialId !== undefined && (entry === undefined || entry.authType !== 'password'))
|
|
26
|
+
throw new Error('FTP password credential entry was not found');
|
|
27
|
+
const secrets = entry === undefined ? await this.credentials.readFtp(profile.id) : await this.credentials.readEntry(entry.id);
|
|
28
|
+
if (!secrets.password)
|
|
29
|
+
throw Object.assign(new Error('FTP password is not configured'), { code: 'CREDENTIAL_MISSING' });
|
|
30
|
+
const resolved = entry === undefined ? profile : { ...profile, username: entry.username };
|
|
31
|
+
return FtpFileSystemSession.open(ftpEndpoint(resolved), resolved, secrets.password, this.dialer, signal);
|
|
32
|
+
}
|
|
33
|
+
resolveProfile(profile) {
|
|
34
|
+
if (profile.credentialId === undefined)
|
|
35
|
+
return profile;
|
|
36
|
+
const entry = this.store.credentialEntry(profile.credentialId);
|
|
37
|
+
return entry?.authType === 'password' ? { ...profile, username: entry.username } : profile;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export async function connectFtpProfile(profile, password, dialer, signal) {
|
|
41
|
+
return FtpFileSystemSession.open(ftpEndpoint(profile), profile, password, dialer, signal);
|
|
42
|
+
}
|
|
43
|
+
class FtpFileSystemSession {
|
|
44
|
+
endpoint;
|
|
45
|
+
profile;
|
|
46
|
+
client;
|
|
47
|
+
closed = false;
|
|
48
|
+
constructor(endpoint, profile, client) {
|
|
49
|
+
this.endpoint = endpoint;
|
|
50
|
+
this.profile = profile;
|
|
51
|
+
this.client = client;
|
|
52
|
+
}
|
|
53
|
+
static async open(endpoint, profile, password, dialer, signal) {
|
|
54
|
+
signal?.throwIfAborted();
|
|
55
|
+
const client = new Client(profile.connectTimeoutMs, { allowSeparateTransferHost: false });
|
|
56
|
+
client.prepareTransfer = createPassiveTransfer(profile, dialer, signal);
|
|
57
|
+
const tlsOptions = {
|
|
58
|
+
host: profile.host,
|
|
59
|
+
rejectUnauthorized: true,
|
|
60
|
+
...(net.isIP(profile.tlsServerName ?? profile.host) === 0 ? { servername: profile.tlsServerName ?? profile.host } : {}),
|
|
61
|
+
};
|
|
62
|
+
try {
|
|
63
|
+
const raw = await dialer.connect(profile.host, profile.port, profile.proxy, profile.connectTimeoutMs, signal);
|
|
64
|
+
if (profile.protocol === 'ftps-implicit') {
|
|
65
|
+
const secure = tls.connect({ ...tlsOptions, socket: raw });
|
|
66
|
+
const welcome = handleWelcome(client);
|
|
67
|
+
client.ftp.socket = secure;
|
|
68
|
+
await Promise.all([waitForSecureConnect(secure, signal), welcome]);
|
|
69
|
+
client.ftp.tlsOptions = tlsOptions;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
const welcome = handleWelcome(client);
|
|
73
|
+
client.ftp.socket = raw;
|
|
74
|
+
await welcome;
|
|
75
|
+
if (profile.protocol === 'ftps-explicit')
|
|
76
|
+
await client.useTLS(tlsOptions);
|
|
77
|
+
}
|
|
78
|
+
await client.login(profile.username, password);
|
|
79
|
+
await client.useDefaultSettings();
|
|
80
|
+
if (profile.initialPath !== '/')
|
|
81
|
+
await client.cd(profile.initialPath);
|
|
82
|
+
return new FtpFileSystemSession(endpoint, profile, client);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
client.close();
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async list(value, signal) {
|
|
90
|
+
const requested = value.trim() || this.profile.initialPath;
|
|
91
|
+
const resolved = await this.resolveDirectory(requested, signal);
|
|
92
|
+
const entries = (await this.run(this.client.list(resolved), signal)).map(entry => ftpEntry(resolved, entry));
|
|
93
|
+
return { path: resolved, parent: remoteParent(resolved), entries: sortRemoteEntries(entries) };
|
|
94
|
+
}
|
|
95
|
+
async stat(value, signal) {
|
|
96
|
+
const normalized = value.replaceAll('\\', '/').replace(/\/+$/, '') || '/';
|
|
97
|
+
if (normalized === '/')
|
|
98
|
+
return { name: '/', path: '/', kind: 'directory', size: 0, modifiedAt: 0 };
|
|
99
|
+
const parent = remoteParent(normalized) ?? '/';
|
|
100
|
+
const match = (await this.list(parent, signal)).entries.find(entry => entry.name === remoteName(normalized));
|
|
101
|
+
if (match === undefined)
|
|
102
|
+
throw Object.assign(new Error(`remote path ${value} was not found`), { status: 404 });
|
|
103
|
+
return match;
|
|
104
|
+
}
|
|
105
|
+
async download(value, destination, signal) {
|
|
106
|
+
await this.run(this.client.downloadTo(destination, value), signal);
|
|
107
|
+
}
|
|
108
|
+
async upload(value, source, overwrite, signal) {
|
|
109
|
+
if (!overwrite) {
|
|
110
|
+
try {
|
|
111
|
+
await this.stat(value, signal);
|
|
112
|
+
throw Object.assign(new Error('A file with this name already exists'), { status: 409 });
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
if (error.status !== 404)
|
|
116
|
+
throw error;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
await this.run(this.client.uploadFrom(source, value), signal);
|
|
120
|
+
}
|
|
121
|
+
async ensureDirectory(value, signal) { await this.run(this.client.ensureDir(value), signal); }
|
|
122
|
+
async remove(value, recursive, signal) {
|
|
123
|
+
const entry = await this.stat(value, signal);
|
|
124
|
+
if (entry.kind === 'directory') {
|
|
125
|
+
if (!recursive)
|
|
126
|
+
throw Object.assign(new Error('remote path is a directory'), { status: 409 });
|
|
127
|
+
await this.run(this.client.removeDir(value), signal);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
await this.run(this.client.remove(value), signal);
|
|
131
|
+
}
|
|
132
|
+
close() { if (!this.closed) {
|
|
133
|
+
this.closed = true;
|
|
134
|
+
this.client.close();
|
|
135
|
+
} }
|
|
136
|
+
async resolveDirectory(value, signal) {
|
|
137
|
+
const previous = await this.run(this.client.pwd(), signal);
|
|
138
|
+
try {
|
|
139
|
+
await this.run(this.client.cd(value), signal);
|
|
140
|
+
return await this.run(this.client.pwd(), signal);
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
await this.run(this.client.cd(previous), signal).catch(() => { });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async run(operation, signal) {
|
|
147
|
+
if (this.closed)
|
|
148
|
+
throw new Error('FTP session is closed');
|
|
149
|
+
signal?.throwIfAborted();
|
|
150
|
+
if (signal === undefined)
|
|
151
|
+
return operation;
|
|
152
|
+
const abort = () => this.close();
|
|
153
|
+
signal.addEventListener('abort', abort, { once: true });
|
|
154
|
+
try {
|
|
155
|
+
return await operation;
|
|
156
|
+
}
|
|
157
|
+
finally {
|
|
158
|
+
signal.removeEventListener('abort', abort);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
function createPassiveTransfer(profile, dialer, defaultSignal) {
|
|
163
|
+
return async (ftp) => {
|
|
164
|
+
let response;
|
|
165
|
+
let port;
|
|
166
|
+
try {
|
|
167
|
+
response = await ftp.request('EPSV');
|
|
168
|
+
port = parseEpsvPort(response.message);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
response = await ftp.request('PASV');
|
|
172
|
+
port = parsePasvPort(response.message);
|
|
173
|
+
}
|
|
174
|
+
const raw = await dialer.connect(profile.host, port, profile.proxy, profile.connectTimeoutMs, defaultSignal);
|
|
175
|
+
let socket = raw;
|
|
176
|
+
if (ftp.hasTLS) {
|
|
177
|
+
socket = tls.connect({
|
|
178
|
+
...ftp.tlsOptions,
|
|
179
|
+
socket: raw,
|
|
180
|
+
session: ftp.tlsSessionStore ?? ftp.socket.getSession(),
|
|
181
|
+
});
|
|
182
|
+
socket.on('session', session => { ftp.tlsSessionStore = session; });
|
|
183
|
+
}
|
|
184
|
+
ftp.dataSocket = socket;
|
|
185
|
+
return response;
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function handleWelcome(client) {
|
|
189
|
+
return client.ftp.handle(undefined, (response, task) => {
|
|
190
|
+
if (response instanceof Error)
|
|
191
|
+
task.reject(response);
|
|
192
|
+
else if (response.code >= 200 && response.code < 300)
|
|
193
|
+
task.resolve(response);
|
|
194
|
+
else
|
|
195
|
+
task.reject(new FTPError(response));
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
function waitForSecureConnect(socket, signal) {
|
|
199
|
+
signal?.throwIfAborted();
|
|
200
|
+
return new Promise((resolve, reject) => {
|
|
201
|
+
const abort = () => { cleanup(); socket.destroy(); reject(signal?.reason instanceof Error ? signal.reason : new Error('FTPS connection was aborted')); };
|
|
202
|
+
const ready = () => { cleanup(); resolve(); };
|
|
203
|
+
const failed = (error) => { cleanup(); reject(error); };
|
|
204
|
+
const cleanup = () => { signal?.removeEventListener('abort', abort); socket.off('secureConnect', ready); socket.off('error', failed); };
|
|
205
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
206
|
+
socket.once('secureConnect', ready);
|
|
207
|
+
socket.once('error', failed);
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
function parseEpsvPort(message) {
|
|
211
|
+
const value = /[|!]{3}(\d+)[|!]/.exec(message)?.[1];
|
|
212
|
+
const port = Number(value);
|
|
213
|
+
if (!Number.isSafeInteger(port) || port < 1 || port > 65_535)
|
|
214
|
+
throw new Error(`invalid EPSV response: ${message}`);
|
|
215
|
+
return port;
|
|
216
|
+
}
|
|
217
|
+
function parsePasvPort(message) {
|
|
218
|
+
const match = /(?:\d+,){3}\d+,(\d+),(\d+)/.exec(message);
|
|
219
|
+
if (match === null)
|
|
220
|
+
throw new Error(`invalid PASV response: ${message}`);
|
|
221
|
+
const port = (Number(match[1]) & 255) * 256 + (Number(match[2]) & 255);
|
|
222
|
+
if (port < 1 || port > 65_535)
|
|
223
|
+
throw new Error(`invalid PASV response: ${message}`);
|
|
224
|
+
return port;
|
|
225
|
+
}
|
|
226
|
+
function ftpEntry(directory, entry) {
|
|
227
|
+
return {
|
|
228
|
+
name: entry.name, path: remoteJoin(directory, entry.name),
|
|
229
|
+
kind: entry.isDirectory ? 'directory' : entry.isFile ? 'file' : entry.isSymbolicLink ? 'symlink' : 'other',
|
|
230
|
+
size: entry.size, modifiedAt: entry.modifiedAt?.getTime() ?? 0,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
function ftpEndpoint(profile) {
|
|
234
|
+
return {
|
|
235
|
+
id: endpointId('ftp', profile.id), kind: 'ftp', protocol: profile.protocol, name: profile.name,
|
|
236
|
+
...(profile.group === undefined ? {} : { group: profile.group }),
|
|
237
|
+
address: `${profile.username}@${profile.host}:${profile.port}`, initialPath: profile.initialPath,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=ftp-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ftp-adapter.js","sourceRoot":"","sources":["../src/ftp-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type FtpProfileView, type ProxyEntryView, type VaultEntryView } from './client-api.js';
|
|
2
|
+
export declare function FtpConnectionsDialog({ profiles, vaultEntries, proxyEntries, onClose, onChanged }: {
|
|
3
|
+
profiles: FtpProfileView[];
|
|
4
|
+
vaultEntries: VaultEntryView[];
|
|
5
|
+
proxyEntries: ProxyEntryView[];
|
|
6
|
+
onClose(): void;
|
|
7
|
+
onChanged(): void;
|
|
8
|
+
}): JSX.Element;
|
|
9
|
+
//# sourceMappingURL=ftp-profile-editor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ftp-profile-editor.d.ts","sourceRoot":"","sources":["../src/ftp-profile-editor.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAO,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAKpG,wBAAgB,oBAAoB,CAAC,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE;IAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;IAAC,YAAY,EAAE,cAAc,EAAE,CAAC;IAAC,YAAY,EAAE,cAAc,EAAE,CAAC;IAAC,OAAO,IAAI,IAAI,CAAC;IAAC,SAAS,IAAI,IAAI,CAAA;CAAE,GAAG,GAAG,CAAC,OAAO,CAoClP"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { IconChevronLeftOutline14, IconDataOutline16, IconPlusOutline16, IconTrashOutline16, IconWarningOutline16, } from '@deepseek-ai/dsh-client-ui-primitives';
|
|
4
|
+
import { api } from './client-api.js';
|
|
5
|
+
import { Dialog, Field, errorMessage } from './ui-components.js';
|
|
6
|
+
export function FtpConnectionsDialog({ profiles, vaultEntries, proxyEntries, onClose, onChanged }) {
|
|
7
|
+
const [editing, setEditing] = useState();
|
|
8
|
+
const [deleting, setDeleting] = useState();
|
|
9
|
+
const [error, setError] = useState();
|
|
10
|
+
const detailOpen = editing !== undefined || deleting !== undefined;
|
|
11
|
+
const select = (profile) => { setDeleting(undefined); setEditing(profile); setError(undefined); };
|
|
12
|
+
const create = () => { setDeleting(undefined); setEditing('new'); setError(undefined); };
|
|
13
|
+
const confirmDelete = (profile) => { setEditing(undefined); setDeleting(profile); setError(undefined); };
|
|
14
|
+
const remove = async (profile) => {
|
|
15
|
+
setError(undefined);
|
|
16
|
+
try {
|
|
17
|
+
await api(`/ftp-profiles/${encodeURIComponent(profile.id)}`, { method: 'DELETE' });
|
|
18
|
+
setDeleting(undefined);
|
|
19
|
+
onChanged();
|
|
20
|
+
}
|
|
21
|
+
catch (reason) {
|
|
22
|
+
setError(errorMessage(reason));
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
return _jsx(Dialog, { className: "dsh-ssh-ftp-manager-dialog", title: "\u6587\u4EF6\u8FDE\u63A5", subtitle: "\u7BA1\u7406 FTP \u4E0E FTPS\uFF1BSFTP \u76F4\u63A5\u590D\u7528\u5DF2\u6709 SSH \u4E3B\u673A", onClose: onClose, children: _jsxs("div", { className: `dsh-ssh-ftp-manager${detailOpen ? ' has-detail' : ''}`, children: [_jsxs("aside", { className: "dsh-ssh-ftp-manager-list", children: [_jsxs("header", { children: [_jsxs("span", { children: [_jsx("strong", { children: "FTP / FTPS" }), _jsxs("small", { children: [profiles.length, " \u4E2A\u8FDE\u63A5"] })] }), _jsxs("button", { type: "button", className: "dsh-ssh-primary-button", onClick: create, children: [_jsx(IconPlusOutline16, { size: 15 }), "\u65B0\u5EFA"] })] }), profiles.length === 0 ? _jsxs("div", { className: "dsh-ssh-ftp-list-empty", children: [_jsx("span", { children: _jsx(IconDataOutline16, { size: 20 }) }), _jsx("strong", { children: "\u8FD8\u6CA1\u6709\u72EC\u7ACB\u6587\u4EF6\u8FDE\u63A5" }), _jsx("p", { children: "SFTP \u4F1A\u663E\u793A\u5728\u6587\u4EF6\u7A97\u683C\u7684\u8FDE\u63A5\u5217\u8868\u4E2D\uFF1B\u8FD9\u91CC\u53EA\u7BA1\u7406 FTP \u4E0E FTPS\u3002" }), _jsx("button", { type: "button", className: "dsh-ssh-secondary-button", onClick: create, children: "\u65B0\u5EFA FTPS \u8FDE\u63A5" })] }) : _jsx("div", { className: "dsh-ssh-ftp-profile-list", role: "list", children: profiles.map(profile => {
|
|
26
|
+
const active = (editing !== 'new' && editing?.id === profile.id) || deleting?.id === profile.id;
|
|
27
|
+
return _jsxs("article", { role: "listitem", className: active ? 'is-active' : '', children: [_jsxs("button", { type: "button", className: "dsh-ssh-ftp-profile-main", onClick: () => select(profile), children: [_jsx("span", { className: `dsh-ssh-protocol-badge is-${profile.protocol}`, children: protocolLabel(profile.protocol) }), _jsxs("span", { children: [_jsx("strong", { title: profile.name, children: profile.name }), _jsxs("small", { title: `${profile.username}@${profile.host}:${profile.port}`, children: [profile.username, "@", profile.host, ":", profile.port] })] }), _jsx("i", { className: profile.credential.configured ? 'is-ready' : 'is-missing', children: profile.credential.configured ? '可用' : '缺少密码' })] }), _jsx("button", { type: "button", className: "dsh-ssh-icon-button is-danger", "aria-label": `删除 ${profile.name}`, onClick: () => confirmDelete(profile), children: _jsx(IconTrashOutline16, { size: 15 }) })] }, profile.id);
|
|
28
|
+
}) })] }), _jsx("main", { className: "dsh-ssh-ftp-manager-detail", children: deleting !== undefined ? _jsx(DeleteConnection, { profile: deleting, error: error, onBack: () => setDeleting(undefined), onDelete: () => remove(deleting) })
|
|
29
|
+
: editing !== undefined ? _jsx(FtpProfileEditor, { value: editing === 'new' ? undefined : editing, vaultEntries: vaultEntries, proxyEntries: proxyEntries, onBack: () => setEditing(undefined), onSaved: () => { setEditing(undefined); onChanged(); } }, editing === 'new' ? 'new' : editing.id)
|
|
30
|
+
: _jsxs("div", { className: "dsh-ssh-ftp-manager-overview", children: [_jsx("span", { children: _jsx(IconDataOutline16, { size: 22 }) }), _jsx("h3", { children: "\u9009\u62E9\u4E00\u4E2A\u8FDE\u63A5\u8FDB\u884C\u7F16\u8F91" }), _jsx("p", { children: "\u6587\u4EF6\u7A97\u683C\u4F1A\u628A\u8FD9\u91CC\u4FDD\u5B58\u7684 FTP\u3001FTPS \u4E0E SSH \u4E3B\u673A\u63D0\u4F9B\u7684 SFTP \u6C47\u603B\u6210\u8FDE\u63A5\u5217\u8868\u3002" }), _jsxs("dl", { children: [_jsxs("div", { children: [_jsx("dt", { children: "FTPS" }), _jsx("dd", { children: "\u52A0\u5BC6\u63A7\u5236\u4E0E\u6587\u4EF6\u6570\u636E\uFF0C\u9ED8\u8BA4\u4E25\u683C\u6821\u9A8C\u8BC1\u4E66" })] }), _jsxs("div", { children: [_jsx("dt", { children: "FTP" }), _jsx("dd", { children: "\u517C\u5BB9\u65E7\u670D\u52A1\u5668\uFF0C\u4F46\u8D26\u53F7\u548C\u6587\u4EF6\u5185\u5BB9\u4E0D\u52A0\u5BC6" })] }), _jsxs("div", { children: [_jsx("dt", { children: "SFTP" }), _jsx("dd", { children: "\u7531 SSH \u4E3B\u673A\u7BA1\u7406\uFF0C\u4E0D\u5728\u8FD9\u91CC\u91CD\u590D\u914D\u7F6E" })] })] })] }) })] }) });
|
|
31
|
+
}
|
|
32
|
+
function DeleteConnection({ profile, error, onBack, onDelete }) {
|
|
33
|
+
const [deleting, setDeleting] = useState(false);
|
|
34
|
+
return _jsxs("div", { className: "dsh-ssh-ftp-delete-panel", children: [_jsxs("button", { type: "button", className: "dsh-ssh-ftp-detail-back", onClick: onBack, children: [_jsx(IconChevronLeftOutline14, { size: 14 }), "\u8FD4\u56DE\u8FDE\u63A5\u5217\u8868"] }), _jsx("span", { className: "dsh-ssh-ftp-delete-mark", children: _jsx(IconWarningOutline16, { size: 20 }) }), _jsxs("h3", { children: ["\u5220\u9664\u201C", profile.name, "\u201D\uFF1F"] }), _jsx("p", { children: "\u5C06\u79FB\u9664\u8BE5 FTP/FTPS \u8FDE\u63A5\u53CA\u5176\u72EC\u7ACB\u4FDD\u5B58\u7684\u5BC6\u7801\uFF0C\u4E0D\u4F1A\u5220\u9664\u8FDC\u7AEF\u670D\u52A1\u5668\u4E0A\u7684\u4EFB\u4F55\u6587\u4EF6\u3002" }), _jsxs("code", { children: [profile.username, "@", profile.host, ":", profile.port] }), error && _jsx("p", { className: "dsh-ssh-inline-error", role: "alert", children: error }), _jsxs("div", { className: "dsh-ssh-dialog-actions", children: [_jsx("button", { type: "button", className: "dsh-ssh-secondary-button", onClick: onBack, disabled: deleting, children: "\u53D6\u6D88" }), _jsx("button", { type: "button", className: "dsh-ssh-danger-button", disabled: deleting, onClick: () => { setDeleting(true); void onDelete().finally(() => setDeleting(false)); }, children: deleting ? '正在删除…' : '删除连接' })] })] });
|
|
35
|
+
}
|
|
36
|
+
function FtpProfileEditor({ value, vaultEntries, proxyEntries, onBack, onSaved }) {
|
|
37
|
+
const passwordEntries = vaultEntries.filter(entry => entry.authType === 'password');
|
|
38
|
+
const [form, setForm] = useState({
|
|
39
|
+
name: value?.name ?? '', group: value?.group ?? '', protocol: value?.protocol ?? 'ftps-explicit',
|
|
40
|
+
host: value?.host ?? '', port: String(value?.port ?? 21), username: value?.username ?? '', credentialId: value?.credentialId ?? '', password: '',
|
|
41
|
+
proxyId: value?.proxy.type === 'saved' ? value.proxy.proxyId : '', initialPath: value?.initialPath ?? '/', connectTimeoutMs: String(value?.connectTimeoutMs ?? 15_000), tlsServerName: value?.tlsServerName ?? '',
|
|
42
|
+
});
|
|
43
|
+
const [saving, setSaving] = useState(false);
|
|
44
|
+
const [testing, setTesting] = useState(false);
|
|
45
|
+
const [testResult, setTestResult] = useState();
|
|
46
|
+
const [error, setError] = useState();
|
|
47
|
+
const payload = () => ({
|
|
48
|
+
profile: {
|
|
49
|
+
name: form.name, ...(form.group.trim() ? { group: form.group.trim() } : {}), protocol: form.protocol, host: form.host, port: Number(form.port), username: form.username,
|
|
50
|
+
...(form.credentialId ? { credentialId: form.credentialId } : {}), proxy: form.proxyId ? { type: 'saved', proxyId: form.proxyId } : { type: 'none' },
|
|
51
|
+
initialPath: form.initialPath, connectTimeoutMs: Number(form.connectTimeoutMs), ...(form.tlsServerName.trim() ? { tlsServerName: form.tlsServerName.trim() } : {}),
|
|
52
|
+
}, secrets: { password: form.password },
|
|
53
|
+
});
|
|
54
|
+
const submit = async (event) => {
|
|
55
|
+
event.preventDefault();
|
|
56
|
+
setSaving(true);
|
|
57
|
+
setError(undefined);
|
|
58
|
+
setTestResult(undefined);
|
|
59
|
+
try {
|
|
60
|
+
await api(value === undefined ? '/ftp-profiles' : `/ftp-profiles/${encodeURIComponent(value.id)}`, { method: value === undefined ? 'POST' : 'PUT', body: JSON.stringify(payload()) });
|
|
61
|
+
onSaved();
|
|
62
|
+
}
|
|
63
|
+
catch (reason) {
|
|
64
|
+
setError(errorMessage(reason));
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
setSaving(false);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const test = async () => {
|
|
71
|
+
setTesting(true);
|
|
72
|
+
setError(undefined);
|
|
73
|
+
setTestResult(undefined);
|
|
74
|
+
try {
|
|
75
|
+
await api('/ftp-profiles/test-draft', { method: 'POST', body: JSON.stringify({ ...payload(), ...(value === undefined ? {} : { profileId: value.id }) }) });
|
|
76
|
+
setTestResult('连接成功,初始目录可读取');
|
|
77
|
+
}
|
|
78
|
+
catch (reason) {
|
|
79
|
+
setError(errorMessage(reason));
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
setTesting(false);
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const protocolChanged = (protocol) => setForm(current => ({ ...current, protocol, port: current.port === '21' || current.port === '990' ? String(protocol === 'ftps-implicit' ? 990 : 21) : current.port }));
|
|
86
|
+
return _jsxs("form", { className: "dsh-ssh-ftp-editor-form", onSubmit: event => { void submit(event); }, children: [_jsxs("header", { className: "dsh-ssh-ftp-editor-heading", children: [_jsxs("button", { type: "button", className: "dsh-ssh-ftp-detail-back", onClick: onBack, children: [_jsx(IconChevronLeftOutline14, { size: 14 }), "\u8FD4\u56DE\u8FDE\u63A5\u5217\u8868"] }), _jsxs("span", { children: [_jsx("strong", { children: value === undefined ? '新建文件连接' : value.name }), _jsx("small", { children: value === undefined ? '填写服务器和认证信息' : '修改后可先测试再保存' })] })] }), _jsxs("div", { className: "dsh-ssh-ftp-editor-scroll", children: [_jsxs("section", { className: "dsh-ssh-ftp-editor-section", children: [_jsxs("div", { className: "dsh-ssh-form-section-heading", children: [_jsx("strong", { children: "\u8FDE\u63A5\u7C7B\u578B" }), _jsx("small", { children: "\u4F18\u5148\u4F7F\u7528 FTPS\uFF1B\u4EC5\u5728\u670D\u52A1\u5668\u4E0D\u652F\u6301 TLS \u65F6\u9009\u62E9 FTP" })] }), _jsx("div", { className: "dsh-ssh-ftp-protocol-options", role: "radiogroup", "aria-label": "\u8FDE\u63A5\u534F\u8BAE", children: [['ftps-explicit', 'FTPS', '显式 TLS · 推荐'], ['ftps-implicit', 'FTPS-I', '隐式 TLS'], ['ftp', 'FTP', '未加密']].map(option => _jsxs("button", { type: "button", role: "radio", "aria-checked": form.protocol === option[0], className: form.protocol === option[0] ? 'is-active' : '', onClick: () => protocolChanged(option[0]), children: [_jsx("span", { className: `dsh-ssh-protocol-badge is-${option[0]}`, children: option[1] }), _jsxs("span", { children: [_jsx("strong", { children: option[1] }), _jsx("small", { children: option[2] })] })] }, option[0])) }), form.protocol === 'ftp' && _jsx("p", { className: "dsh-ssh-form-warning", children: "\u666E\u901A FTP \u7684\u8D26\u53F7\u3001\u5BC6\u7801\u548C\u6587\u4EF6\u5185\u5BB9\u5747\u4E0D\u52A0\u5BC6\u3002" })] }), _jsxs("section", { className: "dsh-ssh-ftp-editor-section", children: [_jsxs("div", { className: "dsh-ssh-form-section-heading", children: [_jsx("strong", { children: "\u670D\u52A1\u5668" }), _jsx("small", { children: "\u540D\u79F0\u7528\u4E8E\u8FDE\u63A5\u5217\u8868\uFF0C\u5206\u7EC4\u7528\u4E8E\u533A\u5206\u73AF\u5883\u6216\u7528\u9014" })] }), _jsxs("div", { className: "dsh-ssh-form-grid", children: [_jsx(Field, { label: "\u8FDE\u63A5\u540D\u79F0", children: _jsx("input", { autoFocus: value === undefined, required: true, maxLength: 80, value: form.name, onChange: event => setForm({ ...form, name: event.target.value }) }) }), _jsx(Field, { label: "\u5206\u7EC4\uFF08\u53EF\u9009\uFF09", children: _jsx("input", { maxLength: 64, value: form.group, onChange: event => setForm({ ...form, group: event.target.value }) }) })] }), _jsxs("div", { className: "dsh-ssh-form-grid is-host", children: [_jsx(Field, { label: "\u670D\u52A1\u5668\u5730\u5740", children: _jsx("input", { required: true, maxLength: 253, spellCheck: false, value: form.host, onChange: event => setForm({ ...form, host: event.target.value }) }) }), _jsx(Field, { label: "\u7AEF\u53E3", children: _jsx("input", { required: true, type: "number", min: "1", max: "65535", value: form.port, onChange: event => setForm({ ...form, port: event.target.value }) }) })] })] }), _jsxs("section", { className: "dsh-ssh-ftp-editor-section", children: [_jsxs("div", { className: "dsh-ssh-form-section-heading", children: [_jsx("strong", { children: "\u8EAB\u4EFD\u8BA4\u8BC1" }), _jsx("small", { children: "\u5BC6\u7801\u53EA\u5199\u5165 DSH \u51ED\u636E\u670D\u52A1\uFF0C\u4E0D\u4F1A\u5728\u754C\u9762\u56DE\u663E" })] }), _jsxs("div", { className: "dsh-ssh-form-grid", children: [_jsx(Field, { label: "\u7528\u6237\u540D", children: _jsx("input", { required: true, maxLength: 128, autoComplete: "username", value: form.username, onChange: event => setForm({ ...form, username: event.target.value }) }) }), _jsx(Field, { label: "\u51ED\u636E\u6765\u6E90", children: _jsxs("select", { value: form.credentialId, onChange: event => setForm({ ...form, credentialId: event.target.value }), children: [_jsx("option", { value: "", children: "\u6B64\u8FDE\u63A5\u5355\u72EC\u4FDD\u5B58\u5BC6\u7801" }), passwordEntries.map(entry => _jsxs("option", { value: entry.id, children: [entry.name, " \u00B7 ", entry.username] }, entry.id))] }) })] }), !form.credentialId && _jsx(Field, { label: "\u5BC6\u7801", hint: value?.credential.configured && value.credential.source === 'profile' ? '已保存;留空保持不变' : '保存后不会回显', children: _jsx("input", { required: value === undefined || value.credential.source !== 'profile' || !value.credential.configured, type: "password", autoComplete: "new-password", value: form.password, onChange: event => setForm({ ...form, password: event.target.value }) }) })] }), _jsxs("section", { className: "dsh-ssh-ftp-editor-section", children: [_jsxs("div", { className: "dsh-ssh-form-section-heading", children: [_jsx("strong", { children: "\u8DEF\u5F84\u4E0E\u7F51\u7EDC" }), _jsx("small", { children: "\u4EE3\u7406\u590D\u7528 SSH \u63D2\u4EF6\u7684\u4EE3\u7406\u5E93\uFF0C\u63A7\u5236\u548C\u6570\u636E\u8FDE\u63A5\u4F7F\u7528\u540C\u4E00\u8DEF\u5F84" })] }), _jsxs("div", { className: "dsh-ssh-form-grid", children: [_jsx(Field, { label: "\u521D\u59CB\u76EE\u5F55", children: _jsx("input", { required: true, maxLength: 4096, spellCheck: false, value: form.initialPath, onChange: event => setForm({ ...form, initialPath: event.target.value }) }) }), _jsx(Field, { label: "\u8FDE\u63A5\u4EE3\u7406", children: _jsxs("select", { value: form.proxyId, onChange: event => setForm({ ...form, proxyId: event.target.value }), children: [_jsx("option", { value: "", children: "\u76F4\u8FDE" }), proxyEntries.map(entry => _jsxs("option", { value: entry.id, children: [entry.name, " \u00B7 ", entry.proxyType.toUpperCase()] }, entry.id))] }) })] }), _jsxs("details", { className: "dsh-ssh-form-advanced", children: [_jsx("summary", { children: "\u9AD8\u7EA7\u8FDE\u63A5\u8BBE\u7F6E" }), _jsxs("div", { className: "dsh-ssh-form-grid", children: [_jsx(Field, { label: "\u8FDE\u63A5\u8D85\u65F6\uFF08\u6BEB\u79D2\uFF09", children: _jsx("input", { required: true, type: "number", min: "1000", max: "120000", step: "1000", value: form.connectTimeoutMs, onChange: event => setForm({ ...form, connectTimeoutMs: event.target.value }) }) }), _jsx(Field, { label: "TLS \u670D\u52A1\u5668\u540D\u79F0", hint: "\u8BC1\u4E66\u540D\u79F0\u4E0E\u4E3B\u673A\u4E0D\u540C\u65F6\u586B\u5199", children: _jsx("input", { maxLength: 253, spellCheck: false, value: form.tlsServerName, onChange: event => setForm({ ...form, tlsServerName: event.target.value }) }) })] })] })] }), testResult && _jsx("p", { className: "dsh-ssh-inline-success", role: "status", children: testResult }), error && _jsx("p", { className: "dsh-ssh-inline-error", role: "alert", children: error })] }), _jsxs("footer", { className: "dsh-ssh-ftp-editor-actions", children: [_jsx("button", { type: "button", className: "dsh-ssh-secondary-button", onClick: () => { void test(); }, disabled: testing || saving, children: testing ? '正在测试…' : '测试连接' }), _jsx("span", {}), _jsx("button", { type: "button", className: "dsh-ssh-secondary-button", onClick: onBack, disabled: saving || testing, children: "\u53D6\u6D88" }), _jsx("button", { type: "submit", className: "dsh-ssh-primary-button", disabled: saving || testing, children: saving ? '正在保存…' : '保存连接' })] })] });
|
|
87
|
+
}
|
|
88
|
+
function protocolLabel(protocol) { return protocol === 'ftp' ? 'FTP' : protocol === 'ftps-explicit' ? 'FTPS' : 'FTPS-I'; }
|
|
89
|
+
//# sourceMappingURL=ftp-profile-editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ftp-profile-editor.js","sourceRoot":"","sources":["../src/ftp-profile-editor.tsx"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,EAAE,MAAM,IAAI,YAAY,EAAiB,KAAK,MAAM,IAAI,SAAS,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAGlD,OAAO,EAAE,MAAM,IAAI,YAAY,EAAiB,KAAK,MAAM,IAAI,SAAS,EAAE,MAAM,aAAa,CAAA;AAgB7F,eAAO,MAAM,MAAM,0DAAe,CAAA;AAClC,MAAM,MAAM,MAAM,GAAG,SAAS,CAAA;AAC9B,cAAc,aAAa,CAAA;AAC3B,eAAO,MAAM,IAAI,YAAY,CAAA;AAC7B,eAAO,MAAM,MAAM,UAAqD,CAAA;AAQxE,wBAAgB,KAAK,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAgD/D"}
|
package/lib/index.js
CHANGED
|
@@ -7,6 +7,12 @@ import { SshStore } from './store.js';
|
|
|
7
7
|
import { AiTerminalManager, BrowserTerminalManager } from './terminal.js';
|
|
8
8
|
import { registerSshTools } from './tools.js';
|
|
9
9
|
import { ActivityEventBus } from './activity-events.js';
|
|
10
|
+
import { NetworkDialer } from './network-dialer.js';
|
|
11
|
+
import { SftpFileSystemAdapter } from './sftp-adapter.js';
|
|
12
|
+
import { FtpFileSystemAdapter } from './ftp-adapter.js';
|
|
13
|
+
import { RemoteFileSystems } from './remote-file-systems.js';
|
|
14
|
+
import { FileTransferManager } from './file-transfer-manager.js';
|
|
15
|
+
import { EndpointSessionManager } from './endpoint-session-manager.js';
|
|
10
16
|
export const Config = ConfigSchema;
|
|
11
17
|
export * from './domain.js';
|
|
12
18
|
export const name = 'dsh-ssh';
|
|
@@ -22,11 +28,18 @@ export function apply(context, config) {
|
|
|
22
28
|
});
|
|
23
29
|
const credentials = new SshCredentialVault(ctx.credentials);
|
|
24
30
|
const connector = new SshConnector(store, credentials);
|
|
31
|
+
const dialer = new NetworkDialer(store, credentials);
|
|
32
|
+
const files = new RemoteFileSystems([
|
|
33
|
+
new SftpFileSystemAdapter(store, connector),
|
|
34
|
+
new FtpFileSystemAdapter(store, credentials, dialer),
|
|
35
|
+
]);
|
|
36
|
+
const transfers = new FileTransferManager(files);
|
|
37
|
+
const fileSessions = new EndpointSessionManager(files);
|
|
25
38
|
const forwards = new ForwardManager(connector, store);
|
|
26
39
|
const terminals = new BrowserTerminalManager(connector);
|
|
27
40
|
const activityEvents = new ActivityEventBus();
|
|
28
41
|
const aiTerminals = new AiTerminalManager(connector, event => { activityEvents.publish(event); });
|
|
29
|
-
const disposeTools = registerSshTools(context, store, connector, forwards, aiTerminals);
|
|
42
|
+
const disposeTools = registerSshTools(context, store, connector, forwards, aiTerminals, files, transfers);
|
|
30
43
|
let disposeApi;
|
|
31
44
|
const mountApi = (runtime) => {
|
|
32
45
|
if (!resolved.exposeWeb)
|
|
@@ -35,7 +48,7 @@ export function apply(context, config) {
|
|
|
35
48
|
if (webServer === undefined)
|
|
36
49
|
throw new Error('dsh-ssh exposeWeb requires webServer');
|
|
37
50
|
disposeApi = registerSshApi(webServer, resolved.apiPrefix, {
|
|
38
|
-
store, credentials, connector, forwards, terminals, aiTerminals, activityEvents,
|
|
51
|
+
store, credentials, connector, dialer, files, transfers, fileSessions, forwards, terminals, aiTerminals, activityEvents,
|
|
39
52
|
sessionCwd: sessionId => runtime.agents.get(sessionId)?.session.header.cwd,
|
|
40
53
|
});
|
|
41
54
|
};
|
|
@@ -52,6 +65,8 @@ export function apply(context, config) {
|
|
|
52
65
|
disposeApi?.();
|
|
53
66
|
await terminals.closeAll();
|
|
54
67
|
await aiTerminals.closeAll();
|
|
68
|
+
await transfers.closeAll();
|
|
69
|
+
fileSessions.closeAll();
|
|
55
70
|
await forwards.closeAll();
|
|
56
71
|
};
|
|
57
72
|
}, 'dsh-ssh.runtime');
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,aAAa,EAA4B,MAAM,aAAa,CAAA;AAC7F,OAAO,EAAE,cAAc,EAAsB,MAAM,UAAU,CAAA;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AACrC,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Socket } from 'node:net';
|
|
2
|
+
import type { FtpProxyConfig } from './domain.js';
|
|
3
|
+
import { SshCredentialVault } from './credentials.js';
|
|
4
|
+
import { SshStore } from './store.js';
|
|
5
|
+
/** Opens one routed TCP socket. FTP control and passive data channels share this boundary. */
|
|
6
|
+
export declare class NetworkDialer {
|
|
7
|
+
private readonly store;
|
|
8
|
+
private readonly credentials;
|
|
9
|
+
constructor(store: SshStore, credentials: SshCredentialVault);
|
|
10
|
+
connect(host: string, port: number, route: FtpProxyConfig, timeoutMs: number, signal?: AbortSignal): Promise<Socket>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=network-dialer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-dialer.d.ts","sourceRoot":"","sources":["../src/network-dialer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAErD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,8FAA8F;AAC9F,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,KAAK;IAAY,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAA7C,KAAK,EAAE,QAAQ,EAAmB,WAAW,EAAE,kBAAkB;IAExF,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;CAc3H"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { connectHttpProxy, connectSocket, connectSocks5Proxy } from './proxy.js';
|
|
2
|
+
/** Opens one routed TCP socket. FTP control and passive data channels share this boundary. */
|
|
3
|
+
export class NetworkDialer {
|
|
4
|
+
store;
|
|
5
|
+
credentials;
|
|
6
|
+
constructor(store, credentials) {
|
|
7
|
+
this.store = store;
|
|
8
|
+
this.credentials = credentials;
|
|
9
|
+
}
|
|
10
|
+
async connect(host, port, route, timeoutMs, signal) {
|
|
11
|
+
signal?.throwIfAborted();
|
|
12
|
+
if (route.type === 'none')
|
|
13
|
+
return connectSocket(host, port, timeoutMs, signal);
|
|
14
|
+
const proxy = this.store.proxyEntry(route.proxyId);
|
|
15
|
+
if (proxy === undefined)
|
|
16
|
+
throw Object.assign(new Error(`proxy entry ${route.proxyId} was not found`), { status: 404 });
|
|
17
|
+
const secrets = await this.credentials.readProxyEntry(proxy.id);
|
|
18
|
+
const auth = {
|
|
19
|
+
...(proxy.username === undefined ? {} : { username: proxy.username }),
|
|
20
|
+
...(secrets.proxyPassword === undefined ? {} : { password: secrets.proxyPassword }),
|
|
21
|
+
};
|
|
22
|
+
return proxy.proxyType === 'http'
|
|
23
|
+
? connectHttpProxy(proxy.host, proxy.port, host, port, auth, timeoutMs, signal)
|
|
24
|
+
: connectSocks5Proxy(proxy.host, proxy.port, host, port, auth, timeoutMs, signal);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=network-dialer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-dialer.js","sourceRoot":"","sources":["../src/network-dialer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAGhF,8FAA8F;AAC9F,MAAM,OAAO,aAAa;IACK;IAAkC;IAA/D,YAA6B,KAAe,EAAmB,WAA+B;QAAjE,UAAK,GAAL,KAAK,CAAU;QAAmB,gBAAW,GAAX,WAAW,CAAoB;IAAG,CAAC;IAElG,KAAK,CAAC,OAAO,CAAC,IAAY,EAAE,IAAY,EAAE,KAAqB,EAAE,SAAiB,EAAE,MAAoB;QACtG,MAAM,EAAE,cAAc,EAAE,CAAA;QACxB,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,CAAA;QAC9E,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QAClD,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,eAAe,KAAK,CAAC,OAAO,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;QACtH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC/D,MAAM,IAAI,GAAG;YACX,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;YACrE,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;SACpF,CAAA;QACD,OAAO,KAAK,CAAC,SAAS,KAAK,MAAM;YAC/B,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC;YAC/E,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,CAAA;IACrF,CAAC;CACF"}
|
package/lib/proxy.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export interface ProxyCredentials {
|
|
|
3
3
|
username?: string;
|
|
4
4
|
password?: string;
|
|
5
5
|
}
|
|
6
|
-
export declare function connectHttpProxy(proxyHost: string, proxyPort: number, targetHost: string, targetPort: number, credentials: ProxyCredentials, timeoutMs: number): Promise<Socket>;
|
|
7
|
-
export declare function connectSocks5Proxy(proxyHost: string, proxyPort: number, targetHost: string, targetPort: number, credentials: ProxyCredentials, timeoutMs: number): Promise<Socket>;
|
|
8
|
-
export declare function connectSocket(host: string, port: number, timeoutMs: number): Promise<Socket>;
|
|
6
|
+
export declare function connectHttpProxy(proxyHost: string, proxyPort: number, targetHost: string, targetPort: number, credentials: ProxyCredentials, timeoutMs: number, signal?: AbortSignal): Promise<Socket>;
|
|
7
|
+
export declare function connectSocks5Proxy(proxyHost: string, proxyPort: number, targetHost: string, targetPort: number, credentials: ProxyCredentials, timeoutMs: number, signal?: AbortSignal): Promise<Socket>;
|
|
8
|
+
export declare function connectSocket(host: string, port: number, timeoutMs: number, signal?: AbortSignal): Promise<Socket>;
|
|
9
9
|
//# sourceMappingURL=proxy.d.ts.map
|
package/lib/proxy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AACA,OAAY,EAAE,KAAK,MAAM,EAAE,MAAM,UAAU,CAAA;AAE3C,MAAM,WAAW,gBAAgB;IAAG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE;AAE1E,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,gBAAgB,EAC7B,SAAS,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AACA,OAAY,EAAE,KAAK,MAAM,EAAE,MAAM,UAAU,CAAA;AAE3C,MAAM,WAAW,gBAAgB;IAAG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE;AAE1E,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,gBAAgB,EAC7B,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,CAAC,CAgBjB;AAED,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,gBAAgB,EAC7B,SAAS,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,CAAC,CAgCjB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAYxH"}
|
package/lib/proxy.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Buffer } from 'node:buffer';
|
|
2
2
|
import net from 'node:net';
|
|
3
|
-
export async function connectHttpProxy(proxyHost, proxyPort, targetHost, targetPort, credentials, timeoutMs) {
|
|
4
|
-
const socket = await connectSocket(proxyHost, proxyPort, timeoutMs);
|
|
3
|
+
export async function connectHttpProxy(proxyHost, proxyPort, targetHost, targetPort, credentials, timeoutMs, signal) {
|
|
4
|
+
const socket = await connectSocket(proxyHost, proxyPort, timeoutMs, signal);
|
|
5
5
|
const authority = `${targetHost}:${targetPort}`;
|
|
6
6
|
const headers = [`CONNECT ${authority} HTTP/1.1`, `Host: ${authority}`, 'Proxy-Connection: Keep-Alive'];
|
|
7
7
|
if (credentials.username !== undefined) {
|
|
@@ -17,8 +17,8 @@ export async function connectHttpProxy(proxyHost, proxyPort, targetHost, targetP
|
|
|
17
17
|
}
|
|
18
18
|
return socket;
|
|
19
19
|
}
|
|
20
|
-
export async function connectSocks5Proxy(proxyHost, proxyPort, targetHost, targetPort, credentials, timeoutMs) {
|
|
21
|
-
const socket = await connectSocket(proxyHost, proxyPort, timeoutMs);
|
|
20
|
+
export async function connectSocks5Proxy(proxyHost, proxyPort, targetHost, targetPort, credentials, timeoutMs, signal) {
|
|
21
|
+
const socket = await connectSocket(proxyHost, proxyPort, timeoutMs, signal);
|
|
22
22
|
const useAuth = credentials.username !== undefined;
|
|
23
23
|
socket.write(Buffer.from(useAuth ? [5, 2, 0, 2] : [5, 1, 0]));
|
|
24
24
|
const greeting = await readExact(socket, 2, timeoutMs);
|
|
@@ -60,13 +60,17 @@ export async function connectSocks5Proxy(proxyHost, proxyPort, targetHost, targe
|
|
|
60
60
|
throw closeError(socket, 'SOCKS5 proxy returned an invalid address type');
|
|
61
61
|
return socket;
|
|
62
62
|
}
|
|
63
|
-
export async function connectSocket(host, port, timeoutMs) {
|
|
63
|
+
export async function connectSocket(host, port, timeoutMs, signal) {
|
|
64
|
+
signal?.throwIfAborted();
|
|
64
65
|
return new Promise((resolve, reject) => {
|
|
65
66
|
const socket = net.connect({ host, port });
|
|
66
67
|
const timer = setTimeout(() => socket.destroy(new Error(`connection to ${host}:${port} timed out`)), timeoutMs);
|
|
67
|
-
const
|
|
68
|
+
const abort = () => { socket.destroy(signal?.reason instanceof Error ? signal.reason : new Error('connection was aborted')); };
|
|
69
|
+
const cleanup = () => { clearTimeout(timer); signal?.removeEventListener('abort', abort); socket.off('error', failed); };
|
|
70
|
+
const failed = (error) => { cleanup(); reject(error); };
|
|
71
|
+
signal?.addEventListener('abort', abort, { once: true });
|
|
68
72
|
socket.once('connect', () => { cleanup(); resolve(socket); });
|
|
69
|
-
socket.once('error',
|
|
73
|
+
socket.once('error', failed);
|
|
70
74
|
});
|
|
71
75
|
}
|
|
72
76
|
async function readUntil(socket, marker, max, timeoutMs) {
|