@aemeath/surf-cli 0.1.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/LICENSE +21 -0
- package/README.md +102 -0
- package/SECURITY.md +21 -0
- package/dist/adapters/credential-store.d.ts +26 -0
- package/dist/adapters/credential-store.js +69 -0
- package/dist/adapters/credential-store.js.map +1 -0
- package/dist/adapters/openvpn-runner.d.ts +56 -0
- package/dist/adapters/openvpn-runner.js +413 -0
- package/dist/adapters/openvpn-runner.js.map +1 -0
- package/dist/adapters/state-store.d.ts +10 -0
- package/dist/adapters/state-store.js +38 -0
- package/dist/adapters/state-store.js.map +1 -0
- package/dist/adapters/surfshark-account-client.d.ts +31 -0
- package/dist/adapters/surfshark-account-client.js +226 -0
- package/dist/adapters/surfshark-account-client.js.map +1 -0
- package/dist/adapters/surfshark-config-client.d.ts +6 -0
- package/dist/adapters/surfshark-config-client.js +29 -0
- package/dist/adapters/surfshark-config-client.js.map +1 -0
- package/dist/adapters/xdg-paths.d.ts +14 -0
- package/dist/adapters/xdg-paths.js +46 -0
- package/dist/adapters/xdg-paths.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +81 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/auth.d.ts +3 -0
- package/dist/commands/auth.js +118 -0
- package/dist/commands/auth.js.map +1 -0
- package/dist/commands/doctor.d.ts +3 -0
- package/dist/commands/doctor.js +21 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/prompt.d.ts +4 -0
- package/dist/commands/prompt.js +35 -0
- package/dist/commands/prompt.js.map +1 -0
- package/dist/commands/servers.d.ts +3 -0
- package/dist/commands/servers.js +38 -0
- package/dist/commands/servers.js.map +1 -0
- package/dist/commands/vpn.d.ts +7 -0
- package/dist/commands/vpn.js +137 -0
- package/dist/commands/vpn.js.map +1 -0
- package/dist/core/errors.d.ts +12 -0
- package/dist/core/errors.js +37 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/types.d.ts +56 -0
- package/dist/core/types.js +29 -0
- package/dist/core/types.js.map +1 -0
- package/dist/services/auth-service.d.ts +16 -0
- package/dist/services/auth-service.js +49 -0
- package/dist/services/auth-service.js.map +1 -0
- package/dist/services/doctor-service.d.ts +11 -0
- package/dist/services/doctor-service.js +61 -0
- package/dist/services/doctor-service.js.map +1 -0
- package/dist/services/server-catalog-service.d.ts +17 -0
- package/dist/services/server-catalog-service.js +112 -0
- package/dist/services/server-catalog-service.js.map +1 -0
- package/dist/services/vpn-service.d.ts +26 -0
- package/dist/services/vpn-service.js +133 -0
- package/dist/services/vpn-service.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
3
|
+
import { setTimeout as delay } from 'node:timers/promises';
|
|
4
|
+
import { SurfCliError } from '../core/errors.js';
|
|
5
|
+
export class OpenVpnRunner {
|
|
6
|
+
async start(options) {
|
|
7
|
+
const useSudo = options.useSudo ?? shouldUseSudo();
|
|
8
|
+
const args = buildOpenVpnArgs(options);
|
|
9
|
+
if (useSudo) {
|
|
10
|
+
console.error('🔑 sudo is required to run OpenVPN. Please enter your SYSTEM (PC) password below.');
|
|
11
|
+
}
|
|
12
|
+
if (useSudo && options.foreground) {
|
|
13
|
+
await runInteractive('sudo', ['-v']);
|
|
14
|
+
}
|
|
15
|
+
const command = useSudo ? 'sudo' : 'openvpn';
|
|
16
|
+
const commandArgs = useSudo
|
|
17
|
+
? options.foreground
|
|
18
|
+
? ['openvpn', ...args]
|
|
19
|
+
: ['-b', 'openvpn', ...args]
|
|
20
|
+
: args;
|
|
21
|
+
if (options.foreground) {
|
|
22
|
+
await runInteractive(command, commandArgs);
|
|
23
|
+
return { pid: 0 };
|
|
24
|
+
}
|
|
25
|
+
const capturedOutput = createProcessOutputCapture();
|
|
26
|
+
const child = spawn(command, commandArgs, {
|
|
27
|
+
detached: !useSudo,
|
|
28
|
+
stdio: useSudo ? 'inherit' : ['ignore', 'pipe', 'pipe']
|
|
29
|
+
});
|
|
30
|
+
child.stdout?.setEncoding('utf8');
|
|
31
|
+
child.stderr?.setEncoding('utf8');
|
|
32
|
+
child.stdout?.on('data', (chunk) => capturedOutput.appendStdout(chunk));
|
|
33
|
+
child.stderr?.on('data', (chunk) => capturedOutput.appendStderr(chunk));
|
|
34
|
+
const childExit = watchChildExit(child, { ignoreSuccessfulExit: useSudo });
|
|
35
|
+
let pid;
|
|
36
|
+
try {
|
|
37
|
+
pid = await waitForInitialization({
|
|
38
|
+
childPid: useSudo ? undefined : child.pid,
|
|
39
|
+
pidFilePath: options.pidFilePath,
|
|
40
|
+
logFilePath: options.logFilePath,
|
|
41
|
+
timeoutMs: options.initTimeoutMs ?? 45_000,
|
|
42
|
+
getProcessOutput: () => capturedOutput.snapshot(),
|
|
43
|
+
childExit
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
await killSpawnedChild(child, options.pidFilePath, useSudo);
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
if (!useSudo) {
|
|
51
|
+
child.unref();
|
|
52
|
+
}
|
|
53
|
+
return { pid };
|
|
54
|
+
}
|
|
55
|
+
async terminate(pid, useSudo = shouldUseSudo()) {
|
|
56
|
+
if (useSudo) {
|
|
57
|
+
await runInteractive('sudo', ['kill', '-TERM', String(pid)]);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
process.kill(pid, 'SIGTERM');
|
|
61
|
+
}
|
|
62
|
+
async isAlive(pid) {
|
|
63
|
+
return isPidAlive(pid);
|
|
64
|
+
}
|
|
65
|
+
async isManagedOpenVpnProcess(pid, configPath) {
|
|
66
|
+
const command = await readProcessCommand(pid);
|
|
67
|
+
if (!command) {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
return command.includes('openvpn') && command.includes(configPath);
|
|
71
|
+
}
|
|
72
|
+
async readStatus(statusFilePath) {
|
|
73
|
+
try {
|
|
74
|
+
return parseOpenVpnStatus(await readFile(statusFilePath, 'utf8'));
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
if (shouldIgnoreStatusReadError(error)) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
export function shouldIgnoreStatusReadError(error) {
|
|
85
|
+
return (error instanceof Error &&
|
|
86
|
+
'code' in error &&
|
|
87
|
+
(error.code === 'ENOENT' || error.code === 'EACCES'));
|
|
88
|
+
}
|
|
89
|
+
export function buildOpenVpnArgs(options) {
|
|
90
|
+
return [
|
|
91
|
+
'--config',
|
|
92
|
+
options.configPath,
|
|
93
|
+
'--auth-user-pass',
|
|
94
|
+
options.authFilePath,
|
|
95
|
+
'--auth-nocache',
|
|
96
|
+
'--writepid',
|
|
97
|
+
options.pidFilePath,
|
|
98
|
+
'--status',
|
|
99
|
+
options.statusFilePath,
|
|
100
|
+
'10',
|
|
101
|
+
'--log-append',
|
|
102
|
+
options.logFilePath,
|
|
103
|
+
'--verb',
|
|
104
|
+
'3'
|
|
105
|
+
];
|
|
106
|
+
}
|
|
107
|
+
export function parseOpenVpnStatus(raw) {
|
|
108
|
+
const statistics = {};
|
|
109
|
+
let updatedAt;
|
|
110
|
+
for (const line of raw.split(/\r?\n/)) {
|
|
111
|
+
if (!line.trim()) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
const [key, ...rest] = line.split(',');
|
|
115
|
+
const value = rest.join(',');
|
|
116
|
+
if (!key) {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (key === 'Updated') {
|
|
120
|
+
updatedAt = value;
|
|
121
|
+
}
|
|
122
|
+
else if (value) {
|
|
123
|
+
statistics[key] = value;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return { ...(updatedAt ? { updatedAt } : {}), statistics, raw };
|
|
127
|
+
}
|
|
128
|
+
export function protocolToOpenVpnFileSuffix(protocol) {
|
|
129
|
+
return `_${protocol}.ovpn`;
|
|
130
|
+
}
|
|
131
|
+
export async function findOpenVpnProcesses() {
|
|
132
|
+
if (process.platform === 'linux') {
|
|
133
|
+
return findOpenVpnProcessesFromProc();
|
|
134
|
+
}
|
|
135
|
+
return findOpenVpnProcessesFromPs();
|
|
136
|
+
}
|
|
137
|
+
export async function terminateProcess(pid, signal = 'SIGTERM') {
|
|
138
|
+
try {
|
|
139
|
+
process.kill(pid, signal);
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
if (!(error instanceof Error && 'code' in error)) {
|
|
144
|
+
throw error;
|
|
145
|
+
}
|
|
146
|
+
const code = error.code;
|
|
147
|
+
if (code === 'ESRCH') {
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
if (code === 'EPERM') {
|
|
151
|
+
await runInteractive('sudo', [
|
|
152
|
+
'kill',
|
|
153
|
+
`-${signal === 'SIGTERM' ? 'TERM' : 'KILL'}`,
|
|
154
|
+
String(pid)
|
|
155
|
+
]);
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
throw error;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
async function findOpenVpnProcessesFromProc() {
|
|
162
|
+
const processes = [];
|
|
163
|
+
let entries;
|
|
164
|
+
try {
|
|
165
|
+
entries = await readdir('/proc');
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
for (const entry of entries) {
|
|
171
|
+
const pid = Number.parseInt(entry, 10);
|
|
172
|
+
if (!Number.isFinite(pid) || pid <= 0) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
const command = await readProcessCommand(pid);
|
|
176
|
+
if (command && command.includes('openvpn')) {
|
|
177
|
+
processes.push({ pid, commandLine: command });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return processes;
|
|
181
|
+
}
|
|
182
|
+
async function findOpenVpnProcessesFromPs() {
|
|
183
|
+
return new Promise((resolve) => {
|
|
184
|
+
const child = spawn('ps', ['-eo', 'pid=,command='], {
|
|
185
|
+
stdio: ['ignore', 'pipe', 'ignore']
|
|
186
|
+
});
|
|
187
|
+
let output = '';
|
|
188
|
+
child.stdout.setEncoding('utf8');
|
|
189
|
+
child.stdout.on('data', (chunk) => {
|
|
190
|
+
output += chunk.toString();
|
|
191
|
+
});
|
|
192
|
+
child.on('close', () => {
|
|
193
|
+
const processes = [];
|
|
194
|
+
for (const line of output.split(/\r?\n/)) {
|
|
195
|
+
const trimmed = line.trim();
|
|
196
|
+
if (!trimmed)
|
|
197
|
+
continue;
|
|
198
|
+
const match = trimmed.match(/^(\d+)\s+(.+)$/);
|
|
199
|
+
if (!match)
|
|
200
|
+
continue;
|
|
201
|
+
const pid = Number.parseInt(match[1], 10);
|
|
202
|
+
const commandLine = match[2];
|
|
203
|
+
if (commandLine.includes('openvpn')) {
|
|
204
|
+
processes.push({ pid, commandLine });
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
resolve(processes);
|
|
208
|
+
});
|
|
209
|
+
child.on('error', () => resolve([]));
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
function shouldUseSudo() {
|
|
213
|
+
return typeof process.getuid === 'function' ? process.getuid() !== 0 : true;
|
|
214
|
+
}
|
|
215
|
+
async function waitForInitialization(options) {
|
|
216
|
+
const deadline = Date.now() + options.timeoutMs;
|
|
217
|
+
let lastLog = '';
|
|
218
|
+
let childExit = null;
|
|
219
|
+
while (Date.now() < deadline) {
|
|
220
|
+
if (!childExit && options.childExit) {
|
|
221
|
+
childExit = await settledChildExit(options.childExit);
|
|
222
|
+
}
|
|
223
|
+
const log = await readOptionalText(options.logFilePath);
|
|
224
|
+
if (log) {
|
|
225
|
+
lastLog = log.slice(-4_000);
|
|
226
|
+
if (/Initialization Sequence Completed/i.test(log)) {
|
|
227
|
+
const pid = await readPidFile(options.pidFilePath);
|
|
228
|
+
if (pid) {
|
|
229
|
+
return pid;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (/AUTH_FAILED|auth-failure/i.test(log)) {
|
|
233
|
+
throw new SurfCliError('AUTH_FAILED', 'OpenVPN rejected the configured Surfshark service credentials.');
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (childExit || (options.childPid && !(await isPidAlive(options.childPid)))) {
|
|
237
|
+
throw new SurfCliError('CONNECTION_FAILED', formatInitializationFailure({
|
|
238
|
+
lastLog,
|
|
239
|
+
processOutput: options.getProcessOutput?.(),
|
|
240
|
+
childExit
|
|
241
|
+
}));
|
|
242
|
+
}
|
|
243
|
+
await delay(500);
|
|
244
|
+
}
|
|
245
|
+
throw new SurfCliError('CONNECTION_FAILED', `OpenVPN did not report successful initialization within ${Math.round(options.timeoutMs / 1000)} seconds. Last diagnostic output:\n${formatDiagnosticOutput({
|
|
246
|
+
lastLog,
|
|
247
|
+
processOutput: options.getProcessOutput?.(),
|
|
248
|
+
childExit
|
|
249
|
+
})}`);
|
|
250
|
+
}
|
|
251
|
+
const OUTPUT_CAPTURE_LIMIT = 4_000;
|
|
252
|
+
function createProcessOutputCapture() {
|
|
253
|
+
let stdout = '';
|
|
254
|
+
let stderr = '';
|
|
255
|
+
return {
|
|
256
|
+
appendStdout(chunk) {
|
|
257
|
+
stdout = trimCapturedOutput(stdout + chunk.toString());
|
|
258
|
+
},
|
|
259
|
+
appendStderr(chunk) {
|
|
260
|
+
stderr = trimCapturedOutput(stderr + chunk.toString());
|
|
261
|
+
},
|
|
262
|
+
snapshot() {
|
|
263
|
+
return { stdout, stderr };
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
function trimCapturedOutput(output) {
|
|
268
|
+
return output.length > OUTPUT_CAPTURE_LIMIT ? output.slice(-OUTPUT_CAPTURE_LIMIT) : output;
|
|
269
|
+
}
|
|
270
|
+
function watchChildExit(child, options = {}) {
|
|
271
|
+
return new Promise((resolve) => {
|
|
272
|
+
child.on('error', (error) => resolve({ code: null, signal: null, error: error.message }));
|
|
273
|
+
child.on('exit', (code, signal) => {
|
|
274
|
+
if (options.ignoreSuccessfulExit && code === 0) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
resolve({ code, signal });
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
async function settledChildExit(childExit) {
|
|
282
|
+
return Promise.race([childExit, Promise.resolve(null)]);
|
|
283
|
+
}
|
|
284
|
+
export function formatInitializationFailure(options) {
|
|
285
|
+
return `OpenVPN exited before initialization completed. Last diagnostic output:\n${formatDiagnosticOutput(options)}`;
|
|
286
|
+
}
|
|
287
|
+
export function formatDiagnosticOutput(options) {
|
|
288
|
+
const lastLog = options.lastLog?.trim();
|
|
289
|
+
if (lastLog) {
|
|
290
|
+
return lastLog;
|
|
291
|
+
}
|
|
292
|
+
const stderr = options.processOutput?.stderr.trim();
|
|
293
|
+
if (stderr) {
|
|
294
|
+
return stderr;
|
|
295
|
+
}
|
|
296
|
+
const stdout = options.processOutput?.stdout.trim();
|
|
297
|
+
if (stdout) {
|
|
298
|
+
return stdout;
|
|
299
|
+
}
|
|
300
|
+
if (options.childExit) {
|
|
301
|
+
if (options.childExit.error) {
|
|
302
|
+
return options.childExit.error;
|
|
303
|
+
}
|
|
304
|
+
const code = options.childExit.code === null ? 'unknown' : String(options.childExit.code);
|
|
305
|
+
const signal = options.childExit.signal ?? 'none';
|
|
306
|
+
return `(no log output; process exited with code ${code}, signal ${signal})`;
|
|
307
|
+
}
|
|
308
|
+
return '(no log output)';
|
|
309
|
+
}
|
|
310
|
+
async function readPidFile(pidFilePath) {
|
|
311
|
+
const text = await readOptionalText(pidFilePath);
|
|
312
|
+
if (!text) {
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
const pid = Number.parseInt(text.trim(), 10);
|
|
316
|
+
return Number.isFinite(pid) && pid > 0 ? pid : null;
|
|
317
|
+
}
|
|
318
|
+
async function readOptionalText(filePath) {
|
|
319
|
+
try {
|
|
320
|
+
return await readFile(filePath, 'utf8');
|
|
321
|
+
}
|
|
322
|
+
catch (error) {
|
|
323
|
+
if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
throw error;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
async function isPidAlive(pid) {
|
|
330
|
+
try {
|
|
331
|
+
process.kill(pid, 0);
|
|
332
|
+
return true;
|
|
333
|
+
}
|
|
334
|
+
catch (error) {
|
|
335
|
+
// ESRCH: process does not exist
|
|
336
|
+
// EPERM: process exists but we lack permission (e.g. root-owned openvpn via sudo)
|
|
337
|
+
if (error instanceof Error &&
|
|
338
|
+
'code' in error &&
|
|
339
|
+
error.code === 'EPERM') {
|
|
340
|
+
return true;
|
|
341
|
+
}
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
async function readProcessCommand(pid) {
|
|
346
|
+
if (process.platform === 'linux') {
|
|
347
|
+
try {
|
|
348
|
+
const raw = await readFile(`/proc/${pid}/cmdline`, 'utf8');
|
|
349
|
+
return raw.replace(/\0/g, ' ');
|
|
350
|
+
}
|
|
351
|
+
catch {
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
return new Promise((resolve) => {
|
|
356
|
+
const child = spawn('ps', ['-p', String(pid), '-o', 'command='], {
|
|
357
|
+
stdio: ['ignore', 'pipe', 'ignore']
|
|
358
|
+
});
|
|
359
|
+
let output = '';
|
|
360
|
+
child.stdout.setEncoding('utf8');
|
|
361
|
+
child.stdout.on('data', (chunk) => {
|
|
362
|
+
output += chunk;
|
|
363
|
+
});
|
|
364
|
+
child.on('close', (code) => resolve(code === 0 ? output.trim() : null));
|
|
365
|
+
child.on('error', () => resolve(null));
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
async function killSpawnedChild(child, pidFilePath, useSudo) {
|
|
369
|
+
// Try to read the OpenVPN PID from the pidfile (more reliable for sudo -b)
|
|
370
|
+
const pid = await readPidFile(pidFilePath);
|
|
371
|
+
if (useSudo) {
|
|
372
|
+
const targetPid = pid ?? child.pid;
|
|
373
|
+
if (targetPid) {
|
|
374
|
+
try {
|
|
375
|
+
await runInteractive('sudo', ['kill', '-TERM', String(targetPid)]);
|
|
376
|
+
}
|
|
377
|
+
catch {
|
|
378
|
+
// Best-effort: kill may fail if process already exited
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
// Non-sudo: try child.kill first, then pidfile PID as fallback
|
|
384
|
+
try {
|
|
385
|
+
child.kill('SIGTERM');
|
|
386
|
+
}
|
|
387
|
+
catch {
|
|
388
|
+
// May fail if process already exited
|
|
389
|
+
}
|
|
390
|
+
if (pid && pid !== child.pid) {
|
|
391
|
+
try {
|
|
392
|
+
process.kill(pid, 'SIGTERM');
|
|
393
|
+
}
|
|
394
|
+
catch {
|
|
395
|
+
// ESRCH is fine
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
async function runInteractive(command, args) {
|
|
400
|
+
await new Promise((resolve, reject) => {
|
|
401
|
+
const child = spawn(command, args, { stdio: 'inherit' });
|
|
402
|
+
child.on('error', (error) => reject(error));
|
|
403
|
+
child.on('close', (code) => {
|
|
404
|
+
if (code === 0) {
|
|
405
|
+
resolve();
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
reject(new SurfCliError('CONNECTION_FAILED', `${command} ${args.join(' ')} exited with status ${code}.`));
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
//# sourceMappingURL=openvpn-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openvpn-runner.js","sourceRoot":"","sources":["../../src/adapters/openvpn-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ActiveConnection, type AppState } from '../core/types.js';
|
|
2
|
+
import { type AppPaths } from './xdg-paths.js';
|
|
3
|
+
export declare class JsonStateStore {
|
|
4
|
+
private readonly paths;
|
|
5
|
+
constructor(paths?: AppPaths);
|
|
6
|
+
getState(): Promise<AppState>;
|
|
7
|
+
setActiveConnection(activeConnection: ActiveConnection): Promise<void>;
|
|
8
|
+
clearActiveConnection(): Promise<void>;
|
|
9
|
+
private writeState;
|
|
10
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { readFile, rename, writeFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { appStateSchema } from '../core/types.js';
|
|
4
|
+
import { ensureAppDirectories, getAppPaths } from './xdg-paths.js';
|
|
5
|
+
export class JsonStateStore {
|
|
6
|
+
paths;
|
|
7
|
+
constructor(paths = getAppPaths()) {
|
|
8
|
+
this.paths = paths;
|
|
9
|
+
}
|
|
10
|
+
async getState() {
|
|
11
|
+
try {
|
|
12
|
+
const raw = await readFile(this.paths.stateFile, 'utf8');
|
|
13
|
+
return appStateSchema.parse(JSON.parse(raw));
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
if (isNodeError(error) && error.code === 'ENOENT') {
|
|
17
|
+
return {};
|
|
18
|
+
}
|
|
19
|
+
throw error;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async setActiveConnection(activeConnection) {
|
|
23
|
+
await this.writeState({ activeConnection });
|
|
24
|
+
}
|
|
25
|
+
async clearActiveConnection() {
|
|
26
|
+
await this.writeState({});
|
|
27
|
+
}
|
|
28
|
+
async writeState(state) {
|
|
29
|
+
await ensureAppDirectories(this.paths);
|
|
30
|
+
const temporaryPath = path.join(this.paths.stateDir, `.state-${process.pid}.json`);
|
|
31
|
+
await writeFile(temporaryPath, `${JSON.stringify(state, null, 2)}\n`, { mode: 0o600 });
|
|
32
|
+
await rename(temporaryPath, this.paths.stateFile);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function isNodeError(error) {
|
|
36
|
+
return error instanceof Error && 'code' in error;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=state-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-store.js","sourceRoot":"","sources":["../../src/adapters/state-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,cAAc,EAAwC,MAAM,kBAAkB,CAAC;AACxF,OAAO,EAAE,oBAAoB,EAAE,WAAW,EAAiB,MAAM,gBAAgB,CAAC;AAElF,MAAM,OAAO,cAAc;IACI;IAA7B,YAA6B,QAAkB,WAAW,EAAE;QAA/B,UAAK,GAAL,KAAK,CAA0B;IAAG,CAAC;IAEhE,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YACzD,OAAO,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QAC/C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAClD,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,gBAAkC;QAC1D,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,qBAAqB;QACzB,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;IAEO,KAAK,CAAC,UAAU,CAAC,KAAe;QACtC,MAAM,oBAAoB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,UAAU,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;QACnF,MAAM,SAAS,CAAC,aAAa,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACvF,MAAM,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACpD,CAAC;CACF;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type OpenVpnCredentials } from '../core/types.js';
|
|
2
|
+
export interface EmailLoginOutcome {
|
|
3
|
+
authenticated: boolean;
|
|
4
|
+
twoFactorRequired: boolean;
|
|
5
|
+
credentials: OpenVpnCredentials | null;
|
|
6
|
+
message: string;
|
|
7
|
+
}
|
|
8
|
+
export interface LoginCodeChallenge {
|
|
9
|
+
code: string;
|
|
10
|
+
hash: string;
|
|
11
|
+
expiresAfterSeconds: number;
|
|
12
|
+
}
|
|
13
|
+
export interface CodeLoginOutcome {
|
|
14
|
+
activated: boolean;
|
|
15
|
+
credentials: OpenVpnCredentials | null;
|
|
16
|
+
message: string;
|
|
17
|
+
}
|
|
18
|
+
export declare class SurfsharkAccountClient {
|
|
19
|
+
private readonly baseUrl;
|
|
20
|
+
private readonly jar;
|
|
21
|
+
constructor(baseUrl?: string);
|
|
22
|
+
loginWithEmail(email: string, password: string): Promise<EmailLoginOutcome>;
|
|
23
|
+
createLoginCodeChallenge(): Promise<LoginCodeChallenge>;
|
|
24
|
+
waitForLoginCodeActivation(challenge: LoginCodeChallenge, options?: {
|
|
25
|
+
pollIntervalMs?: number;
|
|
26
|
+
timeoutMs?: number;
|
|
27
|
+
}): Promise<CodeLoginOutcome>;
|
|
28
|
+
fetchOpenVpnCredentialsFromSession(): Promise<OpenVpnCredentials | null>;
|
|
29
|
+
private request;
|
|
30
|
+
}
|
|
31
|
+
export declare function extractOpenVpnCredentials(value: unknown): OpenVpnCredentials | null;
|