From 561eab0f0e1518924c677742f8a5dfb466cde6d3 Mon Sep 17 00:00:00 2001 From: "stirlingbot[bot]" <195170888+stirlingbot[bot]@users.noreply.github.com> Date: Sun, 30 Mar 2025 12:11:05 +0100 Subject: [PATCH 01/18] :globe_with_meridians: Sync Translations + Update README Progress Table (#3263) ### Description of Changes This Pull Request was automatically generated to synchronize updates to translation files and documentation. Below are the details of the changes made: #### **1. Synchronization of Translation Files** - Updated translation files (`messages_*.properties`) to reflect changes in the reference file `messages_en_GB.properties`. - Ensured consistency and synchronization across all supported language files. - Highlighted any missing or incomplete translations. #### **2. Update README.md** - Generated the translation progress table in `README.md`. - Added a summary of the current translation status for all supported languages. - Included up-to-date statistics on translation coverage. #### **Why these changes are necessary** - Keeps translation files aligned with the latest reference updates. - Ensures the documentation reflects the current translation progress. --- Auto-generated by [create-pull-request][1]. [1]: https://github.com/peter-evans/create-pull-request --------- Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com> --- README.md | 2 +- src/main/resources/messages_pl_PL.properties | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index dc227034..5aace961 100644 --- a/README.md +++ b/README.md @@ -139,7 +139,7 @@ Stirling-PDF currently supports 39 languages! | Korean (한국어) (ko_KR) | ![95%](https://geps.dev/progress/95) | | Norwegian (Norsk) (no_NB) | ![89%](https://geps.dev/progress/89) | | Persian (فارسی) (fa_IR) | ![90%](https://geps.dev/progress/90) | -| Polish (Polski) (pl_PL) | ![82%](https://geps.dev/progress/82) | +| Polish (Polski) (pl_PL) | ![98%](https://geps.dev/progress/98) | | Portuguese (Português) (pt_PT) | ![93%](https://geps.dev/progress/93) | | Portuguese Brazilian (Português) (pt_BR) | ![96%](https://geps.dev/progress/96) | | Romanian (Română) (ro_RO) | ![77%](https://geps.dev/progress/77) | diff --git a/src/main/resources/messages_pl_PL.properties b/src/main/resources/messages_pl_PL.properties index 7cde4c3e..dcc4350e 100644 --- a/src/main/resources/messages_pl_PL.properties +++ b/src/main/resources/messages_pl_PL.properties @@ -1036,10 +1036,10 @@ decrypt.unexpectedError=Wystąpił błąd podczas przetwarzania pliku. Spróbuj decrypt.serverError=Błąd serwera podczas odszyfrowywania: {0} decrypt.success=Plik został pomyślnie odszyfrowany. -#multiTool-advert -multiTool-advert.message=Ta funkcja jest również dostępna na naszej stronie narzędzia wielofunkcyjnego. Sprawdź ją, aby uzyskać lepszy interfejs zarządzania stronami i dodatkowe funkcje! +#multiTool-advert +multiTool-advert.message=Ta funkcja jest również dostępna na naszej stronie narzędzia wielofunkcyjnego. Sprawdź ją, aby uzyskać lepszy interfejs zarządzania stronami i dodatkowe funkcje! -#view pdf +#view pdf viewPdf.title=Przeglądaj/Edytuj PDF viewPdf.header=Podejrzyj PDF From 7ba2884280e7c4a407b425e3691259b426246a61 Mon Sep 17 00:00:00 2001 From: "stirlingbot[bot]" <195170888+stirlingbot[bot]@users.noreply.github.com> Date: Sun, 30 Mar 2025 12:11:20 +0100 Subject: [PATCH 02/18] =?UTF-8?q?=F0=9F=A4=96=20format=20everything=20with?= =?UTF-8?q?=20pre-commit=20by=20=20(#3265)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Auto-generated by [create-pull-request][1] with **stirlingbot** [1]: https://github.com/peter-evans/create-pull-request Signed-off-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com> Co-authored-by: stirlingbot[bot] <195170888+stirlingbot[bot]@users.noreply.github.com> --- src/main/resources/static/js/usage.js | 56 +++++++++++++-------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/main/resources/static/js/usage.js b/src/main/resources/static/js/usage.js index a9c98ed9..624e4ec7 100644 --- a/src/main/resources/static/js/usage.js +++ b/src/main/resources/static/js/usage.js @@ -27,7 +27,7 @@ function getChartColors() { } // Watch for theme changes and update chart if needed -function setupThemeChangeListener() { +function setupThemeChangeListener() { // Start observing theme changes document.addEventListener("modeChanged", (event) => { @@ -41,7 +41,7 @@ function setupThemeChangeListener() { } }, 100); }); - + // Also watch for system preference changes window .matchMedia('(prefers-color-scheme: dark)') @@ -60,22 +60,22 @@ function setupThemeChangeListener() { function filterData() { const includeHome = document.getElementById('hideHomeCheckbox').checked; const includeLogin = document.getElementById('hideLoginCheckbox').checked; - + filteredData = allEndpointData.filter(item => { if (!includeHome && item.endpoint === '/') return false; if (!includeLogin && item.endpoint === '/login') return false; return true; }); - + // Sort and calculate sortedData = [...filteredData].sort((a, b) => b.count - a.count); totalEndpoints = filteredData.length; totalVisits = filteredData.reduce((sum, item) => sum + item.count, 0); - + // Update stats document.getElementById('totalEndpoints').textContent = totalEndpoints.toLocaleString(); document.getElementById('totalVisits').textContent = totalVisits.toLocaleString(); - + // Update the chart with current limit const currentLimit = document.getElementById('currentlyShowing').textContent; const limit = (currentLimit === endpointStatsTranslations.all) @@ -96,33 +96,33 @@ async function fetchEndpointData() { ${endpointStatsTranslations.loading} `; chartContainer.appendChild(loadingDiv); - + // Also add animation to refresh button const refreshBtn = document.getElementById('refreshBtn'); refreshBtn.classList.add('refreshing'); refreshBtn.disabled = true; - + const response = await fetch('/api/v1/info/load/all'); if (!response.ok) { throw new Error('Network response was not ok'); } - + const data = await response.json(); allEndpointData = data; - + // Apply filters filterData(); - + // Remove loading state chartContainer.removeChild(loadingDiv); refreshBtn.classList.remove('refreshing'); refreshBtn.disabled = false; - + } catch (error) { console.error('Error fetching endpoint data:', error); // Show error message to user showError(endpointStatsTranslations.failedToLoad); - + // Reset refresh button const refreshBtn = document.getElementById('refreshBtn'); refreshBtn.classList.remove('refreshing'); @@ -141,24 +141,24 @@ function formatEndpointName(endpoint) { function updateTable(data) { const tableBody = document.getElementById('endpointTableBody'); tableBody.innerHTML = ''; - + data.forEach((item, index) => { const percentage = ((item.count / totalVisits) * 100).toFixed(2); const row = document.createElement('tr'); - + // Format endpoint for better readability let displayEndpoint = item.endpoint; if (displayEndpoint.length > 40) { displayEndpoint = displayEndpoint.substring(0, 37) + '...'; } - + row.innerHTML = ` ${index + 1} ${displayEndpoint} ${item.count.toLocaleString()} ${percentage}% `; - + tableBody.appendChild(row); }); } @@ -172,10 +172,10 @@ function updateChart(dataLimit) { const displayedPercentage = totalVisits > 0 ? ((displayedVisits / totalVisits) * 100).toFixed(2) : '0'; - + document.getElementById('displayedVisits').textContent = displayedVisits.toLocaleString(); document.getElementById('displayedPercentage').textContent = displayedPercentage; - + // If the limit equals the total filtered items, show "All"; otherwise "Top X" document.getElementById('currentlyShowing').textContent = (dataLimit === filteredData.length) @@ -303,30 +303,30 @@ function updateChart(dataLimit) { document.addEventListener('DOMContentLoaded', function() { // Set up theme change listener setupThemeChangeListener(); - + // Initial data fetch fetchEndpointData(); - + // Set up button event listeners document.getElementById('top10Btn').addEventListener('click', function() { updateChart(10); setActiveButton(this); }); - + document.getElementById('top20Btn').addEventListener('click', function() { updateChart(20); setActiveButton(this); }); - + document.getElementById('allBtn').addEventListener('click', function() { updateChart(filteredData.length); setActiveButton(this); }); - + document.getElementById('refreshBtn').addEventListener('click', function() { fetchEndpointData(); }); - + // Set up filter checkbox listeners document.getElementById('hideHomeCheckbox').addEventListener('change', filterData); document.getElementById('hideLoginCheckbox').addEventListener('change', filterData); @@ -350,14 +350,14 @@ function showError(message) { error ${message} `; - + chartContainer.innerHTML = ''; chartContainer.appendChild(errorDiv); - + // Add retry button functionality document.getElementById('errorRetryBtn').addEventListener('click', fetchEndpointData); } From bcf7fab825bc672ab6745e2fe77b2403a5cb1ad0 Mon Sep 17 00:00:00 2001 From: Ludy Date: Sun, 30 Mar 2025 16:20:05 +0200 Subject: [PATCH 03/18] Add default authority assignment and enhanced user creation method (#3266) # Description of Changes Please provide a summary of the changes, including: - **What was changed**: - Automatically assign the `USER` role to newly created users in the `saveUser(String username, String password)` method. - Introduced a new `saveUser(String username, String password, boolean firstLogin, boolean enabled)` method to allow setting `firstLogin` and `enabled` flags at creation time. - Added `"anonymoususer"` to the list of restricted usernames in `isUsernameValid`. - **Why the change was made**: - Ensures users have proper default roles assigned to avoid permission issues post-creation. - Provides more flexibility for user creation in scenarios like pre-provisioning or scripting users with specific states. - Prevents the creation of potentially reserved or insecure usernames like `anonymoususer`. --- ## Checklist ### General - [x] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [x] 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/HowToAddNewLanguage.md) (if applicable) - [x] I have performed a self-review of my own code - [x] 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/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### 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/DeveloperGuide.md#6-testing) for more details. --- .../SPDF/config/security/UserService.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/stirling/software/SPDF/config/security/UserService.java b/src/main/java/stirling/software/SPDF/config/security/UserService.java index 155ed76b..f3627d49 100644 --- a/src/main/java/stirling/software/SPDF/config/security/UserService.java +++ b/src/main/java/stirling/software/SPDF/config/security/UserService.java @@ -205,6 +205,7 @@ public class UserService implements UserServiceInterface { user.setPassword(passwordEncoder.encode(password)); user.setEnabled(true); user.setAuthenticationType(AuthenticationType.WEB); + user.addAuthority(new Authority(Role.USER.getRoleId(), user)); userRepository.save(user); databaseService.exportDatabase(); } @@ -230,6 +231,22 @@ public class UserService implements UserServiceInterface { saveUser(username, password, role, false); } + public void saveUser(String username, String password, boolean firstLogin, boolean enabled) + throws IllegalArgumentException, SQLException, UnsupportedProviderException { + if (!isUsernameValid(username)) { + throw new IllegalArgumentException(getInvalidUsernameMessage()); + } + User user = new User(); + user.setUsername(username); + user.setPassword(passwordEncoder.encode(password)); + user.addAuthority(new Authority(Role.USER.getRoleId(), user)); + user.setEnabled(enabled); + user.setAuthenticationType(AuthenticationType.WEB); + user.setFirstLogin(firstLogin); + userRepository.save(user); + databaseService.exportDatabase(); + } + public void deleteUser(String username) { Optional userOpt = findByUsernameIgnoreCase(username); if (userOpt.isPresent()) { @@ -352,6 +369,7 @@ public class UserService implements UserServiceInterface { List notAllowedUserList = new ArrayList<>(); notAllowedUserList.add("ALL_USERS".toLowerCase()); + notAllowedUserList.add("anonymoususer"); boolean notAllowedUser = notAllowedUserList.contains(username.toLowerCase()); return (isValidSimpleUsername || isValidEmail) && !notAllowedUser; } From 3f0e8786941d23e5661d9ef220a0beb85a00299e Mon Sep 17 00:00:00 2001 From: daenur Date: Mon, 31 Mar 2025 10:54:34 +0300 Subject: [PATCH 04/18] Fix Ukrainian & Russian translation (#3271) # Description of Changes Ukrainian & Russian translation has been improved Closes #(issue_number) --- ## Checklist ### General - [x] 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/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/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### 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/DeveloperGuide.md#6-testing) for more details. --- src/main/resources/messages_ru_RU.properties | 48 ++++++++++---------- src/main/resources/messages_uk_UA.properties | 48 ++++++++++---------- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/main/resources/messages_ru_RU.properties b/src/main/resources/messages_ru_RU.properties index 5df70b61..ac4d80d0 100644 --- a/src/main/resources/messages_ru_RU.properties +++ b/src/main/resources/messages_ru_RU.properties @@ -138,7 +138,7 @@ analytics.settings=Вы можете изменить настройки ана # NAVBAR # ############# navbar.favorite=Избранное -navbar.recent=New and recently updated +navbar.recent=Новое и недавно обновленное navbar.darkmode=Темный режим navbar.language=Языки navbar.settings=Настройки @@ -233,29 +233,29 @@ adminUserSettings.totalUsers=Всего пользователей: adminUserSettings.lastRequest=Последний запрос adminUserSettings.usage=View Usage -endpointStatistics.title=Endpoint Statistics -endpointStatistics.header=Endpoint Statistics -endpointStatistics.top10=Top 10 -endpointStatistics.top20=Top 20 -endpointStatistics.all=All -endpointStatistics.refresh=Refresh -endpointStatistics.includeHomepage=Include Homepage ('/') -endpointStatistics.includeLoginPage=Include Login Page ('/login') -endpointStatistics.totalEndpoints=Total Endpoints -endpointStatistics.totalVisits=Total Visits -endpointStatistics.showing=Showing -endpointStatistics.selectedVisits=Selected Visits -endpointStatistics.endpoint=Endpoint -endpointStatistics.visits=Visits -endpointStatistics.percentage=Percentage -endpointStatistics.loading=Loading... -endpointStatistics.failedToLoad=Failed to load endpoint data. Please try refreshing. -endpointStatistics.home=Home -endpointStatistics.login=Login -endpointStatistics.top=Top -endpointStatistics.numberOfVisits=Number of Visits -endpointStatistics.visitsTooltip=Visits: {0} ({1}% of total) -endpointStatistics.retry=Retry +endpointStatistics.title=Статистика конечных точек +endpointStatistics.header=Статистика конечных точек +endpointStatistics.top10=Топ 10 +endpointStatistics.top20=Топ 20 +endpointStatistics.all=Все +endpointStatistics.refresh=Обновить +endpointStatistics.includeHomepage=Включить главную страницу ('/') +endpointStatistics.includeLoginPage=Включить страницу входа ('/login') +endpointStatistics.totalEndpoints=Всего конечных точек +endpointStatistics.totalVisits=Всего посещений +endpointStatistics.showing=Показано +endpointStatistics.selectedVisits=Выбранные посещения +endpointStatistics.endpoint=Конечная точка +endpointStatistics.visits=Посещения +endpointStatistics.percentage=Процент +endpointStatistics.loading=Загрузка... +endpointStatistics.failedToLoad=Не удалось загрузить данные конечной точки. Пожалуйста, попробуйте обновить. +endpointStatistics.home=Главная +endpointStatistics.login=Вход +endpointStatistics.top=Топ +endpointStatistics.numberOfVisits=Количество посещений +endpointStatistics.visitsTooltip=Посещения: {0} ({1}% от общего числа) +endpointStatistics.retry=Повторить database.title=Импорт/экспорт базы данных database.header=Импорт/экспорт базы данных diff --git a/src/main/resources/messages_uk_UA.properties b/src/main/resources/messages_uk_UA.properties index 2dc40e30..e1bc3da2 100644 --- a/src/main/resources/messages_uk_UA.properties +++ b/src/main/resources/messages_uk_UA.properties @@ -233,29 +233,29 @@ adminUserSettings.totalUsers=Всього користувачів: adminUserSettings.lastRequest=Останній запит adminUserSettings.usage=View Usage -endpointStatistics.title=Endpoint Statistics -endpointStatistics.header=Endpoint Statistics -endpointStatistics.top10=Top 10 -endpointStatistics.top20=Top 20 -endpointStatistics.all=All -endpointStatistics.refresh=Refresh -endpointStatistics.includeHomepage=Include Homepage ('/') -endpointStatistics.includeLoginPage=Include Login Page ('/login') -endpointStatistics.totalEndpoints=Total Endpoints -endpointStatistics.totalVisits=Total Visits -endpointStatistics.showing=Showing -endpointStatistics.selectedVisits=Selected Visits -endpointStatistics.endpoint=Endpoint -endpointStatistics.visits=Visits -endpointStatistics.percentage=Percentage -endpointStatistics.loading=Loading... -endpointStatistics.failedToLoad=Failed to load endpoint data. Please try refreshing. -endpointStatistics.home=Home -endpointStatistics.login=Login -endpointStatistics.top=Top -endpointStatistics.numberOfVisits=Number of Visits -endpointStatistics.visitsTooltip=Visits: {0} ({1}% of total) -endpointStatistics.retry=Retry +endpointStatistics.title=Статистика кінцевих точок +endpointStatistics.header=Статистика кінцевих точок +endpointStatistics.top10=Топ 10 +endpointStatistics.top20=Топ 20 +endpointStatistics.all=Всі +endpointStatistics.refresh=Оновити +endpointStatistics.includeHomepage=Включити головну сторінку ('/') +endpointStatistics.includeLoginPage=Включити сторінку входу ('/login') +endpointStatistics.totalEndpoints=Всього кінцевих точок +endpointStatistics.totalVisits=Всього відвідувань +endpointStatistics.showing=Показано +endpointStatistics.selectedVisits=Вибрані відвідування +endpointStatistics.endpoint=Кінцева точка +endpointStatistics.visits=Відвідування +endpointStatistics.percentage=Відсоток +endpointStatistics.loading=Завантаження... +endpointStatistics.failedToLoad=Не вдалося завантажити дані кінцевих точок. Спробуйте оновити. +endpointStatistics.home=Головна +endpointStatistics.login=Вхід +endpointStatistics.top=Топ +endpointStatistics.numberOfVisits=Кількість відвідувань +endpointStatistics.visitsTooltip=Відвідування: {0} ({1}% від загальної кількості) +endpointStatistics.retry=Повторити database.title=Імпорт/експорт бази даних database.header=Імпорт/експорт бази даних @@ -282,7 +282,7 @@ session.refreshPage=Оновити сторінку ############# # HOME-PAGE # ############# -home.desc=Ваш локальний універсальний магазин для всіх ваших потреб у PDF. +home.desc=Ваше локальне рішення для всіх потреб, пов'язаних із PDF. home.searchBar=Пошук функцій... From 0b0c2c7c9e435f9da73b4a54dbf174b3e8b75545 Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Wed, 2 Apr 2025 13:31:42 +0100 Subject: [PATCH 05/18] Removing redundant logoutUrl from oauth (#3281) Removed redundant logoutUrl from oauth code --- ## Checklist ### General - [x] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [x] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [x] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md) (if applicable) - [x] I have performed a self-review of my own code - [x] My changes generate no new warnings ### Documentation - [x] 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) - [x] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [x] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [x] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing) for more details. --- .../SPDF/config/security/oauth2/OAuth2Configuration.java | 1 - .../software/SPDF/controller/web/OtherWebController.java | 3 ++- .../stirling/software/SPDF/model/ApplicationProperties.java | 1 - .../stirling/software/SPDF/model/provider/GitHubProvider.java | 1 - .../stirling/software/SPDF/model/provider/GoogleProvider.java | 1 - .../software/SPDF/model/provider/KeycloakProvider.java | 1 - .../java/stirling/software/SPDF/model/provider/Provider.java | 3 --- 7 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/main/java/stirling/software/SPDF/config/security/oauth2/OAuth2Configuration.java b/src/main/java/stirling/software/SPDF/config/security/oauth2/OAuth2Configuration.java index 4fe03c48..c43d8a60 100644 --- a/src/main/java/stirling/software/SPDF/config/security/oauth2/OAuth2Configuration.java +++ b/src/main/java/stirling/software/SPDF/config/security/oauth2/OAuth2Configuration.java @@ -186,7 +186,6 @@ public class OAuth2Configuration { oauth.getClientSecret(), oauth.getScopes(), UsernameAttribute.valueOf(oauth.getUseAsUsername().toUpperCase()), - oauth.getLogoutUrl(), null, null, null); diff --git a/src/main/java/stirling/software/SPDF/controller/web/OtherWebController.java b/src/main/java/stirling/software/SPDF/controller/web/OtherWebController.java index c70560e3..a4b2cc96 100644 --- a/src/main/java/stirling/software/SPDF/controller/web/OtherWebController.java +++ b/src/main/java/stirling/software/SPDF/controller/web/OtherWebController.java @@ -122,7 +122,8 @@ public class OtherWebController { return Arrays.stream(files) .filter(file -> file.getName().endsWith(".traineddata")) .map(file -> file.getName().replace(".traineddata", "")) - .filter(lang -> !lang.equalsIgnoreCase("osd")).sorted() + .filter(lang -> !lang.equalsIgnoreCase("osd")) + .sorted() .toList(); } diff --git a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java index 36f6f82b..6956a28f 100644 --- a/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java +++ b/src/main/java/stirling/software/SPDF/model/ApplicationProperties.java @@ -230,7 +230,6 @@ public class ApplicationProperties { private Collection scopes = new ArrayList<>(); private String provider; private Client client = new Client(); - private String logoutUrl; public void setScopes(String scopes) { List scopesList = diff --git a/src/main/java/stirling/software/SPDF/model/provider/GitHubProvider.java b/src/main/java/stirling/software/SPDF/model/provider/GitHubProvider.java index 8d8aaf80..7057ec90 100644 --- a/src/main/java/stirling/software/SPDF/model/provider/GitHubProvider.java +++ b/src/main/java/stirling/software/SPDF/model/provider/GitHubProvider.java @@ -29,7 +29,6 @@ public class GitHubProvider extends Provider { clientSecret, scopes, useAsUsername != null ? useAsUsername : UsernameAttribute.LOGIN, - null, AUTHORIZATION_URI, TOKEN_URI, USER_INFO_URI); diff --git a/src/main/java/stirling/software/SPDF/model/provider/GoogleProvider.java b/src/main/java/stirling/software/SPDF/model/provider/GoogleProvider.java index a8e65c61..1bb217c9 100644 --- a/src/main/java/stirling/software/SPDF/model/provider/GoogleProvider.java +++ b/src/main/java/stirling/software/SPDF/model/provider/GoogleProvider.java @@ -30,7 +30,6 @@ public class GoogleProvider extends Provider { clientSecret, scopes, useAsUsername, - null, AUTHORIZATION_URI, TOKEN_URI, USER_INFO_URI); diff --git a/src/main/java/stirling/software/SPDF/model/provider/KeycloakProvider.java b/src/main/java/stirling/software/SPDF/model/provider/KeycloakProvider.java index bf272599..c01d27c2 100644 --- a/src/main/java/stirling/software/SPDF/model/provider/KeycloakProvider.java +++ b/src/main/java/stirling/software/SPDF/model/provider/KeycloakProvider.java @@ -29,7 +29,6 @@ public class KeycloakProvider extends Provider { useAsUsername, null, null, - null, null); } diff --git a/src/main/java/stirling/software/SPDF/model/provider/Provider.java b/src/main/java/stirling/software/SPDF/model/provider/Provider.java index da1d19f3..c15bc34a 100644 --- a/src/main/java/stirling/software/SPDF/model/provider/Provider.java +++ b/src/main/java/stirling/software/SPDF/model/provider/Provider.java @@ -25,7 +25,6 @@ public class Provider { private String clientSecret; private Collection scopes; private UsernameAttribute useAsUsername; - private String logoutUrl; private String authorizationUri; private String tokenUri; private String userInfoUri; @@ -38,7 +37,6 @@ public class Provider { String clientSecret, Collection scopes, UsernameAttribute useAsUsername, - String logoutUrl, String authorizationUri, String tokenUri, String userInfoUri) { @@ -50,7 +48,6 @@ public class Provider { this.scopes = scopes == null ? new ArrayList<>() : scopes; this.useAsUsername = useAsUsername != null ? validateUsernameAttribute(useAsUsername) : EMAIL; - this.logoutUrl = logoutUrl; this.authorizationUri = authorizationUri; this.tokenUri = tokenUri; this.userInfoUri = userInfoUri; From d55823ecb1f17b974e45c2873c03dc11f7078314 Mon Sep 17 00:00:00 2001 From: Dario Ghunney Ware Date: Wed, 2 Apr 2025 13:37:19 +0100 Subject: [PATCH 06/18] MacOS Installer for `x86_64` Distributions (#3269) - Updated `jpackage` task to create an additional installer for MacOS with Intel (x86_64) chips - Created tasks to download zulu-jre-17 to a temp folder to use when building x86_64 installer and then delete afterwards Closes #1531 --- ## Checklist ### General - [x] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [x] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [x] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md) (if applicable) - [x] I have performed a self-review of my own code - [x] My changes generate no new warnings ### Documentation - [x] 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) - [x] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [x] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ### Testing (if applicable) - [x] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing) for more details. --- .github/workflows/multiOSReleases.yml | 1 + build.gradle | 144 ++++++++++++++++++++++---- 2 files changed, 126 insertions(+), 19 deletions(-) diff --git a/.github/workflows/multiOSReleases.yml b/.github/workflows/multiOSReleases.yml index 12c36510..6ddf64c2 100644 --- a/.github/workflows/multiOSReleases.yml +++ b/.github/workflows/multiOSReleases.yml @@ -180,6 +180,7 @@ jobs: mv "./build/jpackage/Stirling-PDF-${{ needs.read_versions.outputs.version }}.exe" "./binaries/Stirling-PDF-win-installer.exe" elif [ "${{ matrix.os }}" = "macos-latest" ]; then mv "./build/jpackage/Stirling-PDF-${{ needs.read_versions.outputs.versionMac }}.dmg" "./binaries/Stirling-PDF-mac-installer.dmg" + mv "./build/jpackage/Stirling-PDF-x86_64-${{ needs.read_versions.outputs.versionMac }}.dmg" "./binaries/Stirling-PDF-mac-x86_64-installer.dmg" else mv "./build/jpackage/stirling-pdf_${{ needs.read_versions.outputs.version }}-1_amd64.deb" "./binaries/Stirling-PDF-linux-installer.deb" fi diff --git a/build.gradle b/build.gradle index 8a9c2f69..a8d2e19b 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,9 @@ plugins { } import com.github.jk1.license.render.* +import org.gradle.internal.os.OperatingSystem +import java.nio.file.Files +import java.time.Year ext { springBootVersion = "3.4.4" @@ -22,6 +25,7 @@ ext { bouncycastleVersion = "1.80" springSecuritySamlVersion = "6.4.4" openSamlVersion = "4.3.2" + tempJrePath = null } group = "stirling.software" @@ -102,8 +106,8 @@ openApi { } //0.11.5 to 2024.11.5 -def getMacVersion(String version) { - def currentYear = java.time.Year.now().getValue() +static def getMacVersion(String version) { + def currentYear = Year.now().getValue() def versionParts = version.split("\\.", 2) return "${currentYear}.${versionParts.length > 1 ? versionParts[1] : versionParts[0]}" } @@ -114,6 +118,7 @@ jpackage { mainJar = "Stirling-PDF-${project.version}.jar" appName = "Stirling-PDF" appVersion = project.version +// appVersion = "2005.45.1" vendor = "Stirling-Software" appDescription = "Stirling PDF - Your Local PDF Editor" icon = "src/main/resources/static/favicon.ico" @@ -160,22 +165,22 @@ jpackage { icon = "src/main/resources/static/favicon.icns" type = "dmg" macPackageIdentifier = "com.stirling.software.pdf" - macPackageName = "Stirling-PDF" + macPackageName = "Stirling-PDF_aarch64" macAppCategory = "public.app-category.productivity" macSign = false // Enable signing macAppStore = false // Not targeting App Store initially - - //installDir = "Applications" - - // Add license and other documentation to DMG - /*macDmgContent = [ - "README.md", - "LICENSE", - "CHANGELOG.md" - ]*/ - - // Enable Mac-specific entitlements - //macEntitlements = "entitlements.plist" // You'll need to create this file +// +// //installDir = "Applications" +// +// // Add license and other documentation to DMG +// /*macDmgContent = [ +// "README.md", +// "LICENSE", +// "CHANGELOG.md" +// ]*/ +// +// // Enable Mac-specific entitlements +// //macEntitlements = "entitlements.plist" // You'll need to create this file } // Linux-specific configuration @@ -221,6 +226,107 @@ jpackage { licenseFile = "LICENSE" } +tasks.register('jpackageMacX64') { + group = 'distribution' + description = 'Packages app for MacOS x86_64' + + if (OperatingSystem.current().isMacOsX()) { + println "MacOS detected. Downloading temp JRE." + dependsOn("downloadTempJre") + } else { + return + } + + doLast { + def jrePath = project.ext.tempJrePath + + if (!jrePath) { + throw new GradleException("JRE path not found.") + } + + def outputStream = new ByteArrayOutputStream() + def errorStream = new ByteArrayOutputStream() + + def result = exec { + commandLine 'jpackage', + '--type', 'dmg', + '--name', 'Stirling-PDF-x86_64', + '--input', 'build/libs', + '--main-jar', "Stirling-PDF-${project.version}.jar", + '--main-class', 'stirling.software.SPDF.SPDFApplication', + '--runtime-image', file(jrePath + "/zulu-17.jre/Contents/Home"), + '--dest', 'build/jpackage', + '--icon', 'src/main/resources/static/favicon.icns', + '--app-version', getMacVersion(project.version.toString()), + '--mac-package-name', 'Stirling-PDF', + '--mac-package-identifier', 'com.stirling.software.pdf', + '--mac-app-category', 'public.app-category.productivity' + standardOutput = outputStream + errorOutput = errorStream + ignoreExitValue = true + } + + def stdout = outputStream.toString("UTF-8") + def stderr = errorStream.toString("UTF-8") + + if (!stdout.isBlank()) { + println "📝 jpackage stdout:\n$stdout" + } + + if (result.exitValue != 0) { + throw new GradleException("❌ jpackage failed with exit code ${result.exitValue}.\n\n$stderr") + } + } +} + +jpackage.finalizedBy(jpackageMacX64) + +tasks.register('downloadTempJre') { + group = 'distribution' + description = 'Downloads and extracts a temporary JRE' + + doLast { + try { + def jreUrl = 'https://cdn.azul.com/zulu/bin/zulu17.56.15-ca-jre17.0.14-macosx_x64.tar.gz' + def tmpDir = Files.createTempDirectory('zulu-jre').toFile() + def jreArchive = new File(tmpDir, 'jre.tar.gz') + def jreDir = new File(tmpDir, 'jre') + + println "🔽 Downloading JRE to $jreArchive..." + jreArchive.withOutputStream { out -> + new URI(jreUrl).toURL().withInputStream { from -> out << from } + } + + println "📦 Extracting JRE to $jreDir..." + jreDir.mkdirs() + providers.exec { + commandLine 'tar', '-xzf', jreArchive.absolutePath, '-C', jreDir.absolutePath, '--strip-components=1' + }.result.get() + + println "✅ JRE ready at: $jreDir" + ext.tempJrePath = jreDir.absolutePath + project.ext.tempJrePath = jreDir.absolutePath + } catch (Exception e) { + println "Failed to download JRE. ${e.getLocalizedMessage()}" + cleanTempJre + } + } +} + +tasks.register('cleanTempJre') { + dependsOn('jpackageMacX64') + group = 'distribution' + description = 'Deletes the temporary JRE' + + doLast { + def path = project.ext.tempJrePath + + if (path && new File("$path").exists()) { + println "🧹 Cleaning up temporary JRE: $path" + new File("$path").parentFile.deleteDir() + } + } +} launch4j { icon = "${projectDir}/src/main/resources/static/favicon.ico" @@ -328,13 +434,13 @@ dependencies { implementation "org.springframework.boot:spring-boot-starter-thymeleaf:$springBootVersion" implementation 'com.posthog.java:posthog:1.2.0' implementation 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20240325.1' - + if (System.getenv("DOCKER_ENABLE_SECURITY") != "false") { - + implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'io.micrometer:micrometer-registry-prometheus' - + implementation "org.springframework.boot:spring-boot-starter-security:$springBootVersion" implementation "org.thymeleaf.extras:thymeleaf-extras-springsecurity5:3.1.3.RELEASE" implementation "org.springframework.boot:spring-boot-starter-data-jpa:$springBootVersion" @@ -459,12 +565,12 @@ jar { attributes "Implementation-Title": "Stirling-PDF", "Implementation-Version": project.version } - } tasks.named("test") { useJUnitPlatform() } + task printVersion { doLast { println project.version From 842581a747bae8f8febf6b7306540293150b399b Mon Sep 17 00:00:00 2001 From: Sai Kumar <40134996+saikumarjetti@users.noreply.github.com> Date: Wed, 2 Apr 2025 18:08:14 +0530 Subject: [PATCH 07/18] Validation for input file (#3196) # Description of Changes Please provide a summary of the changes, including: - Added an invalid event listener for the input element, which will be triggered if the input is empty and the element is required in the form. This is a global change, where all pages using this component will have this functionality. Closes #1841 --- ## Checklist ### General - [x] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [x] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [x] I have read the [How to add new languages to Stirling-PDF](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md) (if applicable) - [x] I have performed a self-review of my own code - [x] My changes generate no new warnings ### Documentation - [x] 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) - [x] I have read the section [Add New Translation Tags](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/HowToAddNewLanguage.md#add-new-translation-tags) (for new translation tags only) ### UI Changes (if applicable) - [x] Screenshots or videos demonstrating the UI changes are attached (e.g., as comments or direct attachments in the PR) ![image](https://github.com/user-attachments/assets/c53af9fa-b933-420f-9ee3-7b4600c44ea4) ![image](https://github.com/user-attachments/assets/8da04fa1-58be-42eb-977a-c850f917c011) ![image](https://github.com/user-attachments/assets/48dcce19-68c3-4676-a6d2-28b1b0e86004) ### Testing (if applicable) - [x] I have tested my changes locally. Refer to the [Testing Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md#6-testing) for more details. --------- Co-authored-by: Anthony Stirling <77850077+Frooodle@users.noreply.github.com> --- src/main/resources/messages_en_GB.properties | 3 ++- src/main/resources/messages_en_US.properties | 1 + src/main/resources/static/js/fileInput.js | 7 +++++++ src/main/resources/templates/fragments/common.html | 2 +- 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/resources/messages_en_GB.properties b/src/main/resources/messages_en_GB.properties index 1c02cac0..ea3f0e8d 100644 --- a/src/main/resources/messages_en_GB.properties +++ b/src/main/resources/messages_en_GB.properties @@ -83,6 +83,7 @@ loading=Loading... addToDoc=Add to Document reset=Reset apply=Apply +noFileSelected=No file selected. Please upload one. legal.privacy=Privacy Policy legal.terms=Terms and Conditions @@ -1308,7 +1309,7 @@ survey.button=Take Survey survey.dontShowAgain=Don't show again survey.meeting.1=If you're using Stirling PDF at work, we'd love to speak to you. We're offering technical support sessions in exchange for a 15 minute user discovery session. survey.meeting.2=This is a chance to: -survey.meeting.3=Get help with deployment, integrations, or troubleshooting +survey.meeting.3=Get help with deployment, integrations, or troubleshooting survey.meeting.4=Provide direct feedback on performance, edge cases, and feature gaps survey.meeting.5=Help us refine Stirling PDF for real-world enterprise use survey.meeting.6=If you're interested, you can book time with our team directly. (English speaking only) diff --git a/src/main/resources/messages_en_US.properties b/src/main/resources/messages_en_US.properties index 0c35d6c5..e56767c4 100644 --- a/src/main/resources/messages_en_US.properties +++ b/src/main/resources/messages_en_US.properties @@ -83,6 +83,7 @@ loading=Loading... addToDoc=Add to Document reset=Reset apply=Apply +noFileSelected=No file selected. Please upload one. legal.privacy=Privacy Policy legal.terms=Terms and Conditions diff --git a/src/main/resources/static/js/fileInput.js b/src/main/resources/static/js/fileInput.js index 7e89e6cc..28331ef0 100644 --- a/src/main/resources/static/js/fileInput.js +++ b/src/main/resources/static/js/fileInput.js @@ -35,6 +35,7 @@ function setupFileInput(chooser) { const pdfPrompt = chooser.getAttribute('data-bs-pdf-prompt'); const inputContainerId = chooser.getAttribute('data-bs-element-container-id'); const showUploads = chooser.getAttribute('data-bs-show-uploads') === "true"; + const noFileSelectedPrompt = chooser.getAttribute('data-bs-no-file-selected'); let inputContainer = document.getElementById(inputContainerId); const input = document.getElementById(elementId); @@ -58,6 +59,12 @@ function setupFileInput(chooser) { inputBtn.click(); }); + // Handle form validation if the input is left empty + input.addEventListener("invalid", (e) => { + e.preventDefault(); + alert(noFileSelectedPrompt); + }); + const dragenterListener = function () { dragCounter++; if (!overlay) { diff --git a/src/main/resources/templates/fragments/common.html b/src/main/resources/templates/fragments/common.html index 66fa94b5..a407f60e 100644 --- a/src/main/resources/templates/fragments/common.html +++ b/src/main/resources/templates/fragments/common.html @@ -228,7 +228,7 @@ loading: '[[#{loading}]]' };
+ th:attr="data-bs-unique-id=${name}, data-bs-element-id=${name+'-input'}, data-bs-element-container-id=${name+'-input-container'}, data-bs-show-uploads=${showUploads}, data-bs-files-selected=#{filesSelected}, data-bs-pdf-prompt=#{pdfPrompt}, data-bs-no-file-selected=#{noFileSelected}">