feat: Passkey (WebAuthn) login (#1111)

* feat(auth): passkey (WebAuthn) login — server endpoints, schema + admin toggle

Add @simplewebauthn/server registration and primary (discoverable) login ceremonies under /api/auth/passkey, a webauthn_credentials + single-use webauthn_challenges schema (migration), the instance-wide passkey_login toggle (default off) enforced before auth by a guard, and require_mfa satisfaction via a verified passkey. RP ID/origin come only from server config (webauthn_rp_id/origins -> APP_URL), never request headers.

* feat(auth): passkey enrolment, login button + admin settings UI

PasskeysSection in account settings (add/rename/remove with a current-password step-up), a 'Sign in with a passkey' button on the login page, the admin enable + RP-ID/origins controls, and a per-user admin reset action.

* i18n(auth): passkey strings across all locales

Add login/settings/admin passkey keys to en and all 19 translated locales.
This commit is contained in:
Maurice
2026-06-05 18:54:13 +02:00
committed by GitHub
parent 247433fb2a
commit a876fb2634
83 changed files with 2421 additions and 8 deletions
+24
View File
@@ -290,6 +290,30 @@ const settings: TranslationStrings = {
'settings.about.supporter.tier.hostelBunkmate': 'Hostel Bunkmate', // en-fallback
"settings.currency": "Currency",
"settings.currencyHint": "All amounts in Costs are converted to and shown in this currency.",
'settings.passkey.title': 'مفاتيح المرور',
'settings.passkey.description':
'سجّل الدخول بشكل أسرع وأكثر مقاومة للتصيّد باستخدام مفتاح مرور — ببصمة إصبعك أو وجهك أو رمز PIN أو مفتاح أمان مادي. تبقى كلمة المرور كنسخة احتياطية.',
'settings.passkey.notConfigured':
'مفاتيح المرور مفعّلة لكنها لم تُهيّأ بالكامل على هذا الخادم بعد. اطلب من المسؤول تعيين نطاق WebAuthn.',
'settings.passkey.add': 'إضافة مفتاح مرور',
'settings.passkey.addTitle': 'إضافة مفتاح مرور',
'settings.passkey.passwordPrompt':
'أكّد كلمة المرور الحالية، ثم اتبع التعليمات على جهازك.',
'settings.passkey.passwordRequired': 'كلمة المرور الحالية مطلوبة.',
'settings.passkey.namePlaceholder': 'الاسم (اختياري، مثل "iPhone")',
'settings.passkey.addedToast': 'تمت إضافة مفتاح المرور',
'settings.passkey.added': 'تمت الإضافة',
'settings.passkey.addError': 'تعذّرت إضافة مفتاح المرور',
'settings.passkey.cancelled': 'تم إلغاء إعداد مفتاح المرور',
'settings.passkey.deleted': 'تمت إزالة مفتاح المرور',
'settings.passkey.deleteConfirm':
'إزالة مفتاح المرور هذا؟ أكّد بكلمة المرور الخاصة بك.',
'settings.passkey.rename': 'إعادة التسمية',
'settings.passkey.defaultName': 'مفتاح المرور',
'settings.passkey.synced': 'متزامن',
'settings.passkey.deviceBound': 'هذا الجهاز',
'settings.passkey.lastUsed': 'آخر استخدام',
'settings.passkey.neverUsed': 'لم يُستخدم قط',
};
export default settings;