mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-14 10:34:06 +02:00
translations and login page (#5008)
# Description of Changes <!-- Please provide a summary of the changes, including: - What was changed - Why the change was made - Any challenges encountered Closes #(issue_number) --> --- ## 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/devGuide/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 tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/devGuide/DeveloperGuide.md#6-testing) for more details.
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
#############################################################################################################
|
||||
|
||||
security:
|
||||
enableLogin: false # set to 'true' to enable login
|
||||
enableLogin: true # set to 'true' to enable login
|
||||
csrfDisabled: false # set to 'true' to disable CSRF protection (not recommended for production)
|
||||
loginAttemptCount: 5 # lock user account after 5 tries; when using e.g. Fail2Ban you can deactivate the function with -1
|
||||
loginResetTimeMinutes: 120 # lock account for 2 hours after x attempts
|
||||
|
||||
+33
@@ -120,6 +120,37 @@ public class ProprietaryUIDataController {
|
||||
// Add enableLogin flag so frontend doesn't need to call /app-config
|
||||
data.setEnableLogin(securityProps.getEnableLogin());
|
||||
|
||||
// Check if this is first-time setup with default credentials
|
||||
// The isFirstLogin flag captures: default username/password usage and unchanged state
|
||||
boolean isFirstTimeSetup = false;
|
||||
boolean showDefaultCredentials = false;
|
||||
|
||||
List<User> allUsers = userRepository.findAll();
|
||||
List<User> realUsers =
|
||||
allUsers.stream()
|
||||
.filter(
|
||||
user ->
|
||||
!Role.INTERNAL_API_USER
|
||||
.getRoleId()
|
||||
.equals(user.getUsername()))
|
||||
.toList();
|
||||
long userCount = realUsers.size();
|
||||
|
||||
if (userCount == 0) {
|
||||
isFirstTimeSetup = true;
|
||||
showDefaultCredentials = true;
|
||||
} else if (userCount == 1) {
|
||||
Optional<User> adminUser = userRepository.findByUsernameIgnoreCase("admin");
|
||||
|
||||
if (adminUser.isPresent() && Boolean.TRUE.equals(adminUser.get().getIsFirstLogin())) {
|
||||
isFirstTimeSetup = true;
|
||||
showDefaultCredentials = true;
|
||||
}
|
||||
}
|
||||
|
||||
data.setFirstTimeSetup(isFirstTimeSetup);
|
||||
data.setShowDefaultCredentials(showDefaultCredentials);
|
||||
|
||||
OAUTH2 oauth = securityProps.getOauth2();
|
||||
|
||||
if (oauth != null && oauth.getEnabled()) {
|
||||
@@ -456,6 +487,8 @@ public class ProprietaryUIDataController {
|
||||
private Map<String, String> providerList;
|
||||
private String loginMethod;
|
||||
private boolean altLogin;
|
||||
private boolean firstTimeSetup;
|
||||
private boolean showDefaultCredentials;
|
||||
}
|
||||
|
||||
@Data
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -3517,6 +3517,8 @@
|
||||
"accountCreatedSuccess": "Account created successfully! You can now sign in.",
|
||||
"passwordChangedSuccess": "Password changed successfully! Please sign in with your new password.",
|
||||
"credentialsUpdated": "Your credentials have been updated. Please sign in again.",
|
||||
"defaultCredentials": "Default Login Credentials",
|
||||
"changePasswordWarning": "Please change your password after logging in for the first time",
|
||||
"slides": {
|
||||
"overview": {
|
||||
"alt": "Stirling PDF overview",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useNavigate, useSearchParams } from 'react-router-dom';
|
||||
import { Text, Stack, Alert } from '@mantine/core';
|
||||
import { springAuth } from '@app/auth/springAuthClient';
|
||||
import { useAuth } from '@app/auth/UseSession';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -29,6 +30,8 @@ export default function Login() {
|
||||
const [enabledProviders, setEnabledProviders] = useState<string[]>([]);
|
||||
const [hasSSOProviders, setHasSSOProviders] = useState(false);
|
||||
const [_enableLogin, setEnableLogin] = useState<boolean | null>(null);
|
||||
const [isFirstTimeSetup, setIsFirstTimeSetup] = useState(false);
|
||||
const [showDefaultCredentials, setShowDefaultCredentials] = useState(false);
|
||||
|
||||
// Redirect immediately if user has valid session (JWT already validated by AuthProvider)
|
||||
useEffect(() => {
|
||||
@@ -55,6 +58,10 @@ export default function Login() {
|
||||
|
||||
setEnableLogin(data.enableLogin ?? true);
|
||||
|
||||
// Set first-time setup flags
|
||||
setIsFirstTimeSetup(data.firstTimeSetup ?? false);
|
||||
setShowDefaultCredentials(data.showDefaultCredentials ?? false);
|
||||
|
||||
// Extract provider IDs from the providerList map
|
||||
// The keys are like "/oauth2/authorization/google" - extract the last part
|
||||
const providerIds = Object.keys(data.providerList || {})
|
||||
@@ -259,6 +266,31 @@ export default function Login() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Help section - only show on first-time setup with default credentials */}
|
||||
{isFirstTimeSetup && showDefaultCredentials && (
|
||||
<Alert
|
||||
color="blue"
|
||||
variant="light"
|
||||
radius="md"
|
||||
mt="xl"
|
||||
>
|
||||
<Stack gap="xs" align="center">
|
||||
<Text size="sm" fw={600} ta="center">
|
||||
{t('login.defaultCredentials', 'Default Login Credentials')}
|
||||
</Text>
|
||||
<Text size="sm" ta="center">
|
||||
<Text component="span" fw={600}>{t('login.username', 'Username')}:</Text> admin
|
||||
</Text>
|
||||
<Text size="sm" ta="center">
|
||||
<Text component="span" fw={600}>{t('login.password', 'Password')}:</Text> stirling
|
||||
</Text>
|
||||
<Text size="xs" c="dimmed" ta="center" mt="xs">
|
||||
{t('login.changePasswordWarning', 'Please change your password after logging in for the first time')}
|
||||
</Text>
|
||||
</Stack>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
</AuthLayout>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user