mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
[auth] Fix "prepareStoredNsecSwitch is not a function" when switching to a saved nsec account
Switching (from NIP-07) to an added nsec account threw "this.prepareStoredNsecSwitch is not a function". Root cause: bindCoordinator binds every coordinator method to the Application instance, so inside handleProfileSwitchRequest `this` === app. Its call to the sibling `this.prepareStoredNsecSwitch(pubkey)` therefore resolves against the Application and needs an app-level delegator (like handleProfileSwitchRequest, handleModerationSettingsChange, and waitForIdentityRefresh all have). The #48 work added prepareStoredNsecSwitch as a coordinator sibling but not its delegator, and its tests only exercised authService.switchProfile — not the full app wiring — so it slipped through. Fix: add the app.prepareStoredNsecSwitch delegator (-> this._auth.prepareStoredNsecSwitch). Tests: tests/profile-switch-coordinator-delegators.test.mjs (4) — asserts every sibling handleProfileSwitchRequest calls via this.X exists as an app method. Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
772d4202c7
commit
a2c9f44307
2 files changed
+61
No files matched your search
@@ -3330,6 +3330,17 @@ class Application {
|
||||
return this._auth.handleProfileSwitchRequest(...args);
|
||||
}
|
||||
|
||||
// Coordinator methods are bound to `this` (the Application) by bindCoordinator,
|
||||
// so a sibling call like `this.prepareStoredNsecSwitch(...)` inside
|
||||
// handleProfileSwitchRequest resolves against the Application — it needs this
|
||||
// delegator to exist (like handleProfileSwitchRequest above). Without it,
|
||||
// switching to a stored-nsec account threw "this.prepareStoredNsecSwitch is not
|
||||
// a function".
|
||||
async prepareStoredNsecSwitch(...args) {
|
||||
this._initCoordinators();
|
||||
return this._auth.prepareStoredNsecSwitch(...args);
|
||||
}
|
||||
|
||||
async waitForIdentityRefresh(...args) {
|
||||
this._initCoordinators();
|
||||
return this._auth.waitForIdentityRefresh(...args);
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
// Switching to a saved nsec account threw "this.prepareStoredNsecSwitch is not a
|
||||
// function". Root cause: bindCoordinator binds every coordinator method to the
|
||||
// Application (`this` === app), so when a coordinator method calls a SIBLING via
|
||||
// `this.sibling(...)` it resolves against the Application — which therefore needs
|
||||
// an app-level delegator for that sibling. handleProfileSwitchRequest calls
|
||||
// this.prepareStoredNsecSwitch / this.handleModerationSettingsChange /
|
||||
// this.waitForIdentityRefresh; the nsec one was missing its delegator.
|
||||
//
|
||||
// test_integrity_note:
|
||||
// change_type: ["new_tests"]
|
||||
// scenarios:
|
||||
// - id: SCN-profile-switch-coordinator-delegators
|
||||
// given: "the Application class"
|
||||
// when: "handleProfileSwitchRequest runs (bound to app) and calls siblings"
|
||||
// then: "every sibling it calls exists as an app-level method/delegator"
|
||||
// observable_outcomes:
|
||||
// - "Application.prototype.prepareStoredNsecSwitch is a function"
|
||||
// - "the other siblings it invokes are also app methods"
|
||||
// determinism_controls:
|
||||
// - "static prototype inspection; no network/clock/DOM"
|
||||
// anti_cheat_rationale:
|
||||
// prevents: ["hard-coded return value"]
|
||||
// relaxation:
|
||||
// did_relax_any_assertion: false
|
||||
|
||||
import "./test-helpers/setup-localstorage.mjs";
|
||||
import test from "node:test";
|
||||
import { strict as assert } from "node:assert";
|
||||
import { Application } from "../js/app.js";
|
||||
|
||||
// Every coordinator sibling that handleProfileSwitchRequest calls via `this.X`
|
||||
// must exist as an app-level method, because bindCoordinator binds the coordinator
|
||||
// methods to the Application instance.
|
||||
const REQUIRED_APP_METHODS = [
|
||||
"handleProfileSwitchRequest",
|
||||
"prepareStoredNsecSwitch", // was missing -> the reported bug
|
||||
"handleModerationSettingsChange",
|
||||
"waitForIdentityRefresh",
|
||||
];
|
||||
|
||||
for (const name of REQUIRED_APP_METHODS) {
|
||||
test(`Application exposes ${name}() so the bound profile-switch flow can call it`, () => {
|
||||
assert.equal(
|
||||
typeof Application.prototype[name],
|
||||
"function",
|
||||
`Application.prototype.${name} must be a function (coordinator siblings are ` +
|
||||
`bound to app; handleProfileSwitchRequest calls it via this.${name}())`,
|
||||
);
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user