mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-05 04:12:25 +00:00
Merge branch 'unstable' into content-docs-audit-10961466235628399718
This commit is contained in:
6 files changed
+114
-9
No files matched your search
@@ -800,6 +800,8 @@ export class NostrClient {
|
||||
get sessionActorCipherClosuresPrivateKey() { return this.signerManager.sessionActorCipherClosuresPrivateKey; }
|
||||
set sessionActorCipherClosuresPrivateKey(val) { this.signerManager.sessionActorCipherClosuresPrivateKey = val; }
|
||||
|
||||
get extensionPermissionCache() { return this.signerManager.extensionPermissionCache; }
|
||||
|
||||
get pool() { return this.connectionManager.pool; }
|
||||
set pool(val) { this.connectionManager.pool = val; }
|
||||
|
||||
@@ -940,6 +942,23 @@ export class NostrClient {
|
||||
}
|
||||
}
|
||||
|
||||
resolveEventDTag(event, fallbackEvent = null) {
|
||||
if (!event || typeof event !== "object") {
|
||||
if (fallbackEvent) {
|
||||
return this.resolveEventDTag(fallbackEvent);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
const val = getDTagValueFromTags(event.tags);
|
||||
if (val) {
|
||||
return val;
|
||||
}
|
||||
if (fallbackEvent) {
|
||||
return this.resolveEventDTag(fallbackEvent);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
getActiveKey(video) {
|
||||
return getActiveKey(video);
|
||||
}
|
||||
@@ -2973,6 +2992,21 @@ export class NostrClient {
|
||||
return this.signerManager.ensureActiveSignerForPubkey(pubkey);
|
||||
}
|
||||
|
||||
async registerPrivateKeySigner({ privateKey, pubkey }) {
|
||||
if (!privateKey) {
|
||||
throw new Error("Private key is required.");
|
||||
}
|
||||
const adapter = await createNsecAdapter({ privateKey, pubkey });
|
||||
this.signerManager.setActiveSigner(adapter);
|
||||
this.sessionActor = {
|
||||
pubkey: adapter.pubkey,
|
||||
privateKey: privateKey,
|
||||
source: "nsec",
|
||||
createdAt: Date.now(),
|
||||
};
|
||||
return adapter;
|
||||
}
|
||||
|
||||
async loginWithExtension(options) {
|
||||
return this.signerManager.loginWithExtension(options);
|
||||
}
|
||||
@@ -2981,6 +3015,10 @@ export class NostrClient {
|
||||
return this.signerManager.connectRemoteSigner(params);
|
||||
}
|
||||
|
||||
installNip46Client(client) {
|
||||
this.signerManager.installNip46Client(client);
|
||||
}
|
||||
|
||||
async useStoredRemoteSigner(options) {
|
||||
return this.signerManager.useStoredRemoteSigner(options);
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ import {
|
||||
summarizeUrlForLog,
|
||||
} from "../nip46LoggingUtils.js";
|
||||
|
||||
import { bytesToHex } from "../../../vendor/crypto-helpers.bundle.min.js";
|
||||
import { devLogger, userLogger } from "../../utils/logger.js";
|
||||
import { createPrivateKeyCipherClosures } from "../signerHelpers.js";
|
||||
import { queueSignEvent } from "../signRequestQueue.js";
|
||||
@@ -263,6 +264,10 @@ export class SignerManager {
|
||||
this.extensionReady = false;
|
||||
this.extensionPermissionsGranted = false;
|
||||
this.extensionPermissionCache = new Map();
|
||||
const storedPermissions = readStoredNip07Permissions();
|
||||
for (const method of storedPermissions) {
|
||||
this.extensionPermissionCache.set(method, true);
|
||||
}
|
||||
this.sessionActorCipherClosures = null;
|
||||
this.sessionActorCipherClosuresPrivateKey = null;
|
||||
this.remoteSignerListeners = new Set();
|
||||
@@ -311,21 +316,45 @@ export class SignerManager {
|
||||
|
||||
async ensureSessionActor() {
|
||||
if (this.sessionActor) {
|
||||
return this.sessionActor;
|
||||
return this.sessionActor.pubkey;
|
||||
}
|
||||
|
||||
if (this.lockedSessionActor) {
|
||||
return this.lockedSessionActor;
|
||||
return this.lockedSessionActor.pubkey;
|
||||
}
|
||||
|
||||
const storedEntry = readStoredSessionActorEntry();
|
||||
if (storedEntry) {
|
||||
this.lockedSessionActor = storedEntry;
|
||||
this.sessionActor = storedEntry;
|
||||
return storedEntry;
|
||||
return storedEntry.pubkey;
|
||||
}
|
||||
|
||||
return null;
|
||||
const tools = await ensureNostrTools();
|
||||
let privateKey = "";
|
||||
if (tools && typeof tools.generateSecretKey === "function") {
|
||||
const secret = tools.generateSecretKey();
|
||||
privateKey = bytesToHex(secret);
|
||||
} else if (tools && typeof tools.generatePrivateKey === "function") {
|
||||
privateKey = tools.generatePrivateKey();
|
||||
} else {
|
||||
throw new Error("Failed to generate session actor: nostr-tools missing key generation.");
|
||||
}
|
||||
|
||||
let pubkey = "";
|
||||
if (tools && typeof tools.getPublicKey === "function") {
|
||||
pubkey = tools.getPublicKey(privateKey);
|
||||
}
|
||||
|
||||
const newActor = {
|
||||
pubkey,
|
||||
privateKey,
|
||||
source: "generated",
|
||||
createdAt: Date.now(),
|
||||
};
|
||||
|
||||
this.sessionActor = newActor;
|
||||
return pubkey;
|
||||
}
|
||||
|
||||
clearStoredSessionActor() {
|
||||
@@ -423,6 +452,9 @@ export class SignerManager {
|
||||
if (missing.length === 0) {
|
||||
this.extensionPermissionsGranted = true;
|
||||
this.extensionPermissionCache.set(cacheKey, true);
|
||||
for (const method of methods) {
|
||||
this.extensionPermissionCache.set(method, true);
|
||||
}
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
@@ -441,6 +473,9 @@ export class SignerManager {
|
||||
writeStoredNip07Permissions(missing);
|
||||
this.extensionPermissionsGranted = true;
|
||||
this.extensionPermissionCache.set(cacheKey, true);
|
||||
for (const method of missing) {
|
||||
this.extensionPermissionCache.set(method, true);
|
||||
}
|
||||
return { ok: true };
|
||||
}
|
||||
return { ok: false, error: "permission-denied" };
|
||||
@@ -548,6 +583,16 @@ export class SignerManager {
|
||||
return { pubkey: normalized, signer: adapter };
|
||||
}
|
||||
|
||||
installNip46Client(client) {
|
||||
if (!client) {
|
||||
return;
|
||||
}
|
||||
this.nip46Client = client;
|
||||
this.pubkey = client.userPubkey || client.remotePubkey; // Fallback
|
||||
this.setActiveSigner(client.getActiveSigner());
|
||||
this.emitRemoteSignerChange();
|
||||
}
|
||||
|
||||
async connectRemoteSigner({
|
||||
connectionString,
|
||||
remember = true,
|
||||
@@ -894,6 +939,10 @@ export class SignerManager {
|
||||
};
|
||||
}
|
||||
|
||||
signEventWithPrivateKey(event, privateKey) {
|
||||
return signEventWithPrivateKey(event, privateKey);
|
||||
}
|
||||
|
||||
logout() {
|
||||
const previousPubkey = this.pubkey;
|
||||
this.pubkey = null;
|
||||
|
||||
@@ -5,6 +5,9 @@ import { normalizeNostrPubkey, sanitizeRelayList } from "./nip46Client.js";
|
||||
import { DEFAULT_RELAY_URLS, RELAY_URLS } from "./toolkit.js";
|
||||
|
||||
export class RelayBatchFetcher {
|
||||
/**
|
||||
* @param {import("./client.js").NostrClient} client
|
||||
*/
|
||||
constructor(client) {
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@@ -484,7 +484,17 @@ export function clearStoredSessionActor() {
|
||||
|
||||
export function isSessionActor(nostrClient) {
|
||||
const sa = nostrClient?.sessionActor;
|
||||
return !!sa && sa.source !== "nsec";
|
||||
if (!sa) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
nostrClient?.pubkey &&
|
||||
sa.pubkey &&
|
||||
nostrClient.pubkey !== sa.pubkey
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return sa.source !== "nsec";
|
||||
}
|
||||
|
||||
function _closeSessionActorDb() {
|
||||
|
||||
@@ -458,10 +458,11 @@ describe("NIP-07 Login Permissions", () => {
|
||||
it("NIP-07 login does not wait for deferred permission grants", async () => {
|
||||
clearStoredPermissions();
|
||||
const env = setupLoginEnvironment();
|
||||
const originalEnsurePermissions = nostrClient.ensureExtensionPermissions;
|
||||
const target = nostrClient.signerManager || nostrClient;
|
||||
const originalEnsurePermissions = target.ensureExtensionPermissions;
|
||||
let completionPromise;
|
||||
|
||||
nostrClient.ensureExtensionPermissions = async () => {
|
||||
target.ensureExtensionPermissions = async () => {
|
||||
completionPromise = new Promise((_, reject) => {
|
||||
setTimeout(() => reject(new Error("permission denied")), 300);
|
||||
});
|
||||
@@ -484,7 +485,7 @@ describe("NIP-07 Login Permissions", () => {
|
||||
"deferred permission grants should still reject",
|
||||
);
|
||||
} finally {
|
||||
nostrClient.ensureExtensionPermissions = originalEnsurePermissions;
|
||||
target.ensureExtensionPermissions = originalEnsurePermissions;
|
||||
env.restore();
|
||||
nostrClient.logout();
|
||||
clearStoredPermissions();
|
||||
|
||||
@@ -15,7 +15,11 @@ test("ensureActiveSignerForPubkey prefers concurrent login over late extension i
|
||||
const client = new NostrClient();
|
||||
client.pubkey = HEX_PUBKEY;
|
||||
// Pre-condition: Cache permissions to trigger the waitForNip07Extension logic
|
||||
client.extensionPermissionCache.add("sign_event");
|
||||
if (typeof client.extensionPermissionCache.add === 'function') {
|
||||
client.extensionPermissionCache.add("sign_event");
|
||||
} else if (typeof client.extensionPermissionCache.set === 'function') {
|
||||
client.extensionPermissionCache.set("sign_event", true);
|
||||
}
|
||||
|
||||
// Mock a NIP-46 signer that might be set during the race
|
||||
const mockNip46Signer = {
|
||||
|
||||
Reference in new issue
Block a user