Merge remote-tracking branch 'origin/main' into config
This commit is contained in:
commit
f9111e556c
68 changed files with 184 additions and 80 deletions
34
README.md
34
README.md
|
@ -222,27 +222,47 @@ The Current list of settings is
|
|||
```yaml
|
||||
security:
|
||||
enableLogin: false # set to 'true' to enable login
|
||||
csrfDisabled: true
|
||||
csrfDisabled: true # Set to 'true' to disable CSRF protection (not recommended for production)
|
||||
loginAttemptCount: 5 # lock user account after 5 tries
|
||||
loginResetTimeMinutes : 120 # lock account for 2 hours after x attempts
|
||||
# initialLogin:
|
||||
# username: "admin" # Initial username for the first login
|
||||
# password: "stirling" # Initial password for the first login
|
||||
# oauth2:
|
||||
# enabled: false # set to 'true' to enable login (Note: enableLogin must also be 'true' for this to work)
|
||||
# issuer: "" # set to any provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) end-point
|
||||
# clientId: "" # Client ID from your provider
|
||||
# clientSecret: "" # Client Secret from your provider
|
||||
# autoCreateUser: false # set to 'true' to allow auto-creation of non-existing users
|
||||
# useAsUsername: "email" # Default is 'email'; custom fields can be used as the username
|
||||
# scopes: "openid, profile, email" # Specify the scopes for which the application will request permissions
|
||||
# provider: "google" # Set this to your OAuth provider's name, e.g., 'google' or 'keycloak'
|
||||
|
||||
system:
|
||||
defaultLocale: 'en-US' # Set the default language (e.g. 'de-DE', 'fr-FR', etc)
|
||||
googlevisibility: false # 'true' to allow Google visibility (via robots.txt), 'false' to disallow
|
||||
customStaticFilePath: '/customFiles/static/' # Directory path for custom static files
|
||||
rootURIPath: '/pdf-app' # ie set to /pdf-app to Set the application's root URI to localhost:8080/pdf-app
|
||||
customStaticFilePath: '/customFiles/static/' # Customise static files (e.g., logo, images, CSS) by placing them in this directory.
|
||||
maxFileSize: 10485760 # Maximum file size for uploads in bytes.
|
||||
enableAlphaFunctionality: false # Set to enable functionality which might need more testing before it fully goes live (This feature might make no changes)
|
||||
showUpdate: true # see when a new update is available
|
||||
showUpdateOnlyAdmin: false # Only admins can see when a new update is available, depending on showUpdate it must be set to 'true'
|
||||
customHTMLFiles: false # enable to have files placed in /customFiles/templates override the existing template html files
|
||||
|
||||
#ui:
|
||||
# appName: exampleAppName # Application's visible name
|
||||
# homeDescription: I am a description # Short description or tagline shown on homepage.
|
||||
# appNameNavbar: navbarName # Name displayed on the navigation bar
|
||||
ui:
|
||||
appName: null # Application's visible name
|
||||
homeDescription: null # Short description or tagline shown on homepage.
|
||||
appNameNavbar: null # Name displayed on the navigation bar
|
||||
|
||||
endpoints:
|
||||
toRemove: [] # List endpoints to disable (e.g. ['img-to-pdf', 'remove-pages'])
|
||||
groupsToRemove: [] # List groups to disable (e.g. ['LibreOffice'])
|
||||
|
||||
metrics:
|
||||
enabled: true # 'true' to enable Info APIs endpoints (view http://localhost:8080/swagger-ui/index.html#/API to learn more), 'false' to disable
|
||||
enabled: true # 'true' to enable Info APIs (`/api/*`) endpoints, 'false' to disable
|
||||
|
||||
autoPipeline:
|
||||
outputFolder: /output # Directory for auto-pipeline outputs.
|
||||
```
|
||||
|
||||
There is an additional config file ``/configs/custom_settings.yml`` were users familiar with java and spring application.properties can input their own settings on-top of Stirling-PDFs existing ones
|
||||
|
|
|
@ -54,10 +54,8 @@ public class InitialSecuritySetup {
|
|||
&& !initialPassword.isEmpty()
|
||||
&& !userService.findByUsernameIgnoreCase(initialUsername).isPresent()) {
|
||||
try {
|
||||
if (userService.isUsernameValid(initialUsername)) {
|
||||
userService.saveUser(initialUsername, initialPassword, Role.ADMIN.getRoleId());
|
||||
logger.info("Admin user created: " + initialUsername);
|
||||
}
|
||||
userService.saveUser(initialUsername, initialPassword, Role.ADMIN.getRoleId());
|
||||
logger.info("Admin user created: " + initialUsername);
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.error("Failed to initialize security setup", e);
|
||||
System.exit(1);
|
||||
|
|
|
@ -197,7 +197,13 @@ public class UserService implements UserServiceInterface {
|
|||
}
|
||||
|
||||
public boolean hasUsers() {
|
||||
return userRepository.count() > 0;
|
||||
long userCount = userRepository.count();
|
||||
if (userRepository
|
||||
.findByUsernameIgnoreCase(Role.INTERNAL_API_USER.getRoleId())
|
||||
.isPresent()) {
|
||||
userCount -= 1;
|
||||
}
|
||||
return userCount > 0;
|
||||
}
|
||||
|
||||
public void updateUserSettings(String username, Map<String, String> updates) {
|
||||
|
|
|
@ -4,9 +4,12 @@
|
|||
|
||||
security:
|
||||
enableLogin: false # set to 'true' to enable login
|
||||
csrfDisabled: true
|
||||
csrfDisabled: true # Set to 'true' to disable CSRF protection (not recommended for production)
|
||||
loginAttemptCount: 5 # lock user account after 5 tries
|
||||
loginResetTimeMinutes : 120 # lock account for 2 hours after x attempts
|
||||
# initialLogin:
|
||||
# username: "admin" # Initial username for the first login
|
||||
# password: "stirling" # Initial password for the first login
|
||||
# oauth2:
|
||||
# enabled: false # set to 'true' to enable login (Note: enableLogin must also be 'true' for this to work)
|
||||
# issuer: "" # set to any provider that supports OpenID Connect Discovery (/.well-known/openid-configuration) end-point
|
||||
|
@ -20,9 +23,13 @@ security:
|
|||
system:
|
||||
defaultLocale: 'en-US' # Set the default language (e.g. 'de-DE', 'fr-FR', etc)
|
||||
googlevisibility: false # 'true' to allow Google visibility (via robots.txt), 'false' to disallow
|
||||
rootURIPath: '/pdf-app' # ie set to /pdf-app to Set the application's root URI to localhost:8080/pdf-app
|
||||
customStaticFilePath: '/customFiles/static/' # Customise static files (e.g., logo, images, CSS) by placing them in this directory.
|
||||
maxFileSize: 10485760 # Maximum file size for uploads in bytes.
|
||||
enableAlphaFunctionality: false # Set to enable functionality which might need more testing before it fully goes live (This feature might make no changes)
|
||||
showUpdate: true # see when a new update is available
|
||||
showUpdateOnlyAdmin: false # Only admins can see when a new update is available, depending on showUpdate it must be set to 'true'
|
||||
customHTMLFiles: false # enable to have files placed in /customFiles/templates override the existing template html files
|
||||
|
||||
ui:
|
||||
appName: null # Application's visible name
|
||||
|
|
|
@ -65,7 +65,7 @@ label {
|
|||
margin-left: auto;
|
||||
}
|
||||
|
||||
#bg-card {
|
||||
.bg-card {
|
||||
background-color: var(--md-sys-color-surface-5);
|
||||
border-radius: 3rem;
|
||||
padding: 25px 0 0;
|
||||
|
|
|
@ -58,7 +58,7 @@ td {
|
|||
border-bottom: none;
|
||||
}
|
||||
|
||||
#bg-card {
|
||||
.bg-card {
|
||||
background-color: var(--md-sys-color-surface-5);
|
||||
border-radius: 3rem;
|
||||
padding: 2.5rem;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card"></div>
|
||||
<div class="col-md-6 bg-card"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
<span th:text="#{${messageType}}">Default message if not found</span>
|
||||
</div>
|
||||
</th:block>
|
||||
|
||||
<!-- At the top of the user settings -->
|
||||
<h3 class="text-center"><span th:text="#{welcome} + ' ' + ${username}">User</span>!</h3>
|
||||
<th:block th:if="${error}">
|
||||
|
@ -28,13 +29,15 @@
|
|||
<span th:text="${error}">Error Message</span>
|
||||
</div>
|
||||
</th:block>
|
||||
|
||||
<!-- Change Username Form -->
|
||||
<th:block th:if="${!oAuth2Login}">
|
||||
<h4 th:text="#{account.changeUsername}">Change Username?</h4>
|
||||
<form id="bg-card" class="mt-4 mb-4" action="api/v1/user/change-username" method="post">
|
||||
<form id="formsavechangeusername" class="bg-card mt-4 mb-4" action="api/v1/user/change-username" method="post">
|
||||
<div class="mb-3">
|
||||
<label for="newUsername" th:text="#{account.newUsername}">Change Username</label>
|
||||
<input type="text" class="form-control" name="newUsername" id="newUsername" th:placeholder="#{account.newUsername}">
|
||||
<span id="usernameError" style="display: none;" th:text="#{invalidUsernameMessage}">Invalid username!</span>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="currentPassword" th:text="#{password}">Password</label>
|
||||
|
@ -49,10 +52,10 @@
|
|||
<!-- Change Password Form -->
|
||||
<th:block th:if="${!oAuth2Login}">
|
||||
<h4 th:text="#{account.changePassword}">Change Password?</h4>
|
||||
<form id="bg-card" class="mt-4 mb-4" action="api/v1/user/change-password" method="post">
|
||||
<form id="formsavechangepassword" class="bg-card mt-4 mb-4" action="api/v1/user/change-password" method="post">
|
||||
<div class="mb-3">
|
||||
<label for="currentPassword" th:text="#{account.oldPassword}">Old Password</label>
|
||||
<input type="password" class="form-control" name="currentPassword" id="currentPasswordPassword" th:placeholder="#{account.oldPassword}">
|
||||
<input type="password" class="form-control" name="currentPassword" id="currentPassword" th:placeholder="#{account.oldPassword}">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="newPassword" th:text="#{account.newPassword}">New Password</label>
|
||||
|
@ -95,6 +98,76 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script th:inline="javascript">
|
||||
jQuery.validator.addMethod("usernamePattern", function(value, element) {
|
||||
return this.optional(element) || /^[a-zA-Z0-9][a-zA-Z0-9@._+-]*[a-zA-Z0-9]$|^(?=.{1,64}@)[A-Za-z0-9]+(\.[A-Za-z0-9_+.-]+)*@[^-][A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(\.[A-Za-z]{2,})$/.test(value);
|
||||
}, /*[[#{invalidUsernameMessage}]]*/ "Invalid username format");
|
||||
$(document).ready(function() {
|
||||
$('#formsavechangepassword').validate({
|
||||
rules: {
|
||||
currentPassword: {
|
||||
required: true
|
||||
},
|
||||
newPassword: {
|
||||
required: true
|
||||
},
|
||||
confirmNewPassword: {
|
||||
required: true
|
||||
}
|
||||
}
|
||||
});
|
||||
$('#formsavechangeusername').validate({
|
||||
rules: {
|
||||
newUsername: {
|
||||
required: true,
|
||||
usernamePattern: true
|
||||
},
|
||||
currentPassword: {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
messages: {
|
||||
newUsername: {
|
||||
usernamePattern: /*[[#{invalidUsernameMessage}]]*/ "Invalid username format"
|
||||
},
|
||||
},
|
||||
errorPlacement: function(error, element) {
|
||||
if (element.attr("name") === "newUsername") {
|
||||
$("#usernameError").text(error.text()).show();
|
||||
} else {
|
||||
error.insertAfter(element);
|
||||
}
|
||||
},
|
||||
success: function(label, element) {
|
||||
if ($(element).attr("name") === "newUsername") {
|
||||
$("#usernameError").hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
$('#formsavechangepassword').on('submit', function(event) {
|
||||
var newPassword = $('#newPassword').val();
|
||||
var confirmNewPassword = $('#confirmNewPassword').val();
|
||||
|
||||
if (newPassword !== confirmNewPassword) {
|
||||
alert('New Password and Confirm New Password must match.');
|
||||
event.preventDefault();
|
||||
}
|
||||
});
|
||||
$('#newUsername').on('input', function() {
|
||||
var usernameInput = $(this);
|
||||
var isValid = usernameInput[0].checkValidity();
|
||||
var errorSpan = $('#usernameError');
|
||||
|
||||
if (isValid) {
|
||||
usernameInput.removeClass('invalid').addClass('valid');
|
||||
errorSpan.hide();
|
||||
} else {
|
||||
usernameInput.removeClass('valid').addClass('invalid');
|
||||
errorSpan.show();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<script>
|
||||
function copyToClipboard() {
|
||||
|
@ -180,7 +253,7 @@
|
|||
</script>
|
||||
|
||||
<h4 th:text="#{account.syncTitle}">Sync browser settings with Account</h4>
|
||||
<div id="bg-card" class="container mt-4">
|
||||
<div class="bg-card container mt-4">
|
||||
<h3 th:text="#{account.settingsCompare}">Settings Comparison:</h3>
|
||||
<table id="settingsTable" class="table table-bordered table-sm table-striped">
|
||||
<thead>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8" id="bg-card">
|
||||
<div class="col-md-8 bg-card">
|
||||
|
||||
<!-- User Settings Title -->
|
||||
<h2 class="text-center" th:text="#{adminUserSettings.header}">Admin User Control Settings</h2>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon advance">cut</span>
|
||||
<span class="tool-header-text" th:text="#{autoSplitPDF.header}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-9" id="bg-card">
|
||||
<div class="col-md-9 bg-card">
|
||||
|
||||
<!-- User Settings Title -->
|
||||
<h2 class="text-center" th:text="#{changeCreds.header}">User Settings</h2>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon convert">draft</span>
|
||||
<span class="tool-header-text" th:text="#{fileToPDF.header}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="mb-3" id="bg-card">
|
||||
<div class="mb-3 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon convert">html</span>
|
||||
<span class="tool-header-text" th:text="#{HTMLToPDF.header}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon image">image</span>
|
||||
<span class="tool-header-text" th:text="#{imageToPDF.header}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon convert">markdown</span>
|
||||
<span class="tool-header-text" th:text="#{MarkdownToPDF.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon convert">csv</span>
|
||||
<span class="tool-header-text" th:text="#{PDFToCSV.header}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon convert">html</span>
|
||||
<span class="tool-header-text" th:text="#{PDFToHTML.header}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon image">image</span>
|
||||
<span class="tool-header-text" th:text="#{pdfToImage.header}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon convert">picture_as_pdf</span>
|
||||
<span class="tool-header-text" th:text="#{pdfToPDFA.header}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon ppt">slideshow</span>
|
||||
<span class="tool-header-text" th:text="#{PDFToPresentation.header}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon convert">text_fields</span>
|
||||
<span class="tool-header-text" th:text="#{PDFToText.header}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon word">description</span>
|
||||
<span class="tool-header-text" th:text="#{PDFToWord.header}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon convert">code</span>
|
||||
<span class="tool-header-text" th:text="#{PDFToXML.header}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon convert">link</span>
|
||||
<span class="tool-header-text" th:text="#{URLToPDF.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon organize">crop</span>
|
||||
<span class="tool-header-text" th:text="#{crop.header}"></span>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
|
||||
<div class="container">
|
||||
<div th:insert="~{fragments/errorBanner.html :: errorBanner}"></div>
|
||||
<div id="bg-card" class="text-center">
|
||||
<div class="bg-card text-center">
|
||||
<h1 class="display-2" th:text="#{oops}"></h1>
|
||||
<p class="lead" th:if="${param.status == '404'}" th:text="#{error.404.1}"></p>
|
||||
<p class="lead" th:unless="${param.status == '404'}" th:text="#{error.404.2}"></p>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon organize">upload</span>
|
||||
<span class="tool-header-text" th:text="#{pageExtracter.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<h2 th:text="#{licenses.header}">3rd Party licenses</h2>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container" id="dropContainer">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 "bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon organize">add_to_photos</span>
|
||||
<span class="tool-header-text" th:text="#{merge.header}"></span>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon other">add_photo_alternate</span>
|
||||
<span class="tool-header-text" th:text="#{addImage.header}"></span>
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon other">123</span>
|
||||
<span class="tool-header-text" th:text="#{addPageNumbers.header}"></span>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-12" id="bg-card">
|
||||
<div class="col-md-12 bg-card">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-3">
|
||||
<div id="sliders-container" style="display:none;">
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon advance">crop</span>
|
||||
<span class="tool-header-text" th:text="#{autoCrop.header}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon advance">text_fields_alt</span>
|
||||
<span class="tool-header-text" th:text="#{auto-rename.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon other">assignment</span>
|
||||
<span class="tool-header-text" th:text="#{changeMetadata.header}"></span>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-9" id="bg-card">
|
||||
<div class="col-md-9 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon other">compare</span>
|
||||
<span class="tool-header-text" th:text="#{compare.header}"></span>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon advance">zoom_in_map</span>
|
||||
<span class="tool-header-text" th:text="#{compress.header}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon advance">scanner</span>
|
||||
<span class="tool-header-text" th:text="#{home.ScannerImageSplit.title}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon other">photo_library</span>
|
||||
<span class="tool-header-text" th:text="#{extractImages.header}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon other">layers_clear</span>
|
||||
<span class="tool-header-text" th:text="#{flatten.header}"></span>
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon other">quick_reference_all</span>
|
||||
<span class="tool-header-text" th:text="#{ocr.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon other">thread_unread</span>
|
||||
<span class="tool-header-text" th:text="#{removeAnnotations.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon other">scan_delete</span>
|
||||
<span class="tool-header-text" th:text="#{removeBlanks.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon advance">build</span>
|
||||
<span class="tool-header-text" th:text="#{repair.header}"></span>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-12" id="bg-card">
|
||||
<div class="col-md-12 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon advance">javascript</span>
|
||||
<span class="tool-header-text" th:text="#{showJS.header}"></span>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon security">approval</span>
|
||||
<span class="tool-header-text" th:text="#{AddStampRequest.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon organize">dashboard</span>
|
||||
<span class="tool-header-text" th:text="#{pageLayout.header}"></span>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-12">
|
||||
<div id="bg-card">
|
||||
<div class="bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon advance">construction</span>
|
||||
<span class="tool-header-text" th:text="#{multiTool.header}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon advance">layers</span>
|
||||
<span class="tool-header-text" th:text="#{overlay-pdfs.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon organize">format_list_bulleted</span>
|
||||
<span class="tool-header-text" th:text="#{pdfOrganiser.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon organize">looks_one</span>
|
||||
<span class="tool-header-text" th:text="#{pdfToSinglePage.header}"></span>
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
<br /><br />
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon advance">family_history</span>
|
||||
<span class="tool-header-text" th:text="#{pipeline.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon organize">delete</span>
|
||||
<span class="tool-header-text" th:text="#{pageRemover.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon organize">rotate_right</span>
|
||||
<span class="tool-header-text" th:text="#{rotate.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon organize">fullscreen</span>
|
||||
<span class="tool-header-text" th:text="#{scalePages.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon security">lock</span>
|
||||
<span class="tool-header-text" th:text="#{addPassword.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon security">water_drop</span>
|
||||
<span class="tool-header-text" th:text="#{watermark.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon security">ink_eraser</span>
|
||||
<span class="tool-header-text" th:text="#{autoRedact.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon security">workspace_premium</span>
|
||||
<span class="tool-header-text" th:text="#{certSign.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon security">encrypted</span>
|
||||
<span class="tool-header-text" th:text="#{permissions.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon other">info</span>
|
||||
<span class="tool-header-text" th:text="#{getPdfInfo.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon security">lock_open_right</span>
|
||||
<span class="tool-header-text" th:text="#{removePassword.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon security">water_drop</span>
|
||||
<span class="tool-header-text" th:text="#{remove-watermark.header}"></span>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon security">sanitizer</span>
|
||||
<span class="tool-header-text" th:text="#{sanitizePDF.header}"></span>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon sign">signature</span>
|
||||
<span class="tool-header-text" th:text="#{sign.header}"></span>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon advance">vertical_split</span>
|
||||
<span class="tool-header-text" th:text="#{split-by-size-or-count.header}"></span>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon advance">grid_on</span>
|
||||
<span class="tool-header-text" th:text="#{split-by-sections.header}"></span>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<br><br>
|
||||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-6" id="bg-card">
|
||||
<div class="col-md-6 bg-card">
|
||||
<div class="tool-header">
|
||||
<span class="material-symbols-rounded tool-header-icon organize">cut</span>
|
||||
<span class="tool-header-text" th:text="#{split.header}"></span>
|
||||
|
|
Loading…
Reference in a new issue