aicq-openclaw-plugin 1.5.2 → 1.5.4

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.
Files changed (2) hide show
  1. package/dist/index.js +71 -8
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -8648,7 +8648,7 @@ var ServerClient = class {
8648
8648
  this.ws.terminate();
8649
8649
  }
8650
8650
  }, this.config.requestTimeoutMs);
8651
- this.ws.on("open", () => {
8651
+ this.ws.on("open", async () => {
8652
8652
  clearTimeout(connectTimeout);
8653
8653
  this.wsConnected = true;
8654
8654
  this.reconnectDelay = this.config.initialReconnectDelay;
@@ -8656,13 +8656,22 @@ var ServerClient = class {
8656
8656
  this.connectStartTimestamp = 0;
8657
8657
  this.hourlyCheckMode = false;
8658
8658
  this.cancelHourlyCheck();
8659
- this.setConnectionState("online");
8660
8659
  this.logger.info("[Server] WebSocket connected");
8660
+ if (!this.authToken) {
8661
+ this.logger.info("[Server] No auth token \u2014 attempting agent authentication...");
8662
+ const authed = await this.authenticateAsAgent();
8663
+ if (!authed) {
8664
+ this.logger.warn("[Server] Agent auth failed on reconnect \u2014 closing socket");
8665
+ this.ws?.close(1008, "Auth required");
8666
+ return;
8667
+ }
8668
+ }
8669
+ this.setConnectionState("online");
8661
8670
  this.wsSend({
8662
8671
  type: "online",
8663
8672
  nodeId: this.store.agentId,
8664
8673
  publicKey: Buffer.from(this.store.identityKeys.publicKey).toString("base64"),
8665
- ...this.authToken ? { token: this.authToken } : {}
8674
+ token: this.authToken
8666
8675
  });
8667
8676
  this.startHeartbeat();
8668
8677
  });
@@ -8812,6 +8821,47 @@ var ServerClient = class {
8812
8821
  // ----------------------------------------------------------------
8813
8822
  // REST API methods
8814
8823
  // ----------------------------------------------------------------
8824
+ /**
8825
+ * Authenticate as an AI Agent using challenge-response.
8826
+ *
8827
+ * Flow:
8828
+ * 1. POST /api/v1/auth/challenge → get challenge + challengeId
8829
+ * 2. Sign challenge with Ed25519 private key
8830
+ * 3. POST /api/v1/auth/login-agent → get JWT token
8831
+ *
8832
+ * Returns true if authentication succeeded and token was set.
8833
+ */
8834
+ async authenticateAsAgent() {
8835
+ const publicKeyBase64 = Buffer.from(this.store.identityKeys.publicKey).toString("base64");
8836
+ const challengeResp = await this.fetchPost("/api/v1/auth/challenge", {
8837
+ publicKey: publicKeyBase64
8838
+ });
8839
+ if (!challengeResp?.challenge || !challengeResp?.challengeId) {
8840
+ this.logger.warn("[Server] Failed to request agent challenge");
8841
+ return false;
8842
+ }
8843
+ let signature;
8844
+ try {
8845
+ const message = Buffer.from(challengeResp.challenge, "utf8");
8846
+ const nacl3 = await Promise.resolve().then(() => __toESM(require_nacl_fast(), 1));
8847
+ signature = nacl3.sign.detached(message, this.store.identityKeys.secretKey);
8848
+ } catch (err) {
8849
+ this.logger.error("[Server] Failed to sign challenge:", err);
8850
+ return false;
8851
+ }
8852
+ const loginResp = await this.fetchPost("/api/v1/auth/login-agent", {
8853
+ publicKey: publicKeyBase64,
8854
+ signature: Buffer.from(signature).toString("base64"),
8855
+ challengeId: challengeResp.challengeId
8856
+ });
8857
+ if (!loginResp?.session?.token) {
8858
+ this.logger.warn("[Server] Agent login failed \u2014 no token in response");
8859
+ return false;
8860
+ }
8861
+ this.setAuthToken(loginResp.session.token);
8862
+ this.logger.info("[Server] Agent authenticated successfully");
8863
+ return true;
8864
+ }
8815
8865
  /**
8816
8866
  * Register this node on the server.
8817
8867
  * Captures JWT token from response if returned.
@@ -15169,11 +15219,24 @@ var plugin = definePluginEntry({
15169
15219
  }
15170
15220
  const serverUrl = config2.serverUrl;
15171
15221
  const aicqAgentId = identityService.getAgentId();
15172
- try {
15173
- serverClient.connectWebSocket();
15174
- } catch (e) {
15175
- logger.warn("[Init] WS connect failed: " + (e instanceof Error ? e.message : e));
15176
- }
15222
+ (async () => {
15223
+ try {
15224
+ logger.info("[Init] Authenticating agent with server...");
15225
+ const authed = await serverClient.authenticateAsAgent();
15226
+ if (authed) {
15227
+ logger.info("[Init] Agent authentication successful");
15228
+ } else {
15229
+ logger.warn("[Init] Agent authentication failed \u2014 will retry on reconnect");
15230
+ }
15231
+ } catch (e) {
15232
+ logger.warn("[Init] Agent auth error: " + (e instanceof Error ? e.message : e));
15233
+ }
15234
+ try {
15235
+ serverClient.connectWebSocket();
15236
+ } catch (e) {
15237
+ logger.warn("[Init] WS connect failed: " + (e instanceof Error ? e.message : e));
15238
+ }
15239
+ })();
15177
15240
  serverClient.onConnectionStateChange((newState, prevState) => {
15178
15241
  logger.info("[Init] Connection state changed: " + prevState + " \u2192 " + newState);
15179
15242
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aicq-openclaw-plugin",
3
- "version": "1.5.2",
3
+ "version": "1.5.4",
4
4
  "description": "AICQ OpenClaw plugin - end-to-end encrypted P2P chat for AI agents with offline queue support",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",