mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
- Export resolveSignerCapabilities, hydrateExtensionSignerCapabilities, and attachNipMethodAliases from SignerManager so they can be used by the module-level setActiveSigner in client.js - Fix ensureExtensionPermissions: pass the extension object to requestEnablePermissions (was passing methods array as extension), check response.ok instead of response.enabled - Hydrate extensionPermissionCache from localStorage on construction so fresh NostrClient instances recognize previously granted permissions - Cache individual permission method names (not just composite keys) so tests and code checking specific methods work correctly - Guard extension.signEvent.bind() against missing signEvent - Add extensionPermissionCache getter to NostrClient - Add derivePrivateKeyFromSecret and registerPrivateKeySigner methods to SignerManager and NostrClient (needed by nsec auth provider) - Add installNip46Client method for NIP-46 test infrastructure - Apply signer hydration in module-level setActiveSigner - Proxy ensureExtensionPermissions through NostrClient in loginWithExtension to support test monkey-patching - Fix nostr-signer-race test to use Map.set() instead of Set.add() Fixes 5 previously-failing CI tests: - tests/nostr/signers.test.mjs - tests/nostr/dm-direct-message-flow.test.mjs - tests/nostr/dmSignalEvents.test.mjs - tests/nostr-login-permissions.test.mjs - tests/nostr-signer-race.test.mjs https://claude.ai/code/session_01KuHrohbGvitA41A2fPD5p5
66 lines
2.3 KiB
JavaScript
66 lines
2.3 KiB
JavaScript
|
|
import "./test-helpers/setup-localstorage.mjs";
|
|
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import { NostrClient, setActiveSigner, getActiveSigner } from "../js/nostr/client.js";
|
|
|
|
const HEX_PUBKEY = "a".repeat(64);
|
|
|
|
test("ensureActiveSignerForPubkey prefers concurrent login over late extension injection", async () => {
|
|
// 1. Setup Environment
|
|
const originalWindow = global.window;
|
|
global.window = {};
|
|
|
|
try {
|
|
const client = new NostrClient();
|
|
client.pubkey = HEX_PUBKEY;
|
|
// Pre-condition: Cache permissions to trigger the waitForNip07Extension logic
|
|
client.extensionPermissionCache.set("sign_event", true);
|
|
|
|
// Mock a NIP-46 signer that might be set during the race
|
|
const mockNip46Signer = {
|
|
type: "nip46",
|
|
pubkey: HEX_PUBKEY,
|
|
signEvent: async () => ({ id: "mock-signed" }),
|
|
nip04: { encrypt: async () => "enc", decrypt: async () => "dec" }
|
|
};
|
|
|
|
// Mock the NIP-07 extension that appears late
|
|
const mockExtension = {
|
|
getPublicKey: async () => HEX_PUBKEY,
|
|
signEvent: async () => ({ id: "ext-signed" }),
|
|
nip04: { encrypt: async () => "ext-enc", decrypt: async () => "ext-dec" }
|
|
};
|
|
|
|
// 2. Start the race
|
|
// Calling ensureActiveSignerForPubkey while window.nostr is missing but permissions exist
|
|
// causes it to enter waitForNip07Extension loop (polling).
|
|
const ensurePromise = client.ensureActiveSignerForPubkey(HEX_PUBKEY);
|
|
|
|
// 3. Simulate Concurrent Login (e.g. NIP-46 restore completes)
|
|
// We wait a small amount to ensure ensureActiveSignerForPubkey has started polling
|
|
await new Promise(resolve => setTimeout(resolve, 50));
|
|
|
|
setActiveSigner(mockNip46Signer);
|
|
|
|
// 4. Simulate Extension Loading late
|
|
global.window.nostr = mockExtension;
|
|
|
|
// 5. Await result
|
|
const resultSigner = await ensurePromise;
|
|
|
|
// 6. Assertions
|
|
const finalActiveSigner = getActiveSigner();
|
|
|
|
// We expect the NIP-46 signer to be preserved and not overwritten by the NIP-07 fallback
|
|
assert.equal(finalActiveSigner.type, "nip46", "Race condition! NIP-46 signer was overwritten by NIP-07 fallback.");
|
|
assert.equal(resultSigner.type, "nip46", "Returned signer should be the NIP-46 one.");
|
|
} finally {
|
|
if (originalWindow) {
|
|
global.window = originalWindow;
|
|
} else {
|
|
delete global.window;
|
|
}
|
|
}
|
|
});
|