-
Notifications
You must be signed in to change notification settings - Fork 1
Implement Automatic NIP-98 HTTP Authentication #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
460b393
d58bea9
92570e9
fd3bc49
6721ae4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -12,9 +12,18 @@ import { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| addTrustedOrigin, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| getAutoSign | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } from './storage.js'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { sha256 } from '@noble/hashes/sha256'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { bytesToHex } from '@noble/hashes/utils'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log('[Podkey] Background service worker started'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // NIP-98 auth event cache: key = `${url}:${method}:${bodyHash}`, value = { event, expires } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const nip98Cache = new Map(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const CACHE_TTL = 60000; // 60 seconds | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Track retry state to prevent infinite loops: key = requestId, value = true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const retryState = new Map(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+25
to
+26
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const retryState = new Map(); | |
| const retryState = new Map(); | |
| const RETRY_STATE_TTL = 60000; // 60 seconds | |
| // Periodically clear retry state to avoid memory leaks and stale entries | |
| setInterval(() => { | |
| retryState.clear(); | |
| }, RETRY_STATE_TTL); |
Copilot
AI
Jan 5, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The btoa function in JavaScript only works with ASCII strings (characters 0-255). If the JSON event contains Unicode characters (e.g., in content or tags), btoa will throw an error "The string to be encoded contains characters outside of the Latin1 range."
Use a proper base64 encoding method that handles Unicode. You can either:
- First encode to UTF-8 bytes, then to base64
- Use a library function or TextEncoder with proper base64 conversion
Example fix: Convert the string to a Uint8Array first, then encode to base64 properly.
| * Encode signed event to Authorization header value | |
| * @param {object} signedEvent - Signed Nostr event | |
| * @returns {string} Base64-encoded event for Authorization header | |
| */ | |
| function encodeNip98Header (signedEvent) { | |
| const eventJson = JSON.stringify(signedEvent); | |
| // Use btoa for base64 encoding (available in service workers) | |
| return btoa(eventJson); | |
| * Encode a UTF-8 string to base64 safely (handles Unicode correctly) | |
| * @param {string} str | |
| * @returns {string} Base64-encoded string | |
| */ | |
| function utf8ToBase64 (str) { | |
| const bytes = new TextEncoder().encode(str); | |
| let binary = ''; | |
| for (let i = 0; i < bytes.length; i++) { | |
| binary += String.fromCharCode(bytes[i]); | |
| } | |
| return btoa(binary); | |
| } | |
| /** | |
| * Encode signed event to Authorization header value | |
| * @param {object} signedEvent - Signed Nostr event | |
| * @returns {string} Base64-encoded event for Authorization header | |
| */ | |
| function encodeNip98Header (signedEvent) { | |
| const eventJson = JSON.stringify(signedEvent); | |
| // Encode JSON as UTF-8 bytes before base64 to support Unicode content | |
| return utf8ToBase64(eventJson); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The cache does not implement any cleanup mechanism for expired entries. Over time, the nip98Cache Map will accumulate stale entries that are never removed, causing a memory leak.
Add periodic cleanup or implement lazy cleanup when checking cached entries. For example, you could add a cleanup function that runs periodically or check and remove expired entries when accessing the cache.