From 4c6aed3cffb9b891782f0830f9333ea18a9ee574 Mon Sep 17 00:00:00 2001 From: bbassie <17990055+bbassie@users.noreply.github.com> Date: Wed, 4 Nov 2026 00:37:37 +0000 Subject: [PATCH] Return the host record from verifyHostToken Matches verifyUserToken returning the user. HostConnection._saveInfo is renamed saveRecord to match User.saveRecord. Co-Authored-By: Claude Opus 5.5 --- docs/devs/plugin-migration-to-2.1.md | 1 + packages/controller/src/HostConnection.ts | 6 +++--- packages/controller/src/HostManager.ts | 8 ++++---- packages/controller/src/WsServer.ts | 2 +- test/controller/HostManager.test.js | 8 ++++---- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/docs/devs/plugin-migration-to-2.1.md b/docs/devs/plugin-migration-to-2.1.md index 6a01c757..42471313 100644 --- a/docs/devs/plugin-migration-to-2.1.md +++ b/docs/devs/plugin-migration-to-2.1.md @@ -97,6 +97,7 @@ The host manager also signs and checks host tokens and creates and deletes hosts - `controller.generateHostToken(hostId)` is now `controller.hosts.signHostToken(hostId)`. - `controller.verifyHostToken(token)` is now `controller.hosts.verifyHostToken(token)`. + It returns the `HostRecord` instead of the host id. - `controller.hostPairing.createHost(name)` is now `controller.hosts.createHost(name)`. It returns the new `HostRecord` instead of `{ hostId, token, name }`, sign a token for it with `signHostToken`. - `controller.hosts.revokeHost(hostId, revokedBy)` deletes a host the same way `HostRevokeRequest` does. diff --git a/packages/controller/src/HostConnection.ts b/packages/controller/src/HostConnection.ts index a37c5ea0..5df65ab3 100644 --- a/packages/controller/src/HostConnection.ts +++ b/packages/controller/src/HostConnection.ts @@ -68,7 +68,7 @@ export default class HostConnection extends BaseConnection { this._controller.instances.records.setMany(instances); this.info.connected = false; - this._saveInfo(); + this.saveRecord(); }); this.handle(lib.GetFactorioCredentialsRequest, this.handleGetFactorioCredentialsRequest.bind(this)); @@ -173,7 +173,7 @@ export default class HostConnection extends BaseConnection { } /** Store changes to the host record, unless the host was revoked */ - private _saveInfo() { + saveRecord() { if (this._controller.hosts.getMutable(this.id) === this.info) { this._controller.hosts.records.set(this.info); } @@ -182,7 +182,7 @@ export default class HostConnection extends BaseConnection { async handleHostInfoUpdateEvent(event: lib.HostInfoUpdateEvent) { this.info.name = event.update.name; this.info.publicAddress = event.update.publicAddress; - this._saveInfo(); + this.saveRecord(); } async handleInstanceStatusChangedEvent(request: lib.InstanceStatusChangedEvent) { diff --git a/packages/controller/src/HostManager.ts b/packages/controller/src/HostManager.ts index af46dfa2..94783de8 100644 --- a/packages/controller/src/HostManager.ts +++ b/packages/controller/src/HostManager.ts @@ -127,23 +127,23 @@ export default class HostManager { * Check a host token * * @param token - Host token to check. - * @returns ID of the host the token was issued to. + * @returns the host the token was issued to. * @throws if the token is invalid, its host is not registered or it was issued before tokenValidAfter. */ - verifyHostToken(token: string): number { + verifyHostToken(token: string): HostRecord { // migrate: allow pre-rename tokens issued to hosts before alpha-14 const payload = jwt.verify(token, this._controller.authSecret, { audience: ["host", "slave"] }); if (typeof payload === "string") { throw new Error("unexpected JsonWebToken type"); } const hostId = payload.host !== undefined ? payload.host : payload.slave; - const host = this.records.get(hostId); + const host = this.records.getMutable(hostId); if (!host) { throw new Error("host is not registered, start the host again to request to join the cluster"); } if (!payload.iat || payload.iat < host.tokenValidAfter) { throw new Error("invalid token"); } - return hostId; + return host; } } diff --git a/packages/controller/src/WsServer.ts b/packages/controller/src/WsServer.ts index 5d2b2518..7fcc85b0 100644 --- a/packages/controller/src/WsServer.ts +++ b/packages/controller/src/WsServer.ts @@ -252,7 +252,7 @@ ${err.stack}` } try { - if (this.controller.hosts.verifyHostToken(data.token) !== data.id) { + if (this.controller.hosts.verifyHostToken(data.token).id !== data.id) { throw new Error("missmatched host id"); } } catch (err: any) { diff --git a/test/controller/HostManager.test.js b/test/controller/HostManager.test.js index 4a9d807b..d148abd6 100644 --- a/test/controller/HostManager.test.js +++ b/test/controller/HostManager.test.js @@ -63,7 +63,7 @@ describe("controller/src/HostManager", function() { assert.equal(host.connected, false); assert(host.tokenValidAfter >= before, "tokenValidAfter predates the call"); assert(host.tokenValidAfter <= Math.floor(Date.now() / 1000), "tokenValidAfter is in the future"); - assert.equal(hosts.verifyHostToken(hosts.signHostToken(host.id)), host.id); + assert.equal(hosts.verifyHostToken(hosts.signHostToken(host.id)), host); }); it("should not reuse the id of an existing host", function() { hosts.records.set(new HostRecord(5, "existing", "", new Map())); @@ -91,12 +91,12 @@ describe("controller/src/HostManager", function() { hosts.records.set(new HostRecord(5, "five", "", new Map())); }); - it("should return the id of the host", function() { - assert.equal(hosts.verifyHostToken(hosts.signHostToken(5)), 5); + it("should return the mutable host record", function() { + assert.equal(hosts.verifyHostToken(hosts.signHostToken(5)), hosts.getMutable(5)); }); it("should accept a token from before the slave rename", function() { const token = jwt.sign({ aud: "slave", slave: 5 }, controller.authSecret); - assert.equal(hosts.verifyHostToken(token), 5); + assert.equal(hosts.verifyHostToken(token).id, 5); }); it("should reject a token for an unknown host", function() { assert.throws(() => hosts.verifyHostToken(hosts.signHostToken(6)), /host is not registered/);