@push.rocks/smartvpn 2.3.1 → 2.4.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.
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "format": "tsrust.build-provenance.v2",
3
- "binarySha256": "d4e6f89ac9278183338ea8a83fd112ef8b7516576057234f7bab8181291089a1",
3
+ "binarySha256": "83e952eba6fa08fe0e4e34a2a29c133d5777eecbc60f269e67ec8ea0d7a8f55c",
4
4
  "buildInfo": {
5
5
  "projectName": "@push.rocks/smartvpn",
6
- "projectVersion": "2.3.1",
7
- "gitCommit": "a96a22bd5ff5fe870e72c225b51f4715c1b25c40",
6
+ "projectVersion": "2.4.0",
7
+ "gitCommit": "f1b6c5bc99f76c52bdfeee01fc3c7655c301de37",
8
8
  "gitDirty": false,
9
- "builtAt": "2026-09-17T15:20:47.136Z",
10
- "tsrustVersion": "1.13.0",
9
+ "builtAt": "2026-09-28T08:27:27.717Z",
10
+ "tsrustVersion": "1.15.1",
11
11
  "binary": "smartvpn_daemon",
12
12
  "target": "linux_amd64_musl"
13
13
  }
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "format": "tsrust.build-provenance.v2",
3
- "binarySha256": "9c8bdf211d7bbb9425e7dcf44ead8b39b584e6fd1b18cfdddff07b51133fb16d",
3
+ "binarySha256": "5189ed1c065c805727c6a1927465bf4decfa769854f6ad2e3a4ed2b0d00cccdc",
4
4
  "buildInfo": {
5
5
  "projectName": "@push.rocks/smartvpn",
6
- "projectVersion": "2.3.1",
7
- "gitCommit": "a96a22bd5ff5fe870e72c225b51f4715c1b25c40",
6
+ "projectVersion": "2.4.0",
7
+ "gitCommit": "f1b6c5bc99f76c52bdfeee01fc3c7655c301de37",
8
8
  "gitDirty": false,
9
- "builtAt": "2026-09-17T15:20:47.476Z",
10
- "tsrustVersion": "1.13.0",
9
+ "builtAt": "2026-09-28T08:29:27.183Z",
10
+ "tsrustVersion": "1.15.1",
11
11
  "binary": "smartvpn_daemon",
12
12
  "target": "linux_arm64_musl"
13
13
  }
@@ -2,8 +2,8 @@
2
2
  * autocreated commitinfo by @push.rocks/commitinfo
3
3
  */
