wispjs 3.0.1 → 3.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.
@@ -266,10 +266,13 @@ declare class PoolWorker {
266
266
  private intentionalDisconnect;
267
267
  private reconnectAttempts;
268
268
  private readonly maxReconnectAttempts;
269
+ private reauthTimer?;
269
270
  constructor(pool: WebsocketPool);
270
271
  private createSocket;
271
272
  private start;
272
273
  connect(): Promise<void>;
274
+ private scheduleReauth;
275
+ private reauth;
273
276
  private handleDisconnect;
274
277
  disconnect(): Promise<void>;
275
278
  private processWork;
@@ -1,5 +1,10 @@
1
1
  import { WispWebSocket } from "./ws_adapter.js";
2
2
  const WISP_DEBUG = process.env.WISP_DEBUG === "true";
3
+ const REAUTH_INTERVAL = (() => {
4
+ const parsed = process.env.WISP_REAUTH_INTERVAL ? parseInt(process.env.WISP_REAUTH_INTERVAL) : NaN;
5
+ return Number.isFinite(parsed) ? parsed : 9 * 60 * 1000;
6
+ })();
7
+ const REAUTH_TIMEOUT = 10000;
3
8
  /**
4
9
  * A single Worker within a {@link WebsocketPool}
5
10
  *
@@ -78,16 +83,59 @@ class PoolWorker {
78
83
  this.reconnectAttempts = 0;
79
84
  this.connected = true;
80
85
  clearTimeout(timeout);
86
+ this.scheduleReauth();
81
87
  resolve();
82
88
  });
83
89
  socket.connect();
84
90
  });
85
91
  }
92
+ // Resets the re-auth clock. Runs on every successful auth.
93
+ scheduleReauth() {
94
+ clearTimeout(this.reauthTimer);
95
+ this.reauthTimer = setTimeout(() => this.reauth(), REAUTH_INTERVAL);
96
+ }
97
+ // Re-auths the live socket with a fresh token. A failed re-auth is treated
98
+ // as a dead connection and handed to the reconnect path.
99
+ async reauth() {
100
+ if (!this.connected || this.intentionalDisconnect || this.done) {
101
+ return;
102
+ }
103
+ if (this.pool.refreshDetails) {
104
+ try {
105
+ const details = await this.pool.refreshDetails();
106
+ this.url = details.url;
107
+ this.token = details.token;
108
+ }
109
+ catch (e) {
110
+ this.logger.error("Re-auth: failed to refresh details", e);
111
+ return this.handleDisconnect("reauth refresh failure");
112
+ }
113
+ }
114
+ const socket = this.socket;
115
+ const ok = await new Promise((resolve) => {
116
+ const onSuccess = () => {
117
+ clearTimeout(timeout);
118
+ resolve(true);
119
+ };
120
+ const timeout = setTimeout(() => {
121
+ socket.off("auth success", onSuccess);
122
+ resolve(false);
123
+ }, REAUTH_TIMEOUT);
124
+ socket.once("auth success", onSuccess);
125
+ socket.emit("auth", this.token);
126
+ });
127
+ if (!ok) {
128
+ this.logger.error("Re-auth: no auth success in time");
129
+ return this.handleDisconnect("reauth failure");
130
+ }
131
+ this.scheduleReauth();
132
+ }
86
133
  // Recovers from an unexpected disconnect by reconnecting with a freshly
87
134
  // fetched token (the JWT is short-lived). After maxReconnectAttempts the
88
135
  // worker is marked dead so the pool stops handing it work.
89
136
  async handleDisconnect(reason) {
90
137
  this.connected = false;
138
+ clearTimeout(this.reauthTimer);
91
139
  if (this.intentionalDisconnect || this.done) {
92
140
  return;
93
141
  }
@@ -119,6 +167,7 @@ class PoolWorker {
119
167
  disconnect() {
120
168
  this.intentionalDisconnect = true;
121
169
  this.connected = false;
170
+ clearTimeout(this.reauthTimer);
122
171
  return new Promise((resolve) => {
123
172
  const timeout = setTimeout(() => {
124
173
  this.logger.error("Socket didn't disconnect in time");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wispjs",
3
- "version": "3.0.1",
3
+ "version": "3.1.0",
4
4
  "type": "module",
5
5
  "description": "A package for interacting with Wisp-based server panels",
6
6
  "main": "dist/wisp.js",