mirror of
https://github.com/HolgerHatGarKeineNode/einundzwanzig-app.git
synced 2026-01-24 12:03:17 +00:00
🔑 Implement LNURL-Auth support with error handling, frontend polling, and test coverage
- Added `LnurlAuthController` to handle LNURL authentication flow with signature verification, user creation, and session expiry checks. - Integrated authentication error polling in `nostrLogin.js`. - Added `LoginKeyFactory` for testing and database seed purposes. - Created feature tests (`LnurlAuthTest`) to validate LNURL callback, error responses, and session handling. - Extended `login.blade.php` with dynamic error handling and reset logic for expired sessions.
This commit is contained in:
@@ -1,9 +1,15 @@
|
||||
import {npubEncode} from "nostr-tools/nip19";
|
||||
|
||||
export default () => ({
|
||||
pollingInterval: null,
|
||||
errorCheckInterval: null,
|
||||
authErrorShown: false,
|
||||
startTime: null,
|
||||
pollCount: 0,
|
||||
MAX_POLL_COUNT: 30,
|
||||
|
||||
async init() {
|
||||
|
||||
this.startTime = Date.now();
|
||||
},
|
||||
|
||||
async openNostrLogin() {
|
||||
@@ -14,4 +20,78 @@ export default () => ({
|
||||
this.$dispatch('nostrLoggedIn', {pubkey: npub});
|
||||
},
|
||||
|
||||
initErrorPolling() {
|
||||
this.errorCheckInterval = setInterval(() => {
|
||||
this.checkForErrors();
|
||||
}, 4000);
|
||||
},
|
||||
|
||||
async checkForErrors() {
|
||||
if (this.authErrorShown) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const livewireComponent = this.$el.closest('[wire\\:id]')?.__livewire;
|
||||
if (!livewireComponent) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.pollCount++;
|
||||
const elapsedSeconds = Math.floor((Date.now() - this.startTime) / 1000);
|
||||
|
||||
const response = await fetch('/api/check-auth-error', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]')?.content,
|
||||
},
|
||||
body: JSON.stringify({
|
||||
k1: livewireComponent.entangle('k1')[0],
|
||||
elapsed_seconds: elapsedSeconds,
|
||||
}),
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
if (data.error) {
|
||||
this.showAuthError(data.error);
|
||||
this.authErrorShown = true;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error checking for auth errors:', error);
|
||||
}
|
||||
},
|
||||
|
||||
showAuthError(error) {
|
||||
let message = error || 'Authentication failed. Please try again.';
|
||||
let variant = 'danger';
|
||||
|
||||
if (message.includes('incompatible') || message.includes('format')) {
|
||||
message = 'Wallet signature format incompatible. Please try a different wallet.';
|
||||
variant = 'warning';
|
||||
} else if (message.includes('expired') || message.includes('Session')) {
|
||||
message = 'Session expired. Please try again.';
|
||||
variant = 'warning';
|
||||
}
|
||||
|
||||
if (window.Flux && window.Flux.toast) {
|
||||
window.Flux.toast({
|
||||
heading: 'Authentication Error',
|
||||
text: message,
|
||||
variant: variant,
|
||||
duration: 8000,
|
||||
});
|
||||
}
|
||||
|
||||
this.$dispatch('auth-error', {message, variant});
|
||||
},
|
||||
|
||||
destroy() {
|
||||
if (this.errorCheckInterval) {
|
||||
clearInterval(this.errorCheckInterval);
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user