mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2025-08-06 13:48:58 +02:00
Merge remote-tracking branch 'origin/main' into team
This commit is contained in:
commit
255c99b3de
2
.github/workflows/dependency-review.yml
vendored
2
.github/workflows/dependency-review.yml
vendored
@ -24,4 +24,4 @@ jobs:
|
|||||||
- name: "Checkout Repository"
|
- name: "Checkout Repository"
|
||||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||||
- name: "Dependency Review"
|
- name: "Dependency Review"
|
||||||
uses: actions/dependency-review-action@ce3cf9537a52e8119d91fd484ab5b8a807627bf8 # v4.6.0
|
uses: actions/dependency-review-action@38ecb5b593bf0eb19e335c03f97670f792489a8b # v4.7.0
|
||||||
|
@ -541,7 +541,7 @@ This would generate n entries of tr for each person in exampleData
|
|||||||
|
|
||||||
```html
|
```html
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" th:href="@{/new-feature}">New Feature</a>
|
<a class="nav-link" th:href="@{'/new-feature'}">New Feature</a>
|
||||||
</li>
|
</li>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ Visit our comprehensive documentation at [docs.stirlingpdf.com](https://docs.sti
|
|||||||
|
|
||||||
## Supported Languages
|
## Supported Languages
|
||||||
|
|
||||||
Stirling-PDF currently supports 39 languages!
|
Stirling-PDF currently supports 40 languages!
|
||||||
|
|
||||||
| Language | Progress |
|
| Language | Progress |
|
||||||
| -------------------------------------------- | -------------------------------------- |
|
| -------------------------------------------- | -------------------------------------- |
|
||||||
@ -156,7 +156,7 @@ Stirling-PDF currently supports 39 languages!
|
|||||||
| Turkish (Türkçe) (tr_TR) |  |
|
| Turkish (Türkçe) (tr_TR) |  |
|
||||||
| Ukrainian (Українська) (uk_UA) |  |
|
| Ukrainian (Українська) (uk_UA) |  |
|
||||||
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
| Vietnamese (Tiếng Việt) (vi_VN) |  |
|
||||||
|
| Malayalam (മലയാളം) (ml_ML) |  |
|
||||||
|
|
||||||
## Stirling PDF Enterprise
|
## Stirling PDF Enterprise
|
||||||
|
|
||||||
|
@ -479,7 +479,7 @@ dependencies {
|
|||||||
testImplementation "org.springframework.boot:spring-boot-starter-test:$springBootVersion"
|
testImplementation "org.springframework.boot:spring-boot-starter-test:$springBootVersion"
|
||||||
|
|
||||||
// Batik
|
// Batik
|
||||||
implementation "org.apache.xmlgraphics:batik-all:1.18"
|
implementation "org.apache.xmlgraphics:batik-all:1.19"
|
||||||
|
|
||||||
// TwelveMonkeys
|
// TwelveMonkeys
|
||||||
runtimeOnly "com.twelvemonkeys.imageio:imageio-batik:$imageioVersion"
|
runtimeOnly "com.twelvemonkeys.imageio:imageio-batik:$imageioVersion"
|
||||||
@ -527,7 +527,7 @@ dependencies {
|
|||||||
implementation "org.bouncycastle:bcprov-jdk18on:$bouncycastleVersion"
|
implementation "org.bouncycastle:bcprov-jdk18on:$bouncycastleVersion"
|
||||||
implementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastleVersion"
|
implementation "org.bouncycastle:bcpkix-jdk18on:$bouncycastleVersion"
|
||||||
implementation "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion"
|
implementation "org.springframework.boot:spring-boot-starter-actuator:$springBootVersion"
|
||||||
implementation "io.micrometer:micrometer-core:1.14.6"
|
implementation "io.micrometer:micrometer-core:1.14.7"
|
||||||
implementation group: "com.google.zxing", name: "core", version: "3.5.3"
|
implementation group: "com.google.zxing", name: "core", version: "3.5.3"
|
||||||
// https://mvnrepository.com/artifact/org.commonmark/commonmark
|
// https://mvnrepository.com/artifact/org.commonmark/commonmark
|
||||||
implementation "org.commonmark:commonmark:0.24.0"
|
implementation "org.commonmark:commonmark:0.24.0"
|
||||||
|
@ -73,7 +73,7 @@ public class InitialSetup {
|
|||||||
// Initialize Terms and Conditions
|
// Initialize Terms and Conditions
|
||||||
String termsUrl = applicationProperties.getLegal().getTermsAndConditions();
|
String termsUrl = applicationProperties.getLegal().getTermsAndConditions();
|
||||||
if (StringUtils.isEmpty(termsUrl)) {
|
if (StringUtils.isEmpty(termsUrl)) {
|
||||||
String defaultTermsUrl = "https://www.stirlingpdf.com/terms-and-conditions";
|
String defaultTermsUrl = "https://www.stirlingpdf.com/terms";
|
||||||
GeneralUtils.saveKeyToSettings("legal.termsAndConditions", defaultTermsUrl);
|
GeneralUtils.saveKeyToSettings("legal.termsAndConditions", defaultTermsUrl);
|
||||||
applicationProperties.getLegal().setTermsAndConditions(defaultTermsUrl);
|
applicationProperties.getLegal().setTermsAndConditions(defaultTermsUrl);
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ public class MetricsConfig {
|
|||||||
return new MeterFilter() {
|
return new MeterFilter() {
|
||||||
@Override
|
@Override
|
||||||
public MeterFilterReply accept(Meter.Id id) {
|
public MeterFilterReply accept(Meter.Id id) {
|
||||||
if (id.getName().equals("http.requests")) {
|
if ("http.requests".equals(id.getName())) {
|
||||||
return MeterFilterReply.NEUTRAL;
|
return MeterFilterReply.NEUTRAL;
|
||||||
}
|
}
|
||||||
return MeterFilterReply.DENY;
|
return MeterFilterReply.DENY;
|
||||||
|
@ -5,7 +5,9 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
|
|
||||||
import io.swagger.v3.oas.models.Components;
|
import io.swagger.v3.oas.models.Components;
|
||||||
import io.swagger.v3.oas.models.OpenAPI;
|
import io.swagger.v3.oas.models.OpenAPI;
|
||||||
|
import io.swagger.v3.oas.models.info.Contact;
|
||||||
import io.swagger.v3.oas.models.info.Info;
|
import io.swagger.v3.oas.models.info.Info;
|
||||||
|
import io.swagger.v3.oas.models.info.License;
|
||||||
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
import io.swagger.v3.oas.models.security.SecurityRequirement;
|
||||||
import io.swagger.v3.oas.models.security.SecurityScheme;
|
import io.swagger.v3.oas.models.security.SecurityScheme;
|
||||||
|
|
||||||
@ -31,14 +33,25 @@ public class OpenApiConfig {
|
|||||||
// default version if all else fails
|
// default version if all else fails
|
||||||
version = "1.0.0";
|
version = "1.0.0";
|
||||||
}
|
}
|
||||||
if (!applicationProperties.getSecurity().getEnableLogin()) {
|
Info info =
|
||||||
return new OpenAPI()
|
|
||||||
.components(new Components())
|
|
||||||
.info(
|
|
||||||
new Info()
|
new Info()
|
||||||
.title(DEFAULT_TITLE)
|
.title(DEFAULT_TITLE)
|
||||||
.version(version)
|
.version(version)
|
||||||
.description(DEFAULT_DESCRIPTION));
|
.license(
|
||||||
|
new License()
|
||||||
|
.name("MIT")
|
||||||
|
.url(
|
||||||
|
"https://raw.githubusercontent.com/Stirling-Tools/Stirling-PDF/refs/heads/main/LICENSE")
|
||||||
|
.identifier("MIT"))
|
||||||
|
.termsOfService("https://www.stirlingpdf.com/terms")
|
||||||
|
.contact(
|
||||||
|
new Contact()
|
||||||
|
.name("Stirling Software")
|
||||||
|
.url("https://www.stirlingpdf.com")
|
||||||
|
.email("contact@stirlingpdf.com"))
|
||||||
|
.description(DEFAULT_DESCRIPTION);
|
||||||
|
if (!applicationProperties.getSecurity().getEnableLogin()) {
|
||||||
|
return new OpenAPI().components(new Components()).info(info);
|
||||||
} else {
|
} else {
|
||||||
SecurityScheme apiKeyScheme =
|
SecurityScheme apiKeyScheme =
|
||||||
new SecurityScheme()
|
new SecurityScheme()
|
||||||
@ -47,11 +60,7 @@ public class OpenApiConfig {
|
|||||||
.name("X-API-KEY");
|
.name("X-API-KEY");
|
||||||
return new OpenAPI()
|
return new OpenAPI()
|
||||||
.components(new Components().addSecuritySchemes("apiKey", apiKeyScheme))
|
.components(new Components().addSecuritySchemes("apiKey", apiKeyScheme))
|
||||||
.info(
|
.info(info)
|
||||||
new Info()
|
|
||||||
.title(DEFAULT_TITLE)
|
|
||||||
.version(version)
|
|
||||||
.description(DEFAULT_DESCRIPTION))
|
|
||||||
.addSecurityItem(new SecurityRequirement().addList("apiKey"));
|
.addSecurityItem(new SecurityRequirement().addList("apiKey"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ premium:
|
|||||||
appId: ''
|
appId: ''
|
||||||
|
|
||||||
mail:
|
mail:
|
||||||
enabled: true # set to 'true' to enable sending emails
|
enabled: false # set to 'true' to enable sending emails
|
||||||
host: smtp.example.com # SMTP server hostname
|
host: smtp.example.com # SMTP server hostname
|
||||||
port: 587 # SMTP server port
|
port: 587 # SMTP server port
|
||||||
username: '' # SMTP server username
|
username: '' # SMTP server username
|
||||||
@ -85,7 +85,7 @@ mail:
|
|||||||
from: '' # sender email address
|
from: '' # sender email address
|
||||||
|
|
||||||
legal:
|
legal:
|
||||||
termsAndConditions: https://www.stirlingpdf.com/terms-and-conditions # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
|
termsAndConditions: https://www.stirlingpdf.com/terms # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
|
||||||
privacyPolicy: https://www.stirlingpdf.com/privacy-policy # URL to the privacy policy of your application (e.g. https://example.com/privacy). Empty string to disable or filename to load from local file in static folder
|
privacyPolicy: https://www.stirlingpdf.com/privacy-policy # URL to the privacy policy of your application (e.g. https://example.com/privacy). Empty string to disable or filename to load from local file in static folder
|
||||||
accessibilityStatement: '' # URL to the accessibility statement of your application (e.g. https://example.com/accessibility). Empty string to disable or filename to load from local file in static folder
|
accessibilityStatement: '' # URL to the accessibility statement of your application (e.g. https://example.com/accessibility). Empty string to disable or filename to load from local file in static folder
|
||||||
cookiePolicy: '' # URL to the cookie policy of your application (e.g. https://example.com/cookie). Empty string to disable or filename to load from local file in static folder
|
cookiePolicy: '' # URL to the cookie policy of your application (e.g. https://example.com/cookie). Empty string to disable or filename to load from local file in static folder
|
||||||
|
@ -2,11 +2,10 @@
|
|||||||
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}" xmlns:th="https://www.thymeleaf.org">
|
<html th:lang="${#locale.language}" th:dir="#{language.direction}" th:data-language="${#locale.toString()}" xmlns:th="https://www.thymeleaf.org">
|
||||||
<head>
|
<head>
|
||||||
<th:block th:insert="~{fragments/common :: head(title=#{adminUserSettings.title}, header=#{adminUserSettings.header})}"></th:block>
|
<th:block th:insert="~{fragments/common :: head(title=#{adminUserSettings.title}, header=#{adminUserSettings.header})}"></th:block>
|
||||||
<link rel="stylesheet" th:href="@{/css/modern-tables.css}">
|
|
||||||
<style>
|
<style>
|
||||||
.active-user {
|
.active-user {
|
||||||
color: var(--md-sys-color-tertiary);
|
color: green;
|
||||||
font-weight: 600;
|
text-shadow: 0 0 5px green;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-overflow {
|
.text-overflow {
|
||||||
@ -23,354 +22,215 @@
|
|||||||
<div id="page-container">
|
<div id="page-container">
|
||||||
<div id="content-wrap">
|
<div id="content-wrap">
|
||||||
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
|
<th:block th:insert="~{fragments/navbar.html :: navbar}"></th:block>
|
||||||
|
<br><br>
|
||||||
<div class="data-container">
|
<div class="container">
|
||||||
<div class="data-panel">
|
<div class="row justify-content-center">
|
||||||
<div class="data-header">
|
<div class="col-md-9 bg-card">
|
||||||
<h1 class="data-title">
|
<div class="tool-header">
|
||||||
<span class="data-icon">
|
<span class="material-symbols-rounded tool-header-icon organize">manage_accounts</span>
|
||||||
<span class="material-symbols-rounded">manage_accounts</span>
|
<span class="tool-header-text" th:text="#{adminUserSettings.header}">Admin User Control Settings</span>
|
||||||
</span>
|
|
||||||
<span th:text="#{adminUserSettings.header}">Admin User Control Settings</span>
|
|
||||||
</h1>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="data-body">
|
<!-- User Settings Title -->
|
||||||
<!-- User Stats Banner -->
|
<div style="background: var(--md-sys-color-outline-variant);padding: .8rem; margin: 10px 0; border-radius: 2rem; text-align: center;">
|
||||||
<div class="data-panel data-mb-3" style="background-color: var(--md-sys-color-primary-container);">
|
<a href="#"
|
||||||
<div class="data-body" style="padding: 1.25rem;">
|
|
||||||
<div style="display: flex; flex-wrap: wrap; justify-content: space-around; align-items: center; gap: 1.5rem;">
|
|
||||||
<div style="display: flex; align-items: center; gap: 0.75rem;">
|
|
||||||
<span class="material-symbols-rounded" style="font-size: 2.25rem; color: var(--md-sys-color-primary);">
|
|
||||||
group
|
|
||||||
</span>
|
|
||||||
<div>
|
|
||||||
<div style="color: var(--md-sys-color-primary); font-size: 0.875rem; font-weight: 500;" th:text="#{adminUserSettings.totalUsers}">Total Users</div>
|
|
||||||
<div style="color: var(--md-sys-color-primary); font-size: 1.5rem; font-weight: 700;">
|
|
||||||
<span th:text="${totalUsers}"></span>
|
|
||||||
<span th:if="${@runningProOrHigher}" th:text="'/' + ${maxPaidUsers}" style="font-size: 1rem;"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="display: flex; align-items: center; gap: 0.75rem;">
|
|
||||||
<span class="material-symbols-rounded" style="font-size: 2.25rem; color: var(--md-sys-color-primary);">
|
|
||||||
check_circle
|
|
||||||
</span>
|
|
||||||
<div>
|
|
||||||
<div style="color: var(--md-sys-color-primary); font-size: 0.875rem; font-weight: 500;" th:text="#{adminUserSettings.activeUsers}">Active Users</div>
|
|
||||||
<div style="color: var(--md-sys-color-primary); font-size: 1.5rem; font-weight: 700;" th:text="${activeUsers}"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="display: flex; align-items: center; gap: 0.75rem;">
|
|
||||||
<span class="material-symbols-rounded" style="font-size: 2.25rem; color: var(--md-sys-color-primary);">
|
|
||||||
person_off
|
|
||||||
</span>
|
|
||||||
<div>
|
|
||||||
<div style="color: var(--md-sys-color-primary); font-size: 0.875rem; font-weight: 500;" th:text="#{adminUserSettings.disabledUsers}">Disabled Users</div>
|
|
||||||
<div style="color: var(--md-sys-color-primary); font-size: 1.5rem; font-weight: 700;" th:text="${disabledUsers}"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Alert Messages -->
|
|
||||||
<div th:if="${addMessage}" class="alert alert-danger data-mb-3">
|
|
||||||
<span th:text="#{${addMessage}}">Default message if not found</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div th:if="${changeMessage}" class="alert alert-danger data-mb-3">
|
|
||||||
<span th:text="#{${changeMessage}}">Default message if not found</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div th:if="${deleteMessage}" class="alert alert-danger data-mb-3">
|
|
||||||
<span th:text="#{${deleteMessage}}">Default message if not found</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Admin Actions -->
|
|
||||||
<div class="data-section-title">User Management</div>
|
|
||||||
<div class="data-actions data-mb-3">
|
|
||||||
<button
|
|
||||||
th:data-bs-toggle="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? null : 'modal'"
|
th:data-bs-toggle="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? null : 'modal'"
|
||||||
th:data-bs-target="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? null : '#addUserModal'"
|
th:data-bs-target="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? null : '#addUserModal'"
|
||||||
th:class="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? 'data-btn data-btn-danger' : 'data-btn data-btn-primary'"
|
th:class="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? 'btn btn-danger' : 'btn btn-outline-success'"
|
||||||
th:title="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? #{adminUserSettings.maxUsersReached} : #{adminUserSettings.addUser}">
|
th:title="${@runningProOrHigher && totalUsers >= maxPaidUsers} ? #{adminUserSettings.maxUsersReached} : #{adminUserSettings.addUser}">
|
||||||
<span class="material-symbols-rounded">person_add</span>
|
<span class="material-symbols-rounded">person_add</span>
|
||||||
<span th:text="#{adminUserSettings.addUser}">Add New User</span>
|
<span th:text="#{adminUserSettings.addUser}">Add New User</span>
|
||||||
</button>
|
|
||||||
|
|
||||||
<a href="/teams" class="data-btn data-btn-secondary" th:title="#{adminUserSettings.teams}">
|
|
||||||
<span class="material-symbols-rounded">group</span>
|
|
||||||
<span th:text="#{adminUserSettings.teams}">Manage Teams</span>
|
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<button
|
<a href="#"
|
||||||
data-bs-toggle="modal"
|
data-bs-toggle="modal"
|
||||||
data-bs-target="#changeUserRoleModal"
|
data-bs-target="#changeUserRoleModal"
|
||||||
class="data-btn data-btn-secondary"
|
class="btn btn-outline-success"
|
||||||
th:title="#{adminUserSettings.changeUserRole}">
|
th:title="#{adminUserSettings.changeUserRole}">
|
||||||
<span class="material-symbols-rounded">edit</span>
|
<span class="material-symbols-rounded">edit</span>
|
||||||
<span th:text="#{adminUserSettings.changeUserRole}">Change User's Role</span>
|
<span th:text="#{adminUserSettings.changeUserRole}">Change User's Role</span>
|
||||||
</button>
|
</a>
|
||||||
|
|
||||||
<a href="/usage" th:if="${@runningEE}" class="data-btn data-btn-secondary" th:title="#{adminUserSettings.usage}">
|
<a th:href="@{'/usage'}" th:if="${@runningEE}"
|
||||||
|
class="btn btn-outline-success"
|
||||||
|
th:title="#{adminUserSettings.usage}">
|
||||||
<span class="material-symbols-rounded">analytics</span>
|
<span class="material-symbols-rounded">analytics</span>
|
||||||
<span th:text="#{adminUserSettings.usage}">Usage Statistics</span>
|
<span th:text="#{adminUserSettings.usage}">Usage Statistics</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<div class="my-4">
|
||||||
|
<strong style="margin-left: 20px;" th:text="#{adminUserSettings.totalUsers}">Total Users:</strong>
|
||||||
|
<span th:text="${totalUsers}"></span>
|
||||||
|
<span th:if="${@runningProOrHigher}" th:text="'/'+${maxPaidUsers}"></span>
|
||||||
|
|
||||||
|
<strong style="margin-left: 20px;" th:text="#{adminUserSettings.activeUsers}">Active Users:</strong>
|
||||||
|
<span th:text="${activeUsers}"></span>
|
||||||
|
|
||||||
|
<strong style="margin-left: 20px;" th:text="#{adminUserSettings.disabledUsers}">Disabled Users:</strong>
|
||||||
|
<span th:text="${disabledUsers}"></span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Users Table -->
|
|
||||||
<div class="table-responsive">
|
<div th:if="${addMessage}" class="p-3" style="background: var(--md-sys-color-outline-variant);border-radius: 2rem; text-align: center;">
|
||||||
<table class="data-table">
|
<div class="alert alert-danger mb-auto">
|
||||||
|
<span th:text="#{${addMessage}}">Default message if not found</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div th:if="${changeMessage}" class="p-3" style="background: var(--md-sys-color-outline-variant);border-radius: 2rem; text-align: center;">
|
||||||
|
<div class="alert alert-danger mb-auto">
|
||||||
|
<span th:text="#{${changeMessage}}">Default message if not found</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div th:if="${deleteMessage}" class="alert alert-danger">
|
||||||
|
<span th:text="#{${deleteMessage}}">Default message if not found</span>
|
||||||
|
</div>
|
||||||
|
<div class="bg-card mt-3 mb-3 table-responsive">
|
||||||
|
<table class="table table-striped table-hover">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">#</th>
|
<th scope="col">#</th>
|
||||||
<th scope="col" th:title="#{username}" th:text="#{username}">Username</th>
|
<th scope="col" th:title="#{username}" th:text="#{username}">Username</th>
|
||||||
<th scope="col" th:title="#{adminUserSettings.team}" th:text="#{adminUserSettings.team}">Team</th>
|
|
||||||
<th scope="col" th:title="#{adminUserSettings.roles}" th:text="#{adminUserSettings.roles}">Roles</th>
|
<th scope="col" th:title="#{adminUserSettings.roles}" th:text="#{adminUserSettings.roles}">Roles</th>
|
||||||
<th scope="col" th:title="#{adminUserSettings.authenticated}" class="text-overflow" th:text="#{adminUserSettings.authenticated}">Authenticated</th>
|
<th scope="col" th:title="#{adminUserSettings.authenticated}" class="text-overflow" th:text="#{adminUserSettings.authenticated}">Authenticated</th>
|
||||||
<th scope="col" th:title="#{adminUserSettings.lastRequest}" class="text-overflow" th:text="#{adminUserSettings.lastRequest}">Last Request</th>
|
<th scope="col" th:title="#{adminUserSettings.lastRequest}" class="text-overflow" th:text="#{adminUserSettings.lastRequest}">Last Request</th>
|
||||||
<th scope="col" th:title="#{adminUserSettings.actions}" th:text="#{adminUserSettings.actions}">Actions</th>
|
<th scope="col" th:title="#{adminUserSettings.actions}" th:text="#{adminUserSettings.actions}" colspan="2">Actions</th>
|
||||||
|
<!-- <th scope="col"></th> -->
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr th:each="user : ${users}">
|
<tr th:each="user : ${users}">
|
||||||
<td th:text="${user.id}"></td>
|
<th scope="row" style="align-content: center;" th:text="${user.id}"></th>
|
||||||
<td th:text="${user.username}" th:classappend="${userSessions[user.username] ? 'active-user' : ''}"></td>
|
<td style="align-content: center;" th:text="${user.username}" th:classappend="${userSessions[user.username] ? 'active-user' : ''}"></td>
|
||||||
<td th:text="${user.team != null ? user.team.name : '—'}"></td>
|
<td style="align-content: center;" th:text="#{${user.roleName}}"></td>
|
||||||
<td>
|
<td style="align-content: center;" th:text="${user.authenticationType}"></td>
|
||||||
<span class="data-badge" style="background-color: var(--md-sys-color-secondary-container); color: var(--md-sys-color-secondary); padding: 0.25rem 0.5rem; border-radius: 1rem; font-size: 0.875rem; display: inline-flex; align-items: center; gap: 0.25rem;">
|
<td style="align-content: center;" th:text="${userLastRequest[user.username] != null ? #dates.format(userLastRequest[user.username], 'yyyy-MM-dd HH:mm:ss') : 'N/A'}"></td>
|
||||||
<span class="material-symbols-rounded" style="font-size: 1rem;">shield</span>
|
<td style="align-content: center;">
|
||||||
<span th:text="#{${user.roleName}}">Role</span>
|
<form th:if="${user.username != currentUsername}" th:action="@{'/api/v1/user/admin/deleteUser/' + ${user.username}}" method="post" onsubmit="return confirmDeleteUser()">
|
||||||
</span>
|
<button type="submit" th:title="#{adminUserSettings.deleteUser}" class="btn btn-info btn-sm"><span class="material-symbols-rounded">person_remove</span></button>
|
||||||
</td>
|
|
||||||
<td th:text="${user.authenticationType}"></td>
|
|
||||||
<td th:text="${userLastRequest[user.username] != null ? #dates.format(userLastRequest[user.username], 'yyyy-MM-dd HH:mm:ss') : 'N/A'}"></td>
|
|
||||||
<td>
|
|
||||||
<div class="data-action-cell">
|
|
||||||
<form th:if="${user.username != currentUsername}" th:action="@{'/api/v1/user/admin/deleteUser/' + ${user.username}}" method="post" onsubmit="return confirmDeleteUser()" style="display: inline;">
|
|
||||||
<button type="submit" th:title="#{adminUserSettings.deleteUser}" class="data-icon-btn data-icon-btn-danger">
|
|
||||||
<span class="material-symbols-rounded">person_remove</span>
|
|
||||||
</button>
|
|
||||||
</form>
|
</form>
|
||||||
|
<a th:if="${user.username == currentUsername}" th:title="#{adminUserSettings.editOwnProfil}" th:href="@{'/account'}" class="btn btn-outline-success btn-sm"><span class="material-symbols-rounded">edit</span></a>
|
||||||
<a th:if="${user.username == currentUsername}" th:title="#{adminUserSettings.editOwnProfil}" th:href="@{'/account'}" class="data-icon-btn data-icon-btn-primary">
|
</td>
|
||||||
<span class="material-symbols-rounded">edit</span>
|
<td style="align-content: center;">
|
||||||
</a>
|
<form th:action="@{'/api/v1/user/admin/changeUserEnabled/' + ${user.username}}" method="post" onsubmit="return confirmChangeUserStatus()">
|
||||||
|
|
||||||
<form th:action="@{'/api/v1/user/admin/changeUserEnabled/' + ${user.username}}" method="post" onsubmit="return confirmChangeUserStatus()" style="display: inline;">
|
|
||||||
<input type="hidden" name="enabled" th:value="!${user.enabled}" />
|
<input type="hidden" name="enabled" th:value="!${user.enabled}" />
|
||||||
<button type="submit" th:if="${user.enabled}" th:title="#{adminUserSettings.enabledUser}" class="data-icon-btn data-icon-btn-primary">
|
<button type="submit" th:if="${user.enabled}" th:title="#{adminUserSettings.enabledUser}" class="btn btn-success btn-sm">
|
||||||
<span class="material-symbols-rounded">person</span>
|
<span class="material-symbols-rounded">person</span>
|
||||||
</button>
|
</button>
|
||||||
<button type="submit" th:unless="${user.enabled}" th:title="#{adminUserSettings.disabledUser}" class="data-icon-btn data-icon-btn-danger">
|
<button type="submit" th:unless="${user.enabled}" th:title="#{adminUserSettings.disabledUser}" class="btn btn-danger btn-sm">
|
||||||
<span class="material-symbols-rounded">person_off</span>
|
<span class="material-symbols-rounded">person_off</span>
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
<p th:if="${!@runningProOrHigher}" th:text="#{enterpriseEdition.ssoAdvert}"></p>
|
||||||
<p th:if="${!@runningProOrHigher}" class="data-mt-3" th:text="#{enterpriseEdition.ssoAdvert}"></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Change User Role Modal -->
|
|
||||||
<div class="modal fade" id="changeUserRoleModal" tabindex="-1" aria-labelledby="changeUserRoleModalLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog modal-dialog-centered">
|
|
||||||
<form th:action="@{'/api/v1/user/admin/changeRole'}" method="post" class="modal-content data-modal">
|
|
||||||
<div class="data-modal-header">
|
|
||||||
<h5 class="data-modal-title">
|
|
||||||
<span class="data-icon">
|
|
||||||
<span class="material-symbols-rounded">edit</span>
|
|
||||||
</span>
|
|
||||||
<span th:text="#{adminUserSettings.changeUserRole}">Change User's Role</span>
|
|
||||||
</h5>
|
|
||||||
<button type="button" class="data-btn-close" data-bs-dismiss="modal" aria-label="Close">
|
|
||||||
<span class="material-symbols-rounded">close</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="data-modal-body">
|
|
||||||
<div class="data-mb-2">
|
|
||||||
<button class="data-btn data-btn-secondary" data-toggle="tooltip" data-placement="auto" th:title="#{downgradeCurrentUserLongMessage}" style="padding: 0.25rem 0.5rem;">
|
|
||||||
<span class="material-symbols-rounded">help</span>
|
|
||||||
<span th:text="#{help}">Help</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="data-form-group">
|
|
||||||
<label for="username" class="data-form-label" th:text="#{username}">Username</label>
|
|
||||||
<select name="username" id="username" class="data-form-control" required>
|
|
||||||
<option value="" disabled selected th:text="#{selectFillter}">-- Select --</option>
|
|
||||||
<option th:each="user : ${users}" th:if="${user.username != currentUsername}" th:value="${user.username}" th:text="${user.username}">Username</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="data-form-group">
|
|
||||||
<label for="role" class="data-form-label" th:text="#{adminUserSettings.role}">Role</label>
|
|
||||||
<select name="role" id="role" class="data-form-control" required>
|
|
||||||
<option value="" disabled selected th:text="#{selectFillter}">-- Select --</option>
|
|
||||||
<option th:each="roleDetail : ${roleDetails}" th:value="${roleDetail.key}" th:text="#{${roleDetail.value}}">Role</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="data-form-group">
|
|
||||||
<label for="team" class="data-form-label" th:text="#{adminUserSettings.team}">Team</label>
|
|
||||||
<select name="teamId" id="team" class="data-form-control" required>
|
|
||||||
<option value="" th:text="#{selectFillter}">-- Select --</option>
|
|
||||||
<option th:each="team : ${teams}" th:value="${team.id}" th:text="${team.name}"></option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="data-form-actions">
|
|
||||||
<button type="button" class="data-btn data-btn-secondary" data-bs-dismiss="modal">
|
|
||||||
<span class="material-symbols-rounded">close</span>
|
|
||||||
<span th:text="#{cancel}">Cancel</span>
|
|
||||||
</button>
|
|
||||||
<button type="submit" class="data-btn data-btn-primary">
|
|
||||||
<span class="material-symbols-rounded">check</span>
|
|
||||||
<span th:text="#{adminUserSettings.submit}">Save User</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Add User Modal -->
|
|
||||||
<div class="modal fade" id="addUserModal" tabindex="-1" aria-labelledby="addUserModalLabel" aria-hidden="true">
|
|
||||||
<div class="modal-dialog modal-dialog-centered">
|
|
||||||
<form id="formsaveuser" th:action="@{'/api/v1/user/admin/saveUser'}" method="post" class="modal-content data-modal">
|
|
||||||
<div class="data-modal-header">
|
|
||||||
<h5 class="data-modal-title">
|
|
||||||
<span class="data-icon">
|
|
||||||
<span class="material-symbols-rounded">person_add</span>
|
|
||||||
</span>
|
|
||||||
<span th:text="#{adminUserSettings.addUser}">Add New User</span>
|
|
||||||
</h5>
|
|
||||||
<button type="button" class="data-btn-close" data-bs-dismiss="modal" aria-label="Close">
|
|
||||||
<span class="material-symbols-rounded">close</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="data-modal-body">
|
|
||||||
<div class="data-mb-2">
|
|
||||||
<button class="data-btn data-btn-secondary" data-toggle="tooltip" data-placement="auto" th:title="#{adminUserSettings.usernameInfo}" style="padding: 0.25rem 0.5rem;">
|
|
||||||
<span class="material-symbols-rounded">help</span>
|
|
||||||
<span th:text="#{help}">Help</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="data-form-group">
|
|
||||||
<label for="username" class="data-form-label" th:text="#{username}">Username</label>
|
|
||||||
<input type="text" class="data-form-control" name="username" id="username" th:title="#{adminUserSettings.usernameInfo}" required>
|
|
||||||
<span id="usernameError" style="display: none; color: var(--md-sys-color-error);" th:text="#{invalidUsernameMessage}">Invalid username!</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="data-form-group" id="passwordContainer">
|
|
||||||
<label for="password" class="data-form-label" th:text="#{password}">Password</label>
|
|
||||||
<input type="password" class="data-form-control" name="password" id="password" required>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="data-form-group">
|
|
||||||
<label for="role" class="data-form-label" th:text="#{adminUserSettings.role}">Role</label>
|
|
||||||
<select name="role" class="data-form-control" id="role" required>
|
|
||||||
<option value="" disabled selected th:text="#{selectFillter}">-- Select --</option>
|
|
||||||
<option th:each="roleDetail : ${roleDetails}" th:value="${roleDetail.key}" th:text="#{${roleDetail.value}}">Role</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="data-form-group">
|
|
||||||
<label for="team" class="data-form-label" th:text="#{adminUserSettings.team}">Team</label>
|
|
||||||
<select name="teamId" class="data-form-control" required>
|
|
||||||
<option value="" th:text="#{selectFillter}">-- Select --</option>
|
|
||||||
<option th:each="team : ${teams}" th:value="${team.id}" th:text="${team.name}"></option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="data-form-group">
|
|
||||||
<label for="authType" class="data-form-label">Authentication Type</label>
|
|
||||||
<select id="authType" name="authType" class="data-form-control" required>
|
|
||||||
<option value="web" selected>WEB</option>
|
|
||||||
<option value="sso">SSO</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="data-form-group" id="checkboxContainer">
|
|
||||||
<div class="form-check">
|
|
||||||
<input type="checkbox" class="form-check-input" id="forceChange" name="forceChange">
|
|
||||||
<label class="form-check-label" for="forceChange" th:text="#{adminUserSettings.forceChange}">Force user to change username/password on login</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="data-form-actions">
|
|
||||||
<button type="button" class="data-btn data-btn-secondary" data-bs-dismiss="modal">
|
|
||||||
<span class="material-symbols-rounded">close</span>
|
|
||||||
<span th:text="#{cancel}">Cancel</span>
|
|
||||||
</button>
|
|
||||||
<button type="submit" class="data-btn data-btn-primary">
|
|
||||||
<span class="material-symbols-rounded">check</span>
|
|
||||||
<span th:text="#{adminUserSettings.submit}">Save User</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Add Team Modal -->
|
|
||||||
<div class="modal fade" id="addTeamModal" tabindex="-1" aria-hidden="true">
|
|
||||||
<div class="modal-dialog modal-dialog-centered">
|
|
||||||
<form th:action="@{'/api/v1/team/create'}" method="post" class="modal-content data-modal">
|
|
||||||
<div class="data-modal-header">
|
|
||||||
<h5 class="data-modal-title">
|
|
||||||
<span class="data-icon">
|
|
||||||
<span class="material-symbols-rounded">group_add</span>
|
|
||||||
</span>
|
|
||||||
<span th:text="#{adminUserSettings.createTeam}">Create Team</span>
|
|
||||||
</h5>
|
|
||||||
<button type="button" class="data-btn-close" data-bs-dismiss="modal" aria-label="Close">
|
|
||||||
<span class="material-symbols-rounded">close</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div class="data-modal-body">
|
|
||||||
<div class="data-form-group">
|
|
||||||
<label for="teamName" class="data-form-label" th:text="#{adminUserSettings.teamName}">Team Name</label>
|
|
||||||
<input type="text" name="name" id="teamName" class="data-form-control" required />
|
|
||||||
</div>
|
|
||||||
<div class="data-form-actions">
|
|
||||||
<button type="button" class="data-btn data-btn-secondary" data-bs-dismiss="modal">
|
|
||||||
<span class="material-symbols-rounded">close</span>
|
|
||||||
<span th:text="#{cancel}">Cancel</span>
|
|
||||||
</button>
|
|
||||||
<button type="submit" class="data-btn data-btn-primary">
|
|
||||||
<span class="material-symbols-rounded">check</span>
|
|
||||||
<span th:text="#{adminUserSettings.submit}">Create</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script th:inline="javascript">
|
<script th:inline="javascript">
|
||||||
const delete_confirm_text = /*[[#{adminUserSettings.confirmDeleteUser}]]*/ 'Should the user be deleted?';
|
const delete_confirm_text = /*[[#{adminUserSettings.confirmDeleteUser}]]*/ 'Should the user be deleted?';
|
||||||
const change_confirm_text = /*[[#{adminUserSettings.confirmChangeUserStatus}]]*/ 'Should the user be disabled/enabled?';
|
const change_confirm_text = /*[[#{adminUserSettings.confirmChangeUserStatus}]]*/ 'Should the user be disabled/enabled?';
|
||||||
|
|
||||||
function confirmDeleteUser() {
|
function confirmDeleteUser() {
|
||||||
return confirm(delete_confirm_text);
|
return confirm(delete_confirm_text);
|
||||||
}
|
}
|
||||||
|
|
||||||
function confirmChangeUserStatus() {
|
function confirmChangeUserStatus() {
|
||||||
return confirm(change_confirm_text);
|
return confirm(change_confirm_text);
|
||||||
}
|
}
|
||||||
|
</script>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- change User role Modal start -->
|
||||||
|
<div class="modal fade" id="changeUserRoleModal" tabindex="-1" aria-labelledby="changeUserRoleModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h2 th:text="#{adminUserSettings.changeUserRole}">Change User's Role</h2>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
|
||||||
|
<span class="material-symbols-rounded">close</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<button class="btn btn-outline-info" data-toggle="tooltip" data-placement="auto" th:title="#{downgradeCurrentUserLongMessage}" th:text="#{help}">Help</button>
|
||||||
|
<form th:action="@{'/api/v1/user/admin/changeRole'}" method="post">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="username" th:text="#{username}">Username</label>
|
||||||
|
<select name="username" class="form-control" required>
|
||||||
|
<option value="" disabled selected th:text="#{selectFillter}">-- Select --</option>
|
||||||
|
<option th:each="user : ${users}" th:if="${user.username != currentUsername}" th:value="${user.username}" th:text="${user.username}">Username</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="role" th:text="#{adminUserSettings.role}">Role</label>
|
||||||
|
<select name="role" class="form-control" required>
|
||||||
|
<option value="" disabled selected th:text="#{selectFillter}">-- Select --</option>
|
||||||
|
<option th:each="roleDetail : ${roleDetails}" th:value="${roleDetail.key}" th:text="#{${roleDetail.value}}">Role</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Add other fields as required -->
|
||||||
|
<button type="submit" class="btn btn-primary" th:text="#{adminUserSettings.submit}">Save User</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- change User role Modal end -->
|
||||||
|
|
||||||
|
<!-- Add User Modal start -->
|
||||||
|
<div class="modal fade" id="addUserModal" tabindex="-1" aria-labelledby="addUserModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title" id="addUserModalLabel" th:text="#{adminUserSettings.addUser}">Add New User</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close">
|
||||||
|
<span class="material-symbols-rounded">close</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<button class="btn btn-outline-info" data-toggle="tooltip" data-placement="auto" th:title="#{adminUserSettings.usernameInfo}" th:text="#{help}">Help</button>
|
||||||
|
<form id="formsaveuser" th:action="@{'/api/v1/user/admin/saveUser'}" method="post">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="username" th:text="#{username}">Username</label>
|
||||||
|
<input type="text" class="form-control" name="username" id="username" th:title="#{adminUserSettings.usernameInfo}" required>
|
||||||
|
<span id="usernameError" style="display: none;" th:text="#{invalidUsernameMessage}">Invalid username!</span>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3" id="passwordContainer">
|
||||||
|
<label for="password" th:text="#{password}">Password</label>
|
||||||
|
<input type="password" class="form-control" name="password" id="password" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="role" th:text="#{adminUserSettings.role}">Role</label>
|
||||||
|
<select name="role" class="form-control" id="role" required>
|
||||||
|
<option value="" disabled selected th:text="#{selectFillter}">-- Select --</option>
|
||||||
|
<option th:each="roleDetail : ${roleDetails}" th:value="${roleDetail.key}" th:text="#{${roleDetail.value}}">Role</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="authType">Authentication Type</label>
|
||||||
|
<select id="authType" name="authType" class="form-control" required>
|
||||||
|
<option value="web" selected>WEB</option>
|
||||||
|
<option value="sso">SSO</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-check mb-3" id="checkboxContainer">
|
||||||
|
<input type="checkbox" class="form-check-input" id="forceChange" name="forceChange">
|
||||||
|
<label class="form-check-label" for="forceChange" th:text="#{adminUserSettings.forceChange}">Force user to change username/password on login</label>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary" th:text="#{adminUserSettings.submit}">Save User</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Add User Modal end -->
|
||||||
|
|
||||||
|
<script th:inline="javascript">
|
||||||
jQuery.validator.addMethod("usernamePattern", function(value, element) {
|
jQuery.validator.addMethod("usernamePattern", function(value, element) {
|
||||||
// Regular expression for user name: Min. 3 characters, max. 50 characters
|
// Regular expression for user name: Min. 3 characters, max. 50 characters
|
||||||
const regexUsername = /^[a-zA-Z0-9](?!.*[-@._+]{2,})([a-zA-Z0-9@._+-]{1,48})[a-zA-Z0-9]$/;
|
const regexUsername = /^[a-zA-Z0-9](?!.*[-@._+]{2,})([a-zA-Z0-9@._+-]{1,48})[a-zA-Z0-9]$/;
|
||||||
@ -381,7 +241,6 @@
|
|||||||
// Check if the field is optional or meets the requirements
|
// Check if the field is optional or meets the requirements
|
||||||
return this.optional(element) || regexUsername.test(value) || regexEmail.test(value);
|
return this.optional(element) || regexUsername.test(value) || regexEmail.test(value);
|
||||||
}, /*[[#{invalidUsernameMessage}]]*/ "Invalid username format");
|
}, /*[[#{invalidUsernameMessage}]]*/ "Invalid username format");
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
$('[data-toggle="tooltip"]').tooltip();
|
$('[data-toggle="tooltip"]').tooltip();
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
<link rel="stylesheet" th:href="@{'/pdfjs-legacy/css/viewer-redact.css'}">
|
<link rel="stylesheet" th:href="@{'/pdfjs-legacy/css/viewer-redact.css'}">
|
||||||
<script th:src="@{'/pdfjs-legacy/js/viewer.mjs'}" type="module"></script>
|
<script th:src="@{'/pdfjs-legacy/js/viewer.mjs'}" type="module"></script>
|
||||||
<script src='./js/redact.js' type="module"></script>
|
<script th:src="@{'/js/redact.js'}" type="module"></script>
|
||||||
<link rel="stylesheet" th:href="@{'/css/redact.css'}">
|
<link rel="stylesheet" th:href="@{'/css/redact.css'}">
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
# If you want to override with environment parameter follow parameter naming SECURITY_INITIALLOGIN_USERNAME #
|
# If you want to override with environment parameter follow parameter naming SECURITY_INITIALLOGIN_USERNAME #
|
||||||
#############################################################################################################
|
#############################################################################################################
|
||||||
|
|
||||||
|
|
||||||
security:
|
security:
|
||||||
enableLogin: false # set to 'true' to enable login
|
enableLogin: false # set to 'true' to enable login
|
||||||
csrfDisabled: false # set to 'true' to disable CSRF protection (not recommended for production)
|
csrfDisabled: false # set to 'true' to disable CSRF protection (not recommended for production)
|
||||||
@ -62,18 +61,32 @@ security:
|
|||||||
privateKey: classpath:saml-private-key.key # Your private key. Generated from your keypair
|
privateKey: classpath:saml-private-key.key # Your private key. Generated from your keypair
|
||||||
spCert: classpath:saml-public-cert.crt # Your signing certificate. Generated from your keypair
|
spCert: classpath:saml-public-cert.crt # Your signing certificate. Generated from your keypair
|
||||||
|
|
||||||
enterpriseEdition:
|
premium:
|
||||||
enabled: false # set to 'true' to enable enterprise edition
|
|
||||||
key: 00000000-0000-0000-0000-000000000000
|
key: 00000000-0000-0000-0000-000000000000
|
||||||
SSOAutoLogin: false # Enable to auto login to first provided SSO
|
enabled: false # Enable license key checks for pro/enterprise features
|
||||||
|
proFeatures:
|
||||||
|
SSOAutoLogin: false
|
||||||
CustomMetadata:
|
CustomMetadata:
|
||||||
autoUpdateMetadata: false # set to 'true' to automatically update metadata with below values
|
autoUpdateMetadata: false # set to 'true' to automatically update metadata with below values
|
||||||
author: username # supports text such as 'John Doe' or types such as username to autopopulate with user's username
|
author: username # supports text such as 'John Doe' or types such as username to autopopulate with user's username
|
||||||
creator: Stirling-PDF # supports text such as 'Company-PDF'
|
creator: Stirling-PDF # supports text such as 'Company-PDF'
|
||||||
producer: Stirling-PDF # supports text such as 'Company-PDF'
|
producer: Stirling-PDF # supports text such as 'Company-PDF'
|
||||||
|
googleDrive:
|
||||||
|
enabled: false
|
||||||
|
clientId: ''
|
||||||
|
apiKey: ''
|
||||||
|
appId: ''
|
||||||
|
|
||||||
|
mail:
|
||||||
|
enabled: false # set to 'true' to enable sending emails
|
||||||
|
host: smtp.example.com # SMTP server hostname
|
||||||
|
port: 587 # SMTP server port
|
||||||
|
username: '' # SMTP server username
|
||||||
|
password: '' # SMTP server password
|
||||||
|
from: '' # sender email address
|
||||||
|
|
||||||
legal:
|
legal:
|
||||||
termsAndConditions: https://www.stirlingpdf.com/terms-and-conditions # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
|
termsAndConditions: https://www.stirlingpdf.com/terms # URL to the terms and conditions of your application (e.g. https://example.com/terms). Empty string to disable or filename to load from local file in static folder
|
||||||
privacyPolicy: https://www.stirlingpdf.com/privacy-policy # URL to the privacy policy of your application (e.g. https://example.com/privacy). Empty string to disable or filename to load from local file in static folder
|
privacyPolicy: https://www.stirlingpdf.com/privacy-policy # URL to the privacy policy of your application (e.g. https://example.com/privacy). Empty string to disable or filename to load from local file in static folder
|
||||||
accessibilityStatement: '' # URL to the accessibility statement of your application (e.g. https://example.com/accessibility). Empty string to disable or filename to load from local file in static folder
|
accessibilityStatement: '' # URL to the accessibility statement of your application (e.g. https://example.com/accessibility). Empty string to disable or filename to load from local file in static folder
|
||||||
cookiePolicy: '' # URL to the cookie policy of your application (e.g. https://example.com/cookie). Empty string to disable or filename to load from local file in static folder
|
cookiePolicy: '' # URL to the cookie policy of your application (e.g. https://example.com/cookie). Empty string to disable or filename to load from local file in static folder
|
||||||
@ -88,6 +101,7 @@ system:
|
|||||||
customHTMLFiles: false # enable to have files placed in /customFiles/templates override the existing template HTML files
|
customHTMLFiles: false # enable to have files placed in /customFiles/templates override the existing template HTML files
|
||||||
tessdataDir: /usr/share/tessdata # path to the directory containing the Tessdata files. This setting is relevant for Windows systems. For Windows users, this path should be adjusted to point to the appropriate directory where the Tessdata files are stored.
|
tessdataDir: /usr/share/tessdata # path to the directory containing the Tessdata files. This setting is relevant for Windows systems. For Windows users, this path should be adjusted to point to the appropriate directory where the Tessdata files are stored.
|
||||||
enableAnalytics: true # set to 'true' to enable analytics, set to 'false' to disable analytics; for enterprise users, this is set to true
|
enableAnalytics: true # set to 'true' to enable analytics, set to 'false' to disable analytics; for enterprise users, this is set to true
|
||||||
|
enableUrlToPDF: false # Set to 'true' to enable URL to PDF, INTERNAL ONLY, known security issues, should not be used externally
|
||||||
disableSanitize: false # set to true to disable Sanitize HTML; (can lead to injections in HTML)
|
disableSanitize: false # set to true to disable Sanitize HTML; (can lead to injections in HTML)
|
||||||
datasource:
|
datasource:
|
||||||
enableCustomDatabase: false # Enterprise users ONLY, set this property to 'true' if you would like to use your own custom database configuration
|
enableCustomDatabase: false # Enterprise users ONLY, set this property to 'true' if you would like to use your own custom database configuration
|
||||||
@ -100,13 +114,12 @@ system:
|
|||||||
name: postgres # set the name of your database. Should match the name of the database you create
|
name: postgres # set the name of your database. Should match the name of the database you create
|
||||||
customPaths:
|
customPaths:
|
||||||
pipeline:
|
pipeline:
|
||||||
watchedFoldersDir: "" #Defaults to /pipeline/watchedFolders
|
watchedFoldersDir: '' # Defaults to /pipeline/watchedFolders
|
||||||
finishedFoldersDir: "" #Defaults to /pipeline/finishedFolders
|
finishedFoldersDir: '' # Defaults to /pipeline/finishedFolders
|
||||||
operations:
|
operations:
|
||||||
weasyprint: "" #Defaults to /opt/venv/bin/weasyprint
|
weasyprint: '' # Defaults to /opt/venv/bin/weasyprint
|
||||||
unoconvert: "" #Defaults to /opt/venv/bin/unoconvert
|
unoconvert: '' # Defaults to /opt/venv/bin/unoconvert
|
||||||
|
fileUploadLimit: '' # Defaults to "". No limit when string is empty. Set a number, between 0 and 999, followed by one of the following strings to set a limit. "KB", "MB", "GB".
|
||||||
|
|
||||||
|
|
||||||
ui:
|
ui:
|
||||||
appName: '' # application's visible name
|
appName: '' # application's visible name
|
||||||
|
Loading…
Reference in New Issue
Block a user