SSO Auto login and template cleanup
This commit is contained in:
@@ -27,4 +27,9 @@ public class EEAppConfig {
|
||||
public boolean runningEnterpriseEdition() {
|
||||
return licenseKeyChecker.getEnterpriseEnabledResult();
|
||||
}
|
||||
|
||||
@Bean(name = "SSOAutoLogin")
|
||||
public boolean ssoAutoLogin() {
|
||||
return applicationProperties.getEnterpriseEdition().isSsoAutoLogin();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ public class KeygenLicenseVerifier {
|
||||
.build();
|
||||
|
||||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
|
||||
log.info(" validateLicenseResponse body: " + response.body());
|
||||
log.debug(" validateLicenseResponse body: " + response.body());
|
||||
JsonNode jsonResponse = objectMapper.readTree(response.body());
|
||||
if (response.statusCode() == 200) {
|
||||
|
||||
|
||||
@@ -366,6 +366,7 @@ public class ApplicationProperties {
|
||||
private boolean enabled;
|
||||
@ToString.Exclude private String key;
|
||||
private int maxUsers;
|
||||
private boolean ssoAutoLogin;
|
||||
private CustomMetadata customMetadata = new CustomMetadata();
|
||||
|
||||
@Data
|
||||
|
||||
@@ -63,6 +63,7 @@ security:
|
||||
enterpriseEdition:
|
||||
enabled: false # set to 'true' to enable enterprise edition
|
||||
key: 00000000-0000-0000-0000-000000000000
|
||||
SSOAutoLogin: false # Enable to auto login to first provided SSO
|
||||
CustomMetadata:
|
||||
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
|
||||
@@ -86,8 +87,8 @@ system:
|
||||
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
|
||||
datasource:
|
||||
enableCustomDatabase: false # set this property to 'true' if you would like to use your own custom database configuration
|
||||
customDatabaseUrl: jdbc:postgresql://localhost:5432/postgres # set the url for your own custom database connection. If provided, the type, hostName, port and name are not necessary and will not be used
|
||||
enableCustomDatabase: false # Enterprise users ONLY, set this property to 'true' if you would like to use your own custom database configuration
|
||||
customDatabaseUrl: '' # eg jdbc:postgresql://localhost:5432/postgres, set the url for your own custom database connection. If provided, the type, hostName, port and name are not necessary and will not be used
|
||||
username: postgres # set the database username
|
||||
password: postgres # set the database password
|
||||
type: postgresql # the type of the database to set (e.g. 'h2', 'postgresql')
|
||||
|
||||
@@ -11,48 +11,88 @@
|
||||
<div class="your-container-class"></div>
|
||||
<div class="container-flex">
|
||||
<main class="form-signin">
|
||||
<script>
|
||||
document.addEventListener('modeChanged', function(e) {
|
||||
var mode = e.detail;
|
||||
|
||||
document.body.classList.remove("light-mode", "dark-mode", "rainbow-mode"); // remove all mode classes first
|
||||
|
||||
switch (mode) {
|
||||
case "on":
|
||||
document.body.classList.add("dark-mode");
|
||||
break;
|
||||
case "off":
|
||||
document.body.classList.add("light-mode");
|
||||
break;
|
||||
case "rainbow":
|
||||
document.body.classList.add("rainbow-mode");
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const defaultLocale = getStoredOrDefaultLocale();
|
||||
checkUserLanguage(defaultLocale);
|
||||
|
||||
const dropdownItems = document.querySelectorAll('.lang_dropdown-item');
|
||||
let activeItem;
|
||||
|
||||
for (let i = 0; i < dropdownItems.length; i++) {
|
||||
const item = dropdownItems[i];
|
||||
item.classList.remove('active');
|
||||
if (item.dataset.bsLanguageCode === defaultLocale) {
|
||||
item.classList.add('active');
|
||||
activeItem = item;
|
||||
}
|
||||
item.addEventListener('click', handleDropdownItemClick);
|
||||
}
|
||||
|
||||
const dropdown = document.getElementById('languageDropdown');
|
||||
|
||||
if (activeItem) {
|
||||
dropdown.innerHTML = activeItem.innerHTML; // This will set the dropdown button's content to the active language's flag and name
|
||||
}
|
||||
});
|
||||
<script th:inline="javascript">
|
||||
const redirectAttempts = parseInt(localStorage.getItem('ssoRedirectAttempts') || '0');
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const hasRedirectError = urlParams.has('error');
|
||||
const hasLogout = urlParams.has('logout');
|
||||
const hasMessage = urlParams.has('message');
|
||||
const MAX_REDIRECT_ATTEMPTS = 3;
|
||||
|
||||
document.addEventListener('modeChanged', function(e) {
|
||||
var mode = e.detail;
|
||||
|
||||
document.body.classList.remove("light-mode", "dark-mode", "rainbow-mode"); // remove all mode classes first
|
||||
|
||||
switch (mode) {
|
||||
case "on":
|
||||
document.body.classList.add("dark-mode");
|
||||
break;
|
||||
case "off":
|
||||
document.body.classList.add("light-mode");
|
||||
break;
|
||||
case "rainbow":
|
||||
document.body.classList.add("rainbow-mode");
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
const runningEE = [[${@runningEE}]];
|
||||
const SSOAutoLogin = [[${@SSOAutoLogin}]];
|
||||
const loginMethod = [[${loginMethod}]];
|
||||
const providerList = [[${providerlist}]];
|
||||
const shouldAutoRedirect = !hasRedirectError &&
|
||||
!hasLogout &&
|
||||
!hasMessage &&
|
||||
redirectAttempts < MAX_REDIRECT_ATTEMPTS &&
|
||||
loginMethod !== 'normal' && runningEE && SSOAutoLogin;
|
||||
|
||||
console.log('Should redirect:', shouldAutoRedirect, {
|
||||
'No error': !hasRedirectError,
|
||||
'No logout': !hasLogout,
|
||||
'No message': !hasMessage,
|
||||
'Under max attempts': redirectAttempts < MAX_REDIRECT_ATTEMPTS,
|
||||
'Is OAuth2': loginMethod === 'oauth2'
|
||||
});
|
||||
|
||||
if (shouldAutoRedirect && providerList && Object.keys(providerList).length > 0) {
|
||||
localStorage.setItem('ssoRedirectAttempts', redirectAttempts + 1);
|
||||
const firstProvider = Object.keys(providerList)[0];
|
||||
window.location.href = firstProvider;
|
||||
}
|
||||
|
||||
// Reset redirect attempts if successful login or after 1 hour
|
||||
const lastAttemptTime = parseInt(localStorage.getItem('lastRedirectAttempt') || '0');
|
||||
if (Date.now() - lastAttemptTime > 3600000) { // 1 hour
|
||||
localStorage.setItem('ssoRedirectAttempts', '0');
|
||||
}
|
||||
localStorage.setItem('lastRedirectAttempt', Date.now().toString());
|
||||
|
||||
|
||||
const defaultLocale = getStoredOrDefaultLocale();
|
||||
checkUserLanguage(defaultLocale);
|
||||
|
||||
const dropdownItems = document.querySelectorAll('.lang_dropdown-item');
|
||||
let activeItem;
|
||||
|
||||
for (let i = 0; i < dropdownItems.length; i++) {
|
||||
const item = dropdownItems[i];
|
||||
item.classList.remove('active');
|
||||
if (item.dataset.bsLanguageCode === defaultLocale) {
|
||||
item.classList.add('active');
|
||||
activeItem = item;
|
||||
}
|
||||
item.addEventListener('click', handleDropdownItemClick);
|
||||
}
|
||||
|
||||
const dropdown = document.getElementById('languageDropdown');
|
||||
|
||||
if (activeItem) {
|
||||
dropdown.innerHTML = activeItem.innerHTML; // This will set the dropdown button's content to the active language's flag and name
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<div class="text-center">
|
||||
<img class="my-4" th:src="@{'/favicon.svg'}" alt="favicon" width="144" height="144">
|
||||
|
||||
Reference in New Issue
Block a user