APP-Backend / src /views /auth /auth-view.js
Luca448's picture
Feature: Add Supabase Zero-Knowledge E2E Account Sync
3ed9766
Raw History Blame Contribute Delete
5.42 kB
import { authService } from '../../services/auth-service.js';
export class AuthView {
constructor(onSuccess) {
this.onSuccess = onSuccess;
this.container = document.createElement('div');
this.container.className = 'auth-modal-overlay';
this.isLogin = true;
}
show() {
document.body.appendChild(this.container);
// Add CSS globally if not exists
if (!document.getElementById('auth-styles')) {
const style = document.createElement('style');
style.id = 'auth-styles';
style.innerHTML = `
.auth-modal-overlay {
position: fixed; top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0, 0, 0, 0.7);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
z-index: 99999;
display: flex; align-items: center; justify-content: center;
padding: 24px;
animation: fade-in 0.3s ease;
}
.auth-modal {
background: rgba(20, 20, 25, 0.8);
border: 1px solid rgba(255, 255, 255, 0.1);
border-radius: 24px;
padding: 32px;
width: 100%; max-width: 400px;
box-shadow: 0 24px 64px rgba(0,0,0,0.4);
}
.auth-input {
width: 100%; padding: 14px 16px;
background: rgba(0,0,0,0.3); border: 1px solid rgba(255,255,255,0.1);
border-radius: 12px; color: white; font-size: 16px;
margin-bottom: 16px; outline: none; transition: border-color 0.2s;
}
.auth-input:focus { border-color: var(--primary-accent); }
.auth-btn {
width: 100%; padding: 16px; border-radius: 12px;
background: var(--primary-accent); color: white;
font-weight: 600; font-size: 16px; border: none; cursor: pointer;
margin-bottom: 16px; transition: transform 0.1s, opacity 0.2s;
}
.auth-btn:active { transform: scale(0.98); }
.auth-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.auth-switch {
text-align: center; color: var(--text-secondary); font-size: 14px;
}
.auth-switch span { color: var(--primary-accent); cursor: pointer; font-weight: 500; }
.auth-error { color: #ff453a; font-size: 14px; margin-bottom: 16px; text-align: center; }
`;
document.head.appendChild(style);
}
this.render();
}
hide() {
this.container.remove();
}
render() {
this.container.innerHTML = `
<div class="auth-modal">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 24px;">
<h2 style="font-size: 24px; margin: 0;">${this.isLogin ? 'Anmelden' : 'Registrieren'}</h2>
<button class="close-auth-btn" style="background: none; border: none; color: var(--text-secondary); cursor: pointer;">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>
</button>
</div>
<p style="color: var(--text-secondary); font-size: 14px; line-height: 1.5; margin-bottom: 24px;">
Dein Passwort wird lokal verwendet, um deine API Keys mit Zero-Knowledge AES-256 zu verschlüsseln. Niemand außer dir kann deine Daten lesen.
</p>
<form id="auth-form">
<input type="email" id="auth-email" class="auth-input" placeholder="E-Mail Adresse" required autocomplete="username">
<input type="password" id="auth-password" class="auth-input" placeholder="Passwort (Master Key)" required autocomplete="current-password" minlength="6">
<div id="auth-error" class="auth-error"></div>
<button type="submit" id="auth-submit-btn" class="auth-btn">${this.isLogin ? 'Sicher Anmelden' : 'Account erstellen'}</button>
</form>
<div class="auth-switch">
${this.isLogin ? 'Noch kein Account?' : 'Bereits einen Account?'}
<span id="auth-switch-btn">${this.isLogin ? 'Hier registrieren' : 'Hier anmelden'}</span>
</div>
</div>
`;
this.attachEvents();
}
attachEvents() {
this.container.querySelector('.close-auth-btn').addEventListener('click', () => this.hide());
this.container.querySelector('#auth-switch-btn').addEventListener('click', () => {
this.isLogin = !this.isLogin;
this.render();
});
const form = this.container.querySelector('#auth-form');
form.addEventListener('submit', async (e) => {
e.preventDefault();
const email = form.querySelector('#auth-email').value;
const password = form.querySelector('#auth-password').value;
const btn = form.querySelector('#auth-submit-btn');
const errorDiv = form.querySelector('#auth-error');
btn.disabled = true;
btn.textContent = 'Verschlüssele & Lade...';
errorDiv.textContent = '';
try {
if (this.isLogin) {
await authService.signIn(email, password);
} else {
await authService.signUp(email, password);
}
this.hide();
if (this.onSuccess) this.onSuccess();
} catch (err) {
errorDiv.textContent = err.message || 'Ein Fehler ist aufgetreten.';
btn.disabled = false;
btn.textContent = this.isLogin ? 'Sicher Anmelden' : 'Account erstellen';
}
});
}
}