v1.1: Rebrand Hinterstein Immobilien + echtes Auth-System
- Rebrand: Kunden-Logo, Joseph-Hinterstein-Portrait, Kontakt-Banner, Texte - Login-Pflicht auf /login (Route-Guard), Gruppen Verwaltung/Mieter - Mieter-Registrierung per einmaligem Registrierungscode - Benutzerverwaltung als 6. Modul (/benutzer, nur Verwaltung) - Demo-Zugänge mit Passwort 0815 (j.hinterstein, a.berger, m.wolf) - Mail-Server-API: Token-Auth (/send, X-Api-Token), Mail-Stack live auf Server - Store-Key hinterstein-mieterportal-v2, Doku (kimi.md, README) nachgeführt
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
/** Authentifizierung + Session, Muster aus dem Schulportal. */
|
||||
|
||||
import type { Benutzer, BenutzerRolle } from '../types'
|
||||
|
||||
export const SESSION_KEY = 'mp_benutzer_session'
|
||||
export const SESSION_DAUER_MS = 8 * 60 * 60 * 1000 // 8 h
|
||||
export const BENUTZER_CHANGED_EVENT = 'mp-benutzer-changed'
|
||||
|
||||
/** Demo-Passwort aller Demo-Benutzer (wie Schulportal sha256("0815")). */
|
||||
export const DEMO_PASSWORT = '0815'
|
||||
|
||||
export async function sha256(text: string): Promise<string> {
|
||||
const daten = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(text))
|
||||
return Array.from(new Uint8Array(daten))
|
||||
.map((b) => b.toString(16).padStart(2, '0'))
|
||||
.join('')
|
||||
}
|
||||
|
||||
export interface Session {
|
||||
benutzerId: string
|
||||
rolle: BenutzerRolle
|
||||
bis: number
|
||||
}
|
||||
|
||||
export function ladeSession(): Session | null {
|
||||
try {
|
||||
const raw = localStorage.getItem(SESSION_KEY)
|
||||
if (!raw) return null
|
||||
const s = JSON.parse(raw) as Session
|
||||
if (s.bis < Date.now()) {
|
||||
localStorage.removeItem(SESSION_KEY)
|
||||
return null
|
||||
}
|
||||
return s
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export function speichereSession(benutzerId: string, rolle: BenutzerRolle) {
|
||||
const s: Session = { benutzerId, rolle, bis: Date.now() + SESSION_DAUER_MS }
|
||||
localStorage.setItem(SESSION_KEY, JSON.stringify(s))
|
||||
window.dispatchEvent(new Event(BENUTZER_CHANGED_EVENT))
|
||||
}
|
||||
|
||||
export function beendeSession() {
|
||||
localStorage.removeItem(SESSION_KEY)
|
||||
window.dispatchEvent(new Event(BENUTZER_CHANGED_EVENT))
|
||||
}
|
||||
|
||||
export function aktuellerBenutzer(alle: Benutzer[]): Benutzer | null {
|
||||
const s = ladeSession()
|
||||
if (!s) return null
|
||||
const b = alle.find((x) => x.id === s.benutzerId && x.aktiv)
|
||||
return b ?? null
|
||||
}
|
||||
Reference in New Issue
Block a user