feat(auth): implement password reset functionality
- Added new endpoints for requesting and resetting passwords in the authController. - Updated User model to include resetToken and resetTokenExpires fields for managing password reset requests. - Enhanced emailService to send password reset emails with secure links. - Updated frontend routes and views to support password reset flow, including new ForgotPassword and ResetPassword components. - Improved internationalization files with new translation keys for password reset messages across multiple languages.
This commit is contained in:
@@ -65,7 +65,25 @@
|
||||
"rememberMe": "Aagmeldet bliibe",
|
||||
"loginSuccess": "Erfolgriich aagmeldet",
|
||||
"logoutSuccess": "Erfolgriich abgmeldet",
|
||||
"sessionExpired": "Dini Sitzig isch abglaufe. Du wirsch abgmeldet."
|
||||
"sessionExpired": "Dini Sitzig isch abglaufe. Du wirsch abgmeldet.",
|
||||
"noAccount": "No kei Konto?",
|
||||
"toLogin": "Zum Login",
|
||||
"loginFailed": "Login fehlgschlage. Bitte Zuegangsdaten prüefe.",
|
||||
"activationFailed": "Aktivierig fehlgschlage. Bitte de Link überprüefe.",
|
||||
"forgotPasswordDescription": "Gib dini E-Mail-Adrässe ii. Du bechunsch en Link, zum dis Passwort zruggsetze.",
|
||||
"sendResetLink": "Link schicke",
|
||||
"sending": "Wird gschickt...",
|
||||
"resetEmailSent": "Falls es Konto mit dere E-Mail git, isch en Link zum Zruggsetze gschickt worde. Bitte prüef dis Postfach (au de Spam-Ordner).",
|
||||
"resetRequestFailed": "Aafrag fehlgschlage. Bitte probiers nomal.",
|
||||
"resetPassword": "Nöis Passwort vergee",
|
||||
"newPassword": "Nöis Passwort",
|
||||
"confirmPassword": "Passwort bestätige",
|
||||
"saveNewPassword": "Passwort speichere",
|
||||
"saving": "Wird gspeicheret...",
|
||||
"passwordResetSuccess": "Dis Passwort isch erfolgriich gänderet worde. Du chasch dich jetzt aaloge.",
|
||||
"passwordsDoNotMatch": "D'Passwörter stimed nöd überein.",
|
||||
"passwordTooShort": "S'Passwort muess mindestens 6 Zeiche lang sii.",
|
||||
"resetFailed": "Passwort het nöd chönne gänderet werde. De Link isch villicht abglaufe."
|
||||
},
|
||||
"settings": {
|
||||
"title": "Iistellige",
|
||||
|
||||
@@ -110,7 +110,24 @@
|
||||
"loginFailed": "Login fehlgeschlagen. Bitte Zugangsdaten prüfen und erneut versuchen.",
|
||||
"registerSuccess": "Registrierung erfolgreich! Bitte prüfen Sie Ihre E-Mails, um den Account zu aktivieren.",
|
||||
"registerFailed": "Registrierung fehlgeschlagen. Bitte versuchen Sie es erneut.",
|
||||
"activate": "Aktivieren"
|
||||
"activate": "Aktivieren",
|
||||
"activateAccount": "Account aktivieren",
|
||||
"accountActivated": "Account aktiviert! Du kannst dich jetzt anmelden.",
|
||||
"activationFailed": "Aktivierung fehlgeschlagen. Bitte überprüfe den Link oder versuche es erneut.",
|
||||
"forgotPasswordDescription": "Gib deine E-Mail-Adresse ein. Du erhältst einen Link, um dein Passwort zurückzusetzen.",
|
||||
"sendResetLink": "Link senden",
|
||||
"sending": "Wird gesendet...",
|
||||
"resetEmailSent": "Falls ein Konto mit dieser E-Mail existiert, wurde ein Link zum Zurücksetzen gesendet. Bitte prüfe dein Postfach (auch den Spam-Ordner).",
|
||||
"resetRequestFailed": "Anfrage fehlgeschlagen. Bitte versuche es erneut.",
|
||||
"resetPassword": "Neues Passwort vergeben",
|
||||
"newPassword": "Neues Passwort",
|
||||
"confirmPassword": "Passwort bestätigen",
|
||||
"saveNewPassword": "Passwort speichern",
|
||||
"saving": "Wird gespeichert...",
|
||||
"passwordResetSuccess": "Dein Passwort wurde erfolgreich geändert. Du kannst dich jetzt mit deinem neuen Passwort anmelden.",
|
||||
"passwordsDoNotMatch": "Die Passwörter stimmen nicht überein.",
|
||||
"passwordTooShort": "Das Passwort muss mindestens 6 Zeichen lang sein.",
|
||||
"resetFailed": "Passwort konnte nicht geändert werden. Der Link ist möglicherweise abgelaufen."
|
||||
},
|
||||
"settings": {
|
||||
"title": "Einstellungen",
|
||||
|
||||
@@ -124,7 +124,21 @@
|
||||
"activate": "Aktivieren",
|
||||
"activateAccount": "Account aktivieren",
|
||||
"accountActivated": "Account aktiviert! Du kannst dich jetzt anmelden.",
|
||||
"activationFailed": "Aktivierung fehlgeschlagen. Bitte überprüfe den Link oder versuche es erneut."
|
||||
"activationFailed": "Aktivierung fehlgeschlagen. Bitte überprüfe den Link oder versuche es erneut.",
|
||||
"forgotPasswordDescription": "Gib deine E-Mail-Adresse ein. Du erhältst einen Link, um dein Passwort zurückzusetzen.",
|
||||
"sendResetLink": "Link senden",
|
||||
"sending": "Wird gesendet...",
|
||||
"resetEmailSent": "Falls ein Konto mit dieser E-Mail existiert, wurde ein Link zum Zurücksetzen gesendet. Bitte prüfe dein Postfach (auch den Spam-Ordner).",
|
||||
"resetRequestFailed": "Anfrage fehlgeschlagen. Bitte versuche es erneut.",
|
||||
"resetPassword": "Neues Passwort vergeben",
|
||||
"newPassword": "Neues Passwort",
|
||||
"confirmPassword": "Passwort bestätigen",
|
||||
"saveNewPassword": "Passwort speichern",
|
||||
"saving": "Wird gespeichert...",
|
||||
"passwordResetSuccess": "Dein Passwort wurde erfolgreich geändert. Du kannst dich jetzt mit deinem neuen Passwort anmelden.",
|
||||
"passwordsDoNotMatch": "Die Passwörter stimmen nicht überein.",
|
||||
"passwordTooShort": "Das Passwort muss mindestens 6 Zeichen lang sein.",
|
||||
"resetFailed": "Passwort konnte nicht geändert werden. Der Link ist möglicherweise abgelaufen."
|
||||
},
|
||||
"settings": {
|
||||
"title": "Einstellungen",
|
||||
|
||||
@@ -65,7 +65,25 @@
|
||||
"rememberMe": "Remember me",
|
||||
"loginSuccess": "Successfully logged in",
|
||||
"logoutSuccess": "Successfully logged out",
|
||||
"sessionExpired": "Your session has expired. You will be logged out."
|
||||
"sessionExpired": "Your session has expired. You will be logged out.",
|
||||
"noAccount": "Don't have an account?",
|
||||
"toLogin": "Go to login",
|
||||
"loginFailed": "Login failed. Please check your credentials and try again.",
|
||||
"activationFailed": "Activation failed. Please check the link or try again.",
|
||||
"forgotPasswordDescription": "Enter your email address. You will receive a link to reset your password.",
|
||||
"sendResetLink": "Send link",
|
||||
"sending": "Sending...",
|
||||
"resetEmailSent": "If an account with this email exists, a reset link has been sent. Please check your inbox (and spam folder).",
|
||||
"resetRequestFailed": "Request failed. Please try again.",
|
||||
"resetPassword": "Set new password",
|
||||
"newPassword": "New password",
|
||||
"confirmPassword": "Confirm password",
|
||||
"saveNewPassword": "Save password",
|
||||
"saving": "Saving...",
|
||||
"passwordResetSuccess": "Your password has been changed successfully. You can now log in with your new password.",
|
||||
"passwordsDoNotMatch": "Passwords do not match.",
|
||||
"passwordTooShort": "Password must be at least 6 characters long.",
|
||||
"resetFailed": "Password could not be changed. The link may have expired."
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
|
||||
@@ -65,7 +65,31 @@
|
||||
"rememberMe": "Remember me",
|
||||
"loginSuccess": "Successfully logged in",
|
||||
"logoutSuccess": "Successfully logged out",
|
||||
"sessionExpired": "Your session has expired. You will be logged out."
|
||||
"sessionExpired": "Your session has expired. You will be logged out.",
|
||||
"noAccount": "Don't have an account?",
|
||||
"hasAccount": "Already have an account?",
|
||||
"toLogin": "Go to login",
|
||||
"loginFailed": "Login failed. Please check your credentials and try again.",
|
||||
"registerSuccess": "Registration successful! Please check your email to activate your account.",
|
||||
"registerFailed": "Registration failed. Please try again.",
|
||||
"activate": "Activate",
|
||||
"activateAccount": "Activate account",
|
||||
"accountActivated": "Account activated! You can now log in.",
|
||||
"activationFailed": "Activation failed. Please check the link or try again.",
|
||||
"forgotPasswordDescription": "Enter your email address. You will receive a link to reset your password.",
|
||||
"sendResetLink": "Send link",
|
||||
"sending": "Sending...",
|
||||
"resetEmailSent": "If an account with this email exists, a reset link has been sent. Please check your inbox (and spam folder).",
|
||||
"resetRequestFailed": "Request failed. Please try again.",
|
||||
"resetPassword": "Set new password",
|
||||
"newPassword": "New password",
|
||||
"confirmPassword": "Confirm password",
|
||||
"saveNewPassword": "Save password",
|
||||
"saving": "Saving...",
|
||||
"passwordResetSuccess": "Your password has been changed successfully. You can now log in with your new password.",
|
||||
"passwordsDoNotMatch": "Passwords do not match.",
|
||||
"passwordTooShort": "Password must be at least 6 characters long.",
|
||||
"resetFailed": "Password could not be changed. The link may have expired."
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
|
||||
@@ -65,7 +65,25 @@
|
||||
"rememberMe": "Remember me",
|
||||
"loginSuccess": "Successfully logged in",
|
||||
"logoutSuccess": "Successfully logged out",
|
||||
"sessionExpired": "Your session has expired. You will be logged out."
|
||||
"sessionExpired": "Your session has expired. You will be logged out.",
|
||||
"noAccount": "Don't have an account?",
|
||||
"toLogin": "Go to login",
|
||||
"loginFailed": "Login failed. Please check your credentials and try again.",
|
||||
"activationFailed": "Activation failed. Please check the link or try again.",
|
||||
"forgotPasswordDescription": "Enter your email address. You will receive a link to reset your password.",
|
||||
"sendResetLink": "Send link",
|
||||
"sending": "Sending...",
|
||||
"resetEmailSent": "If an account with this email exists, a reset link has been sent. Please check your inbox (and spam folder).",
|
||||
"resetRequestFailed": "Request failed. Please try again.",
|
||||
"resetPassword": "Set new password",
|
||||
"newPassword": "New password",
|
||||
"confirmPassword": "Confirm password",
|
||||
"saveNewPassword": "Save password",
|
||||
"saving": "Saving...",
|
||||
"passwordResetSuccess": "Your password has been changed successfully. You can now log in with your new password.",
|
||||
"passwordsDoNotMatch": "Passwords do not match.",
|
||||
"passwordTooShort": "Password must be at least 6 characters long.",
|
||||
"resetFailed": "Password could not be changed. The link may have expired."
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
|
||||
@@ -65,7 +65,25 @@
|
||||
"rememberMe": "Recordarme",
|
||||
"loginSuccess": "Sesión iniciada correctamente",
|
||||
"logoutSuccess": "Sesión cerrada correctamente",
|
||||
"sessionExpired": "Tu sesión ha expirado. Serás desconectado."
|
||||
"sessionExpired": "Tu sesión ha expirado. Serás desconectado.",
|
||||
"noAccount": "¿No tienes cuenta?",
|
||||
"toLogin": "Ir al inicio de sesión",
|
||||
"loginFailed": "Inicio de sesión fallido. Por favor verifica tus credenciales.",
|
||||
"activationFailed": "Activación fallida. Por favor verifica el enlace.",
|
||||
"forgotPasswordDescription": "Introduce tu dirección de correo electrónico. Recibirás un enlace para restablecer tu contraseña.",
|
||||
"sendResetLink": "Enviar enlace",
|
||||
"sending": "Enviando...",
|
||||
"resetEmailSent": "Si existe una cuenta con este correo, se ha enviado un enlace de restablecimiento. Revisa tu bandeja de entrada (y la carpeta de spam).",
|
||||
"resetRequestFailed": "Solicitud fallida. Inténtalo de nuevo.",
|
||||
"resetPassword": "Establecer nueva contraseña",
|
||||
"newPassword": "Nueva contraseña",
|
||||
"confirmPassword": "Confirmar contraseña",
|
||||
"saveNewPassword": "Guardar contraseña",
|
||||
"saving": "Guardando...",
|
||||
"passwordResetSuccess": "Tu contraseña ha sido cambiada exitosamente. Ahora puedes iniciar sesión.",
|
||||
"passwordsDoNotMatch": "Las contraseñas no coinciden.",
|
||||
"passwordTooShort": "La contraseña debe tener al menos 6 caracteres.",
|
||||
"resetFailed": "No se pudo cambiar la contraseña. El enlace puede haber expirado."
|
||||
},
|
||||
"settings": {
|
||||
"title": "Configuración",
|
||||
|
||||
@@ -65,7 +65,25 @@
|
||||
"rememberMe": "Tandaan ako",
|
||||
"loginSuccess": "Matagumpay na nag-login",
|
||||
"logoutSuccess": "Matagumpay na nag-logout",
|
||||
"sessionExpired": "Nag-expire na ang iyong session. Ikaw ay ma-logout."
|
||||
"sessionExpired": "Nag-expire na ang iyong session. Ikaw ay ma-logout.",
|
||||
"noAccount": "Wala pang account?",
|
||||
"toLogin": "Pumunta sa login",
|
||||
"loginFailed": "Nabigo ang pag-login. Suriin ang iyong credentials.",
|
||||
"activationFailed": "Nabigo ang activation. Suriin ang link.",
|
||||
"forgotPasswordDescription": "Ilagay ang iyong email address. Makakatanggap ka ng link para i-reset ang password.",
|
||||
"sendResetLink": "Ipadala ang link",
|
||||
"sending": "Ipinapadala...",
|
||||
"resetEmailSent": "Kung may account sa email na ito, ipinadala na ang reset link. Suriin ang inbox (at spam folder).",
|
||||
"resetRequestFailed": "Nabigo ang request. Subukan ulit.",
|
||||
"resetPassword": "Magtakda ng bagong password",
|
||||
"newPassword": "Bagong password",
|
||||
"confirmPassword": "Kumpirmahin ang password",
|
||||
"saveNewPassword": "I-save ang password",
|
||||
"saving": "Sine-save...",
|
||||
"passwordResetSuccess": "Matagumpay na nabago ang password. Maaari ka nang mag-login.",
|
||||
"passwordsDoNotMatch": "Hindi magkatugma ang mga password.",
|
||||
"passwordTooShort": "Ang password ay dapat hindi bababa sa 6 na character.",
|
||||
"resetFailed": "Hindi nabago ang password. Maaaring nag-expire na ang link."
|
||||
},
|
||||
"settings": {
|
||||
"title": "Mga setting",
|
||||
|
||||
@@ -65,7 +65,25 @@
|
||||
"rememberMe": "Se souvenir de moi",
|
||||
"loginSuccess": "Connexion réussie",
|
||||
"logoutSuccess": "Déconnexion réussie",
|
||||
"sessionExpired": "Votre session a expiré. Vous allez être déconnecté."
|
||||
"sessionExpired": "Votre session a expiré. Vous allez être déconnecté.",
|
||||
"noAccount": "Pas encore de compte ?",
|
||||
"toLogin": "Vers la connexion",
|
||||
"loginFailed": "Connexion échouée. Veuillez vérifier vos identifiants.",
|
||||
"activationFailed": "Activation échouée. Veuillez vérifier le lien.",
|
||||
"forgotPasswordDescription": "Entrez votre adresse e-mail. Vous recevrez un lien pour réinitialiser votre mot de passe.",
|
||||
"sendResetLink": "Envoyer le lien",
|
||||
"sending": "Envoi en cours...",
|
||||
"resetEmailSent": "Si un compte avec cette adresse existe, un lien de réinitialisation a été envoyé. Vérifiez votre boîte de réception (et les spams).",
|
||||
"resetRequestFailed": "Demande échouée. Veuillez réessayer.",
|
||||
"resetPassword": "Définir un nouveau mot de passe",
|
||||
"newPassword": "Nouveau mot de passe",
|
||||
"confirmPassword": "Confirmer le mot de passe",
|
||||
"saveNewPassword": "Enregistrer le mot de passe",
|
||||
"saving": "Enregistrement...",
|
||||
"passwordResetSuccess": "Votre mot de passe a été modifié avec succès. Vous pouvez maintenant vous connecter.",
|
||||
"passwordsDoNotMatch": "Les mots de passe ne correspondent pas.",
|
||||
"passwordTooShort": "Le mot de passe doit contenir au moins 6 caractères.",
|
||||
"resetFailed": "Le mot de passe n'a pas pu être modifié. Le lien a peut-être expiré."
|
||||
},
|
||||
"settings": {
|
||||
"title": "Paramètres",
|
||||
|
||||
@@ -65,7 +65,25 @@
|
||||
"rememberMe": "Ricordami",
|
||||
"loginSuccess": "Accesso effettuato con successo",
|
||||
"logoutSuccess": "Uscita effettuata con successo",
|
||||
"sessionExpired": "La tua sessione è scaduta. Verrai disconnesso."
|
||||
"sessionExpired": "La tua sessione è scaduta. Verrai disconnesso.",
|
||||
"noAccount": "Non hai un account?",
|
||||
"toLogin": "Vai al login",
|
||||
"loginFailed": "Accesso fallito. Controlla le credenziali.",
|
||||
"activationFailed": "Attivazione fallita. Controlla il link.",
|
||||
"forgotPasswordDescription": "Inserisci il tuo indirizzo email. Riceverai un link per reimpostare la password.",
|
||||
"sendResetLink": "Invia link",
|
||||
"sending": "Invio in corso...",
|
||||
"resetEmailSent": "Se esiste un account con questa email, è stato inviato un link di reimpostazione. Controlla la posta (e lo spam).",
|
||||
"resetRequestFailed": "Richiesta fallita. Riprova.",
|
||||
"resetPassword": "Imposta nuova password",
|
||||
"newPassword": "Nuova password",
|
||||
"confirmPassword": "Conferma password",
|
||||
"saveNewPassword": "Salva password",
|
||||
"saving": "Salvataggio...",
|
||||
"passwordResetSuccess": "La password è stata cambiata con successo. Ora puoi accedere.",
|
||||
"passwordsDoNotMatch": "Le password non corrispondono.",
|
||||
"passwordTooShort": "La password deve contenere almeno 6 caratteri.",
|
||||
"resetFailed": "La password non è stata modificata. Il link potrebbe essere scaduto."
|
||||
},
|
||||
"settings": {
|
||||
"title": "Impostazioni",
|
||||
|
||||
@@ -65,7 +65,25 @@
|
||||
"rememberMe": "ログイン状態を保持",
|
||||
"loginSuccess": "ログインに成功しました",
|
||||
"logoutSuccess": "ログアウトに成功しました",
|
||||
"sessionExpired": "セッションが期限切れです。ログアウトされます。"
|
||||
"sessionExpired": "セッションが期限切れです。ログアウトされます。",
|
||||
"noAccount": "アカウントをお持ちでないですか?",
|
||||
"toLogin": "ログインへ",
|
||||
"loginFailed": "ログインに失敗しました。認証情報を確認してください。",
|
||||
"activationFailed": "アクティベーションに失敗しました。リンクを確認してください。",
|
||||
"forgotPasswordDescription": "メールアドレスを入力してください。パスワードリセット用のリンクが送信されます。",
|
||||
"sendResetLink": "リンクを送信",
|
||||
"sending": "送信中...",
|
||||
"resetEmailSent": "このメールアドレスのアカウントが存在する場合、リセットリンクが送信されました。受信トレイ(迷惑メールフォルダも)を確認してください。",
|
||||
"resetRequestFailed": "リクエストに失敗しました。再試行してください。",
|
||||
"resetPassword": "新しいパスワードを設定",
|
||||
"newPassword": "新しいパスワード",
|
||||
"confirmPassword": "パスワードを確認",
|
||||
"saveNewPassword": "パスワードを保存",
|
||||
"saving": "保存中...",
|
||||
"passwordResetSuccess": "パスワードが正常に変更されました。新しいパスワードでログインできます。",
|
||||
"passwordsDoNotMatch": "パスワードが一致しません。",
|
||||
"passwordTooShort": "パスワードは6文字以上必要です。",
|
||||
"resetFailed": "パスワードを変更できませんでした。リンクの有効期限が切れている可能性があります。"
|
||||
},
|
||||
"settings": {
|
||||
"title": "設定",
|
||||
|
||||
@@ -65,7 +65,25 @@
|
||||
"rememberMe": "Zapamiętaj mnie",
|
||||
"loginSuccess": "Pomyślnie zalogowano",
|
||||
"logoutSuccess": "Pomyślnie wylogowano",
|
||||
"sessionExpired": "Twoja sesja wygasła. Zostaniesz wylogowany."
|
||||
"sessionExpired": "Twoja sesja wygasła. Zostaniesz wylogowany.",
|
||||
"noAccount": "Nie masz konta?",
|
||||
"toLogin": "Do logowania",
|
||||
"loginFailed": "Logowanie nie powiodło się. Sprawdź dane logowania.",
|
||||
"activationFailed": "Aktywacja nie powiodła się. Sprawdź link.",
|
||||
"forgotPasswordDescription": "Podaj swój adres e-mail. Otrzymasz link do zresetowania hasła.",
|
||||
"sendResetLink": "Wyślij link",
|
||||
"sending": "Wysyłanie...",
|
||||
"resetEmailSent": "Jeśli konto z tym adresem istnieje, wysłano link do resetowania. Sprawdź skrzynkę (i spam).",
|
||||
"resetRequestFailed": "Żądanie nie powiodło się. Spróbuj ponownie.",
|
||||
"resetPassword": "Ustaw nowe hasło",
|
||||
"newPassword": "Nowe hasło",
|
||||
"confirmPassword": "Potwierdź hasło",
|
||||
"saveNewPassword": "Zapisz hasło",
|
||||
"saving": "Zapisywanie...",
|
||||
"passwordResetSuccess": "Hasło zostało zmienione pomyślnie. Możesz się teraz zalogować.",
|
||||
"passwordsDoNotMatch": "Hasła nie są zgodne.",
|
||||
"passwordTooShort": "Hasło musi mieć co najmniej 6 znaków.",
|
||||
"resetFailed": "Nie udało się zmienić hasła. Link mógł wygasnąć."
|
||||
},
|
||||
"settings": {
|
||||
"title": "Ustawienia",
|
||||
|
||||
@@ -65,7 +65,25 @@
|
||||
"rememberMe": "จดจำฉัน",
|
||||
"loginSuccess": "เข้าสู่ระบบสำเร็จ",
|
||||
"logoutSuccess": "ออกจากระบบสำเร็จ",
|
||||
"sessionExpired": "เซสชันของคุณหมดอายุแล้ว คุณจะถูกออกจากระบบ"
|
||||
"sessionExpired": "เซสชันของคุณหมดอายุแล้ว คุณจะถูกออกจากระบบ",
|
||||
"noAccount": "ยังไม่มีบัญชี?",
|
||||
"toLogin": "ไปที่เข้าสู่ระบบ",
|
||||
"loginFailed": "เข้าสู่ระบบล้มเหลว กรุณาตรวจสอบข้อมูลของคุณ",
|
||||
"activationFailed": "การเปิดใช้งานล้มเหลว กรุณาตรวจสอบลิงก์",
|
||||
"forgotPasswordDescription": "กรอกอีเมลของคุณ คุณจะได้รับลิงก์สำหรับรีเซ็ตรหัสผ่าน",
|
||||
"sendResetLink": "ส่งลิงก์",
|
||||
"sending": "กำลังส่ง...",
|
||||
"resetEmailSent": "หากมีบัญชีที่ใช้อีเมลนี้ ลิงก์รีเซ็ตได้ถูกส่งแล้ว กรุณาตรวจสอบกล่องจดหมาย (และสแปม)",
|
||||
"resetRequestFailed": "คำขอล้มเหลว กรุณาลองอีกครั้ง",
|
||||
"resetPassword": "ตั้งรหัสผ่านใหม่",
|
||||
"newPassword": "รหัสผ่านใหม่",
|
||||
"confirmPassword": "ยืนยันรหัสผ่าน",
|
||||
"saveNewPassword": "บันทึกรหัสผ่าน",
|
||||
"saving": "กำลังบันทึก...",
|
||||
"passwordResetSuccess": "เปลี่ยนรหัสผ่านสำเร็จ คุณสามารถเข้าสู่ระบบได้แล้ว",
|
||||
"passwordsDoNotMatch": "รหัสผ่านไม่ตรงกัน",
|
||||
"passwordTooShort": "รหัสผ่านต้องมีอย่างน้อย 6 ตัวอักษร",
|
||||
"resetFailed": "ไม่สามารถเปลี่ยนรหัสผ่านได้ ลิงก์อาจหมดอายุแล้ว"
|
||||
},
|
||||
"settings": {
|
||||
"title": "การตั้งค่า",
|
||||
|
||||
@@ -65,7 +65,25 @@
|
||||
"rememberMe": "Tandaan ako",
|
||||
"loginSuccess": "Matagumpay na nag-login",
|
||||
"logoutSuccess": "Matagumpay na nag-logout",
|
||||
"sessionExpired": "Nag-expire na ang iyong session. Ikaw ay ma-logout."
|
||||
"sessionExpired": "Nag-expire na ang iyong session. Ikaw ay ma-logout.",
|
||||
"noAccount": "Wala pang account?",
|
||||
"toLogin": "Pumunta sa login",
|
||||
"loginFailed": "Nabigo ang pag-login. Suriin ang iyong credentials.",
|
||||
"activationFailed": "Nabigo ang activation. Suriin ang link.",
|
||||
"forgotPasswordDescription": "Ilagay ang iyong email address. Makakatanggap ka ng link para i-reset ang password.",
|
||||
"sendResetLink": "Ipadala ang link",
|
||||
"sending": "Ipinapadala...",
|
||||
"resetEmailSent": "Kung may account sa email na ito, ipinadala na ang reset link. Suriin ang inbox (at spam folder).",
|
||||
"resetRequestFailed": "Nabigo ang request. Subukan ulit.",
|
||||
"resetPassword": "Magtakda ng bagong password",
|
||||
"newPassword": "Bagong password",
|
||||
"confirmPassword": "Kumpirmahin ang password",
|
||||
"saveNewPassword": "I-save ang password",
|
||||
"saving": "Sine-save...",
|
||||
"passwordResetSuccess": "Matagumpay na nabago ang password. Maaari ka nang mag-login.",
|
||||
"passwordsDoNotMatch": "Hindi magkatugma ang mga password.",
|
||||
"passwordTooShort": "Ang password ay dapat hindi bababa sa 6 na character.",
|
||||
"resetFailed": "Hindi nabago ang password. Maaaring nag-expire na ang link."
|
||||
},
|
||||
"settings": {
|
||||
"title": "Mga setting",
|
||||
|
||||
@@ -65,7 +65,25 @@
|
||||
"rememberMe": "记住我",
|
||||
"loginSuccess": "登录成功",
|
||||
"logoutSuccess": "退出成功",
|
||||
"sessionExpired": "您的会话已过期。您将被登出。"
|
||||
"sessionExpired": "您的会话已过期。您将被登出。",
|
||||
"noAccount": "还没有账号?",
|
||||
"toLogin": "去登录",
|
||||
"loginFailed": "登录失败。请检查您的凭据。",
|
||||
"activationFailed": "激活失败。请检查链接。",
|
||||
"forgotPasswordDescription": "输入您的电子邮件地址。您将收到重置密码的链接。",
|
||||
"sendResetLink": "发送链接",
|
||||
"sending": "发送中...",
|
||||
"resetEmailSent": "如果该邮箱存在账号,已发送重置链接。请检查收件箱(和垃圾邮件文件夹)。",
|
||||
"resetRequestFailed": "请求失败。请重试。",
|
||||
"resetPassword": "设置新密码",
|
||||
"newPassword": "新密码",
|
||||
"confirmPassword": "确认密码",
|
||||
"saveNewPassword": "保存密码",
|
||||
"saving": "保存中...",
|
||||
"passwordResetSuccess": "密码已成功更改。您现在可以使用新密码登录。",
|
||||
"passwordsDoNotMatch": "密码不匹配。",
|
||||
"passwordTooShort": "密码至少需要6个字符。",
|
||||
"resetFailed": "无法更改密码。链接可能已过期。"
|
||||
},
|
||||
"settings": {
|
||||
"title": "设置",
|
||||
|
||||
@@ -2,6 +2,8 @@ import { createRouter, createWebHistory } from 'vue-router';
|
||||
import Register from './views/Register.vue';
|
||||
import Login from './views/Login.vue';
|
||||
import Activate from './views/Activate.vue';
|
||||
import ForgotPassword from './views/ForgotPassword.vue';
|
||||
import ResetPassword from './views/ResetPassword.vue';
|
||||
import Home from './views/Home.vue';
|
||||
import CreateClub from './views/CreateClub.vue';
|
||||
import ClubView from './views/ClubView.vue';
|
||||
@@ -26,6 +28,8 @@ const routes = [
|
||||
{ path: '/register', component: Register },
|
||||
{ path: '/login', component: Login },
|
||||
{ path: '/activate/:activationCode', component: Activate },
|
||||
{ path: '/forgot-password', component: ForgotPassword },
|
||||
{ path: '/reset-password/:token', component: ResetPassword },
|
||||
{ path: '/', component: Home },
|
||||
{ path: '/createclub', component: CreateClub },
|
||||
{ path: '/showclub/:clubId', component: ClubView },
|
||||
|
||||
129
frontend/src/views/ForgotPassword.vue
Normal file
129
frontend/src/views/ForgotPassword.vue
Normal file
@@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<div class="forgot-password-container">
|
||||
<h2>{{ $t('auth.forgotPassword') }}</h2>
|
||||
<p class="description">{{ $t('auth.forgotPasswordDescription') }}</p>
|
||||
|
||||
<form v-if="!emailSent" @submit.prevent="submitRequest">
|
||||
<input
|
||||
v-model="email"
|
||||
type="email"
|
||||
:placeholder="$t('auth.email')"
|
||||
required
|
||||
:disabled="loading"
|
||||
/>
|
||||
<button type="submit" :disabled="loading">
|
||||
{{ loading ? $t('auth.sending') : $t('auth.sendResetLink') }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div v-else class="success-message">
|
||||
<p>{{ $t('auth.resetEmailSent') }}</p>
|
||||
</div>
|
||||
|
||||
<div class="back-to-login">
|
||||
<router-link to="/login">← {{ $t('auth.toLogin') }}</router-link>
|
||||
</div>
|
||||
|
||||
<!-- Info Dialog -->
|
||||
<InfoDialog
|
||||
v-model="infoDialog.isOpen"
|
||||
:title="infoDialog.title"
|
||||
:message="infoDialog.message"
|
||||
:details="infoDialog.details"
|
||||
:type="infoDialog.type"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import apiClient from '../apiClient.js';
|
||||
import InfoDialog from '../components/InfoDialog.vue';
|
||||
import { buildInfoConfig, safeErrorMessage } from '../utils/dialogUtils.js';
|
||||
|
||||
export default {
|
||||
components: { InfoDialog },
|
||||
data() {
|
||||
return {
|
||||
email: '',
|
||||
loading: false,
|
||||
emailSent: false,
|
||||
infoDialog: {
|
||||
isOpen: false,
|
||||
title: '',
|
||||
message: '',
|
||||
details: '',
|
||||
type: 'info'
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async showInfo(title, message, details = '', type = 'info') {
|
||||
this.infoDialog = buildInfoConfig({ title, message, details, type });
|
||||
},
|
||||
async submitRequest() {
|
||||
this.loading = true;
|
||||
try {
|
||||
await apiClient.post('/auth/forgot-password', { email: this.email });
|
||||
this.emailSent = true;
|
||||
} catch (error) {
|
||||
const message = safeErrorMessage(error, this.$t('auth.resetRequestFailed'));
|
||||
await this.showInfo(this.$t('messages.error'), message, '', 'error');
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.forgot-password-container {
|
||||
max-width: 400px;
|
||||
margin: 2rem auto;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
color: #666;
|
||||
margin-bottom: 1.5rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.success-message {
|
||||
background-color: #e8f5e9;
|
||||
border: 1px solid #4caf50;
|
||||
border-radius: 6px;
|
||||
padding: 1rem;
|
||||
color: #2e7d32;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.back-to-login {
|
||||
margin-top: 1.5rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.back-to-login a {
|
||||
color: #1976d2;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.back-to-login a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
form input {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
form button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
form button:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
</style>
|
||||
@@ -6,6 +6,9 @@
|
||||
<input v-model="password" type="password" :placeholder="$t('auth.password')" required />
|
||||
<button type="submit">{{ $t('auth.login') }}</button>
|
||||
</form>
|
||||
<div class="forgot-password-link">
|
||||
<router-link to="/forgot-password">{{ $t('auth.forgotPassword') }}</router-link>
|
||||
</div>
|
||||
<div class="register-link">
|
||||
<p>{{ $t('auth.noAccount') }} <router-link to="/register">{{ $t('auth.register') }}</router-link></p>
|
||||
</div>
|
||||
|
||||
144
frontend/src/views/ResetPassword.vue
Normal file
144
frontend/src/views/ResetPassword.vue
Normal file
@@ -0,0 +1,144 @@
|
||||
<template>
|
||||
<div class="reset-password-container">
|
||||
<h2>{{ $t('auth.resetPassword') }}</h2>
|
||||
|
||||
<form v-if="!resetDone" @submit.prevent="submitReset">
|
||||
<input
|
||||
v-model="newPassword"
|
||||
type="password"
|
||||
:placeholder="$t('auth.newPassword')"
|
||||
required
|
||||
minlength="6"
|
||||
:disabled="loading"
|
||||
/>
|
||||
<input
|
||||
v-model="confirmPassword"
|
||||
type="password"
|
||||
:placeholder="$t('auth.confirmPassword')"
|
||||
required
|
||||
minlength="6"
|
||||
:disabled="loading"
|
||||
/>
|
||||
<button type="submit" :disabled="loading">
|
||||
{{ loading ? $t('auth.saving') : $t('auth.saveNewPassword') }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div v-else class="success-message">
|
||||
<p>{{ $t('auth.passwordResetSuccess') }}</p>
|
||||
<router-link to="/login" class="login-button">{{ $t('auth.toLogin') }}</router-link>
|
||||
</div>
|
||||
|
||||
<!-- Info Dialog -->
|
||||
<InfoDialog
|
||||
v-model="infoDialog.isOpen"
|
||||
:title="infoDialog.title"
|
||||
:message="infoDialog.message"
|
||||
:details="infoDialog.details"
|
||||
:type="infoDialog.type"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import apiClient from '../apiClient.js';
|
||||
import InfoDialog from '../components/InfoDialog.vue';
|
||||
import { buildInfoConfig, safeErrorMessage } from '../utils/dialogUtils.js';
|
||||
|
||||
export default {
|
||||
components: { InfoDialog },
|
||||
data() {
|
||||
return {
|
||||
newPassword: '',
|
||||
confirmPassword: '',
|
||||
loading: false,
|
||||
resetDone: false,
|
||||
infoDialog: {
|
||||
isOpen: false,
|
||||
title: '',
|
||||
message: '',
|
||||
details: '',
|
||||
type: 'info'
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async showInfo(title, message, details = '', type = 'info') {
|
||||
this.infoDialog = buildInfoConfig({ title, message, details, type });
|
||||
},
|
||||
async submitReset() {
|
||||
if (this.newPassword !== this.confirmPassword) {
|
||||
await this.showInfo(this.$t('messages.error'), this.$t('auth.passwordsDoNotMatch'), '', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.newPassword.length < 6) {
|
||||
await this.showInfo(this.$t('messages.error'), this.$t('auth.passwordTooShort'), '', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
this.loading = true;
|
||||
try {
|
||||
const token = this.$route.params.token;
|
||||
await apiClient.post('/auth/reset-password', {
|
||||
token,
|
||||
password: this.newPassword
|
||||
});
|
||||
this.resetDone = true;
|
||||
} catch (error) {
|
||||
const message = safeErrorMessage(error, this.$t('auth.resetFailed'));
|
||||
await this.showInfo(this.$t('messages.error'), message, '', 'error');
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.reset-password-container {
|
||||
max-width: 400px;
|
||||
margin: 2rem auto;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
||||
.success-message {
|
||||
background-color: #e8f5e9;
|
||||
border: 1px solid #4caf50;
|
||||
border-radius: 6px;
|
||||
padding: 1rem;
|
||||
color: #2e7d32;
|
||||
text-align: center;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.login-button {
|
||||
display: inline-block;
|
||||
margin-top: 1rem;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
padding: 0.6rem 1.5rem;
|
||||
text-decoration: none;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.login-button:hover {
|
||||
background-color: #43a047;
|
||||
}
|
||||
|
||||
form input {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
form button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
form button:disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user