4
4
  export const commitinfo = {
5
- name: "@push.rocks/smartvpn",
6
- version: "2.3.1",
7
- description: "A VPN solution with TypeScript control plane and Rust data plane daemon"
5
+ name: '@push.rocks/smartvpn',
6
+ version: '2.4.0',
7
+ description: 'A VPN solution with TypeScript control plane and Rust data plane daemon'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxzQkFBc0I7SUFDNUIsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLHlFQUF5RTtDQUN2RixDQUFBIn0=
@@ -1,5 +1,5 @@
1
1
  import * as plugins from './smartvpn.plugins.js';
2
- import type { IVpnClientOptions, IVpnClientConfig, IVpnStatus, IVpnStatistics, IVpnConnectionQuality, IVpnMtuInfo, IVpnConnectionResult, IVpnManagedRuntime, IVpnManagedSessionConfig, IVpnManagedSession } from './smartvpn.interfaces.js';
2
+ import type { IVpnClientOptions, IVpnClientConfig, IVpnStatus, IVpnStatistics, IVpnConnectionQuality, IVpnMtuInfo, IVpnConnectionResult, IVpnManagedRuntime, IVpnManagedSessionConfig, IVpnManagedSessionRenewal, IVpnManagedSession } from './smartvpn.interfaces.js';
3
3
  /**
4
4
  * VPN Client — manages a smartvpn daemon in client mode.
5
5
  */
@@ -30,7 +30,14 @@ export declare class VpnClient extends plugins.events.EventEmitter {
30
30
  * This generation cannot forward again. Disconnect then closes its kernel owner. */
31
31
  stopManagedForwarding(generation: string): Promise<IVpnManagedSession>;
32
32
  inspectManagedSession(generation: string): Promise<IVpnManagedSession>;
33
+ /** Move the live generation's native lease in place, without teardown. The renewal
34
+ * must name the exact authority the generation authenticated under. A rejected
35
+ * renewal leaves the lease in force unchanged; a lapsed lease is never revived,
36
+ * so authenticate a new generation instead. The hub follows its own expiry from
37
+ * the managed network snapshot (SmartVPN hub 2.3.1 or later keeps the session). */
38
+ renewManagedSession(generation: string, renewal: IVpnManagedSessionRenewal): Promise<IVpnManagedSession>;
33
39
  private sessionCommand;
40
+ private requireSessionGeneration;
34
41
  private checkObservation;
35
42
  /**
36
43
  * Start the daemon bridge (spawn or connect).
@@ -104,17 +104,32 @@ export class VpnClient extends plugins.events.EventEmitter {
104
104
  inspectManagedSession(generation) {
105
105
  return this.sessionCommand('inspectManagedSession', generation);
106
106
  }
107
+ /** Move the live generation's native lease in place, without teardown. The renewal
108
+ * must name the exact authority the generation authenticated under. A rejected
109
+ * renewal leaves the lease in force unchanged; a lapsed lease is never revived,
110
+ * so authenticate a new generation instead. The hub follows its own expiry from
111
+ * the managed network snapshot (SmartVPN hub 2.3.1 or later keeps the session). */
112
+ async renewManagedSession(generation, renewal) {
113
+ this.requireSessionGeneration(generation);
114
+ const epoch = this.bridgeEpoch;
115
+ const result = await this.bridge.sendCommand('renewManagedSession', { generation, renewal });
116
+ this.checkSession(result, epoch, generation);
117
+ return result;
118
+ }
107
119
  async sessionCommand(method, generation) {
120
+ this.requireSessionGeneration(generation);
121
+ const epoch = this.bridgeEpoch;
122
+ const result = await this.bridge.sendCommand(method, { generation });
123
+ this.checkSession(result, epoch, generation);
124
+ return result;
125
+ }
126
+ requireSessionGeneration(generation) {
108
127
  if (typeof generation !== 'string' || !/^[a-f0-9]{32}$/.test(generation)) {
109
128
  throw new Error('Managed session generation must be a native 128-bit identifier');
110
129
  }
111
130
  if (generation === this.invalidatedSessionGeneration || generation === this.retiredSessionGeneration) {
112
131
  throw new Error('Managed session observation is unavailable');
113
132
  }
114
- const epoch = this.bridgeEpoch;
115
- const result = await this.bridge.sendCommand(method, { generation });
116
- this.checkSession(result, epoch, generation);
117
- return result;
118
133
  }
119
134
  checkObservation(runtime, epoch, generation) {
120
135
  if (epoch !== this.bridgeEpoch || runtime.generation === this.lastInvalidatedGeneration
@@ -201,4 +216,4 @@ export class VpnClient extends plugins.events.EventEmitter {
201
216
  return this.bridge.running;
202
217
  }
203
218
  }
204
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnR2cG4uY2xhc3Nlcy52cG5jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydHZwbi5jbGFzc2VzLnZwbmNsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLHVCQUF1QixDQUFDO0FBQ2pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQWlCNUQ7O0dBRUc7QUFDSCxNQUFNLE9BQU8sU0FBVSxTQUFRLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWTtJQVd4RCxZQUFZLE9BQTBCO1FBQ3BDLEtBQUssRUFBRSxDQUFDO1FBVEYsZ0JBQVcsR0FBRyxDQUFDLENBQUM7UUFVdEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLFNBQVMsQ0FBcUI7WUFDOUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTO1lBQzVCLElBQUksRUFBRSxRQUFRO1lBQ2Qsa0JBQWtCLEVBQUUsT0FBTyxDQUFDLGtCQUFrQjtTQUMvQyxDQUFDLENBQUM7UUFFSCx3QkFBd0I7UUFDeEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsY0FBYyxFQUFFLEdBQUcsRUFBRTtZQUNsQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsK0JBQStCLENBQUMsQ0FBQztRQUN6RCxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQW1CLEVBQUUsTUFBcUIsRUFBRSxFQUFFO1lBQ3BFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1lBQzlDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDdEMsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsTUFBTSxDQUFD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
219
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnR2cG4uY2xhc3Nlcy52cG5jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydHZwbi5jbGFzc2VzLnZwbmNsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLHVCQUF1QixDQUFDO0FBQ2pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQWtCNUQ7O0dBRUc7QUFDSCxNQUFNLE9BQU8sU0FBVSxTQUFRLE9BQU8sQ0FBQyxNQUFNLENBQUMsWUFBWTtJQVd4RCxZQUFZLE9BQTBCO1FBQ3BDLEtBQUssRUFBRSxDQUFDO1FBVEYsZ0JBQVcsR0FBRyxDQUFDLENBQUM7UUFVdEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLFNBQVMsQ0FBcUI7WUFDOUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTO1lBQzVCLElBQUksRUFBRSxRQUFRO1lBQ2Qsa0JBQWtCLEVBQUUsT0FBTyxDQUFDLGtCQUFrQjtTQUMvQyxDQUFDLENBQUM7UUFFSCx3QkFBd0I7UUFDeEIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsY0FBYyxFQUFFLEdBQUcsRUFBRTtZQUNsQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsK0JBQStCLENBQUMsQ0FBQztRQUN6RCxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQW1CLEVBQUUsTUFBcUIsRUFBRSxFQUFFO1lBQ3BFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO1lBQzlDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDdEMsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsTUFBTSxDQUFD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
@@ -437,6 +437,13 @@ export type TVpnClientCommands = {
437
437
  };
438
438
  result: IVpnManagedSession;
439
439
  };
440
+ renewManagedSession: {
441
+ params: {
442
+ generation: string;
443
+ renewal: IVpnManagedSessionRenewal;
444
+ };
445
+ result: IVpnManagedSession;
446
+ };
440
447
  connect: {
441
448
  params: {
442
449
  config: IVpnClientConfig;
@@ -710,6 +717,18 @@ export interface IVpnManagedSessionConfig {
710
717
  deadlineBoottimeMs: number;
711
718
  };
712
719
  }
720
+ /** Moves a live generation's native lease in place. The identity fields must equal
721
+ * the ones the generation authenticated under; a changed credential requires a new
722
+ * session. The lease follows the authentication rules: same boot, future, at most
723
+ * fifteen minutes away. A later or nearer deadline replaces the one in force; a
724
+ * lease whose deadline already passed is final and never revived. */
725
+ export interface IVpnManagedSessionRenewal {
726
+ serverUrl: string;
727
+ serverPublicKey: string;
728
+ clientPublicKey: string;
729
+ managedNetwork: IManagedNetworkBinding;
730
+ lease: IVpnManagedSessionConfig['lease'];
731
+ }
713
732
  /** Authentication returns the full validated assignment and planned exclusive
714
733
  * TUN name before creating a device or route. Kernel policy remains caller-owned. */
715
734
  export interface IVpnManagedSessionPlan {
@@ -739,6 +758,9 @@ export interface IVpnManagedSession {
739
758
  * disabled. A stopped TUN stays owned until disconnect() joins deletion, or an
740
759
  * owned stdio process is joined by stop(). Socket stop() does not delete it. */
741
760
  runtime: IVpnManagedRuntime | null;
761
+ /** The native lease currently in force. `plan.lease` stays the lease the
762
+ * generation authenticated under; renewal moves only this one. */
763
+ lease: IVpnManagedSessionConfig['lease'];
742
764
  }
743
765
  /** Stopped means the complete packet I/O future ended; retired means the native
744
766
  * session owner ended. Neither proves namespace-wide cleanup, conntrack drain,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@push.rocks/smartvpn",
3
- "version": "2.3.1",
3
+ "version": "2.4.0",
4
4
  "private": false,
5
5
  "description": "A VPN solution with TypeScript control plane and Rust data plane daemon",
6
6
  "type": "module",
@@ -28,11 +28,11 @@
28
28
  "@push.rocks/smartrust": "^2.1.0"
29
29
  },
30
30
  "devDependencies": {
31
- "@git.zone/tsbuild": "^4.4.3",
32
- "@git.zone/tsrun": "^2.0.6",
33
- "@git.zone/tsrust": "^1.13.0",
34
- "@git.zone/tstest": "^6.1.1",
35
- "@types/node": "^26.5.1"
31
+ "@git.zone/tsbuild": "^5.0.0",
32
+ "@git.zone/tsrun": "^3.0.1",
33
+ "@git.zone/tsrust": "^1.15.1",
34
+ "@git.zone/tstest": "^6.3.2",
35
+ "@types/node": "^26.6.2"
36
36
  },
37
37
  "files": [
38
38
  "ts/**/*",
package/readme.md CHANGED
@@ -168,7 +168,26 @@ absolute `CLOCK_BOOTTIME` deadline, future and no more than fifteen minutes away
168
168
  The caller derives this conservative deadline from its independently qualified
169
169
  authority; SmartVPN does not turn wall-clock credentials into trusted time.
170
170
  Native expiry interrupts the whole packet I/O future, including blocked writes,
171
- and remains effective across suspend. Leases cannot be extended in place.
171
+ and remains effective across suspend.
172
+
173
+ `renewManagedSession(generation, renewal)` moves a live generation's lease in place,
174
+ without teardown, in the authenticated, prepared or forwarding phase. The renewal
175
+ names `serverUrl`, `serverPublicKey`, `clientPublicKey` and `managedNetwork`; they
176
+ must equal the values the generation authenticated under, because a changed
177
+ credential requires a new session. It carries no private key. Its `lease` follows
178
+ the authentication rules: the same boot, a future deadline, at most fifteen minutes
179
+ away. A later deadline extends the lease and a nearer one re-arms it. A rejected
180
+ renewal leaves the lease in force unchanged. A lease whose deadline has already
181
+ passed is final: packet I/O stops at that deadline, a late renewal rejects, and
182
+ the caller authenticates a new generation. `plan.lease` never changes; every
183
+ session observation reports the lease in force as `lease`.
184
+
185
+ The native lease is only the node's half. The hub ends a session at the node's
186
+ `expiresAt` from its own managed snapshot, so the controller renews that expiry
187
+ by reconciling a snapshot that changes only `expiresAt`. A hub running SmartVPN
188
+ 2.3.1 or later keeps the live session through that reconcile; an older hub drains
189
+ it. Renew both halves before the nearer of the two deadlines. Renewal adds no
190
+ message between client and hub, so a 2.4 client works with any 2.3.x hub.
172
191
 
173
192
  Register `managed-session-state`, `managed-session-invalidated` and
174
193
  `managed-runtime-invalidated` listeners before
@@ -2,7 +2,7 @@
2
2
  * autocreated commitinfo by @push.rocks/commitinfo
3
3
  */
4
4
  export const commitinfo = {
5
- name: "@push.rocks/smartvpn",
6
- version: "2.3.1",
7
- description: "A VPN solution with TypeScript control plane and Rust data plane daemon"
5
+ name: '@push.rocks/smartvpn',
6
+ version: '2.4.0',
7
+ description: 'A VPN solution with TypeScript control plane and Rust data plane daemon'
8
8
  }
@@ -11,6 +11,7 @@ import type {
11
11
  IVpnManagedRuntime,
12
12
  IVpnManagedRuntimeInvalidation,
13
13
  IVpnManagedSessionConfig,
14
+ IVpnManagedSessionRenewal,
14
15
  IVpnManagedSession,
15
16
  IVpnManagedSessionEvent,
16
17
  TVpnClientCommands,
@@ -135,18 +136,35 @@ export class VpnClient extends plugins.events.EventEmitter {
135
136
  return this.sessionCommand('inspectManagedSession', generation);
136
137
  }
137
138
 
139
+ /** Move the live generation's native lease in place, without teardown. The renewal
140
+ * must name the exact authority the generation authenticated under. A rejected
141
+ * renewal leaves the lease in force unchanged; a lapsed lease is never revived,
142
+ * so authenticate a new generation instead. The hub follows its own expiry from
143
+ * the managed network snapshot (SmartVPN hub 2.3.1 or later keeps the session). */
144
+ public async renewManagedSession(generation: string, renewal: IVpnManagedSessionRenewal): Promise<IVpnManagedSession> {
145
+ this.requireSessionGeneration(generation);
146
+ const epoch = this.bridgeEpoch;
147
+ const result = await this.bridge.sendCommand('renewManagedSession', { generation, renewal });
148
+ this.checkSession(result, epoch, generation);
149
+ return result;
150
+ }
151
+
138
152
  private async sessionCommand(method: 'prepareManagedTunnel' | 'enableManagedForwarding'
139
153
  | 'stopManagedForwarding' | 'inspectManagedSession', generation: string): Promise<IVpnManagedSession> {
154
+ this.requireSessionGeneration(generation);
155
+ const epoch = this.bridgeEpoch;
156
+ const result = await this.bridge.sendCommand(method, { generation });
157
+ this.checkSession(result, epoch, generation);
158
+ return result;
159
+ }
160
+
161
+ private requireSessionGeneration(generation: string): void {
140
162
  if (typeof generation !== 'string' || !/^[a-f0-9]{32}$/.test(generation)) {
141
163
  throw new Error('Managed session generation must be a native 128-bit identifier');
142
164
  }
143
165
  if (generation === this.invalidatedSessionGeneration || generation === this.retiredSessionGeneration) {
144
166
  throw new Error('Managed session observation is unavailable');
145
167
  }
146
- const epoch = this.bridgeEpoch;
147
- const result = await this.bridge.sendCommand(method, { generation });
148
- this.checkSession(result, epoch, generation);
149
- return result;
150
168
  }
151
169
 
152
170
  private checkObservation(runtime: IVpnManagedRuntime, epoch: number, generation?: string): void {
@@ -496,6 +496,7 @@ export type TVpnClientCommands = {
496
496
  enableManagedForwarding: { params: { generation: string }; result: IVpnManagedSession };
497
497
  stopManagedForwarding: { params: { generation: string }; result: IVpnManagedSession };
498
498
  inspectManagedSession: { params: { generation: string }; result: IVpnManagedSession };
499
+ renewManagedSession: { params: { generation: string; renewal: IVpnManagedSessionRenewal }; result: IVpnManagedSession };
499
500
  connect: { params: { config: IVpnClientConfig }; result: IVpnConnectionResult };
500
501
  inspectManagedRuntime: { params: { generation: string }; result: IVpnManagedRuntime };
501
502
  disconnect: { params: Record<string, never>; result: void };
@@ -627,6 +628,19 @@ export interface IVpnManagedSessionConfig {
627
628
  lease: { bootId: string; deadlineBoottimeMs: number };
628
629
  }
629
630
 
631
+ /** Moves a live generation's native lease in place. The identity fields must equal
632
+ * the ones the generation authenticated under; a changed credential requires a new
633
+ * session. The lease follows the authentication rules: same boot, future, at most
634
+ * fifteen minutes away. A later or nearer deadline replaces the one in force; a
635
+ * lease whose deadline already passed is final and never revived. */
636
+ export interface IVpnManagedSessionRenewal {
637
+ serverUrl: string;
638
+ serverPublicKey: string;
639
+ clientPublicKey: string;
640
+ managedNetwork: IManagedNetworkBinding;
641
+ lease: IVpnManagedSessionConfig['lease'];
642
+ }
643
+
630
644
  /** Authentication returns the full validated assignment and planned exclusive
631
645
  * TUN name before creating a device or route. Kernel policy remains caller-owned. */
632
646
  export interface IVpnManagedSessionPlan {
@@ -654,6 +668,9 @@ export interface IVpnManagedSession {
654
668
  * disabled. A stopped TUN stays owned until disconnect() joins deletion, or an
655
669
  * owned stdio process is joined by stop(). Socket stop() does not delete it. */
656
670
  runtime: IVpnManagedRuntime | null;
671
+ /** The native lease currently in force. `plan.lease` stays the lease the
672
+ * generation authenticated under; renewal moves only this one. */
673
+ lease: IVpnManagedSessionConfig['lease'];
657
674
  }
658
675
 
659
676
  /** Stopped means the complete packet I/O future ended; retired means the native