fix(auth): remove signup page from self-hosted builds (#7406)

# Description of Changes

remove signup page from self-hosted builds since all signups are either
default or done via admins
---

## Checklist

### General

- [ ] I have read the [Contribution
Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md)
- [ ] I have read the [Stirling-PDF Developer
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md)
(if applicable)
- [ ] I have read the [How to add new languages to
Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md)
(if applicable)
- [ ] I have performed a self-review of my own code
- [ ] My changes generate no new warnings

### Documentation

- [ ] I have updated relevant docs on [Stirling-PDF's doc
repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/)
(if functionality has heavily changed)
- [ ] I have read the section [Add New Translation
Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/HowToAddNewLanguage.md#add-new-translation-tags)
(for new translation tags only)

### Translations (if applicable)

- [ ] I ran
[`scripts/counter_translation.py`](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/docs/counter_translation.md)

### UI Changes (if applicable)

- [ ] Screenshots or videos demonstrating the UI changes are attached
(e.g., as comments or direct attachments in the PR)

### Testing (if applicable)

- [ ] I have run `task check` to verify linters, typechecks, and tests
pass
- [ ] I have tested my changes locally. Refer to the [Testing
Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#7-testing)
for more details.
This commit is contained in:
Anthony Stirling
2026-08-11 10:16:28 +00:00
committed by GitHub
parent 05eb74022a
commit e6680c4cf5
56 changed files with 89 additions and 468 deletions
@@ -4869,12 +4869,10 @@ enterUsername = "أدخل اسم المستخدم"
failedToSignIn = "فشل تسجيل الدخول بواسطة {{provider}}: {{message}}"
forgotPassword = "هل نسيت كلمة المرور؟"
loggingIn = "جارٍ تسجيل الدخول..."
logIn = "تسجيل الدخول"
login = "تسجيل الدخول"
magicLinkSent = "تم إرسال الرابط السحري إلى {{email}}! تفقد بريدك واضغط الرابط لتسجيل الدخول."
mfaCode = "رمز المصادقة"
mfaRequired = "رمز المصادقة ذات العاملين مطلوب"
noAccount = "ليس لديك حساب؟"
or = "أو"
password = "كلمة المرور"
passwordChangedSuccess = "تم تغيير كلمة المرور بنجاح! يرجى تسجيل الدخول بكلمة المرور الجديدة."
@@ -4869,12 +4869,10 @@ enterUsername = "İstifadəçi adını daxil edin"
failedToSignIn = "{{provider}} ilə daxil olmaq alınmadı: {{message}}"
forgotPassword = "Parolunuzu unutmusunuz?"
loggingIn = "Daxil olunur..."
logIn = "Daxil ol"
login = "Daxil ol"
magicLinkSent = "Sehrli link {{email}} ünvanına göndərildi! Zəhmət olmasa e-poçtunuzu yoxlayın və daxil olmaq üçün linkə klikləyin."
mfaCode = "Doğrulama kodu"
mfaRequired = "İki faktorlu doğrulama kodu tələb olunur"
noAccount = "Hesabınız yoxdur?"
or = "Və ya"
password = "Parol"
passwordChangedSuccess = "Parol uğurla dəyişdirildi! Zəhmət olmasa yeni parolunuzla daxil olun."
@@ -4869,12 +4869,10 @@ enterUsername = "Въведете потребителско име"
failedToSignIn = "Неуспешен вход с {{provider}}: {{message}}"
forgotPassword = "Забравена парола?"
loggingIn = "Влизане..."
logIn = "Вход"
login = "Вход"
magicLinkSent = "Магическа връзка е изпратена до {{email}}! Проверете пощата си и щракнете върху връзката, за да влезете."
mfaCode = "Код за удостоверяване"
mfaRequired = "Изисква се двуфакторен код"
noAccount = "Нямате акаунт?"
or = "Или"
password = "Парола"
passwordChangedSuccess = "Паролата е променена успешно! Моля, влезте с новата парола."
@@ -4869,12 +4869,10 @@ enterUsername = "སྤྱོད་མཁན་གྱི་མིང་ནང་
failedToSignIn = "{{provider}} བེད་སྤྱད་ནས་ནང་འཇུག་མ་ཐུབ་པ: {{message}}"
forgotPassword = "ཁྱེད་རང་གི་གསང་གྲངས་བརྗེད་སོང་ངམ།"
loggingIn = "ཤིང་བཟོ་བ།..."
logIn = "དྲན་ཐོ།"
login = "ནང་འཇུག"
magicLinkSent = "མེ་ཇིག་དྲ་སྦྲེལ་དེ་{{email}} ལ་བཏང་ཡོད། གློག་འཕྲིན་ལ་ལྟས་ཏེ་སྦྲེལ་མཐུད་སྣུན་ནས་ནང་འཇུག་གནང་རོགས།"
mfaCode = "ངོས་འཛིན་ཨང་རྟགས"
mfaRequired = "ཆ་རྐྱེན་གཉིས་ཨང་རྟགས་དགོས"
noAccount = "རྩིས་ཐོ་མེད་དམ?"
or = "ཡང་ན"
password = "གསང་གྲངས"
passwordChangedSuccess = "གསང་གྲངས་ལེགས་འགྲུབ་བྱུང་བ། ཁྱེད་རང་གི་གསང་གྲངས་གསར་པས་ནང་འཇུག་གནང་རོགས།"
@@ -4869,12 +4869,10 @@ enterUsername = "Introduïu el nom d'usuari"
failedToSignIn = "No s'ha pogut iniciar sessió amb {{provider}}: {{message}}"
forgotPassword = "Heu oblidat la contrasenya?"
loggingIn = "Iniciant sessió..."
logIn = "Inicia sessió"
login = "Inicia sessió"
magicLinkSent = "Enllaç màgic enviat a {{email}}! Reviseu el vostre correu i feu clic a l'enllaç per iniciar sessió."
mfaCode = "Codi d'autenticació"
mfaRequired = "Es requereix un codi de dos factors"
noAccount = "No tens cap compte?"
or = "O"
password = "Contrasenya"
passwordChangedSuccess = "Contrasenya canviada correctament! Inicieu sessió amb la nova contrasenya."
@@ -4869,12 +4869,10 @@ enterUsername = "Zadejte uživatelské jméno"
failedToSignIn = "Nepodařilo se přihlásit pomocí {{provider}}: {{message}}"
forgotPassword = "Zapomněli jste heslo?"
loggingIn = "Přihlašování..."
logIn = "Přihlásit se"
login = "Přihlášení"
magicLinkSent = "Magický odkaz byl odeslán na {{email}}! Zkontrolujte e-mail a kliknutím na odkaz se přihlaste."
mfaCode = "Ověřovací kód"
mfaRequired = "Je vyžadován kód pro dvoufázové ověření"
noAccount = "Nemáte účet?"
or = "Nebo"
password = "Heslo"
passwordChangedSuccess = "Heslo bylo úspěšně změněno! Přihlaste se novým heslem."
@@ -4869,12 +4869,10 @@ enterUsername = "Indtast brugernavn"
failedToSignIn = "Kunne ikke logge ind med {{provider}}: {{message}}"
forgotPassword = "Glemt din adgangskode?"
loggingIn = "Logger ind..."
logIn = "Log ind"
login = "Log ind"
magicLinkSent = "Magisk link sendt til {{email}}! Tjek din e-mail og klik på linket for at logge ind."
mfaCode = "Godkendelseskode"
mfaRequired = "Tofaktorkode påkrævet"
noAccount = "Har du ikke en konto?"
or = "Eller"
password = "Adgangskode"
passwordChangedSuccess = "Adgangskoden blev ændret! Log ind med din nye adgangskode."
@@ -4874,12 +4874,10 @@ enterUsername = "Benutzernamen eingeben"
failedToSignIn = "Anmeldung mit {{provider}} fehlgeschlagen: {{message}}"
forgotPassword = "Passwort vergessen?"
loggingIn = "Anmeldung läuft..."
logIn = "Anmelden"
login = "Anmelden"
magicLinkSent = "Magic Link wurde an {{email}} gesendet! Prüfen Sie Ihre E-Mails und klicken Sie auf den Link zur Anmeldung."
mfaCode = "Authentifizierungscode"
mfaRequired = "Zwei-Faktor-Code erforderlich"
noAccount = "Noch kein Konto?"
or = "Oder"
password = "Passwort"
passwordChangedSuccess = "Passwort erfolgreich geändert! Bitte melden Sie sich mit Ihrem neuen Passwort an."
@@ -4869,12 +4869,10 @@ enterUsername = "Εισαγάγετε όνομα χρήστη"
failedToSignIn = "Αποτυχία σύνδεσης με {{provider}}: {{message}}"
forgotPassword = "Ξεχάσατε τον κωδικό σας;"
loggingIn = "Γίνεται σύνδεση..."
logIn = "Σύνδεση"
login = "Σύνδεση"
magicLinkSent = "Στάλθηκε μαγικός σύνδεσμος στο {{email}}! Ελέγξτε το email σας και κάντε κλικ στον σύνδεσμο για να συνδεθείτε."
mfaCode = "Κωδικός ελέγχου ταυτότητας"
mfaRequired = "Απαιτείται κωδικός δύο παραγόντων"
noAccount = "Δεν έχετε λογαριασμό;"
or = "Ή"
password = "Κωδικός πρόσβασης"
passwordChangedSuccess = "Ο κωδικός άλλαξε με επιτυχία! Συνδεθείτε με τον νέο σας κωδικό."
@@ -4869,12 +4869,10 @@ enterUsername = "Enter username"
failedToSignIn = "Failed to sign in with {{provider}}: {{message}}"
forgotPassword = "Forgot your password?"
loggingIn = "Logging In..."
logIn = "Log In"
login = "Login"
magicLinkSent = "Magic link sent to {{email}}! Check your email and click the link to sign in."
mfaCode = "Authentication Code"
mfaRequired = "Two-factor code required"
noAccount = "Don't have an account?"
or = "Or"
password = "Password"
passwordChangedSuccess = "Password changed successfully! Please sign in with your new password."
@@ -4883,12 +4883,10 @@ enterUsername = "Enter username"
failedToSignIn = "Failed to sign in with {{provider}}: {{message}}"
forgotPassword = "Forgot your password?"
loggingIn = "Logging In..."
logIn = "Log In"
login = "Login"
magicLinkSent = "Magic link sent to {{email}}! Check your email and click the link to sign in."
mfaCode = "Authentication Code"
mfaRequired = "Two-factor code required"
noAccount = "Don't have an account?"
or = "Or"
password = "Password"
passwordChangedSuccess = "Password changed successfully! Please sign in with your new password."
@@ -4869,12 +4869,10 @@ enterUsername = "Introduce el nombre de usuario"
failedToSignIn = "Error al iniciar sesión con {{provider}}: {{message}}"
forgotPassword = "¿Has olvidado tu contraseña?"
loggingIn = "Iniciando sesión..."
logIn = "Iniciar sesión"
login = "Iniciar sesión"
magicLinkSent = "¡Enlace mágico enviado a {{email}}! Revisa tu correo electrónico y haz clic en el enlace para iniciar sesión."
mfaCode = "Código de autenticación"
mfaRequired = "Se requiere código de dos factores"
noAccount = "¿No tienes una cuenta?"
or = "O"
password = "Contraseña"
passwordChangedSuccess = "¡Contraseña cambiada correctamente! Inicia sesión con tu nueva contraseña."
@@ -4869,12 +4869,10 @@ enterUsername = "Sartu erabiltzaile-izena"
failedToSignIn = "Ezin izan da saioa hasi {{provider}}: {{message}}"
forgotPassword = "Ahaztu duzu pasahitza?"
loggingIn = "Saioa hasten..."
logIn = "Hasi saioa"
login = "Saioa hasi"
magicLinkSent = "Esteka magikoa bidali zaio {{email}} helbidera! Egiaztatu zure e-posta eta egin klik estekan saioa hasteko."
mfaCode = "Autentifikazio-kodea"
mfaRequired = "Bi faktoreko kodea behar da"
noAccount = "Ez duzu konturik?"
or = "Edo"
password = "Pasahitza"
passwordChangedSuccess = "Pasahitza ongi aldatu da! Hasi saioa pasahitz berriarekin."
@@ -4869,12 +4869,10 @@ enterUsername = "نام کاربری را وارد کنید"
failedToSignIn = "ورود با {{provider}} ناموفق بود: {{message}}"
forgotPassword = "گذرواژه خود را فراموش کرده‌اید؟"
loggingIn = "در حال ورود..."
logIn = "ورود"
login = "ورود"
magicLinkSent = "لینک جادویی به {{email}} ارسال شد! ایمیل خود را بررسی کرده و برای ورود روی لینک کلیک کنید."
mfaCode = "کد احراز هویت"
mfaRequired = "کد احراز هویت دومرحله‌ای لازم است"
noAccount = "حساب کاربری ندارید؟"
or = "یا"
password = "گذرواژه"
passwordChangedSuccess = "گذرواژه با موفقیت تغییر کرد! لطفاً با گذرواژه جدید خود وارد شوید."
@@ -4869,12 +4869,10 @@ enterUsername = "Saisissez le nom dutilisateur"
failedToSignIn = "Échec de connexion avec {{provider}} : {{message}}"
forgotPassword = "Mot de passe oublié ?"
loggingIn = "Connexion…"
logIn = "Se connecter"
login = "Se connecter"
magicLinkSent = "Lien magique envoyé à {{email}} ! Consultez votre e-mail et cliquez sur le lien pour vous connecter."
mfaCode = "Code d'authentification"
mfaRequired = "Code à deux facteurs requis"
noAccount = "Vous navez pas de compte ?"
or = "Ou"
password = "Mot de passe"
passwordChangedSuccess = "Mot de passe modifié avec succès ! Veuillez vous connecter avec votre nouveau mot de passe."
@@ -4869,12 +4869,10 @@ enterUsername = "Cuir isteach ainm úsáideora"
failedToSignIn = "Theip ar shíniú isteach le {{provider}}: {{message}}"
forgotPassword = "An ndearna tú dearmad ar d'fhocal faire?"
loggingIn = "Ag Logáil Isteach..."
logIn = "Logáil Isteach"
login = "Logáil isteach"
magicLinkSent = "Seoladh nasc draíochta chuig {{email}}! Seiceáil do ríomhphost agus cliceáil an nasc chun logáil isteach."
mfaCode = "Cód Fíordheimhnithe"
mfaRequired = "Cód dhá fhachtóir de dhíth"
noAccount = "Nach bhfuil cuntas agat?"
or = "Nó"
password = "Focal faire"
passwordChangedSuccess = "Athraíodh an focal faire go rathúil! Logáil isteach le do fhocal faire nua, le do thoil."
@@ -4869,12 +4869,10 @@ enterUsername = "उपयोगकर्ता नाम दर्ज करे
failedToSignIn = "{{provider}} के साथ साइन इन विफल: {{message}}"
forgotPassword = "पासवर्ड भूल गए?"
loggingIn = "लॉगिन हो रहा है..."
logIn = "लॉग इन"
login = "लॉगिन"
magicLinkSent = "मैजिक लिंक {{email}} पर भेज दिया गया! साइन इन करने के लिए अपना ईमेल जाँचें और लिंक पर क्लिक करें।"
mfaCode = "प्रमाणीकरण कोड"
mfaRequired = "दो-कारक कोड आवश्यक"
noAccount = "खाता नहीं है?"
or = "या"
password = "पासवर्ड"
passwordChangedSuccess = "पासवर्ड सफलतापूर्वक बदला गया! कृपया नए पासवर्ड से साइन इन करें।"
@@ -4869,12 +4869,10 @@ enterUsername = "Unesite korisničko ime"
failedToSignIn = "Prijava putem {{provider}} nije uspjela: {{message}}"
forgotPassword = "Zaboravili ste lozinku?"
loggingIn = "Prijavljivanje..."
logIn = "Prijavite se"
login = "Prijava"
magicLinkSent = "Magic link poslan na {{email}}! Provjerite e-poštu i kliknite poveznicu za prijavu."
mfaCode = "Autentikacijski kod"
mfaRequired = "Potreban je dvofaktorski kod"
noAccount = "Nemate račun?"
or = "Ili"
password = "Lozinka"
passwordChangedSuccess = "Lozinka je uspješno promijenjena! Prijavite se novom lozinkom."
@@ -4869,12 +4869,10 @@ enterUsername = "Adja meg felhasználónevét"
failedToSignIn = "Sikertelen bejelentkezés ezzel: {{provider}}: {{message}}"
forgotPassword = "Elfelejtette a jelszavát?"
loggingIn = "Bejelentkezés..."
logIn = "Bejelentkezés"
login = "Bejelentkezés"
magicLinkSent = "Magic Link elküldve ide: {{email}}! Ellenőrizze e-mailjét, és kattintson a linkre a bejelentkezéshez."
mfaCode = "Hitelesítési kód"
mfaRequired = "Kétfaktoros kód szükséges"
noAccount = "Nincs fiókja?"
or = "Vagy"
password = "Jelszó"
passwordChangedSuccess = "A jelszó sikeresen megváltozott! Jelentkezzen be az új jelszavával."
@@ -4869,12 +4869,10 @@ enterUsername = "Masukkan nama pengguna"
failedToSignIn = "Gagal masuk dengan {{provider}}: {{message}}"
forgotPassword = "Lupa kata sandi?"
loggingIn = "Sedang Masuk..."
logIn = "Masuk"
login = "Masuk"
magicLinkSent = "Tautan ajaib dikirim ke {{email}}! Periksa email Anda dan klik tautannya untuk masuk."
mfaCode = "Kode Autentikasi"
mfaRequired = "Kode autentikasi dua faktor diperlukan"
noAccount = "Belum punya akun?"
or = "Atau"
password = "Kata sandi"
passwordChangedSuccess = "Kata sandi berhasil diubah! Silakan masuk dengan kata sandi baru Anda."
@@ -4869,12 +4869,10 @@ enterUsername = "Inserisci nome utente"
failedToSignIn = "Accesso con {{provider}} non riuscito: {{message}}"
forgotPassword = "Hai dimenticato la password?"
loggingIn = "Accesso in corso..."
logIn = "Accedi"
login = "Accedi"
magicLinkSent = "Magic link inviato a {{email}}! Controlla la posta e clicca il link per accedere."
mfaCode = "Codice di autenticazione"
mfaRequired = "Codice a due fattori richiesto"
noAccount = "Non hai un account?"
or = "Oppure"
password = "Password"
passwordChangedSuccess = "Password modificata con successo! Accedi con la nuova password."
@@ -4869,12 +4869,10 @@ enterUsername = "ユーザー名を入力"
failedToSignIn = "{{provider}} でのサインインに失敗しました:{{message}}"
forgotPassword = "パスワードをお忘れですか?"
loggingIn = "サインイン中..."
logIn = "ログイン"
login = "ログイン"
magicLinkSent = "マジックリンクを {{email}} に送信しました! メールを確認してリンクをクリックし、サインインしてください。"
mfaCode = "認証コード"
mfaRequired = "二要素認証コードが必要です"
noAccount = "アカウントをお持ちでないですか?"
or = "または"
password = "パスワード"
passwordChangedSuccess = "パスワードを変更しました。新しいパスワードでサインインしてください。"
@@ -4869,12 +4869,10 @@ enterUsername = "사용자 이름 입력"
failedToSignIn = "{{provider}}로 로그인하지 못했습니다: {{message}}"
forgotPassword = "비밀번호를 잊으셨나요?"
loggingIn = "로그인 중..."
logIn = "로그인"
login = "로그인"
magicLinkSent = "매직 링크가 {{email}}로 전송되었습니다! 이메일을 확인하고 링크를 클릭해 로그인하세요."
mfaCode = "인증 코드"
mfaRequired = "2단계 인증 코드가 필요합니다"
noAccount = "계정이 없으신가요?"
or = "또는"
password = "비밀번호"
passwordChangedSuccess = "비밀번호가 성공적으로 변경되었습니다! 새 비밀번호로 로그인하세요."
@@ -4869,12 +4869,10 @@ enterUsername = "യൂസർനെയിം നൽകുക"
failedToSignIn = "{{provider}} ഉപയോഗിച്ച് സൈൻ ഇൻ ചെയ്യൽ പരാജയപ്പെട്ടു: {{message}}"
forgotPassword = "നിങ്ങളുടെ പാസ്‌വേഡ് മറന്നോ?"
loggingIn = "ലോഗിൻ ചെയ്യുന്നു..."
logIn = "ലോഗിൻ"
login = "ലോഗിൻ"
magicLinkSent = "മാജിക് ലിങ്ക് {{email}}-ലേക്ക് അയച്ചു! നിങ്ങളുടെ ഇമെയിൽ പരിശോധിച്ച് സൈൻ ഇൻ ചെയ്യാൻ ലിങ്ക് ക്ലിക്ക് ചെയ്യുക."
mfaCode = "സ്ഥിരീകരണ കോഡ്"
mfaRequired = "രണ്ടുഘട്ട കോഡ് ആവശ്യമാണ്"
noAccount = "account ഇല്ലേ?"
or = "അല്ലെങ്കിൽ"
password = "പാസ്‌വേഡ്"
passwordChangedSuccess = "പാസ്‌വേഡ് വിജയകരമായി മാറ്റി! നിങ്ങളുടെ പുതിയ പാസ്‌വേഡുമായ് ദയവായി സൈൻ ഇൻ ചെയ്യുക."
@@ -4869,12 +4869,10 @@ enterUsername = "Voer een gebruikersnaam in"
failedToSignIn = "Inloggen met {{provider}} mislukt: {{message}}"
forgotPassword = "Wachtwoord vergeten?"
loggingIn = "Inloggen..."
logIn = "Inloggen"
login = "Inloggen"
magicLinkSent = "Magic link verzonden naar {{email}}! Controleer uw e-mail en klik op de link om in te loggen."
mfaCode = "Authenticatiecode"
mfaRequired = "Tweefactorcode vereist"
noAccount = "Geen account?"
or = "Of"
password = "Wachtwoord"
passwordChangedSuccess = "Wachtwoord succesvol gewijzigd! Log in met uw nieuwe wachtwoord."
@@ -4869,12 +4869,10 @@ enterUsername = "Skriv inn brukernavn"
failedToSignIn = "Kunne ikke logge inn med {{provider}}: {{message}}"
forgotPassword = "Glemt passordet?"
loggingIn = "Logger inn..."
logIn = "Logg inn"
login = "Logg inn"
magicLinkSent = "Magisk lenke sendt til {{email}}! Sjekk e-posten din og klikk på lenken for å logge inn."
mfaCode = "Autentiseringskode"
mfaRequired = "Tofaktorkode kreves"
noAccount = "Har du ikke en konto?"
or = "Eller"
password = "Passord"
passwordChangedSuccess = "Passord endret! Logg inn med det nye passordet."
@@ -4869,12 +4869,10 @@ enterUsername = "Wpisz nazwę użytkownika"
failedToSignIn = "Nie udało się zalogować przez {{provider}}: {{message}}"
forgotPassword = "Nie pamiętasz hasła?"
loggingIn = "Logowanie..."
logIn = "Zaloguj się"
login = "Logowanie"
magicLinkSent = "Wysłano magiczny link na {{email}}! Sprawdź pocztę i kliknij link, aby się zalogować."
mfaCode = "Kod uwierzytelniający"
mfaRequired = "Wymagany kod dwuskładnikowy"
noAccount = "Nie masz konta?"
or = "lub"
password = "Hasło"
passwordChangedSuccess = "Hasło zostało zmienione! Zaloguj się nowym hasłem."
@@ -4869,12 +4869,10 @@ enterUsername = "Insira o nome de usuário"
failedToSignIn = "Falha ao entrar com {{provider}}: {{message}}"
forgotPassword = "Esqueceu sua senha?"
loggingIn = "Entrando..."
logIn = "Entrar"
login = "Login"
magicLinkSent = "Link mágico enviado para {{email}}! Verifique seu e-mail e clique no link para entrar."
mfaCode = "Código de autenticação"
mfaRequired = "Código de dois fatores necessário"
noAccount = "Não tem uma conta?"
or = "Ou"
password = "Senha"
passwordChangedSuccess = "Senha alterada com sucesso! Faça login com sua nova senha."
@@ -4869,12 +4869,10 @@ enterUsername = "Introduza o nome de utilizador"
failedToSignIn = "Falha ao iniciar sessão com {{provider}}: {{message}}"
forgotPassword = "Esqueceu-se da palavra-passe?"
loggingIn = "A iniciar sessão..."
logIn = "Iniciar sessão"
login = "Início de sessão"
magicLinkSent = "Ligação mágica enviada para {{email}}! Verifique o seu email e clique na ligação para iniciar sessão."
mfaCode = "Código de autenticação"
mfaRequired = "Código de dois fatores obrigatório"
noAccount = "Não tem uma conta?"
or = "Ou"
password = "Palavra-passe"
passwordChangedSuccess = "Palavra-passe alterada com sucesso! Inicie sessão com a sua nova palavra-passe."
@@ -4869,12 +4869,10 @@ enterUsername = "Introduceți numele de utilizator"
failedToSignIn = "Autentificarea cu {{provider}} a eșuat: {{message}}"
forgotPassword = "Ați uitat parola?"
loggingIn = "Autentificare..."
logIn = "Autentificare"
login = "Autentificare"
magicLinkSent = "Linkul magic a fost trimis la {{email}}! Verificați emailul și faceți clic pe link pentru a vă autentifica."
mfaCode = "Cod de autentificare"
mfaRequired = "Este necesar codul de autentificare cu doi factori"
noAccount = "Nu aveți un cont?"
or = "Sau"
password = "Parolă"
passwordChangedSuccess = "Parola a fost schimbată cu succes! Autentificați-vă cu noua parolă."
@@ -4869,12 +4869,10 @@ enterUsername = "Введите имя пользователя"
failedToSignIn = "Не удалось войти через {{provider}}: {{message}}"
forgotPassword = "Забыли пароль?"
loggingIn = "Вход..."
logIn = "Войти"
login = "Войти"
magicLinkSent = "Магическая ссылка отправлена на {{email}}! Проверьте почту и перейдите по ссылке для входа."
mfaCode = "Код аутентификации"
mfaRequired = "Требуется код двухфакторной аутентификации"
noAccount = "Нет аккаунта?"
or = "Или"
password = "Пароль"
passwordChangedSuccess = "Пароль успешно изменен! Пожалуйста, войдите с новым паролем."
@@ -4869,12 +4869,10 @@ enterUsername = "Zadajte používateľské meno"
failedToSignIn = "Prihlásenie cez {{provider}} zlyhalo: {{message}}"
forgotPassword = "Zabudli ste heslo?"
loggingIn = "Prihlasovanie..."
logIn = "Prihlásiť sa"
login = "Prihlásenie"
magicLinkSent = "Magický odkaz bol odoslaný na {{email}}! Skontrolujte si e-mail a kliknite na odkaz na prihlásenie."
mfaCode = "Overovací kód"
mfaRequired = "Vyžaduje sa dvojfaktorový kód"
noAccount = "Nemáte účet?"
or = "Alebo"
password = "Heslo"
passwordChangedSuccess = "Heslo bolo úspešne zmenené! Prihláste sa novým heslom."
@@ -4869,12 +4869,10 @@ enterUsername = "Vnesite uporabniško ime"
failedToSignIn = "Prijava s ponudnikom {{provider}} ni uspela: {{message}}"
forgotPassword = "Ste pozabili geslo?"
loggingIn = "Prijavljanje..."
logIn = "Prijava"
login = "Prijava"
magicLinkSent = "Čarobna povezava je poslana na {{email}}! Preverite e-pošto in kliknite povezavo za prijavo."
mfaCode = "Koda za preverjanje pristnosti"
mfaRequired = "Zahtevana je koda za dvofaktorsko preverjanje pristnosti"
noAccount = "Nimate računa?"
or = "Ali"
password = "Geslo"
passwordChangedSuccess = "Geslo je uspešno spremenjeno! Prijavite se z novim geslom."
@@ -4869,12 +4869,10 @@ enterUsername = "Unesite korisničko ime"
failedToSignIn = "Neuspešna prijava putem {{provider}}: {{message}}"
forgotPassword = "Zaboravili ste lozinku?"
loggingIn = "Prijavljivanje..."
logIn = "Prijava"
login = "Prijava"
magicLinkSent = "Magični link je poslat na {{email}}! Proverite e-mail i kliknite na link da biste se prijavili."
mfaCode = "Autentifikacioni kod"
mfaRequired = "Potreban je dvofaktorski kod"
noAccount = "Nemate nalog?"
or = "Ili"
password = "Lozinka"
passwordChangedSuccess = "Lozinka je uspešno promenjena! Prijavite se novom lozinkom."
@@ -4869,12 +4869,10 @@ enterUsername = "Ange användarnamn"
failedToSignIn = "Det gick inte att logga in med {{provider}}: {{message}}"
forgotPassword = "Glömt lösenordet?"
loggingIn = "Loggar in..."
logIn = "Logga in"
login = "Inloggning"
magicLinkSent = "Magisk länk skickad till {{email}}! Kontrollera din e-post och klicka på länken för att logga in."
mfaCode = "Autentiseringskod"
mfaRequired = "Tvåfaktorskod krävs"
noAccount = "Har du inget konto?"
or = "Eller"
password = "Lösenord"
passwordChangedSuccess = "Lösenordet har ändrats. Logga in med ditt nya lösenord."
@@ -4869,12 +4869,10 @@ enterUsername = "ป้อนชื่อผู้ใช้"
failedToSignIn = "ไม่สามารถลงชื่อเข้าใช้ด้วย {{provider}}: {{message}}"
forgotPassword = "ลืมรหัสผ่านหรือไม่?"
loggingIn = "กำลังเข้าสู่ระบบ..."
logIn = "ลงชื่อเข้าใช้"
login = "เข้าสู่ระบบ"
magicLinkSent = "ส่ง Magic Link ไปยัง {{email}} แล้ว! ตรวจสอบอีเมลของคุณและคลิกลิงก์เพื่อเข้าสู่ระบบ"
mfaCode = "รหัสยืนยันตัวตน"
mfaRequired = "ต้องใช้รหัสการยืนยันแบบสองปัจจัย"
noAccount = "ยังไม่มีบัญชีใช่ไหม?"
or = "หรือ"
password = "รหัสผ่าน"
passwordChangedSuccess = "เปลี่ยนรหัสผ่านสำเร็จ! โปรดลงชื่อเข้าใช้ด้วยรหัสผ่านใหม่ของคุณ"
@@ -4869,12 +4869,10 @@ enterUsername = "Kullanıcı adını girin"
failedToSignIn = "{{provider}} ile giriş yapılamadı: {{message}}"
forgotPassword = "Şifrenizi mi unuttunuz?"
loggingIn = "Giriş Yapılıyor..."
logIn = "Giriş Yap"
login = "Giriş"
magicLinkSent = "Sihirli bağlantı {{email}} adresine gönderildi! Giriş yapmak için e-postanızı kontrol edip bağlantıya tıklayın."
mfaCode = "Kimlik doğrulama kodu"
mfaRequired = "İki faktörlü kimlik doğrulama kodu gerekli"
noAccount = "Hesabınız yok mu?"
or = "Veya"
password = "Şifre"
passwordChangedSuccess = "Şifre başarıyla değiştirildi! Lütfen yeni şifrenizle giriş yapın."
@@ -4869,12 +4869,10 @@ enterUsername = "Введіть ім’я користувача"
failedToSignIn = "Не вдалося увійти через {{provider}}: {{message}}"
forgotPassword = "Забули пароль?"
loggingIn = "Вхід..."
logIn = "Увійти"
login = "Вхід"
magicLinkSent = "Магічне посилання надіслано на {{email}}! Перевірте пошту та перейдіть за посиланням, щоб увійти."
mfaCode = "Код автентифікації"
mfaRequired = "Потрібен код двофакторної автентифікації"
noAccount = "Немає облікового запису?"
or = "Або"
password = "Пароль"
passwordChangedSuccess = "Пароль успішно змінено! Увійдіть із новим паролем."
@@ -4869,12 +4869,10 @@ enterUsername = "Nhập tên người dùng"
failedToSignIn = "Không thể đăng nhập bằng {{provider}}: {{message}}"
forgotPassword = "Quên mật khẩu?"
loggingIn = "Đang đăng nhập..."
logIn = "Đăng nhập"
login = "Đăng nhập"
magicLinkSent = "Magic link đã được gửi tới {{email}}! Hãy kiểm tra email và nhấp vào liên kết để đăng nhập."
mfaCode = "Mã xác thực"
mfaRequired = "Yêu cầu mã hai yếu tố"
noAccount = "Chưa có tài khoản?"
or = "Hoặc"
password = "Mật khẩu"
passwordChangedSuccess = "Đổi mật khẩu thành công! Vui lòng đăng nhập bằng mật khẩu mới."
@@ -4869,12 +4869,10 @@ enterUsername = "输入用户名"
failedToSignIn = "使用 {{provider}} 登录失败:{{message}}"
forgotPassword = "忘记密码?"
loggingIn = "正在登录..."
logIn = "登录"
login = "登录"
magicLinkSent = "魔法链接已发送至 {{email}}!请检查邮箱并点击链接登录。"
mfaCode = "身份验证代码"
mfaRequired = "需要双重身份验证代码"
noAccount = "没有账户?"
or = "或"
password = "密码"
passwordChangedSuccess = "密码修改成功!请使用新密码登录。"
@@ -4869,12 +4869,10 @@ enterUsername = "输入用户名"
failedToSignIn = "使用 {{provider}} 登录失败:{{message}}"
forgotPassword = "忘记密码?"
loggingIn = "正在登录…"
logIn = "登录"
login = "登录"
magicLinkSent = "魔法链接已发送至 {{email}}!请检查邮箱并点击链接登录。"
mfaCode = "认证代码"
mfaRequired = "需要双重身份验证代码"
noAccount = "没有账户?"
or = "或"
password = "密码"
passwordChangedSuccess = "密码修改成功!请使用新密码登录。"
@@ -4869,12 +4869,10 @@ enterUsername = "輸入使用者名稱"
failedToSignIn = "使用 {{provider}} 登入失敗:{{message}}"
forgotPassword = "忘記密碼?"
loggingIn = "正在登入..."
logIn = "登入"
login = "登入"
magicLinkSent = "魔術連結已寄至 {{email}}!請查看您的電子郵件並點選連結登入。"
mfaCode = "驗證碼"
mfaRequired = "需要雙重驗證碼"
noAccount = "還沒有帳號?"
or = "或"
password = "密碼"
passwordChangedSuccess = "密碼變更成功!請使用新密碼登入。"
-6
View File
@@ -310,11 +310,6 @@
"title": "Sign In - Stirling PDF",
"description": "The Free Adobe Acrobat alternative (10M+ Downloads)"
},
"/signup": {
"image": "/og_images/home.png",
"title": "Sign Up - Stirling PDF",
"description": "The Free Adobe Acrobat alternative (10M+ Downloads)"
},
"/mobile-scanner": {
"image": "/og_images/home.png",
"title": "Mobile Scanner - Stirling PDF",
@@ -651,7 +646,6 @@
"/split-pdf-by-sections": "split",
"/split-pdf-by-chapters": "split",
"/login": "/login",
"/signup": "/signup",
"/mobile-scanner": "/mobile-scanner",
"/files": "/files",
"/settings": "/settings",
+6 -6
View File
@@ -311,11 +311,6 @@
"title": "Sign In - Stirling PDF",
"description": "The Free Adobe Acrobat alternative (10M+ Downloads)"
},
"/signup": {
"image": "/og_images/home.png",
"title": "Sign Up - Stirling PDF",
"description": "The Free Adobe Acrobat alternative (10M+ Downloads)"
},
"/mobile-scanner": {
"image": "/og_images/home.png",
"title": "Mobile Scanner - Stirling PDF",
@@ -536,6 +531,11 @@
"title": "Account Link Settings - Stirling PDF",
"description": "The Free Adobe Acrobat alternative (10M+ Downloads)"
},
"/signup": {
"image": "/og_images/home.png",
"title": "Sign Up - Stirling PDF",
"description": "The Free Adobe Acrobat alternative (10M+ Downloads)"
},
"/processor": {
"image": "/og_images/saas/app-processor.png",
"title": "Stirling Processor - Govern every PDF your organization touches",
@@ -664,7 +664,6 @@
"/split-pdf-by-sections": "split",
"/split-pdf-by-chapters": "split",
"/login": "/login",
"/signup": "/signup",
"/mobile-scanner": "/mobile-scanner",
"/files": "/files",
"/settings": "/settings",
@@ -709,6 +708,7 @@
"/settings/frontendThirdPartyLicenses": "/settings/frontendThirdPartyLicenses",
"/settings/payg": "/settings/payg",
"/settings/account-link": "/settings/account-link",
"/signup": "/signup",
"/processor": "/processor",
"/editor": "/editor"
}
@@ -181,11 +181,13 @@ const humanizeLabel = (s) =>
const pageTitles = {
"/login": "Sign In",
"/signup": "Sign Up",
"/mobile-scanner": "Mobile Scanner",
"/files": "Files",
"/settings": "Settings",
};
// Routes only the SaaS build serves - self-hosted has no signup page.
const SAAS_ONLY_PAGE_TITLES = { "/signup": "Sign Up" };
for (const key of navKeys)
pageTitles[`/settings/${key}`] = `${humanizeLabel(key)} Settings`;
@@ -215,6 +217,14 @@ const saasManifest = {
byTool: { ...byTool },
byPath: { ...byPath },
};
for (const [routePath, label] of Object.entries(SAAS_ONLY_PAGE_TITLES)) {
saasManifest.byTool[routePath] = {
image: `/og_images/${DEFAULT_IMAGE_BASENAME}.png`,
title: `${label} - ${SITE_NAME}`,
description: SITE_DESC,
};
saasManifest.byPath[routePath] = routePath;
}
for (const [routePath, entry] of Object.entries(SAAS_ROUTE_OVERRIDES)) {
saasManifest.byTool[routePath] = entry;
saasManifest.byPath[routePath] = routePath;
@@ -0,0 +1,52 @@
import type { Page } from "@playwright/test";
import { test, expect } from "@app/tests/helpers/stub-test-base";
/**
* Self-hosted has no self-service signup: accounts are created by an admin
* (`/api/v1/user/register` is not a public endpoint, so the old page could
* never have worked anonymously). The login screen must not advertise it and
* `/signup` must not render a signup form.
*/
test.describe("Self-hosted signup surface", () => {
test.use({
stubOptions: { enableLogin: true },
autoGoto: false,
});
const stubLoginUiData = async (page: Page) => {
await page.route("**/api/v1/proprietary/ui-data/login", (route) =>
route.fulfill({
json: {
enableLogin: true,
loginMethod: "all",
providerList: {},
ssoAutoLogin: false,
firstTimeSetup: false,
showDefaultCredentials: false,
},
}),
);
};
test("login page offers no sign-up link", async ({ page }) => {
await stubLoginUiData(page);
await page.goto("/login", { waitUntil: "domcontentloaded" });
await expect(page.locator("#email")).toBeVisible({ timeout: 10_000 });
await expect(page.getByText(/don't have an account/i)).toHaveCount(0);
await expect(page.getByRole("button", { name: /sign up/i })).toHaveCount(0);
});
test("/signup redirects to login instead of rendering a signup form", async ({
page,
}) => {
await stubLoginUiData(page);
await page.goto("/signup", { waitUntil: "domcontentloaded" });
await expect(page.locator("#email")).toBeVisible({ timeout: 10_000 });
await expect.poll(() => new URL(page.url()).pathname).toBe("/login");
await expect(page.locator("#confirmPassword")).toHaveCount(0);
});
});
+7 -3
View File
@@ -1,5 +1,5 @@
import { Suspense, lazy } from "react";
import { Routes, Route, useParams } from "react-router-dom";
import { Routes, Route, Navigate, useParams } from "react-router-dom";
import { AppProviders } from "@app/components/AppProviders";
import { AppLayout } from "@app/components/AppLayout";
import { LoadingFallback } from "@app/components/shared/LoadingFallback";
@@ -7,7 +7,6 @@ import { PreferencesProvider } from "@app/contexts/PreferencesContext";
import { ThemeProvider } from "@app/components/shared/ThemeProvider";
import Landing from "@app/routes/Landing";
import Login from "@app/routes/Login";
import Signup from "@app/routes/Signup";
import AuthCallback from "@app/routes/AuthCallback";
import InviteAccept from "@app/routes/InviteAccept";
import ShareLinkPage from "@app/routes/ShareLinkPage";
@@ -83,7 +82,12 @@ export default function App() {
<LoginLandingRedirect />
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
{/* Self-hosted has no signup - accounts are created by an
admin. Old links land on login instead. */}
<Route
path="/signup"
element={<Navigate to="/login" replace />}
/>
<Route path="/auth/callback" element={<AuthCallback />} />
<Route path="/invite/:token" element={<InviteAccept />} />
<Route path="/share/:token" element={<ShareLinkPage />} />
@@ -474,41 +474,6 @@ class SpringAuthClient {
}
}
/**
* Sign up new user
*/
async signUp(credentials: {
email: string;
password: string;
options?: { data?: { full_name?: string }; emailRedirectTo?: string };
}): Promise<AuthResponse> {
try {
const response = await http().post(
"/api/v1/user/register",
{
username: credentials.email,
password: credentials.password,
},
{
withCredentials: true,
},
);
const data = response.data;
// Note: Spring backend auto-confirms users (no email verification)
// Return user but no session (user needs to login)
return { user: data.user, session: null, error: null };
} catch (error: unknown) {
console.error("[SpringAuth] signUp error:", error);
return {
user: null,
session: null,
error: { message: getErrorMessage(error, "Registration failed") },
};
}
}
/**
* Sign in with OAuth/SAML provider (GitHub, Google, Authentik, etc.)
* This redirects to the Spring OAuth2/SAML2 authorization endpoint
@@ -227,67 +227,6 @@ describe("SpringAuthClient", () => {
});
});
describe("signUp", () => {
it("should successfully register new user", async () => {
const credentials = {
email: "newuser@example.com",
password: "newpassword123",
};
const mockUser = {
id: "456",
email: credentials.email,
username: credentials.email,
role: "USER",
};
vi.mocked(apiClient.post).mockResolvedValueOnce({
status: 200,
data: { user: mockUser },
} as unknown as AxiosResponse);
const result = await springAuth.signUp(credentials);
expect(apiClient.post).toHaveBeenCalledWith(
"/api/v1/user/register",
{
username: credentials.email,
password: credentials.password,
},
{ withCredentials: true },
);
expect(result.user).toEqual(mockUser);
expect(result.session).toBeNull(); // No auto-login on signup
expect(result.error).toBeNull();
});
it("should return error on failed registration", async () => {
expectConsole.error(/\[SpringAuth\] signUp error/);
const credentials = {
email: "existing@example.com",
password: "password123",
};
const errorMessage = "User already exists";
const mockError = Object.assign(new Error(errorMessage), {
isAxiosError: true,
response: {
status: 409,
data: { message: errorMessage },
},
});
vi.mocked(apiClient.post).mockRejectedValueOnce(mockError);
const result = await springAuth.signUp(credentials);
expect(result.user).toBeNull();
expect(result.session).toBeNull();
expect(result.error).toBeTruthy();
expect(result.error?.message).toBe(errorMessage);
});
});
describe("signOut", () => {
it("should successfully sign out and clear JWT", async () => {
const mockToken = "jwt-to-clear";
@@ -2,7 +2,6 @@ import { useState } from "react";
import type { Meta, StoryObj } from "@storybook/react-vite";
import { AuthShell } from "@app/auth/ui/AuthShell";
import SpringLoginForm from "@app/auth/ui/SpringLoginForm";
import AuthSignupPrompt from "@app/auth/ui/AuthSignupPrompt";
import AuthDefaultCredentials from "@app/auth/ui/AuthDefaultCredentials";
import type { SpringLoginState } from "@app/auth/ui/useSpringLogin";
import ErrorMessage from "@app/auth/ui/ErrorMessage";
@@ -34,8 +33,6 @@ interface LoginArgs {
providers: string[];
/** all = OAuth + email · normal = email only · oauth2 = SSO only. */
loginMethod: LoginMethod;
/** Show the "Don't have an account? Sign up" prompt below the form. */
showSignupPrompt: boolean;
/** Show the first-time-setup default admin credentials card. */
showDefaultCredentials: boolean;
}
@@ -73,7 +70,6 @@ function useFakeSpringLogin(
function LoginPreview({
providers,
loginMethod,
showSignupPrompt,
showDefaultCredentials,
}: LoginArgs) {
const login = useFakeSpringLogin(providers, loginMethod);
@@ -84,17 +80,14 @@ function LoginPreview({
logoSrc={loginHeader}
logoDarkSrc={darkLogo}
showEmailForm={login.isUserPassAllowed}
footer={
<>
{showDefaultCredentials && <AuthDefaultCredentials />}
{showSignupPrompt && <AuthSignupPrompt onSignUp={() => {}} />}
</>
}
footer={showDefaultCredentials ? <AuthDefaultCredentials /> : undefined}
/>
</AuthShell>
);
}
// The shared signup form, as used by the SaaS and desktop account screens.
// Self-hosted has no signup page - accounts are created by an admin.
function SignupPreview() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
@@ -155,10 +148,6 @@ const meta: Meta<LoginArgs> = {
description:
"all = OAuth + email · normal = email only · oauth2 = SSO only",
},
showSignupPrompt: {
control: "boolean",
description: "Show the sign-up prompt below the form",
},
showDefaultCredentials: {
control: "boolean",
description: "Show the first-time-setup default admin credentials card",
@@ -167,7 +156,6 @@ const meta: Meta<LoginArgs> = {
args: {
providers: ["google", "github", "oidc"],
loginMethod: "all",
showSignupPrompt: true,
showDefaultCredentials: false,
},
};
@@ -1,30 +0,0 @@
import { useTranslation } from "react-i18next";
import { Button } from "@app/ui/Button";
import "@app/auth/ui/auth.css";
interface AuthSignupPromptProps {
/** Navigate to the signup screen. */
onSignUp: () => void;
}
/**
* "Don't have an account? Sign up" row shown beneath the login form. The prompt
* is muted; the action reads as a blue link so it pops.
*/
export default function AuthSignupPrompt({ onSignUp }: AuthSignupPromptProps) {
const { t } = useTranslation();
return (
<div className="auth-signup-prompt">
<span>{t("login.noAccount", "Don't have an account?")}</span>
<Button
type="button"
variant="quiet"
accent="default"
onClick={onSignUp}
className="auth-signup-link"
>
{t("signup.signUp", "Sign up")}
</Button>
</div>
);
}
@@ -659,25 +659,6 @@
color: var(--auth-text-primary);
}
/* "Don't have an account? Sign up" row beneath the login form. */
.auth-signup-prompt {
display: flex;
align-items: center;
justify-content: center;
gap: 0.375rem; /* 6px */
margin-top: 1.5rem; /* 24px */
font-size: 0.875rem; /* 14px */
color: var(--auth-label-text);
}
.auth-signup-link.sui-btn.mantine-Button-root {
padding: 0;
min-height: 0;
height: auto;
font-size: 0.875rem; /* 14px */
font-weight: 700;
}
/* Email login button - red CTA style matching SaaS version */
.auth-cta-button {
background-color: var(--c-brand) !important;
@@ -17,7 +17,6 @@ import { useBackendProbe } from "@app/hooks/useBackendProbe";
import { BASE_PATH, withBasePath } from "@app/constants/app";
import { updateSupportedLanguages } from "@app/i18n";
import SpringLoginForm from "@app/auth/ui/SpringLoginForm";
import AuthSignupPrompt from "@app/auth/ui/AuthSignupPrompt";
import AuthDefaultCredentials from "@app/auth/ui/AuthDefaultCredentials";
import { useSpringLogin } from "@app/auth/ui/useSpringLogin";
import LoggedInState from "@app/routes/login/LoggedInState";
@@ -485,14 +484,9 @@ export default function Login() {
) : undefined
}
footer={
<>
{isFirstTimeSetup &&
showDefaultCredentials &&
isUserPassAllowed && <AuthDefaultCredentials />}
{isUserPassAllowed && (
<AuthSignupPrompt onSignUp={() => navigate("/signup")} />
)}
</>
isFirstTimeSetup && showDefaultCredentials && isUserPassAllowed ? (
<AuthDefaultCredentials />
) : undefined
}
/>
</AuthLayout>
@@ -1,145 +0,0 @@
import { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useTranslation } from "react-i18next";
import { useDocumentMeta } from "@app/hooks/useDocumentMeta";
import { useAuth } from "@app/auth/UseSession";
import AuthLayout from "@app/routes/authShared/AuthLayout";
import "@app/auth/ui/auth.css";
import { BASE_PATH, withBasePath } from "@app/constants/app";
// Import signup components
import ErrorMessage from "@app/auth/ui/ErrorMessage";
import DividerWithText from "@app/components/shared/DividerWithText";
import SignupForm from "@app/routes/signup/SignupForm";
import {
useSignupFormValidation,
SignupFieldErrors,
} from "@app/routes/signup/SignupFormValidation";
import { useAuthService } from "@app/routes/signup/AuthService";
import { Button } from "@app/ui/Button";
import loginHeader from "@app/assets/brand/modern-logo/LoginLightModeHeader.svg";
export default function Signup() {
const navigate = useNavigate();
const { t } = useTranslation();
const { session, loading } = useAuth();
const [isSigningUp, setIsSigningUp] = useState(false);
const [error, setError] = useState<string | null>(null);
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [fieldErrors, setFieldErrors] = useState<SignupFieldErrors>({});
// Redirect immediately if user has valid session (JWT already validated by AuthProvider)
useEffect(() => {
if (!loading && session) {
console.debug("[Signup] User already authenticated, redirecting to home");
navigate("/", { replace: true });
}
}, [session, loading, navigate]);
const baseUrl = window.location.origin + BASE_PATH;
// Set document meta
useDocumentMeta({
title: `${t("signup.title", "Create an account")} - Stirling PDF`,
description: t(
"app.description",
"The Free Adobe Acrobat alternative (10M+ Downloads)",
),
ogTitle: `${t("signup.title", "Create an account")} - Stirling PDF`,
ogDescription: t(
"app.description",
"The Free Adobe Acrobat alternative (10M+ Downloads)",
),
ogImage: `${baseUrl}/og_images/home.png`,
ogUrl: `${window.location.origin}${window.location.pathname}`,
});
const { validateSignupForm } = useSignupFormValidation();
const { signUp } = useAuthService();
const handleSignUp = async () => {
const validation = validateSignupForm(email, password, confirmPassword);
if (!validation.isValid) {
setError(validation.error);
setFieldErrors(validation.fieldErrors || {});
return;
}
try {
setIsSigningUp(true);
setError(null);
setFieldErrors({});
const result = await signUp(email, password, "");
if (result.user) {
// Show success message and redirect to login
setError(null);
setTimeout(() => navigate("/login"), 2000);
}
} catch (err) {
console.error("[Signup] Unexpected error:", err);
setError(
err instanceof Error
? err.message
: t("signup.unexpectedError", { message: "Unknown error" }),
);
} finally {
setIsSigningUp(false);
}
};
return (
<AuthLayout>
<div className="auth-logo-block">
<img
src={loginHeader}
alt="Stirling PDF"
className="auth-logo-header auth-logo-header--light"
/>
<img
src={withBasePath("/modern-logo/LoginDarkModeHeader.svg")}
alt="Stirling PDF"
className="auth-logo-header auth-logo-header--dark"
/>
</div>
<ErrorMessage error={error} />
{/* Signup form - shown immediately */}
<SignupForm
email={email}
password={password}
confirmPassword={confirmPassword}
setEmail={setEmail}
setPassword={setPassword}
setConfirmPassword={setConfirmPassword}
onSubmit={handleSignUp}
isSubmitting={isSigningUp}
fieldErrors={fieldErrors}
showName={false}
showTerms={false}
/>
<DividerWithText
text={t("signup.or", "or")}
respondsToDarkMode={false}
opacity={0.4}
/>
{/* Bottom row - centered */}
<div style={{ textAlign: "center", margin: "0.5rem 0 0.25rem" }}>
<Button
variant="tertiary"
onClick={() => navigate("/login")}
className="auth-link-black"
style={{ color: "var(--c-primary)" }}
>
{t("login.logIn", "Log In")}
</Button>
</div>
</AuthLayout>
);
}
@@ -1,51 +0,0 @@
import { springAuth } from "@app/auth/spring/springAuthClient";
import { BASE_PATH } from "@app/constants/app";
export const useAuthService = () => {
const signUp = async (email: string, password: string, name: string) => {
console.log("[Signup] Creating account for:", email);
const { user, session, error } = await springAuth.signUp({
email: email.trim(),
password: password,
options: {
data: { full_name: name },
emailRedirectTo: `${BASE_PATH}/auth/callback`,
},
});
if (error) {
console.error("[Signup] Sign up error:", error);
throw new Error(error.message);
}
if (user) {
console.log("[Signup] Sign up successful:", user);
return {
user: user,
session: session,
requiresEmailConfirmation: user && !session,
};
}
throw new Error("Unknown error occurred during signup");
};
const signInWithProvider = async (
provider: "github" | "google" | "apple" | "azure",
) => {
const { error } = await springAuth.signInWithOAuth({
provider,
options: { redirectTo: `${BASE_PATH}/auth/callback` },
});
if (error) {
throw new Error(error.message);
}
};
return {
signUp,
signInWithProvider,
};
};
+7 -3
View File
@@ -1,5 +1,5 @@
import { Suspense } from "react";
import { Routes, Route, useParams } from "react-router-dom";
import { Routes, Route, Navigate, useParams } from "react-router-dom";
import { AppProviders } from "@app/components/AppProviders";
import { AppLayout } from "@app/components/AppLayout";
import { LoadingFallback } from "@app/components/shared/LoadingFallback";
@@ -7,7 +7,6 @@ import { PreferencesProvider } from "@app/contexts/PreferencesContext";
import { ThemeProvider } from "@app/components/shared/ThemeProvider";
import Landing from "@app/routes/Landing";
import Login from "@app/routes/Login";
import Signup from "@app/routes/Signup";
import AuthCallback from "@app/routes/AuthCallback";
import InviteAccept from "@app/routes/InviteAccept";
import ShareLinkPage from "@app/routes/ShareLinkPage";
@@ -61,7 +60,12 @@ export default function App() {
<AppLayout>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
{/* Self-hosted has no signup - accounts are created by an
admin. Old links land on login instead. */}
<Route
path="/signup"
element={<Navigate to="/login" replace />}
/>
<Route path="/auth/callback" element={<AuthCallback />} />
<Route path="/invite/:token" element={<InviteAccept />} />
<Route path="/share/:token" element={<ShareLinkPage />} />