64 lines
2.3 KiB
JavaScript
64 lines
2.3 KiB
JavaScript
import { getUserById } from './appwriteAdmin.js'
|
|
|
|
/**
|
|
* Passwortstand je Appwrite-Konto (users.passwordUpdate, aendert sich nur mit dem Passwort).
|
|
* Kunden-Sessions merken sich den Stand beim Login (pwv). Wird das Passwort geaendert - im
|
|
* Kundenbereich oder durch uns im Ticketsystem -, gelten aeltere Sessions nicht mehr: der Kunde
|
|
* ist auf allen anderen Geraeten abgemeldet. Sessions ohne pwv (vor dieser Pruefung angemeldet)
|
|
* laufen normal aus. Kurz zwischengespeichert, damit nicht jede API-Anfrage Appwrite fragt;
|
|
* Aenderungen ueber diesen Server gelten sofort (rememberPasswordVersion).
|
|
*/
|
|
const CACHE_MS = 60 * 1000
|
|
const cache = new Map() // appwriteUserId -> { value, at }
|
|
let lastWarnAt = 0
|
|
|
|
function remember(userId, value) {
|
|
if (cache.size > 2000) {
|
|
const now = Date.now()
|
|
for (const [key, entry] of cache) if (now - entry.at > CACHE_MS) cache.delete(key)
|
|
}
|
|
cache.set(userId, { value, at: Date.now() })
|
|
}
|
|
|
|
export function rememberPasswordVersion(userId, passwordUpdate) {
|
|
if (userId) remember(userId, passwordUpdate || '')
|
|
}
|
|
|
|
export function forgetPasswordVersion(userId) {
|
|
cache.delete(userId)
|
|
}
|
|
|
|
/** Aktueller Stand; '' = Konto ohne Passwort bzw. geloescht. Wirft bei Appwrite-Fehlern. */
|
|
async function currentPasswordVersion(userId) {
|
|
const hit = cache.get(userId)
|
|
if (hit && Date.now() - hit.at < CACHE_MS) return hit.value
|
|
let value
|
|
try {
|
|
const user = await getUserById(userId)
|
|
value = user?.passwordUpdate || ''
|
|
} catch (err) {
|
|
if (err.status !== 404) throw err
|
|
value = ''
|
|
}
|
|
remember(userId, value)
|
|
return value
|
|
}
|
|
|
|
/**
|
|
* false, wenn die Kunden-Session von vor der letzten Passwortaenderung stammt. Sessions der
|
|
* Kundenansicht (Mitarbeiter) und Sessions ohne pwv werden nicht geprueft. Ist Appwrite nicht
|
|
* erreichbar, gilt die Session weiter (sonst waeren bei jeder Stoerung alle abgemeldet).
|
|
*/
|
|
export async function isSessionPasswordCurrent(session) {
|
|
if (!session?.pwv || session.role === 'admin' || !session.appwriteUserId) return true
|
|
try {
|
|
return (await currentPasswordVersion(session.appwriteUserId)) === session.pwv
|
|
} catch (err) {
|
|
if (Date.now() - lastWarnAt > 10 * 60 * 1000) {
|
|
lastWarnAt = Date.now()
|
|
console.warn('[auth] Passwortstand nicht prüfbar, Session gilt weiter:', err.message)
|
|
}
|
|
return true
|
|
}
|
|
}
|