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