parent
79e65e3860
commit
727064aafb
7
client/package-lock.json
generated
7
client/package-lock.json
generated
@ -9,6 +9,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"jsqr": "^1.4.0",
|
||||||
"nostr-login": "^1.7.11",
|
"nostr-login": "^1.7.11",
|
||||||
"nostr-tools": "^2.12.0",
|
"nostr-tools": "^2.12.0",
|
||||||
"qrcode": "^1.5.4",
|
"qrcode": "^1.5.4",
|
||||||
@ -5311,6 +5312,12 @@
|
|||||||
"json5": "lib/cli.js"
|
"json5": "lib/cli.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jsqr": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsqr/-/jsqr-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-dxLob7q65Xg2DvstYkRpkYtmKm2sPJ9oFhrhmudT1dZvNFFTlroai3AWSpLey/w5vMcLBXRgOJsbXpdN9HzU/A==",
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
"node_modules/keyv": {
|
"node_modules/keyv": {
|
||||||
"version": "4.5.4",
|
"version": "4.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||||
|
@ -93,12 +93,16 @@ export async function loginWithNostrLogin(): Promise<string | null> {
|
|||||||
executePostAuthQueue();
|
executePostAuthQueue();
|
||||||
|
|
||||||
return result.pubkey;
|
return result.pubkey;
|
||||||
|
} else if (result.error) {
|
||||||
|
// If we have a specific error message from the authentication service
|
||||||
|
console.error("Authentication failed with message:", result.error);
|
||||||
|
throw new Error(result.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error using Nostr login:", error);
|
console.error("Error using Nostr login:", error);
|
||||||
return null;
|
throw error; // Rethrow to allow the caller to handle specific error messages
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,11 +52,27 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
updateUIBasedOnAuth();
|
updateUIBasedOnAuth();
|
||||||
} else {
|
} else {
|
||||||
console.log('Login attempt failed, showing error');
|
console.log('Login attempt failed, showing error');
|
||||||
alert('Login failed. Please make sure you have a Nostr extension installed (like Alby or nos2x).');
|
alert('Login failed. Authentication with nostr-login was unsuccessful. Please check the console for error details.');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Authentication error:', error);
|
console.error('Authentication error:', error);
|
||||||
alert(`Authentication error: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
||||||
|
let errorMessage = 'Authentication error';
|
||||||
|
|
||||||
|
if (error instanceof Error) {
|
||||||
|
if (error.message.includes('Rejected') || error.message.includes('Cancelled')) {
|
||||||
|
errorMessage = 'Login was cancelled. Please try again when you are ready to authenticate.';
|
||||||
|
} else {
|
||||||
|
errorMessage = error.message;
|
||||||
|
}
|
||||||
|
} else if (error && typeof error === 'object' && 'error' in error) {
|
||||||
|
const errorValue = error.error;
|
||||||
|
errorMessage = typeof errorValue === 'string' ? errorValue : errorMessage;
|
||||||
|
} else {
|
||||||
|
errorMessage = String(error || 'Unknown error');
|
||||||
|
}
|
||||||
|
|
||||||
|
alert(errorMessage);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -271,7 +287,7 @@ async function handleConnectRelay(): Promise<void> {
|
|||||||
updateUIBasedOnAuth();
|
updateUIBasedOnAuth();
|
||||||
updateRelayStatus('Authentication successful. Connecting...', 'connecting');
|
updateRelayStatus('Authentication successful. Connecting...', 'connecting');
|
||||||
} else {
|
} else {
|
||||||
updateRelayStatus('Authentication failed. Please try again or install a Nostr extension like Alby or nos2x.', 'error');
|
updateRelayStatus('Authentication failed. Please try again. nostr-login authentication was unsuccessful.', 'error');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -17,6 +17,9 @@ import type { NostrRelayService } from './services/NostrRelayService';
|
|||||||
// Create a singleton instance of the client event store
|
// Create a singleton instance of the client event store
|
||||||
const clientEventStore = new ClientEventStore();
|
const clientEventStore = new ClientEventStore();
|
||||||
|
|
||||||
|
// Track events that have been published to avoid duplicates
|
||||||
|
const publishedEvents = new Set<string>();
|
||||||
|
|
||||||
// The table UI component (initialized in setup)
|
// The table UI component (initialized in setup)
|
||||||
let clientEventsTable: ClientEventsTable | null = null;
|
let clientEventsTable: ClientEventsTable | null = null;
|
||||||
|
|
||||||
@ -216,12 +219,46 @@ export function trackOutgoingEvent(event: NostrEvent): string | null {
|
|||||||
console.warn(`Expected KIND 21120 event, got ${event.kind}`);
|
console.warn(`Expected KIND 21120 event, got ${event.kind}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if this event is already tracked
|
||||||
|
const existingEvent = clientEventStore.getEvent(event.id);
|
||||||
|
if (existingEvent) {
|
||||||
|
console.log(`Event ${event.id} is already being tracked, not adding again`);
|
||||||
|
return event.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this event has already been published
|
||||||
|
if (publishedEvents.has(event.id)) {
|
||||||
|
console.log(`Event ${event.id} has already been published, not adding again`);
|
||||||
|
return event.id;
|
||||||
|
}
|
||||||
|
|
||||||
// Add to the store
|
// Add to the store
|
||||||
const eventId = clientEventStore.addOutgoingEvent(event);
|
const eventId = clientEventStore.addOutgoingEvent(event);
|
||||||
console.log(`Tracked outgoing event: ${eventId}`);
|
console.log(`Tracked outgoing event: ${eventId}`);
|
||||||
return eventId;
|
return eventId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark an event as published to prevent duplicate publishing
|
||||||
|
* @param eventId The ID of the event that was published
|
||||||
|
*/
|
||||||
|
export function markEventAsPublished(eventId: string): void {
|
||||||
|
if (!eventId) return;
|
||||||
|
|
||||||
|
// Add to the set of published events
|
||||||
|
publishedEvents.add(eventId);
|
||||||
|
console.log(`Marked event ${eventId} as published`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an event has already been published
|
||||||
|
* @param eventId The ID of the event to check
|
||||||
|
* @returns True if the event has been published, false otherwise
|
||||||
|
*/
|
||||||
|
export function isEventPublished(eventId: string): boolean {
|
||||||
|
return publishedEvents.has(eventId);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle a pending 21120 event before it's published
|
* Handle a pending 21120 event before it's published
|
||||||
* @param event The event being prepared
|
* @param event The event being prepared
|
||||||
|
@ -41,7 +41,9 @@ import {
|
|||||||
initClientEventHandler,
|
initClientEventHandler,
|
||||||
trackOutgoingEvent,
|
trackOutgoingEvent,
|
||||||
handleIncomingResponse,
|
handleIncomingResponse,
|
||||||
reconnectRelayService
|
reconnectRelayService,
|
||||||
|
markEventAsPublished,
|
||||||
|
isEventPublished
|
||||||
} from './client-event-handler';
|
} from './client-event-handler';
|
||||||
import type { NostrEvent } from './converter';
|
import type { NostrEvent } from './converter';
|
||||||
// Import functions from internal modules
|
// Import functions from internal modules
|
||||||
@ -609,10 +611,35 @@ function initNostrLogin(): void {
|
|||||||
authManager.setAuthenticated(true, pubkey);
|
authManager.setAuthenticated(true, pubkey);
|
||||||
}
|
}
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.warn("Not currently connected to Nostr extension:", err);
|
console.warn("Not currently connected to Nostr provider:", err);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.warn("Nostr extension not available");
|
console.warn("Nostr provider not available. Using nostr-login if available.");
|
||||||
|
|
||||||
|
// Try to use nostr-login library if available
|
||||||
|
if (NostrLogin) {
|
||||||
|
try {
|
||||||
|
console.log("Using nostr-login in initNostrLogin");
|
||||||
|
const nostrLogin = new NostrLogin();
|
||||||
|
|
||||||
|
nostrLogin.getPublicKey().then((pubkey: string) => {
|
||||||
|
if (pubkey) {
|
||||||
|
console.log(`Found pubkey from nostr-login: ${pubkey.slice(0, 8)}...`);
|
||||||
|
// Update UI to show pubkey
|
||||||
|
updateClientPubkeyDisplay(pubkey);
|
||||||
|
|
||||||
|
// Update auth state in the service
|
||||||
|
authManager.setAuthenticated(true, pubkey);
|
||||||
|
}
|
||||||
|
}).catch((err: Error) => {
|
||||||
|
console.warn("Not currently connected to nostr-login:", err);
|
||||||
|
});
|
||||||
|
} catch (nostrLoginError) {
|
||||||
|
console.error('nostr-login error:', nostrLoginError);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn("No Nostr provider available");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||||
@ -651,11 +678,9 @@ async function ensureAuthenticated(): Promise<boolean> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not authenticated, check if extension is available
|
// Not authenticated, try to use nostr-login or extension
|
||||||
if (!window.nostr) {
|
// We no longer need to check window.nostr because loginWithNostrLogin handles that
|
||||||
console.warn("Nostr extension not available");
|
console.log("No active authentication, attempting to authenticate with nostr-login...");
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Try to get the user's public key
|
// Try to get the user's public key
|
||||||
@ -698,6 +723,12 @@ async function handlePublishEvent(): Promise<void> {
|
|||||||
showLoading(publishResultDiv, 'Publishing to relay...');
|
showLoading(publishResultDiv, 'Publishing to relay...');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Check if this event has already been published
|
||||||
|
if (event.id && isEventPublished(event.id)) {
|
||||||
|
showSuccess(publishResultDiv, "Event was already published, not sending duplicate");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Track the event before publishing
|
// Track the event before publishing
|
||||||
console.log('Tracking outgoing event:', event.id);
|
console.log('Tracking outgoing event:', event.id);
|
||||||
trackOutgoingEvent(event);
|
trackOutgoingEvent(event);
|
||||||
@ -705,6 +736,12 @@ async function handlePublishEvent(): Promise<void> {
|
|||||||
// Publish the event
|
// Publish the event
|
||||||
console.log('Publishing event to relay:', relayUrl);
|
console.log('Publishing event to relay:', relayUrl);
|
||||||
const result = await publishToRelay(event, relayUrl);
|
const result = await publishToRelay(event, relayUrl);
|
||||||
|
|
||||||
|
// Mark the event as published to prevent duplicates
|
||||||
|
if (event.id) {
|
||||||
|
markEventAsPublished(event.id);
|
||||||
|
}
|
||||||
|
|
||||||
showSuccess(publishResultDiv, result);
|
showSuccess(publishResultDiv, result);
|
||||||
|
|
||||||
// Force reconnect to ensure we're subscribed for the response
|
// Force reconnect to ensure we're subscribed for the response
|
||||||
@ -782,6 +819,12 @@ async function handlePublishEvent(): Promise<void> {
|
|||||||
publishResultDiv.innerHTML += '<br><span>Attempting to publish...</span>';
|
publishResultDiv.innerHTML += '<br><span>Attempting to publish...</span>';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Check if this event has already been published
|
||||||
|
if (event.id && isEventPublished(event.id)) {
|
||||||
|
showSuccess(publishResultDiv, "Event was already published, not sending duplicate");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Track the event in our client store
|
// Track the event in our client store
|
||||||
console.log('Tracking outgoing event:', event.id);
|
console.log('Tracking outgoing event:', event.id);
|
||||||
trackOutgoingEvent(event);
|
trackOutgoingEvent(event);
|
||||||
@ -789,6 +832,12 @@ async function handlePublishEvent(): Promise<void> {
|
|||||||
// Publish the event
|
// Publish the event
|
||||||
console.log('Publishing event to relay:', relayUrl);
|
console.log('Publishing event to relay:', relayUrl);
|
||||||
const result = await publishToRelay(event, relayUrl);
|
const result = await publishToRelay(event, relayUrl);
|
||||||
|
|
||||||
|
// Mark the event as published to prevent duplicates
|
||||||
|
if (event.id) {
|
||||||
|
markEventAsPublished(event.id);
|
||||||
|
}
|
||||||
|
|
||||||
showSuccess(publishResultDiv, result);
|
showSuccess(publishResultDiv, result);
|
||||||
|
|
||||||
// Force reconnect to ensure we're subscribed for the response
|
// Force reconnect to ensure we're subscribed for the response
|
||||||
@ -1595,12 +1644,32 @@ document.addEventListener('DOMContentLoaded', function(): void {
|
|||||||
|
|
||||||
// Try to get pubkey again after DOM is ready
|
// Try to get pubkey again after DOM is ready
|
||||||
if (window.nostr) {
|
if (window.nostr) {
|
||||||
window.nostr.getPublicKey().then(pubkey => {
|
window.nostr.getPublicKey().then((pubkey: string) => {
|
||||||
console.log(`DOM ready: Retrieved pubkey: ${pubkey.slice(0, 8)}...`);
|
console.log(`DOM ready: Retrieved pubkey from extension: ${pubkey.slice(0, 8)}...`);
|
||||||
localStorage.setItem('userPublicKey', pubkey);
|
localStorage.setItem('userPublicKey', pubkey);
|
||||||
}).catch(err => {
|
}).catch((err: Error) => {
|
||||||
console.warn("DOM ready: Failed to get pubkey:", err);
|
console.warn("DOM ready: Failed to get pubkey from extension:", err);
|
||||||
});
|
});
|
||||||
|
} else if (NostrLogin) {
|
||||||
|
// Try to use nostr-login if window.nostr is not available
|
||||||
|
try {
|
||||||
|
console.log("DOM ready: Using nostr-login to get pubkey");
|
||||||
|
const nostrLogin = new NostrLogin();
|
||||||
|
|
||||||
|
nostrLogin.getPublicKey().then((pubkey: string) => {
|
||||||
|
if (pubkey) {
|
||||||
|
console.log(`DOM ready: Retrieved pubkey from nostr-login: ${pubkey.slice(0, 8)}...`);
|
||||||
|
localStorage.setItem('userPublicKey', pubkey);
|
||||||
|
updateClientPubkeyDisplay(pubkey);
|
||||||
|
}
|
||||||
|
}).catch((err: Error) => {
|
||||||
|
console.warn("DOM ready: Failed to get pubkey from nostr-login:", err);
|
||||||
|
});
|
||||||
|
} catch (nostrLoginError) {
|
||||||
|
console.error('DOM ready: nostr-login error:', nostrLoginError);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn("DOM ready: No Nostr provider available");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set default HTTP request
|
// Set default HTTP request
|
||||||
|
@ -190,7 +190,7 @@ export class Nostr21121Creator {
|
|||||||
|
|
||||||
// Always add reference to the request event
|
// Always add reference to the request event
|
||||||
if (requestEvent.id) {
|
if (requestEvent.id) {
|
||||||
tags.push(['e', requestEvent.id, '', 'reply']);
|
tags.push(['e', requestEvent.id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add kind reference
|
// Add kind reference
|
||||||
|
@ -438,6 +438,12 @@ if (publishRelayInput) {
|
|||||||
|
|
||||||
// Import the tracking function from client-event-handler
|
// Import the tracking function from client-event-handler
|
||||||
import('./client-event-handler').then(module => {
|
import('./client-event-handler').then(module => {
|
||||||
|
// Check if this event is already published
|
||||||
|
if (signedEvent.id && module.isEventPublished(signedEvent.id)) {
|
||||||
|
showSuccess(publishResult, "Event was already published, not sending duplicate");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Track the event before publishing
|
// Track the event before publishing
|
||||||
try {
|
try {
|
||||||
module.trackOutgoingEvent(signedEvent);
|
module.trackOutgoingEvent(signedEvent);
|
||||||
@ -449,6 +455,10 @@ if (publishRelayInput) {
|
|||||||
// Publish the event using the publishToRelay function
|
// Publish the event using the publishToRelay function
|
||||||
publishToRelay(signedEvent, relayUrl)
|
publishToRelay(signedEvent, relayUrl)
|
||||||
.then((result: string) => {
|
.then((result: string) => {
|
||||||
|
// Mark the event as published to prevent duplicates
|
||||||
|
if (signedEvent.id) {
|
||||||
|
module.markEventAsPublished(signedEvent.id);
|
||||||
|
}
|
||||||
showSuccess(publishResult, result);
|
showSuccess(publishResult, result);
|
||||||
})
|
})
|
||||||
.catch((error: Error) => {
|
.catch((error: Error) => {
|
||||||
@ -685,16 +695,10 @@ if (publishRelayInput) {
|
|||||||
|
|
||||||
// Initialize event listeners when the DOM is fully loaded
|
// Initialize event listeners when the DOM is fully loaded
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
// Set up the click event handler without any automatic encryption
|
// The Convert button event listener is already set in client.ts
|
||||||
const convertButton = document.getElementById('convertButton');
|
// so we don't set it here to avoid duplicate calls and double events
|
||||||
const publishButton = document.getElementById('publishButton');
|
const publishButton = document.getElementById('publishButton');
|
||||||
|
|
||||||
if (convertButton) {
|
|
||||||
convertButton.addEventListener('click', (): void => {
|
|
||||||
void displayConvertedEvent();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add a handler for the publish button to check if an event is available
|
// Add a handler for the publish button to check if an event is available
|
||||||
if (publishButton) {
|
if (publishButton) {
|
||||||
publishButton.addEventListener('click', (): void => {
|
publishButton.addEventListener('click', (): void => {
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* Stateless authentication service that directly uses the Nostr extension.
|
* Stateless authentication service that directly uses the Nostr extension.
|
||||||
* Removed all localStorage and session dependencies.
|
* Removed all localStorage and session dependencies.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type * as nostrTools from 'nostr-tools';
|
import type * as nostrTools from 'nostr-tools';
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for authentication operation results
|
* Interface for authentication operation results
|
||||||
*/
|
*/
|
||||||
@ -64,32 +64,122 @@ export class AuthenticationService {
|
|||||||
*/
|
*/
|
||||||
public async authenticate(): Promise<AuthResult> {
|
public async authenticate(): Promise<AuthResult> {
|
||||||
try {
|
try {
|
||||||
// Check if a Nostr extension is available
|
console.log("AuthenticationService: Using nostr-login for authentication");
|
||||||
if (!window.nostr) {
|
|
||||||
return {
|
// Try to use nostr-login library if available
|
||||||
success: false,
|
const nostrLoginModule = typeof require !== 'undefined' ? require('nostr-login') : null;
|
||||||
error: 'Nostr extension not found. Please install Alby or nos2x.'
|
|
||||||
};
|
if (nostrLoginModule && nostrLoginModule.init) {
|
||||||
|
try {
|
||||||
|
console.log("nostr-login loaded, initializing...");
|
||||||
|
|
||||||
|
// Initialize nostr-login which sets up window.nostr
|
||||||
|
await nostrLoginModule.init({
|
||||||
|
// Options for nostr-login
|
||||||
|
darkMode: document.body.getAttribute('data-theme') === 'dark',
|
||||||
|
noBanner: true, // Don't show the banner
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("nostr-login initialized, window.nostr should be available");
|
||||||
|
|
||||||
|
// Check if window.nostr was successfully set up
|
||||||
|
if (window.nostr) {
|
||||||
|
console.log("Attempting to get pubkey through window.nostr...");
|
||||||
|
// Get pubkey through window.nostr
|
||||||
|
const pubkey = await window.nostr.getPublicKey();
|
||||||
|
console.log("window.nostr.getPublicKey returned:", pubkey);
|
||||||
|
|
||||||
|
if (pubkey) {
|
||||||
|
console.log(`Authentication successful with pubkey: ${pubkey.substring(0, 8)}...`);
|
||||||
|
// Cache the pubkey in memory
|
||||||
|
this.cachedPubkey = pubkey;
|
||||||
|
|
||||||
|
// Notify listeners of authentication change
|
||||||
|
this.notifyAuthStateChanged(true, pubkey);
|
||||||
|
|
||||||
|
// Set the global nostrPubkey for backwards compatibility with existing code
|
||||||
|
if (window) {
|
||||||
|
window.nostrPubkey = pubkey;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
pubkey
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('nostr-login initialized but window.nostr is not available');
|
||||||
|
}
|
||||||
|
} catch (nostrLoginError) {
|
||||||
|
console.error('nostr-login error:', nostrLoginError);
|
||||||
|
console.error('nostr-login stack:', nostrLoginError instanceof Error ? nostrLoginError.stack : 'No stack available');
|
||||||
|
console.error('nostr-login error details:', JSON.stringify(nostrLoginError));
|
||||||
|
|
||||||
|
// Check for specific error types
|
||||||
|
const errorMessage = nostrLoginError instanceof Error ? nostrLoginError.message : String(nostrLoginError);
|
||||||
|
|
||||||
|
if (errorMessage.includes('Already started')) {
|
||||||
|
console.warn('nostr-login was already initialized, this is usually not a problem');
|
||||||
|
// Continue with window.nostr if it's available despite the "Already started" error
|
||||||
|
if (window.nostr) {
|
||||||
|
try {
|
||||||
|
console.log("nostr-login already initialized, using window.nostr directly");
|
||||||
|
const pubkey = await window.nostr.getPublicKey();
|
||||||
|
if (pubkey) {
|
||||||
|
console.log(`Authentication successful with pubkey: ${pubkey.substring(0, 8)}...`);
|
||||||
|
this.cachedPubkey = pubkey;
|
||||||
|
this.notifyAuthStateChanged(true, pubkey);
|
||||||
|
if (window) {
|
||||||
|
window.nostrPubkey = pubkey;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
pubkey
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (directNostrError) {
|
||||||
|
console.error('Direct window.nostr error:', directNostrError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (errorMessage.includes('Rejected by user') || errorMessage.includes('Cancelled')) {
|
||||||
|
console.warn('User rejected or cancelled the nostr-login authentication');
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
error: 'Authentication was cancelled by the user. Please try again.'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// Fall back to window.nostr if NostrLogin fails for other reasons
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Directly request the public key from the Nostr extension
|
// Fall back to window.nostr if NostrLogin is not available
|
||||||
const pubkey = await window.nostr.getPublicKey();
|
if (window.nostr) {
|
||||||
|
console.log("Falling back to window.nostr");
|
||||||
if (pubkey) {
|
|
||||||
// Cache the pubkey in memory
|
|
||||||
this.cachedPubkey = pubkey;
|
|
||||||
|
|
||||||
// Notify listeners of authentication change
|
// Directly request the public key from the Nostr extension
|
||||||
this.notifyAuthStateChanged(true, pubkey);
|
const pubkey = await window.nostr.getPublicKey();
|
||||||
|
|
||||||
// Set the global nostrPubkey for backwards compatibility with existing code
|
if (pubkey) {
|
||||||
if (window) {
|
// Cache the pubkey in memory
|
||||||
window.nostrPubkey = pubkey;
|
this.cachedPubkey = pubkey;
|
||||||
|
|
||||||
|
// Notify listeners of authentication change
|
||||||
|
this.notifyAuthStateChanged(true, pubkey);
|
||||||
|
|
||||||
|
// Set the global nostrPubkey for backwards compatibility with existing code
|
||||||
|
if (window) {
|
||||||
|
window.nostrPubkey = pubkey;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
pubkey
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: false,
|
||||||
pubkey
|
error: 'Authentication failed. No Nostr provider found.'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,9 +209,52 @@ export class AuthenticationService {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// No cached pubkey, try to get it from the extension
|
// Try to use nostr-login library if available
|
||||||
|
const nostrLoginModule = typeof require !== 'undefined' ? require('nostr-login') : null;
|
||||||
|
|
||||||
|
if (nostrLoginModule && nostrLoginModule.init) {
|
||||||
|
try {
|
||||||
|
console.log("Using nostr-login to check authentication");
|
||||||
|
|
||||||
|
// Initialize nostr-login which sets up window.nostr
|
||||||
|
await nostrLoginModule.init({
|
||||||
|
darkMode: document.body.getAttribute('data-theme') === 'dark',
|
||||||
|
noBanner: true, // Don't show the banner
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("nostr-login initialized for auth check, window.nostr should be available");
|
||||||
|
|
||||||
|
// Check if window.nostr was successfully set up
|
||||||
|
if (window.nostr) {
|
||||||
|
console.log("Attempting to get pubkey through window.nostr for auth check...");
|
||||||
|
// Get pubkey through window.nostr
|
||||||
|
const pubkey = await window.nostr.getPublicKey();
|
||||||
|
console.log("window.nostr.getPublicKey returned for auth check:", pubkey);
|
||||||
|
|
||||||
|
if (pubkey) {
|
||||||
|
console.log(`Authentication check successful with pubkey: ${pubkey.substring(0, 8)}...`);
|
||||||
|
this.cachedPubkey = pubkey;
|
||||||
|
// Set the global nostrPubkey for backwards compatibility
|
||||||
|
if (window) {
|
||||||
|
window.nostrPubkey = pubkey;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('nostr-login initialized but window.nostr is not available for auth check');
|
||||||
|
}
|
||||||
|
} catch (nostrLoginError) {
|
||||||
|
console.error('Failed to get pubkey from nostr-login:', nostrLoginError);
|
||||||
|
console.error('nostr-login stack:', nostrLoginError instanceof Error ? nostrLoginError.stack : 'No stack available');
|
||||||
|
console.error('nostr-login error details:', JSON.stringify(nostrLoginError));
|
||||||
|
// Fall back to window.nostr if NostrLogin fails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to window.nostr if NostrLogin is not available
|
||||||
if (window.nostr) {
|
if (window.nostr) {
|
||||||
try {
|
try {
|
||||||
|
console.log("Falling back to window.nostr to check authentication");
|
||||||
const pubkey = await window.nostr.getPublicKey();
|
const pubkey = await window.nostr.getPublicKey();
|
||||||
if (pubkey) {
|
if (pubkey) {
|
||||||
this.cachedPubkey = pubkey;
|
this.cachedPubkey = pubkey;
|
||||||
@ -163,12 +296,52 @@ export class AuthenticationService {
|
|||||||
public async getPubkey(): Promise<string | null> {
|
public async getPubkey(): Promise<string | null> {
|
||||||
// If we have a cached pubkey, return it
|
// If we have a cached pubkey, return it
|
||||||
if (this.cachedPubkey) {
|
if (this.cachedPubkey) {
|
||||||
|
console.log(`Using cached pubkey: ${this.cachedPubkey.substring(0, 8)}...`);
|
||||||
return this.cachedPubkey;
|
return this.cachedPubkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to get pubkey from extension
|
// Try to use nostr-login library if available
|
||||||
|
const nostrLoginModule = typeof require !== 'undefined' ? require('nostr-login') : null;
|
||||||
|
|
||||||
|
if (nostrLoginModule && nostrLoginModule.init) {
|
||||||
|
try {
|
||||||
|
console.log("Using nostr-login to get pubkey");
|
||||||
|
|
||||||
|
// Initialize nostr-login which sets up window.nostr
|
||||||
|
await nostrLoginModule.init({
|
||||||
|
darkMode: document.body.getAttribute('data-theme') === 'dark',
|
||||||
|
noBanner: true, // Don't show the banner
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("nostr-login initialized in getPubkey, window.nostr should be available");
|
||||||
|
|
||||||
|
// Check if window.nostr was successfully set up
|
||||||
|
if (window.nostr) {
|
||||||
|
console.log("Attempting to get pubkey through window.nostr in getPubkey...");
|
||||||
|
// Get pubkey through window.nostr
|
||||||
|
const pubkey = await window.nostr.getPublicKey();
|
||||||
|
console.log("window.nostr.getPublicKey returned in getPubkey:", pubkey);
|
||||||
|
|
||||||
|
if (pubkey) {
|
||||||
|
console.log(`getPubkey successful with: ${pubkey.substring(0, 8)}...`);
|
||||||
|
this.cachedPubkey = pubkey;
|
||||||
|
return pubkey;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error('nostr-login initialized but window.nostr is not available in getPubkey');
|
||||||
|
}
|
||||||
|
} catch (nostrLoginError) {
|
||||||
|
console.error('Failed to get pubkey from nostr-login:', nostrLoginError);
|
||||||
|
console.error('NostrLogin stack:', nostrLoginError instanceof Error ? nostrLoginError.stack : 'No stack available');
|
||||||
|
console.error('NostrLogin error details:', JSON.stringify(nostrLoginError));
|
||||||
|
// Fall back to window.nostr if NostrLogin fails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to window.nostr if NostrLogin is not available
|
||||||
try {
|
try {
|
||||||
if (window.nostr) {
|
if (window.nostr) {
|
||||||
|
console.log("Falling back to window.nostr to get pubkey");
|
||||||
const pubkey = await window.nostr.getPublicKey();
|
const pubkey = await window.nostr.getPublicKey();
|
||||||
if (pubkey) {
|
if (pubkey) {
|
||||||
this.cachedPubkey = pubkey;
|
this.cachedPubkey = pubkey;
|
||||||
|
@ -96,7 +96,7 @@ export class Nostr21121Service {
|
|||||||
|
|
||||||
// Always add reference to the request event
|
// Always add reference to the request event
|
||||||
if (requestEvent.id) {
|
if (requestEvent.id) {
|
||||||
tags.push(['e', requestEvent.id, '']);
|
tags.push(['e', requestEvent.id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the pubkey of the request creator (client) for encryption
|
// Get the pubkey of the request creator (client) for encryption
|
||||||
|
@ -192,21 +192,41 @@ export class Nostr31120Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if window.nostr (Nostr browser extension) is available
|
// Try to use nostr-login library if available
|
||||||
if (!window.nostr) {
|
const NostrLogin = typeof require !== 'undefined' ? require('nostr-login') : null;
|
||||||
throw new Error('No Nostr browser extension found. Please install a NIP-07 compatible extension.');
|
let nostrProvider = null;
|
||||||
|
|
||||||
|
// Try nostr-login first
|
||||||
|
if (NostrLogin) {
|
||||||
|
try {
|
||||||
|
console.log("Using nostr-login in Nostr31120Service");
|
||||||
|
nostrProvider = new NostrLogin();
|
||||||
|
} catch (nostrLoginError) {
|
||||||
|
console.error('NostrLogin error:', nostrLoginError);
|
||||||
|
// Fall back to window.nostr
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get user's public key using the extension
|
// Fall back to window.nostr if nostr-login is not available
|
||||||
|
if (!nostrProvider && window.nostr) {
|
||||||
|
nostrProvider = window.nostr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we have a Nostr provider
|
||||||
|
if (!nostrProvider) {
|
||||||
|
throw new Error('No Nostr provider found. Authentication with nostr-login was unsuccessful.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get user's public key using the Nostr provider
|
||||||
let userPubkey: string;
|
let userPubkey: string;
|
||||||
try {
|
try {
|
||||||
userPubkey = await window.nostr!.getPublicKey();
|
userPubkey = await nostrProvider.getPublicKey();
|
||||||
if (!userPubkey) {
|
if (!userPubkey) {
|
||||||
throw new Error('Failed to get public key from Nostr extension');
|
throw new Error('Failed to get public key from Nostr provider');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error getting public key from Nostr extension:', error);
|
console.error('Error getting public key from Nostr provider:', error);
|
||||||
throw new Error('Failed to get your public key. Please make sure your Nostr extension is working.');
|
throw new Error('Failed to get your public key. Authentication with nostr-login was unsuccessful.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate or use a provided server pubkey
|
// Generate or use a provided server pubkey
|
||||||
@ -269,14 +289,14 @@ export class Nostr31120Service {
|
|||||||
content: content || 'HTTP-over-Nostr server',
|
content: content || 'HTTP-over-Nostr server',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sign the event using the browser extension
|
// Sign the event using the Nostr provider
|
||||||
let signedEvent: NostrEvent;
|
let signedEvent: NostrEvent;
|
||||||
try {
|
try {
|
||||||
signedEvent = await window.nostr!.signEvent(unsignedEvent);
|
signedEvent = await nostrProvider.signEvent(unsignedEvent);
|
||||||
console.log('Event signed successfully with Nostr extension');
|
console.log('Event signed successfully with Nostr provider');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error signing event with Nostr extension:', error);
|
console.error('Error signing event with Nostr provider:', error);
|
||||||
throw new Error('Failed to sign the event with your Nostr extension');
|
throw new Error('Failed to sign the event. Authentication with nostr-login was unsuccessful.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publish to relay
|
// Publish to relay
|
||||||
@ -362,14 +382,39 @@ export class Nostr31120Service {
|
|||||||
content: content || 'HTTP-over-Nostr server',
|
content: content || 'HTTP-over-Nostr server',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sign the event using the browser extension
|
// Sign the event using the Nostr provider
|
||||||
let signedEvent: NostrEvent;
|
let signedEvent: NostrEvent;
|
||||||
try {
|
try {
|
||||||
signedEvent = await window.nostr!.signEvent(unsignedEvent);
|
// Try to use nostr-login library if available
|
||||||
console.log('Event signed successfully with Nostr extension');
|
const NostrLogin = typeof require !== 'undefined' ? require('nostr-login') : null;
|
||||||
|
let nostrProvider = null;
|
||||||
|
|
||||||
|
// Try nostr-login first
|
||||||
|
if (NostrLogin) {
|
||||||
|
try {
|
||||||
|
console.log("Using nostr-login in processEventWithServerKey");
|
||||||
|
nostrProvider = new NostrLogin();
|
||||||
|
} catch (nostrLoginError) {
|
||||||
|
console.error('NostrLogin error:', nostrLoginError);
|
||||||
|
// Fall back to window.nostr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to window.nostr if nostr-login is not available
|
||||||
|
if (!nostrProvider && window.nostr) {
|
||||||
|
nostrProvider = window.nostr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if we have a Nostr provider
|
||||||
|
if (!nostrProvider) {
|
||||||
|
throw new Error('No Nostr provider found. Authentication with nostr-login was unsuccessful.');
|
||||||
|
}
|
||||||
|
|
||||||
|
signedEvent = await nostrProvider.signEvent(unsignedEvent);
|
||||||
|
console.log('Event signed successfully with Nostr provider');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error signing event with Nostr extension:', error);
|
console.error('Error signing event with Nostr provider:', error);
|
||||||
throw new Error('Failed to sign the event with your Nostr extension');
|
throw new Error('Failed to sign the event. Authentication with nostr-login was unsuccessful.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Publish to relay
|
// Publish to relay
|
||||||
|
46
package-lock.json
generated
46
package-lock.json
generated
@ -17,7 +17,6 @@
|
|||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
@ -26,7 +25,6 @@
|
|||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"color-convert": "^2.0.1"
|
"color-convert": "^2.0.1"
|
||||||
},
|
},
|
||||||
@ -41,7 +39,6 @@
|
|||||||
"version": "5.3.1",
|
"version": "5.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
|
||||||
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
"integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
@ -50,7 +47,6 @@
|
|||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
|
||||||
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
"integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"string-width": "^4.2.0",
|
"string-width": "^4.2.0",
|
||||||
"strip-ansi": "^6.0.0",
|
"strip-ansi": "^6.0.0",
|
||||||
@ -61,7 +57,6 @@
|
|||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"color-name": "~1.1.4"
|
"color-name": "~1.1.4"
|
||||||
},
|
},
|
||||||
@ -72,14 +67,12 @@
|
|||||||
"node_modules/color-name": {
|
"node_modules/color-name": {
|
||||||
"version": "1.1.4",
|
"version": "1.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||||
"license": "MIT"
|
|
||||||
},
|
},
|
||||||
"node_modules/decamelize": {
|
"node_modules/decamelize": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
|
||||||
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
|
"integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@ -87,20 +80,17 @@
|
|||||||
"node_modules/dijkstrajs": {
|
"node_modules/dijkstrajs": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
|
||||||
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==",
|
"integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
|
||||||
"license": "MIT"
|
|
||||||
},
|
},
|
||||||
"node_modules/emoji-regex": {
|
"node_modules/emoji-regex": {
|
||||||
"version": "8.0.0",
|
"version": "8.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
|
||||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
|
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||||
"license": "MIT"
|
|
||||||
},
|
},
|
||||||
"node_modules/find-up": {
|
"node_modules/find-up": {
|
||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
|
||||||
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"locate-path": "^5.0.0",
|
"locate-path": "^5.0.0",
|
||||||
"path-exists": "^4.0.0"
|
"path-exists": "^4.0.0"
|
||||||
@ -113,7 +103,6 @@
|
|||||||
"version": "2.0.5",
|
"version": "2.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
|
||||||
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "6.* || 8.* || >= 10.*"
|
"node": "6.* || 8.* || >= 10.*"
|
||||||
}
|
}
|
||||||
@ -122,7 +111,6 @@
|
|||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
@ -130,14 +118,12 @@
|
|||||||
"node_modules/jsqr": {
|
"node_modules/jsqr": {
|
||||||
"version": "1.4.0",
|
"version": "1.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/jsqr/-/jsqr-1.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/jsqr/-/jsqr-1.4.0.tgz",
|
||||||
"integrity": "sha512-dxLob7q65Xg2DvstYkRpkYtmKm2sPJ9oFhrhmudT1dZvNFFTlroai3AWSpLey/w5vMcLBXRgOJsbXpdN9HzU/A==",
|
"integrity": "sha512-dxLob7q65Xg2DvstYkRpkYtmKm2sPJ9oFhrhmudT1dZvNFFTlroai3AWSpLey/w5vMcLBXRgOJsbXpdN9HzU/A=="
|
||||||
"license": "Apache-2.0"
|
|
||||||
},
|
},
|
||||||
"node_modules/locate-path": {
|
"node_modules/locate-path": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
||||||
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"p-locate": "^4.1.0"
|
"p-locate": "^4.1.0"
|
||||||
},
|
},
|
||||||
@ -149,7 +135,6 @@
|
|||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||||
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"p-try": "^2.0.0"
|
"p-try": "^2.0.0"
|
||||||
},
|
},
|
||||||
@ -164,7 +149,6 @@
|
|||||||
"version": "4.1.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
|
||||||
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"p-limit": "^2.2.0"
|
"p-limit": "^2.2.0"
|
||||||
},
|
},
|
||||||
@ -176,7 +160,6 @@
|
|||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
|
||||||
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
"integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
@ -185,7 +168,6 @@
|
|||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
|
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
@ -194,7 +176,6 @@
|
|||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
|
||||||
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
|
"integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.13.0"
|
"node": ">=10.13.0"
|
||||||
}
|
}
|
||||||
@ -203,7 +184,6 @@
|
|||||||
"version": "1.5.4",
|
"version": "1.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz",
|
||||||
"integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==",
|
"integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dijkstrajs": "^1.0.1",
|
"dijkstrajs": "^1.0.1",
|
||||||
"pngjs": "^5.0.0",
|
"pngjs": "^5.0.0",
|
||||||
@ -220,7 +200,6 @@
|
|||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
|
||||||
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
@ -228,20 +207,17 @@
|
|||||||
"node_modules/require-main-filename": {
|
"node_modules/require-main-filename": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
|
||||||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
|
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
|
||||||
"license": "ISC"
|
|
||||||
},
|
},
|
||||||
"node_modules/set-blocking": {
|
"node_modules/set-blocking": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||||
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==",
|
"integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
|
||||||
"license": "ISC"
|
|
||||||
},
|
},
|
||||||
"node_modules/string-width": {
|
"node_modules/string-width": {
|
||||||
"version": "4.2.3",
|
"version": "4.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"emoji-regex": "^8.0.0",
|
"emoji-regex": "^8.0.0",
|
||||||
"is-fullwidth-code-point": "^3.0.0",
|
"is-fullwidth-code-point": "^3.0.0",
|
||||||
@ -255,7 +231,6 @@
|
|||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-regex": "^5.0.1"
|
"ansi-regex": "^5.0.1"
|
||||||
},
|
},
|
||||||
@ -266,14 +241,12 @@
|
|||||||
"node_modules/which-module": {
|
"node_modules/which-module": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.1.tgz",
|
||||||
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==",
|
"integrity": "sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ=="
|
||||||
"license": "ISC"
|
|
||||||
},
|
},
|
||||||
"node_modules/wrap-ansi": {
|
"node_modules/wrap-ansi": {
|
||||||
"version": "6.2.0",
|
"version": "6.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
|
||||||
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
"integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ansi-styles": "^4.0.0",
|
"ansi-styles": "^4.0.0",
|
||||||
"string-width": "^4.1.0",
|
"string-width": "^4.1.0",
|
||||||
@ -286,14 +259,12 @@
|
|||||||
"node_modules/y18n": {
|
"node_modules/y18n": {
|
||||||
"version": "4.0.3",
|
"version": "4.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
|
||||||
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==",
|
"integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
|
||||||
"license": "ISC"
|
|
||||||
},
|
},
|
||||||
"node_modules/yargs": {
|
"node_modules/yargs": {
|
||||||
"version": "15.4.1",
|
"version": "15.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
|
||||||
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
"integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cliui": "^6.0.0",
|
"cliui": "^6.0.0",
|
||||||
"decamelize": "^1.2.0",
|
"decamelize": "^1.2.0",
|
||||||
@ -315,7 +286,6 @@
|
|||||||
"version": "18.1.3",
|
"version": "18.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
|
||||||
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
"integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"camelcase": "^5.0.0",
|
"camelcase": "^5.0.0",
|
||||||
"decamelize": "^1.2.0"
|
"decamelize": "^1.2.0"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user