@aria-cli/wireguard 1.0.36 → 1.0.38

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.
@@ -1,44 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StaleOwnerError = void 0;
4
- exports.ensureOwnerEpochTable = ensureOwnerEpochTable;
5
- exports.claimDbOwnerEpoch = claimDbOwnerEpoch;
6
- class StaleOwnerError extends Error {
7
- kind = "StaleOwnerError";
8
- claimedGeneration;
9
- currentGeneration;
10
- constructor(claimed, current) {
11
- super(`StaleOwnerError: runtime claims generation ${claimed} but store is at generation ${current}. ` +
12
- `This runtime has been superseded and must shut down immediately.`);
13
- this.name = "StaleOwnerError";
14
- this.claimedGeneration = claimed;
15
- this.currentGeneration = current;
16
- }
17
- }
18
- exports.StaleOwnerError = StaleOwnerError;
19
- function ensureOwnerEpochTable(db) {
20
- db.exec(`
21
- CREATE TABLE IF NOT EXISTS owner_epoch (
22
- scope TEXT PRIMARY KEY DEFAULT 'runtime',
23
- owner_generation INTEGER NOT NULL
24
- )
25
- `);
26
- }
27
- function claimDbOwnerEpoch(db, generation) {
28
- ensureOwnerEpochTable(db);
29
- const result = db
30
- .prepare(`INSERT INTO owner_epoch (scope, owner_generation) VALUES ('runtime', ?)
31
- ON CONFLICT(scope) DO UPDATE SET owner_generation = excluded.owner_generation
32
- WHERE excluded.owner_generation > owner_epoch.owner_generation`)
33
- .run(generation);
34
- if (result.changes === 0) {
35
- const row = db
36
- .prepare("SELECT owner_generation FROM owner_epoch WHERE scope = 'runtime'")
37
- .get();
38
- const current = row?.owner_generation ?? 0;
39
- if (current > generation) {
40
- throw new StaleOwnerError(generation, current);
41
- }
42
- }
43
- }
44
- //# sourceMappingURL=db-owner-fencing.js.map
@@ -1,311 +0,0 @@
1
- "use strict";
2
- /**
3
- * DerpRelay — DERP relay client for NAT traversal.
4
- *
5
- * When both peers are behind symmetric NAT, direct WireGuard tunnels fail.
6
- * DerpRelay connects to a relay server via WebSocket and forwards encrypted
7
- * WireGuard packets through it. The relay CANNOT read the content (WireGuard
8
- * encryption is end-to-end).
9
- *
10
- * Implements the same { send(data: Buffer): void } interface as tunnel transports,
11
- * so it plugs into Mailbox.registerTunnel() transparently.
12
- *
13
- * Authentication: Ed25519 signature challenge on connect to prevent impersonation.
14
- * Auto-reconnect: Exponential backoff, matching ResilientTunnel's pattern.
15
- */
16
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
17
- if (k2 === undefined) k2 = k;
18
- var desc = Object.getOwnPropertyDescriptor(m, k);
19
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
20
- desc = { enumerable: true, get: function() { return m[k]; } };
21
- }
22
- Object.defineProperty(o, k2, desc);
23
- }) : (function(o, m, k, k2) {
24
- if (k2 === undefined) k2 = k;
25
- o[k2] = m[k];
26
- }));
27
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
28
- Object.defineProperty(o, "default", { enumerable: true, value: v });
29
- }) : function(o, v) {
30
- o["default"] = v;
31
- });
32
- var __importStar = (this && this.__importStar) || (function () {
33
- var ownKeys = function(o) {
34
- ownKeys = Object.getOwnPropertyNames || function (o) {
35
- var ar = [];
36
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
37
- return ar;
38
- };
39
- return ownKeys(o);
40
- };
41
- return function (mod) {
42
- if (mod && mod.__esModule) return mod;
43
- var result = {};
44
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
45
- __setModuleDefault(result, mod);
46
- return result;
47
- };
48
- })();
49
- var __importDefault = (this && this.__importDefault) || function (mod) {
50
- return (mod && mod.__esModule) ? mod : { "default": mod };
51
- };
52
- Object.defineProperty(exports, "__esModule", { value: true });
53
- exports.DerpRelay = void 0;
54
- const node_events_1 = require("node:events");
55
- const crypto = __importStar(require("node:crypto"));
56
- const ws_1 = __importDefault(require("ws"));
57
- const tools_1 = require("@aria-cli/tools");
58
- /** Max payload size matching WireGuard MTU */
59
- const MAX_PAYLOAD_BYTES = 65535;
60
- /** Max reconnection attempts before declaring dead */
61
- const MAX_RECONNECT_ATTEMPTS = 10;
62
- /** Base backoff interval */
63
- const BASE_BACKOFF_MS = 1_000;
64
- /** Max backoff interval */
65
- const MAX_BACKOFF_MS = 60_000;
66
- /**
67
- * DERP relay client.
68
- *
69
- * Emits: "plaintext" (data: Buffer, fromNodeId: NodeId, displayNameSnapshot?: string), "connected", "disconnected",
70
- * "dead", "error" (Error), "stateChange" (newState, prevState)
71
- */
72
- class DerpRelay extends node_events_1.EventEmitter {
73
- ws = null;
74
- _state = "disconnected";
75
- reconnectAttempts = 0;
76
- reconnectTimer = null;
77
- stopped = false;
78
- closing = false;
79
- relayUrl;
80
- nodeId;
81
- displayNameSnapshot;
82
- signingPrivateKey;
83
- signingPublicKey;
84
- targetNodeId;
85
- signal;
86
- /** Queued messages while not connected */
87
- queue = [];
88
- static MAX_QUEUE = 200;
89
- constructor(options) {
90
- super();
91
- this.relayUrl = options.relayUrl;
92
- this.nodeId = options.nodeId;
93
- this.displayNameSnapshot = options.displayNameSnapshot;
94
- this.signingPrivateKey = options.signingPrivateKey;
95
- this.signingPublicKey = options.signingPublicKey;
96
- this.targetNodeId = options.targetNodeId;
97
- this.signal = options.signal;
98
- if (this.signal) {
99
- this.signal.addEventListener("abort", () => this.disconnect(), { once: true });
100
- }
101
- }
102
- /** Connect to the relay server */
103
- async connect() {
104
- if (this.stopped || this._state === "connected" || this._state === "connecting")
105
- return;
106
- this.closing = false;
107
- this.setState("connecting");
108
- return new Promise((resolve, reject) => {
109
- try {
110
- const ws = new ws_1.default(this.relayUrl);
111
- this.ws = ws;
112
- const timeout = setTimeout(() => {
113
- ws.close();
114
- reject(new Error("Relay connection timeout"));
115
- }, 15_000);
116
- ws.on("open", () => {
117
- clearTimeout(timeout);
118
- if (this.closing) {
119
- ws.close();
120
- reject(new Error("Relay connection aborted: disconnect() called during connect"));
121
- return;
122
- }
123
- this.setState("authenticating");
124
- // Send auth message with our identity
125
- ws.send(JSON.stringify({
126
- type: "auth",
127
- nodeId: this.nodeId,
128
- signingPublicKey: this.signingPublicKey,
129
- }));
130
- });
131
- ws.on("message", (rawData) => {
132
- try {
133
- const data = typeof rawData === "string" ? rawData : rawData.toString();
134
- const msg = JSON.parse(data);
135
- if (msg.type === "challenge" && this._state === "authenticating") {
136
- // Sign the challenge to prove identity
137
- const signature = this.signChallenge(msg.nonce);
138
- ws.send(JSON.stringify({ type: "challenge_response", signature }));
139
- }
140
- else if (msg.type === "auth_ok") {
141
- if (this.closing) {
142
- ws.close();
143
- reject(new Error("Relay connection aborted: disconnect() called during auth"));
144
- return;
145
- }
146
- this.setState("connected");
147
- this.reconnectAttempts = 0;
148
- this.flushQueue();
149
- this.emit("connected");
150
- resolve();
151
- }
152
- else if (msg.type === "auth_error") {
153
- ws.close();
154
- reject(new Error(`Relay auth failed: ${msg.error}`));
155
- }
156
- else if (msg.type === "relay" && this._state === "connected") {
157
- // Incoming relayed data from another peer
158
- const fromNodeId = tools_1.NodeIdSchema.parse(msg.fromNodeId);
159
- const payload = Buffer.from(msg.data, "base64");
160
- this.emit("plaintext", payload, fromNodeId, msg.displayNameSnapshot);
161
- }
162
- else if (msg.type === "peer_offline") {
163
- // Target peer is not connected to relay
164
- const peerLabel = typeof msg.displayNameSnapshot === "string" && msg.displayNameSnapshot.length > 0
165
- ? msg.displayNameSnapshot
166
- : typeof msg.nodeId === "string" && msg.nodeId.length > 0
167
- ? msg.nodeId
168
- : this.targetNodeId;
169
- this.emit("error", new Error(`Peer ${peerLabel} is offline on relay`));
170
- }
171
- }
172
- catch (err) {
173
- this.emit("error", err instanceof Error ? err : new Error(String(err)));
174
- }
175
- });
176
- ws.on("close", () => {
177
- clearTimeout(timeout);
178
- const wasConnecting = this._state === "connecting" || this._state === "authenticating";
179
- this.setState("disconnected");
180
- if (this.stopped || this.closing) {
181
- // Reject the pending connect promise so callers don't hang
182
- if (wasConnecting) {
183
- reject(new Error("Relay connection closed during setup"));
184
- }
185
- }
186
- else {
187
- this.emit("disconnected");
188
- this.attemptReconnect();
189
- }
190
- });
191
- ws.on("error", (err) => {
192
- clearTimeout(timeout);
193
- this.emit("error", err);
194
- if (this._state === "connecting" || this._state === "authenticating") {
195
- reject(err);
196
- }
197
- });
198
- }
199
- catch (err) {
200
- this.setState("disconnected");
201
- reject(err);
202
- }
203
- });
204
- }
205
- /** Send data through the relay to the target peer */
206
- send(data) {
207
- if (this.stopped)
208
- throw new Error("Relay is stopped");
209
- if (data.length > MAX_PAYLOAD_BYTES) {
210
- throw new Error(`Payload exceeds max size (${data.length} > ${MAX_PAYLOAD_BYTES})`);
211
- }
212
- if (this._state !== "connected" || !this.ws) {
213
- this.enqueue(data);
214
- return;
215
- }
216
- this.ws.send(JSON.stringify({
217
- type: "relay",
218
- toNodeId: this.targetNodeId,
219
- data: data.toString("base64"),
220
- }));
221
- }
222
- /** Disconnect from the relay server */
223
- disconnect() {
224
- this.closing = true;
225
- this.stopped = true;
226
- this.clearReconnectTimer();
227
- if (this.ws) {
228
- try {
229
- this.ws.close();
230
- }
231
- catch {
232
- // ignore close errors
233
- }
234
- this.ws = null;
235
- }
236
- this.queue = [];
237
- this.setState("disconnected");
238
- }
239
- /** Get current relay state */
240
- getState() {
241
- return this._state;
242
- }
243
- /** Whether the relay is actively connected */
244
- get isConnected() {
245
- return this._state === "connected";
246
- }
247
- // ── Internal ─────────────────────────────────────────────────────
248
- setState(newState) {
249
- const prev = this._state;
250
- if (prev === newState)
251
- return;
252
- this._state = newState;
253
- this.emit("stateChange", newState, prev);
254
- }
255
- signChallenge(nonce) {
256
- const keyDer = Buffer.from(this.signingPrivateKey, "base64");
257
- const privateKey = crypto.createPrivateKey({
258
- key: keyDer,
259
- format: "der",
260
- type: "pkcs8",
261
- });
262
- const signature = crypto.sign(null, Buffer.from(nonce), privateKey);
263
- return signature.toString("base64");
264
- }
265
- attemptReconnect() {
266
- if (this.stopped)
267
- return;
268
- if (this.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
269
- this.setState("dead");
270
- this.emit("dead");
271
- return;
272
- }
273
- const backoff = Math.min(BASE_BACKOFF_MS * Math.pow(2, this.reconnectAttempts), MAX_BACKOFF_MS);
274
- this.reconnectAttempts++;
275
- this.reconnectTimer = setTimeout(() => {
276
- if (this.stopped)
277
- return;
278
- void this.connect().catch((err) => {
279
- this.emit("error", err instanceof Error ? err : new Error(String(err)));
280
- });
281
- }, backoff);
282
- }
283
- clearReconnectTimer() {
284
- if (this.reconnectTimer) {
285
- clearTimeout(this.reconnectTimer);
286
- this.reconnectTimer = null;
287
- }
288
- }
289
- enqueue(data) {
290
- if (this.queue.length >= DerpRelay.MAX_QUEUE) {
291
- // Drop oldest to make room
292
- this.queue.shift();
293
- }
294
- this.queue.push(data);
295
- }
296
- flushQueue() {
297
- if (this._state !== "connected" || !this.ws)
298
- return;
299
- const pending = this.queue.splice(0);
300
- for (const data of pending) {
301
- try {
302
- this.send(data);
303
- }
304
- catch {
305
- // Drop on failure during flush
306
- }
307
- }
308
- }
309
- }
310
- exports.DerpRelay = DerpRelay;
311
- //# sourceMappingURL=derp-relay.js.map
package/dist/index.js DELETED
@@ -1,100 +0,0 @@
1
- "use strict";
2
- /**
3
- * @aria/wireguard — WireGuard native addon for ARIA secure networking.
4
- *
5
- * Wraps Cloudflare's boringtun (BSD-3) via napi-rs for userspace
6
- * encrypted tunnels. Three hot-path functions: encrypt, decrypt, tick.
7
- *
8
- * @packageDocumentation
9
- */
10
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- var desc = Object.getOwnPropertyDescriptor(m, k);
13
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
- desc = { enumerable: true, get: function() { return m[k]; } };
15
- }
16
- Object.defineProperty(o, k2, desc);
17
- }) : (function(o, m, k, k2) {
18
- if (k2 === undefined) k2 = k;
19
- o[k2] = m[k];
20
- }));
21
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
- Object.defineProperty(o, "default", { enumerable: true, value: v });
23
- }) : function(o, v) {
24
- o["default"] = v;
25
- });
26
- var __importStar = (this && this.__importStar) || (function () {
27
- var ownKeys = function(o) {
28
- ownKeys = Object.getOwnPropertyNames || function (o) {
29
- var ar = [];
30
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
- return ar;
32
- };
33
- return ownKeys(o);
34
- };
35
- return function (mod) {
36
- if (mod && mod.__esModule) return mod;
37
- var result = {};
38
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
- __setModuleDefault(result, mod);
40
- return result;
41
- };
42
- })();
43
- Object.defineProperty(exports, "__esModule", { value: true });
44
- exports.DerpRelay = exports.PeerDiscoveryService = exports.ensureSecureNetwork = exports.decodeInviteToken = exports.createInviteToken = exports.generateSigningKeypair = exports.generateKeyPair = exports.PeerRegistry = exports.NetworkManager = exports.detectNatType = exports.discoverEndpoint = exports.StunClient = exports.ResilientTunnel = exports.SecureTunnel = void 0;
45
- exports.assertNativeAddonAvailable = assertNativeAddonAvailable;
46
- exports.createTunnel = createTunnel;
47
- exports.generateKeypair = generateKeypair;
48
- const path = __importStar(require("node:path"));
49
- /** Lazy-loaded native addon */
50
- let _native = null;
51
- function loadNative() {
52
- if (_native)
53
- return _native;
54
- try {
55
- // The package-root napi loader resolves the platform-specific native addon.
56
- // The dist/ runtime must not depend on a copied dist/wireguard.node shim.
57
- // eslint-disable-next-line @typescript-eslint/no-require-imports
58
- _native = require("../index.js");
59
- return _native;
60
- }
61
- catch (err) {
62
- const reason = err instanceof Error ? err.message : String(err);
63
- throw new Error(`@aria/wireguard: Failed to load native addon via ${path.join(__dirname, "../index.js")} (${process.platform}-${process.arch}). ${reason}`);
64
- }
65
- }
66
- /** Validate that the native addon can be loaded in the current runtime. */
67
- function assertNativeAddonAvailable() {
68
- loadNative();
69
- }
70
- /** Create a new WireGuard tunnel */
71
- function createTunnel(options) {
72
- const native = loadNative();
73
- return new native.WireGuardTunnel(options.privateKey, options.peerPublicKey, options.presharedKey ?? null, options.keepalive ?? 0, options.index ?? null);
74
- }
75
- /** Generate a new X25519 keypair for WireGuard */
76
- function generateKeypair() {
77
- const native = loadNative();
78
- return native.generateKeypair();
79
- }
80
- var tunnel_js_1 = require("./tunnel.js");
81
- Object.defineProperty(exports, "SecureTunnel", { enumerable: true, get: function () { return tunnel_js_1.SecureTunnel; } });
82
- var resilient_tunnel_js_1 = require("./resilient-tunnel.js");
83
- Object.defineProperty(exports, "ResilientTunnel", { enumerable: true, get: function () { return resilient_tunnel_js_1.ResilientTunnel; } });
84
- var nat_js_1 = require("./nat.js");
85
- Object.defineProperty(exports, "StunClient", { enumerable: true, get: function () { return nat_js_1.StunClient; } });
86
- Object.defineProperty(exports, "discoverEndpoint", { enumerable: true, get: function () { return nat_js_1.discoverEndpoint; } });
87
- Object.defineProperty(exports, "detectNatType", { enumerable: true, get: function () { return nat_js_1.detectNatType; } });
88
- var network_js_1 = require("./network.js");
89
- Object.defineProperty(exports, "NetworkManager", { enumerable: true, get: function () { return network_js_1.NetworkManager; } });
90
- Object.defineProperty(exports, "PeerRegistry", { enumerable: true, get: function () { return network_js_1.PeerRegistry; } });
91
- Object.defineProperty(exports, "generateKeyPair", { enumerable: true, get: function () { return network_js_1.generateKeyPair; } });
92
- Object.defineProperty(exports, "generateSigningKeypair", { enumerable: true, get: function () { return network_js_1.generateSigningKeypair; } });
93
- Object.defineProperty(exports, "createInviteToken", { enumerable: true, get: function () { return network_js_1.createInviteToken; } });
94
- Object.defineProperty(exports, "decodeInviteToken", { enumerable: true, get: function () { return network_js_1.decodeInviteToken; } });
95
- Object.defineProperty(exports, "ensureSecureNetwork", { enumerable: true, get: function () { return network_js_1.ensureSecureNetwork; } });
96
- var peer_discovery_js_1 = require("./peer-discovery.js");
97
- Object.defineProperty(exports, "PeerDiscoveryService", { enumerable: true, get: function () { return peer_discovery_js_1.PeerDiscoveryService; } });
98
- var derp_relay_js_1 = require("./derp-relay.js");
99
- Object.defineProperty(exports, "DerpRelay", { enumerable: true, get: function () { return derp_relay_js_1.DerpRelay; } });
100
- //# sourceMappingURL=index.js.map