mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-02 10:52:27 +00:00
fix(auth): optimize login speed and list decryption
- Reduced decryption timeout for user lists from 90s to 15s to fail faster. - Optimized NIP-07 decryption calls to avoid retries and long timeouts during critical loading paths. - Fixed a bug where `loginWithExtension` triggered `getPublicKey` twice, doubling the user interaction time. - Added a 10s grace period for relay health warnings to prevent false positives on startup. - Verified `deferBlocks` logic in `authService` prevents blocking the login UI on slow list decryption. Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
1 parent
13f8b9f6aa
commit
6347ab0db1
5 files changed
+84
-12
No files matched your search
@@ -276,6 +276,7 @@ class Application {
|
||||
this.authLoadingState = { profile: "idle", lists: "idle", dms: "idle" };
|
||||
this.relayUiRefreshTimeout = null;
|
||||
this.lastRelayHealthWarningAt = 0;
|
||||
this.appStartedAt = Date.now();
|
||||
this.activeIntervals = [];
|
||||
this.torrentStatusIntervalId = null;
|
||||
this.torrentStatusNodes = null;
|
||||
@@ -6485,6 +6486,13 @@ class Application {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Give the app a grace period to establish initial connections before complaining.
|
||||
const now = Date.now();
|
||||
const GRACE_PERIOD_MS = 10000;
|
||||
if (now - (this.appStartedAt || now) < GRACE_PERIOD_MS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const relayCandidates = Array.isArray(nostrClient.relays) ? nostrClient.relays : [];
|
||||
if (!relayCandidates.length) {
|
||||
return false;
|
||||
@@ -6495,7 +6503,6 @@ class Application {
|
||||
return false;
|
||||
}
|
||||
|
||||
const now = Date.now();
|
||||
const cooldownMs = 30000;
|
||||
if (now - (this.lastRelayHealthWarningAt || 0) < cooldownMs) {
|
||||
return true;
|
||||
|
||||
+3
-1
@@ -2110,7 +2110,9 @@ export class NostrClient {
|
||||
}
|
||||
}
|
||||
|
||||
const adapter = await createNip07Adapter(extension);
|
||||
const adapter = await createNip07Adapter(extension, {
|
||||
preloadedPubkey: pubkey,
|
||||
});
|
||||
adapter.pubkey = pubkey;
|
||||
setActiveSigner(adapter);
|
||||
|
||||
|
||||
+11
-5
@@ -40,7 +40,7 @@ import { relaySubscriptionService } from "./services/relaySubscriptionService.js
|
||||
|
||||
const SUBSCRIPTION_SET_KIND =
|
||||
getNostrEventSchema(NOTE_TYPES.SUBSCRIPTION_LIST)?.kind ?? 30000;
|
||||
const DECRYPT_TIMEOUT_MS = 90000;
|
||||
const DECRYPT_TIMEOUT_MS = 15000;
|
||||
const DECRYPT_RETRY_DELAY_MS = 10000;
|
||||
|
||||
function normalizeHexPubkey(value) {
|
||||
@@ -937,13 +937,19 @@ class SubscriptionsManager {
|
||||
}
|
||||
|
||||
if (nostrApi) {
|
||||
const decrypterOptions = {
|
||||
priority: NIP07_PRIORITY.HIGH,
|
||||
timeoutMs: 12000,
|
||||
retryMultiplier: 1,
|
||||
};
|
||||
|
||||
if (typeof nostrApi.nip04?.decrypt === "function") {
|
||||
registerDecryptor("nip04", (payload) =>
|
||||
runNip07WithRetry(
|
||||
() => nostrApi.nip04.decrypt(userPubkey, payload),
|
||||
{
|
||||
label: "nip04.decrypt",
|
||||
priority: NIP07_PRIORITY.HIGH,
|
||||
...decrypterOptions,
|
||||
},
|
||||
),
|
||||
);
|
||||
@@ -960,7 +966,7 @@ class SubscriptionsManager {
|
||||
() => nip44.decrypt(userPubkey, payload),
|
||||
{
|
||||
label: "nip44.decrypt",
|
||||
priority: NIP07_PRIORITY.HIGH,
|
||||
...decrypterOptions,
|
||||
},
|
||||
),
|
||||
);
|
||||
@@ -974,7 +980,7 @@ class SubscriptionsManager {
|
||||
() => nip44v2.decrypt(userPubkey, payload),
|
||||
{
|
||||
label: "nip44.v2.decrypt",
|
||||
priority: NIP07_PRIORITY.HIGH,
|
||||
...decrypterOptions,
|
||||
},
|
||||
),
|
||||
);
|
||||
@@ -984,7 +990,7 @@ class SubscriptionsManager {
|
||||
() => nip44v2.decrypt(userPubkey, payload),
|
||||
{
|
||||
label: "nip44.v2.decrypt",
|
||||
priority: NIP07_PRIORITY.HIGH,
|
||||
...decrypterOptions,
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
+11
-5
@@ -79,7 +79,7 @@ export const USER_BLOCK_EVENTS = Object.freeze({
|
||||
const FAST_BLOCKLIST_RELAY_LIMIT = 3;
|
||||
const FAST_BLOCKLIST_TIMEOUT_MS = 2500;
|
||||
const BACKGROUND_BLOCKLIST_TIMEOUT_MS = 6000;
|
||||
const DECRYPT_TIMEOUT_MS = 90000;
|
||||
const DECRYPT_TIMEOUT_MS = 15000;
|
||||
const DECRYPT_RETRY_DELAY_MS = 10000;
|
||||
const MAX_BLOCKLIST_ENTRIES = 5000;
|
||||
|
||||
@@ -1031,6 +1031,12 @@ class UserBlockListManager {
|
||||
}
|
||||
|
||||
const nostrApi = typeof window !== "undefined" ? window?.nostr : null;
|
||||
const decrypterOptions = {
|
||||
priority: NIP07_PRIORITY.HIGH,
|
||||
timeoutMs: 12000,
|
||||
retryMultiplier: 1,
|
||||
};
|
||||
|
||||
if (nostrApi) {
|
||||
if (typeof nostrApi.nip04?.decrypt === "function") {
|
||||
registerDecryptor(
|
||||
@@ -1038,7 +1044,7 @@ class UserBlockListManager {
|
||||
(payload) =>
|
||||
runNip07WithRetry(
|
||||
() => nostrApi.nip04.decrypt(normalized, payload),
|
||||
{ label: "nip04.decrypt", priority: NIP07_PRIORITY.HIGH },
|
||||
{ label: "nip04.decrypt", ...decrypterOptions },
|
||||
),
|
||||
"extension",
|
||||
);
|
||||
@@ -1055,7 +1061,7 @@ class UserBlockListManager {
|
||||
(payload) =>
|
||||
runNip07WithRetry(() => nip44.decrypt(normalized, payload), {
|
||||
label: "nip44.decrypt",
|
||||
priority: NIP07_PRIORITY.HIGH,
|
||||
...decrypterOptions,
|
||||
}),
|
||||
"extension",
|
||||
);
|
||||
@@ -1069,7 +1075,7 @@ class UserBlockListManager {
|
||||
(payload) =>
|
||||
runNip07WithRetry(() => nip44v2.decrypt(normalized, payload), {
|
||||
label: "nip44.v2.decrypt",
|
||||
priority: NIP07_PRIORITY.HIGH,
|
||||
...decrypterOptions,
|
||||
}),
|
||||
"extension",
|
||||
);
|
||||
@@ -1079,7 +1085,7 @@ class UserBlockListManager {
|
||||
(payload) =>
|
||||
runNip07WithRetry(
|
||||
() => nip44v2.decrypt(normalized, payload),
|
||||
{ label: "nip44.v2.decrypt", priority: NIP07_PRIORITY.HIGH },
|
||||
{ label: "nip44.v2.decrypt", ...decrypterOptions },
|
||||
),
|
||||
"extension",
|
||||
);
|
||||
|
||||
@@ -117,6 +117,57 @@ await (async () => {
|
||||
assert.deepEqual(detail.profile, { name: "Test User" });
|
||||
})();
|
||||
|
||||
await (async () => {
|
||||
resetState();
|
||||
setPubkey(SAMPLE_PUBKEY);
|
||||
|
||||
const calls = [];
|
||||
// We leave resolveBlocks undefined/pending forever to simulate slow/hanging blocks
|
||||
let resolveBlocks;
|
||||
|
||||
const service = new AuthService({
|
||||
userBlocks: {
|
||||
loadBlocks: () => {
|
||||
calls.push("blocks:start");
|
||||
return new Promise((resolve) => {
|
||||
resolveBlocks = resolve;
|
||||
});
|
||||
},
|
||||
},
|
||||
relayManager: {
|
||||
loadRelayList: () => {
|
||||
calls.push("relays:start");
|
||||
return Promise.resolve("relays");
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
service.loadOwnProfile = () => {
|
||||
calls.push("profile:start");
|
||||
return Promise.resolve({ name: "Test User" });
|
||||
};
|
||||
|
||||
// Test deferBlocks: true
|
||||
const promise = service.applyPostLoginState({ deferBlocks: true });
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 10));
|
||||
|
||||
// Blocks should NOT be started if deferred
|
||||
// Wait, deferBlocks just means it's not awaited in completionPromise?
|
||||
// No, checking code:
|
||||
// if (!deferBlocks) { const blocksOperation = this.createBlocksLoadOperation... }
|
||||
// So it shouldn't even be called/pushed to concurrentOps.
|
||||
|
||||
assert.deepEqual(calls, ["relays:start", "profile:start"]);
|
||||
|
||||
const result = await promise;
|
||||
// This should resolve even if blocks are not loaded
|
||||
await result.completionPromise;
|
||||
|
||||
assert.equal(result.detail.blocksLoaded, null);
|
||||
assert.equal(result.detail.relaysLoaded, true);
|
||||
})();
|
||||
|
||||
await (async () => {
|
||||
resetState();
|
||||
setPubkey(SAMPLE_PUBKEY);
|
||||
|
||||
Reference in new issue
Block a user