mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-12-27 07:28:30 +00:00
- Removed Logo Configuration from the openmetadata.yaml (#13873)
* - Removed Logi Configuration from the openmetadata.yaml - Migrated Login Configuration to the UI * Removed ApplicationConfig from tests * Added Custom Header Logo Url * Update field to favicon * support login conifguration * chore(ui): update logo and login config md files * fix validation issue * add cypress * restructure folders and set default fallback for favicon * autofocus to first field of edit form --------- Co-authored-by: Chirag Madlani <12962843+chirag-madlani@users.noreply.github.com> Co-authored-by: Sachin Chaurasiya <sachinchaurasiyachotey87@gmail.com>
This commit is contained in:
parent
ab0840aa6f
commit
2577490700
@ -307,16 +307,6 @@ email:
|
||||
password: ${SMTP_SERVER_PWD:-""}
|
||||
transportationStrategy: ${SMTP_SERVER_STRATEGY:-"SMTP_TLS"}
|
||||
|
||||
applicationConfig:
|
||||
logoConfig:
|
||||
customLogoUrlPath: ${OM_CUSTOM_LOGO_URL_PATH:-""} #login page logo
|
||||
customMonogramUrlPath: ${OM_CUSTOM_MONOGRAM_URL_PATH:-""} #nav bar logo
|
||||
loginConfig:
|
||||
maxLoginFailAttempts: ${OM_MAX_FAILED_LOGIN_ATTEMPTS:-3}
|
||||
accessBlockTime: ${OM_LOGIN_ACCESS_BLOCK_TIME:-600}
|
||||
jwtTokenExpiryTime: ${OM_JWT_EXPIRY_TIME:-3600}
|
||||
|
||||
|
||||
web:
|
||||
uriPath: ${WEB_CONF_URI_PATH:-"/api"}
|
||||
hsts:
|
||||
|
||||
@ -175,12 +175,6 @@ services:
|
||||
|
||||
# Heap OPTS Configurations
|
||||
OPENMETADATA_HEAP_OPTS: ${OPENMETADATA_HEAP_OPTS:--Xmx1G -Xms1G}
|
||||
# Application Config
|
||||
OM_CUSTOM_LOGO_URL_PATH: ${OM_CUSTOM_LOGO_URL_PATH:-""}
|
||||
OM_CUSTOM_MONOGRAM_URL_PATH: ${OM_CUSTOM_MONOGRAM_URL_PATH:-""}
|
||||
OM_MAX_FAILED_LOGIN_ATTEMPTS: ${OM_MAX_FAILED_LOGIN_ATTEMPTS:-3}
|
||||
OM_LOGIN_ACCESS_BLOCK_TIME: ${OM_LOGIN_ACCESS_BLOCK_TIME:-600}
|
||||
OM_JWT_EXPIRY_TIME: ${OM_JWT_EXPIRY_TIME:-3600}
|
||||
# Mask passwords values in UI
|
||||
MASK_PASSWORDS_API: ${MASK_PASSWORDS_API:-false}
|
||||
|
||||
@ -329,12 +323,6 @@ services:
|
||||
|
||||
# Heap OPTS Configurations
|
||||
OPENMETADATA_HEAP_OPTS: ${OPENMETADATA_HEAP_OPTS:--Xmx1G -Xms1G}
|
||||
# Application Config
|
||||
OM_CUSTOM_LOGO_URL_PATH: ${OM_CUSTOM_LOGO_URL_PATH:-""}
|
||||
OM_CUSTOM_MONOGRAM_URL_PATH: ${OM_CUSTOM_MONOGRAM_URL_PATH:-""}
|
||||
OM_MAX_FAILED_LOGIN_ATTEMPTS: ${OM_MAX_FAILED_LOGIN_ATTEMPTS:-3}
|
||||
OM_LOGIN_ACCESS_BLOCK_TIME: ${OM_LOGIN_ACCESS_BLOCK_TIME:-600}
|
||||
OM_JWT_EXPIRY_TIME: ${OM_JWT_EXPIRY_TIME:-3600}
|
||||
MASK_PASSWORDS_API: ${MASK_PASSWORDS_API:-true}
|
||||
expose:
|
||||
- 8585
|
||||
|
||||
@ -175,12 +175,6 @@ services:
|
||||
|
||||
# Heap OPTS Configurations
|
||||
OPENMETADATA_HEAP_OPTS: ${OPENMETADATA_HEAP_OPTS:--Xmx1G -Xms1G}
|
||||
# Application Config
|
||||
OM_CUSTOM_LOGO_URL_PATH: ${OM_CUSTOM_LOGO_URL_PATH:-""}
|
||||
OM_CUSTOM_MONOGRAM_URL_PATH: ${OM_CUSTOM_MONOGRAM_URL_PATH:-""}
|
||||
OM_MAX_FAILED_LOGIN_ATTEMPTS: ${OM_MAX_FAILED_LOGIN_ATTEMPTS:-3}
|
||||
OM_LOGIN_ACCESS_BLOCK_TIME: ${OM_LOGIN_ACCESS_BLOCK_TIME:-600}
|
||||
OM_JWT_EXPIRY_TIME: ${OM_JWT_EXPIRY_TIME:-3600}
|
||||
# Mask passwords values in UI
|
||||
MASK_PASSWORDS_API: ${MASK_PASSWORDS_API:-false}
|
||||
|
||||
@ -330,12 +324,6 @@ services:
|
||||
|
||||
# Heap OPTS Configurations
|
||||
OPENMETADATA_HEAP_OPTS: ${OPENMETADATA_HEAP_OPTS:--Xmx1G -Xms1G}
|
||||
# Application Config
|
||||
OM_CUSTOM_LOGO_URL_PATH: ${OM_CUSTOM_LOGO_URL_PATH:-""}
|
||||
OM_CUSTOM_MONOGRAM_URL_PATH: ${OM_CUSTOM_MONOGRAM_URL_PATH:-""}
|
||||
OM_MAX_FAILED_LOGIN_ATTEMPTS: ${OM_MAX_FAILED_LOGIN_ATTEMPTS:-3}
|
||||
OM_LOGIN_ACCESS_BLOCK_TIME: ${OM_LOGIN_ACCESS_BLOCK_TIME:-600}
|
||||
OM_JWT_EXPIRY_TIME: ${OM_JWT_EXPIRY_TIME:-3600}
|
||||
MASK_PASSWORDS_API: ${MASK_PASSWORDS_API:-true}
|
||||
expose:
|
||||
- 8585
|
||||
|
||||
@ -125,12 +125,6 @@ services:
|
||||
|
||||
# Heap OPTS Configurations
|
||||
OPENMETADATA_HEAP_OPTS: ${OPENMETADATA_HEAP_OPTS:--Xmx1G -Xms1G}
|
||||
# Application Config
|
||||
OM_CUSTOM_LOGO_URL_PATH: ${OM_CUSTOM_LOGO_URL_PATH:-""}
|
||||
OM_CUSTOM_MONOGRAM_URL_PATH: ${OM_CUSTOM_MONOGRAM_URL_PATH:-""}
|
||||
OM_MAX_FAILED_LOGIN_ATTEMPTS: ${OM_MAX_FAILED_LOGIN_ATTEMPTS:-3}
|
||||
OM_LOGIN_ACCESS_BLOCK_TIME: ${OM_LOGIN_ACCESS_BLOCK_TIME:-600}
|
||||
OM_JWT_EXPIRY_TIME: ${OM_JWT_EXPIRY_TIME:-3600}
|
||||
# Mask passwords values in UI
|
||||
MASK_PASSWORDS_API: ${MASK_PASSWORDS_API:-false}
|
||||
|
||||
|
||||
@ -167,12 +167,6 @@ services:
|
||||
|
||||
# Heap OPTS Configurations
|
||||
OPENMETADATA_HEAP_OPTS: ${OPENMETADATA_HEAP_OPTS:--Xmx1G -Xms1G}
|
||||
# Application Config
|
||||
OM_CUSTOM_LOGO_URL_PATH: ${OM_CUSTOM_LOGO_URL_PATH:-""}
|
||||
OM_CUSTOM_MONOGRAM_URL_PATH: ${OM_CUSTOM_MONOGRAM_URL_PATH:-""}
|
||||
OM_MAX_FAILED_LOGIN_ATTEMPTS: ${OM_MAX_FAILED_LOGIN_ATTEMPTS:-3}
|
||||
OM_LOGIN_ACCESS_BLOCK_TIME: ${OM_LOGIN_ACCESS_BLOCK_TIME:-600}
|
||||
OM_JWT_EXPIRY_TIME: ${OM_JWT_EXPIRY_TIME:-3600}
|
||||
# Mask passwords values in UI
|
||||
MASK_PASSWORDS_API: ${MASK_PASSWORDS_API:-false}
|
||||
|
||||
@ -321,12 +315,6 @@ services:
|
||||
|
||||
# Heap OPTS Configurations
|
||||
OPENMETADATA_HEAP_OPTS: ${OPENMETADATA_HEAP_OPTS:--Xmx1G -Xms1G}
|
||||
# Application Config
|
||||
OM_CUSTOM_LOGO_URL_PATH: ${OM_CUSTOM_LOGO_URL_PATH:-""}
|
||||
OM_CUSTOM_MONOGRAM_URL_PATH: ${OM_CUSTOM_MONOGRAM_URL_PATH:-""}
|
||||
OM_MAX_FAILED_LOGIN_ATTEMPTS: ${OM_MAX_FAILED_LOGIN_ATTEMPTS:-3}
|
||||
OM_LOGIN_ACCESS_BLOCK_TIME: ${OM_LOGIN_ACCESS_BLOCK_TIME:-600}
|
||||
OM_JWT_EXPIRY_TIME: ${OM_JWT_EXPIRY_TIME:-3600}
|
||||
# Mask passwords values in UI
|
||||
MASK_PASSWORDS_API: ${MASK_PASSWORDS_API:-false}
|
||||
|
||||
|
||||
@ -165,12 +165,6 @@ services:
|
||||
|
||||
# Heap OPTS Configurations
|
||||
OPENMETADATA_HEAP_OPTS: ${OPENMETADATA_HEAP_OPTS:--Xmx1G -Xms1G}
|
||||
# Application Config
|
||||
OM_CUSTOM_LOGO_URL_PATH: ${OM_CUSTOM_LOGO_URL_PATH:-""}
|
||||
OM_CUSTOM_MONOGRAM_URL_PATH: ${OM_CUSTOM_MONOGRAM_URL_PATH:-""}
|
||||
OM_MAX_FAILED_LOGIN_ATTEMPTS: ${OM_MAX_FAILED_LOGIN_ATTEMPTS:-3}
|
||||
OM_LOGIN_ACCESS_BLOCK_TIME: ${OM_LOGIN_ACCESS_BLOCK_TIME:-600}
|
||||
OM_JWT_EXPIRY_TIME: ${OM_JWT_EXPIRY_TIME:-3600}
|
||||
# Mask passwords values in UI
|
||||
MASK_PASSWORDS_API: ${MASK_PASSWORDS_API:-false}
|
||||
|
||||
@ -320,12 +314,6 @@ services:
|
||||
|
||||
# Heap OPTS Configurations
|
||||
OPENMETADATA_HEAP_OPTS: ${OPENMETADATA_HEAP_OPTS:--Xmx1G -Xms1G}
|
||||
# Application Config
|
||||
OM_CUSTOM_LOGO_URL_PATH: ${OM_CUSTOM_LOGO_URL_PATH:-""}
|
||||
OM_CUSTOM_MONOGRAM_URL_PATH: ${OM_CUSTOM_MONOGRAM_URL_PATH:-""}
|
||||
OM_MAX_FAILED_LOGIN_ATTEMPTS: ${OM_MAX_FAILED_LOGIN_ATTEMPTS:-3}
|
||||
OM_LOGIN_ACCESS_BLOCK_TIME: ${OM_LOGIN_ACCESS_BLOCK_TIME:-600}
|
||||
OM_JWT_EXPIRY_TIME: ${OM_JWT_EXPIRY_TIME:-3600}
|
||||
# Mask passwords values in UI
|
||||
MASK_PASSWORDS_API: ${MASK_PASSWORDS_API:-false}
|
||||
|
||||
|
||||
@ -22,7 +22,6 @@ import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.openmetadata.api.configuration.ApplicationConfiguration;
|
||||
import org.openmetadata.api.configuration.ChangeEventConfiguration;
|
||||
import org.openmetadata.schema.api.configuration.events.EventHandlerConfiguration;
|
||||
import org.openmetadata.schema.api.configuration.pipelineServiceClient.PipelineServiceClientConfiguration;
|
||||
@ -78,9 +77,6 @@ public class OpenMetadataApplicationConfig extends Configuration {
|
||||
@Valid
|
||||
private HealthConfiguration healthConfiguration = new HealthConfiguration();
|
||||
|
||||
@JsonProperty("applicationConfig")
|
||||
private ApplicationConfiguration applicationConfiguration = new ApplicationConfiguration();
|
||||
|
||||
@JsonProperty("secretsManagerConfiguration")
|
||||
private SecretsManagerConfiguration secretsManagerConfiguration;
|
||||
|
||||
|
||||
@ -55,6 +55,7 @@ import org.openmetadata.common.utils.CommonUtil;
|
||||
import org.openmetadata.schema.TokenInterface;
|
||||
import org.openmetadata.schema.analytics.ReportData;
|
||||
import org.openmetadata.schema.analytics.WebAnalyticEvent;
|
||||
import org.openmetadata.schema.api.configuration.LoginConfiguration;
|
||||
import org.openmetadata.schema.auth.EmailVerificationToken;
|
||||
import org.openmetadata.schema.auth.PasswordResetToken;
|
||||
import org.openmetadata.schema.auth.PersonalAccessToken;
|
||||
@ -3621,6 +3622,9 @@ public interface CollectionDAO {
|
||||
case CUSTOM_LOGO_CONFIGURATION:
|
||||
value = JsonUtils.readValue(json, LogoConfiguration.class);
|
||||
break;
|
||||
case LOGIN_CONFIGURATION:
|
||||
value = JsonUtils.readValue(json, LoginConfiguration.class);
|
||||
break;
|
||||
case SLACK_APP_CONFIGURATION:
|
||||
value = JsonUtils.readValue(json, String.class);
|
||||
break;
|
||||
|
||||
@ -15,6 +15,7 @@ package org.openmetadata.service.resources.settings;
|
||||
|
||||
import static org.openmetadata.schema.settings.SettingsType.CUSTOM_LOGO_CONFIGURATION;
|
||||
import static org.openmetadata.schema.settings.SettingsType.EMAIL_CONFIGURATION;
|
||||
import static org.openmetadata.schema.settings.SettingsType.LOGIN_CONFIGURATION;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
@ -23,6 +24,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import javax.annotation.CheckForNull;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.openmetadata.api.configuration.LogoConfiguration;
|
||||
import org.openmetadata.schema.api.configuration.LoginConfiguration;
|
||||
import org.openmetadata.schema.email.SmtpSettings;
|
||||
import org.openmetadata.schema.settings.Settings;
|
||||
import org.openmetadata.schema.settings.SettingsType;
|
||||
@ -66,11 +68,31 @@ public class SettingsCache {
|
||||
Settings storedCustomLogoConf = systemRepository.getConfigWithKey(CUSTOM_LOGO_CONFIGURATION.toString());
|
||||
if (storedCustomLogoConf == null) {
|
||||
// Only in case a config doesn't exist in DB we insert it
|
||||
LogoConfiguration logoConfig = applicationConfig.getApplicationConfiguration().getLogoConfig();
|
||||
if (logoConfig != null) {
|
||||
Settings setting = new Settings().withConfigType(CUSTOM_LOGO_CONFIGURATION).withConfigValue(logoConfig);
|
||||
systemRepository.createNewSetting(setting);
|
||||
}
|
||||
Settings setting =
|
||||
new Settings()
|
||||
.withConfigType(CUSTOM_LOGO_CONFIGURATION)
|
||||
.withConfigValue(
|
||||
new LogoConfiguration()
|
||||
.withCustomLogoUrlPath("")
|
||||
.withCustomMonogramUrlPath("")
|
||||
.withCustomFaviconUrlPath(""));
|
||||
systemRepository.createNewSetting(setting);
|
||||
}
|
||||
|
||||
// Initialise Login Configuration
|
||||
// Initialise Logo Setting
|
||||
Settings storedLoginConf = systemRepository.getConfigWithKey(LOGIN_CONFIGURATION.toString());
|
||||
if (storedLoginConf == null) {
|
||||
// Only in case a config doesn't exist in DB we insert it
|
||||
Settings setting =
|
||||
new Settings()
|
||||
.withConfigType(LOGIN_CONFIGURATION)
|
||||
.withConfigValue(
|
||||
new LoginConfiguration()
|
||||
.withMaxLoginFailAttempts(3)
|
||||
.withAccessBlockTime(600)
|
||||
.withJwtTokenExpiryTime(3600));
|
||||
systemRepository.createNewSetting(setting);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -23,10 +23,10 @@ import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import org.openmetadata.api.configuration.ApplicationConfiguration;
|
||||
import org.openmetadata.api.configuration.LogoConfiguration;
|
||||
import org.openmetadata.catalog.security.client.SamlSSOClientConfig;
|
||||
import org.openmetadata.catalog.type.IdentityProviderConfig;
|
||||
import org.openmetadata.schema.api.configuration.LoginConfiguration;
|
||||
import org.openmetadata.schema.api.security.AuthenticationConfiguration;
|
||||
import org.openmetadata.schema.api.security.AuthorizerConfiguration;
|
||||
import org.openmetadata.schema.settings.SettingsType;
|
||||
@ -128,21 +128,19 @@ public class ConfigResource {
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path(("/applicationConfig"))
|
||||
@Path(("/loginConfig"))
|
||||
@Operation(
|
||||
operationId = "getApplicationConfiguration",
|
||||
summary = "Get application configuration",
|
||||
operationId = "getLoginConfiguration",
|
||||
summary = "Get Login configuration",
|
||||
responses = {
|
||||
@ApiResponse(
|
||||
responseCode = "200",
|
||||
description = "Get application configuration",
|
||||
description = "Get Login configuration",
|
||||
content =
|
||||
@Content(
|
||||
mediaType = "application/json",
|
||||
schema = @Schema(implementation = ApplicationConfiguration.class)))
|
||||
@Content(mediaType = "application/json", schema = @Schema(implementation = LoginConfiguration.class)))
|
||||
})
|
||||
public ApplicationConfiguration getApplicationConfiguration() {
|
||||
return openMetadataApplicationConfig.getApplicationConfiguration();
|
||||
public LoginConfiguration getLoginConfiguration() {
|
||||
return SettingsCache.getSetting(SettingsType.LOGIN_CONFIGURATION, LoginConfiguration.class);
|
||||
}
|
||||
|
||||
@GET
|
||||
|
||||
@ -61,12 +61,14 @@ import org.openmetadata.schema.auth.TokenRefreshRequest;
|
||||
import org.openmetadata.schema.email.SmtpSettings;
|
||||
import org.openmetadata.schema.entity.teams.AuthenticationMechanism;
|
||||
import org.openmetadata.schema.entity.teams.User;
|
||||
import org.openmetadata.schema.settings.SettingsType;
|
||||
import org.openmetadata.service.Entity;
|
||||
import org.openmetadata.service.OpenMetadataApplicationConfig;
|
||||
import org.openmetadata.service.auth.JwtResponse;
|
||||
import org.openmetadata.service.exception.CustomExceptionMessage;
|
||||
import org.openmetadata.service.jdbi3.TokenRepository;
|
||||
import org.openmetadata.service.jdbi3.UserRepository;
|
||||
import org.openmetadata.service.resources.settings.SettingsCache;
|
||||
import org.openmetadata.service.security.AuthenticationException;
|
||||
import org.openmetadata.service.security.jwt.JWTTokenGenerator;
|
||||
import org.openmetadata.service.util.EmailUtil;
|
||||
@ -97,7 +99,7 @@ public class BasicAuthenticator implements AuthenticatorHandler {
|
||||
SmtpSettings smtpSettings = config.getSmtpSettings();
|
||||
this.isEmailServiceEnabled = smtpSettings != null && smtpSettings.getEnableSmtpServer();
|
||||
this.isSelfSignUpAvailable = config.getAuthenticationConfiguration().getEnableSelfSignup();
|
||||
this.loginConfiguration = config.getApplicationConfiguration().getLoginConfig();
|
||||
this.loginConfiguration = SettingsCache.getSetting(SettingsType.LOGIN_CONFIGURATION, LoginConfiguration.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -35,6 +35,7 @@ import org.openmetadata.schema.auth.LoginRequest;
|
||||
import org.openmetadata.schema.auth.RefreshToken;
|
||||
import org.openmetadata.schema.entity.teams.User;
|
||||
import org.openmetadata.schema.services.connections.metadata.AuthProvider;
|
||||
import org.openmetadata.schema.settings.SettingsType;
|
||||
import org.openmetadata.service.Entity;
|
||||
import org.openmetadata.service.OpenMetadataApplicationConfig;
|
||||
import org.openmetadata.service.auth.JwtResponse;
|
||||
@ -42,6 +43,7 @@ import org.openmetadata.service.exception.CustomExceptionMessage;
|
||||
import org.openmetadata.service.exception.EntityNotFoundException;
|
||||
import org.openmetadata.service.jdbi3.TokenRepository;
|
||||
import org.openmetadata.service.jdbi3.UserRepository;
|
||||
import org.openmetadata.service.resources.settings.SettingsCache;
|
||||
import org.openmetadata.service.security.AuthenticationException;
|
||||
import org.openmetadata.service.util.EmailUtil;
|
||||
import org.openmetadata.service.util.LdapUtil;
|
||||
@ -69,7 +71,7 @@ public class LdapAuthenticator implements AuthenticatorHandler {
|
||||
this.tokenRepository = Entity.getTokenRepository();
|
||||
this.ldapConfiguration = config.getAuthenticationConfiguration().getLdapConfiguration();
|
||||
this.loginAttemptCache = new LoginAttemptCache(config);
|
||||
this.loginConfiguration = config.getApplicationConfiguration().getLoginConfig();
|
||||
this.loginConfiguration = SettingsCache.getSetting(SettingsType.LOGIN_CONFIGURATION, LoginConfiguration.class);
|
||||
}
|
||||
|
||||
private LDAPConnectionPool getLdapConnectionPool(LdapConfiguration ldapConfiguration) {
|
||||
|
||||
@ -8,14 +8,17 @@ import java.util.concurrent.TimeUnit;
|
||||
import lombok.NonNull;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.openmetadata.schema.api.configuration.LoginConfiguration;
|
||||
import org.openmetadata.schema.settings.SettingsType;
|
||||
import org.openmetadata.service.OpenMetadataApplicationConfig;
|
||||
import org.openmetadata.service.resources.settings.SettingsCache;
|
||||
|
||||
public class LoginAttemptCache {
|
||||
private int maxAttempt = 3;
|
||||
private final LoadingCache<String, Integer> attemptsCache;
|
||||
|
||||
public LoginAttemptCache(OpenMetadataApplicationConfig config) {
|
||||
LoginConfiguration loginConfiguration = config.getApplicationConfiguration().getLoginConfig();
|
||||
LoginConfiguration loginConfiguration =
|
||||
SettingsCache.getSetting(SettingsType.LOGIN_CONFIGURATION, LoginConfiguration.class);
|
||||
long accessBlockTime = 600;
|
||||
if (loginConfiguration != null) {
|
||||
maxAttempt = loginConfiguration.getMaxLoginFailAttempts();
|
||||
|
||||
@ -29,7 +29,8 @@ import javax.ws.rs.client.WebTarget;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.openmetadata.api.configuration.ApplicationConfiguration;
|
||||
import org.openmetadata.api.configuration.LogoConfiguration;
|
||||
import org.openmetadata.schema.api.configuration.LoginConfiguration;
|
||||
import org.openmetadata.schema.api.security.AuthenticationConfiguration;
|
||||
import org.openmetadata.schema.api.security.AuthorizerConfiguration;
|
||||
import org.openmetadata.service.OpenMetadataApplicationConfig;
|
||||
@ -88,12 +89,23 @@ class ConfigResourceTest extends OpenMetadataApplicationTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void get_application_configs_200_OK() throws IOException {
|
||||
WebTarget target = getConfigResource("applicationConfig");
|
||||
ApplicationConfiguration applicationConfiguration =
|
||||
TestUtils.get(target, ApplicationConfiguration.class, TEST_AUTH_HEADERS);
|
||||
assertEquals(config.getApplicationConfiguration().getLogoConfig(), applicationConfiguration.getLogoConfig());
|
||||
assertEquals(config.getApplicationConfiguration().getLoginConfig(), applicationConfiguration.getLoginConfig());
|
||||
void get_Custom_Logo_Configuration_200_OK() throws IOException {
|
||||
// Test Against Default Values
|
||||
WebTarget target = getConfigResource("customLogoConfiguration");
|
||||
LogoConfiguration logoConfiguration = TestUtils.get(target, LogoConfiguration.class, TEST_AUTH_HEADERS);
|
||||
|
||||
assertEquals("", logoConfiguration.getCustomLogoUrlPath());
|
||||
assertEquals("", logoConfiguration.getCustomMonogramUrlPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
void get_Login_Configuration_200_OK() throws IOException {
|
||||
// Test Against Default Values
|
||||
WebTarget target = getConfigResource("loginConfig");
|
||||
LoginConfiguration loginConfiguration = TestUtils.get(target, LoginConfiguration.class, TEST_AUTH_HEADERS);
|
||||
assertEquals(3, loginConfiguration.getMaxLoginFailAttempts());
|
||||
assertEquals(600, loginConfiguration.getAccessBlockTime());
|
||||
assertEquals(3600, loginConfiguration.getJwtTokenExpiryTime());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -179,7 +179,9 @@ public class SystemResourceTest extends OpenMetadataApplicationTest {
|
||||
LogoConfiguration loginConfiguration =
|
||||
JsonUtils.convertValue(logoConfigWrapped.getConfigValue(), LogoConfiguration.class);
|
||||
|
||||
Assertions.assertEquals(config.getApplicationConfiguration().getLogoConfig(), loginConfiguration);
|
||||
// Defaults
|
||||
Assertions.assertEquals("", loginConfiguration.getCustomLogoUrlPath());
|
||||
Assertions.assertEquals("", loginConfiguration.getCustomMonogramUrlPath());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -222,14 +222,4 @@ email:
|
||||
serverPort: ""
|
||||
username: ""
|
||||
password: ""
|
||||
transportationStrategy: "SMTP_TLS"
|
||||
|
||||
applicationConfig:
|
||||
logoConfig:
|
||||
customLogoUrlPath: ""
|
||||
customMonogramUrlPath: ""
|
||||
loginConfig:
|
||||
maxLoginFailAttempts: 3
|
||||
accessBlockTime: 600
|
||||
jwtTokenExpiryTime: 3600
|
||||
|
||||
transportationStrategy: "SMTP_TLS"
|
||||
@ -1,59 +0,0 @@
|
||||
{
|
||||
"$id": "https://open-metadata.org/schema/entity/configuration/applicationConfiguration.json",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "ApplicationConfiguration",
|
||||
"description": "This schema defines the Application Configuration.",
|
||||
"type": "object",
|
||||
"javaType": "org.openmetadata.api.configuration.ApplicationConfiguration",
|
||||
"definitions": {
|
||||
"logoConfiguration": {
|
||||
"description": "This schema defines the Logo Configuration",
|
||||
"type": "object",
|
||||
"javaType": "org.openmetadata.api.configuration.LogoConfiguration",
|
||||
"properties": {
|
||||
"customLogoUrlPath": {
|
||||
"description": "Login Page Logo Image Url",
|
||||
"type": "string"
|
||||
},
|
||||
"customMonogramUrlPath": {
|
||||
"description": "Navigation Bar Logo Image Url",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"loginConfiguration": {
|
||||
"description": "This schema defines the Login Configuration",
|
||||
"type": "object",
|
||||
"javaType": "org.openmetadata.schema.api.configuration.LoginConfiguration",
|
||||
"properties": {
|
||||
"maxLoginFailAttempts": {
|
||||
"description": "Failed Login Attempts allowed for user.",
|
||||
"type": "integer",
|
||||
"default": 3
|
||||
},
|
||||
"accessBlockTime": {
|
||||
"description": "Access Block time for user on exceeding failed attempts(in seconds)",
|
||||
"type": "integer",
|
||||
"default": 600
|
||||
},
|
||||
"jwtTokenExpiryTime": {
|
||||
"description": "Jwt Token Expiry time for login in seconds",
|
||||
"type": "integer",
|
||||
"default": 3600
|
||||
}
|
||||
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"logoConfig" : {
|
||||
"$ref": "#/definitions/logoConfiguration"
|
||||
},
|
||||
"loginConfig": {
|
||||
"$ref": "#/definitions/loginConfiguration"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
{
|
||||
"$id": "https://open-metadata.org/schema/entity/configuration/loginConfiguration.json",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "LogoConfiguration",
|
||||
"description": "This schema defines the Login Configuration",
|
||||
"type": "object",
|
||||
"javaType": "org.openmetadata.schema.api.configuration.LoginConfiguration",
|
||||
"properties": {
|
||||
"maxLoginFailAttempts": {
|
||||
"description": "Failed Login Attempts allowed for user.",
|
||||
"type": "integer",
|
||||
"default": 3
|
||||
},
|
||||
"accessBlockTime": {
|
||||
"description": "Access Block time for user on exceeding failed attempts(in seconds)",
|
||||
"type": "integer",
|
||||
"default": 600
|
||||
},
|
||||
"jwtTokenExpiryTime": {
|
||||
"description": "Jwt Token Expiry time for login in seconds",
|
||||
"type": "integer",
|
||||
"default": 3600
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
{
|
||||
"$id": "https://open-metadata.org/schema/entity/configuration/logoConfiguration.json",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "LogoConfiguration",
|
||||
"description": "This schema defines the Logo Configuration.",
|
||||
"type": "object",
|
||||
"javaType": "org.openmetadata.api.configuration.LogoConfiguration",
|
||||
"properties": {
|
||||
"customLogoUrlPath": {
|
||||
"description": "Login Page Logo Image Url",
|
||||
"type": "string"
|
||||
},
|
||||
"customFaviconUrlPath": {
|
||||
"description": "Favicon Page Logo Image Url",
|
||||
"type": "string"
|
||||
},
|
||||
"customMonogramUrlPath": {
|
||||
"description": "Navigation Bar Logo Image Url",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
@ -24,6 +24,7 @@
|
||||
"slackChat",
|
||||
"emailConfiguration",
|
||||
"customLogoConfiguration",
|
||||
"loginConfiguration",
|
||||
"slackAppConfiguration",
|
||||
"slackBot",
|
||||
"slackInstaller"
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2023 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
describe('template spec', () => {
|
||||
beforeEach(() => {
|
||||
cy.login();
|
||||
cy.get('[data-testid="app-bar-item-settings"]').click();
|
||||
|
||||
cy.get('[data-testid="settings-left-panel"]')
|
||||
.contains('Login Configuration')
|
||||
.scrollIntoView()
|
||||
.click();
|
||||
});
|
||||
|
||||
/* ==== Test Created with Cypress Studio ==== */
|
||||
it('update login configuration should work', function () {
|
||||
/* ==== Generated with Cypress Studio ==== */
|
||||
cy.get('[data-testid="edit-button"]').click();
|
||||
cy.get('[data-testid="jwtTokenExpiryTime"]').clear('3600');
|
||||
cy.get('[data-testid="jwtTokenExpiryTime"]').type('5000');
|
||||
cy.get('[data-testid="accessBlockTime"]').clear('600');
|
||||
cy.get('[data-testid="accessBlockTime"]').type('500');
|
||||
cy.get('[data-testid="maxLoginFailAttempts"]').clear('3');
|
||||
cy.get('[data-testid="maxLoginFailAttempts"]').type('5');
|
||||
cy.get('[data-testid="save-button"] > span').click();
|
||||
cy.get('[data-testid="max-login-fail-attampts"]').should('have.text', '5');
|
||||
cy.get('[data-testid="access-block-time"]').should('have.text', '500');
|
||||
cy.get('[data-testid="jwt-token-expiry-time"]').should(
|
||||
'have.text',
|
||||
'5000 Milliseconds'
|
||||
);
|
||||
/* ==== End Cypress Studio ==== */
|
||||
});
|
||||
|
||||
/* ==== Test Created with Cypress Studio ==== */
|
||||
it('reset login configuration', function () {
|
||||
/* ==== Generated with Cypress Studio ==== */
|
||||
cy.get('[data-testid="edit-button"] > :nth-child(2)').click();
|
||||
cy.get('[data-testid="maxLoginFailAttempts"]').clear('53');
|
||||
cy.get('[data-testid="maxLoginFailAttempts"]').type('3');
|
||||
cy.get('[data-testid="accessBlockTime"]').clear('500');
|
||||
cy.get('[data-testid="accessBlockTime"]').type('300');
|
||||
cy.get('[data-testid="jwtTokenExpiryTime"]').clear('5000');
|
||||
cy.get('[data-testid="jwtTokenExpiryTime"]').type('3600');
|
||||
cy.get('[data-testid="save-button"]').click();
|
||||
cy.get('.Toastify__toast-body > :nth-child(2)').should(
|
||||
'have.text',
|
||||
'Login Configuration updated successfully.'
|
||||
);
|
||||
/* ==== End Cypress Studio ==== */
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,31 @@
|
||||
# Custom Login Configuration
|
||||
|
||||
These are the custom option for application login configuration.
|
||||
|
||||
$$note
|
||||
It might take a few minutes to reflect changes.
|
||||
$$
|
||||
|
||||
Following configuration is needed to allow OpenMetadata to update login configurations.
|
||||
|
||||
$$section
|
||||
|
||||
### Max Login Fail Attempts $(id="maxLoginFailAttempts")
|
||||
|
||||
Failed Login Attempts allowed for user. Default: `3`.
|
||||
$$
|
||||
|
||||
$$section
|
||||
|
||||
### Access Block Time $(id="accessBlockTime")
|
||||
|
||||
Access Block time for user on exceeding failed attempts(in seconds). Default: `600`.
|
||||
$$
|
||||
|
||||
$$section
|
||||
|
||||
### JWT Token Expiry Time $(id="jwtTokenExpiryTime")
|
||||
|
||||
Jwt Token Expiry time for login in seconds. Default: `3600`.
|
||||
$$
|
||||
|
||||
@ -29,3 +29,14 @@ $$
|
||||
$$note
|
||||
Monogram aspect ratio should be 1:1 and Recommended size should be 30 x 30 px
|
||||
$$
|
||||
|
||||
$$section
|
||||
|
||||
### Fav Icon URL $(id="customFaviconUrlPath")
|
||||
|
||||
URL path for favicon.
|
||||
$$
|
||||
|
||||
$$note
|
||||
Favicon aspect ratio should be 1:1 and Recommended size should be 16 x 16 px
|
||||
$$
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { isEmpty } from 'lodash';
|
||||
import React, {
|
||||
createContext,
|
||||
FC,
|
||||
@ -20,11 +21,12 @@ import React, {
|
||||
useMemo,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { LogoConfiguration } from '../../generated/configuration/applicationConfiguration';
|
||||
import { LoginConfiguration } from '../../generated/configuration/loginConfiguration';
|
||||
import { LogoConfiguration } from '../../generated/configuration/logoConfiguration';
|
||||
import { EntityReference } from '../../generated/entity/type';
|
||||
import { getCustomLogoConfig } from '../../rest/settingConfigAPI';
|
||||
|
||||
interface ContextConfig extends LogoConfiguration {
|
||||
interface ContextConfig extends LogoConfiguration, LoginConfiguration {
|
||||
routeElements?: ReactNode;
|
||||
selectedPersona: EntityReference;
|
||||
updateSelectedPersona: (personaFqn: EntityReference) => void;
|
||||
@ -66,14 +68,28 @@ const ApplicationConfigProvider: FC<ApplicationConfigProviderProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
const updateSelectedPersona = useCallback((persona: EntityReference) => {
|
||||
setSelectedPersona(persona);
|
||||
}, []);
|
||||
const updateSelectedPersona = useCallback(
|
||||
(persona: EntityReference) => {
|
||||
setSelectedPersona(persona);
|
||||
},
|
||||
[setSelectedPersona]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
fetchApplicationConfig();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const faviconHref = isEmpty(applicationConfig.customFaviconUrlPath)
|
||||
? '/favicon.png'
|
||||
: applicationConfig.customFaviconUrlPath ?? '/favicon.png';
|
||||
const link = document.querySelector('link[rel~="icon"]');
|
||||
|
||||
if (link) {
|
||||
link.setAttribute('href', faviconHref);
|
||||
}
|
||||
}, [applicationConfig]);
|
||||
|
||||
const contextValue = useMemo(
|
||||
() => ({
|
||||
...applicationConfig,
|
||||
|
||||
@ -336,6 +336,15 @@ const PageNotFound = withSuspenseFallback(
|
||||
React.lazy(() => import('../../pages/page-not-found/PageNotFound'))
|
||||
);
|
||||
|
||||
const EditLoginConfiguration = withSuspenseFallback(
|
||||
React.lazy(
|
||||
() =>
|
||||
import(
|
||||
'../../pages/Configuration/EditLoginConfiguration/EditLoginConfigurationPage'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
const AuthenticatedAppRouter: FunctionComponent = () => {
|
||||
const { permissions } = usePermissionProvider();
|
||||
const { routeElements } = useApplicationConfigContext();
|
||||
@ -806,6 +815,12 @@ const AuthenticatedAppRouter: FunctionComponent = () => {
|
||||
hasPermission={false}
|
||||
path={ROUTES.SETTINGS_EDIT_CUSTOM_LOGO_CONFIG}
|
||||
/>
|
||||
<AdminProtectedRoute
|
||||
exact
|
||||
component={EditLoginConfiguration}
|
||||
hasPermission={false}
|
||||
path={ROUTES.SETTINGS_EDIT_CUSTOM_LOGIN_CONFIG}
|
||||
/>
|
||||
<Route exact component={EditRulePage} path={ROUTES.EDIT_POLICY_RULE} />
|
||||
|
||||
<Route exact component={GlobalSettingPage} path={ROUTES.SETTINGS} />
|
||||
|
||||
@ -133,6 +133,15 @@ const CustomLogoConfigSettingsPage = withSuspenseFallback(
|
||||
)
|
||||
);
|
||||
|
||||
const LoginConfigurationPage = withSuspenseFallback(
|
||||
React.lazy(
|
||||
() =>
|
||||
import(
|
||||
'../../pages/Configuration/LoginConfigurationDetails/LoginConfigurationPage'
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
const ApplicationPageV1 = withSuspenseFallback(
|
||||
React.lazy(() => import('../../pages/Application/ApplicationPage'))
|
||||
);
|
||||
@ -276,6 +285,15 @@ const GlobalSettingRouter = () => {
|
||||
GlobalSettingOptions.CUSTOM_LOGO
|
||||
)}
|
||||
/>
|
||||
<AdminProtectedRoute
|
||||
exact
|
||||
component={LoginConfigurationPage}
|
||||
hasPermission={false}
|
||||
path={getSettingPath(
|
||||
GlobalSettingsMenuCategory.OPEN_METADATA,
|
||||
GlobalSettingOptions.LOGIN_CONFIGURATION
|
||||
)}
|
||||
/>
|
||||
<AdminProtectedRoute
|
||||
exact
|
||||
component={CustomPageSettings}
|
||||
|
||||
@ -58,6 +58,7 @@ export enum GlobalSettingOptions {
|
||||
ADD_DATA_INSIGHT_REPORT_ALERT = 'add-data-insight-report',
|
||||
EDIT_DATA_INSIGHT_REPORT_ALERT = 'edit-data-insight-report',
|
||||
CUSTOM_LOGO = 'customLogo',
|
||||
LOGIN_CONFIGURATION = 'loginConfiguration',
|
||||
CUSTOMIZE_LANDING_PAGE = 'customizeLandingPage',
|
||||
TOPICS = 'topics',
|
||||
CONTAINERS = 'containers',
|
||||
|
||||
@ -312,6 +312,7 @@ export const ROUTES = {
|
||||
EDIT_KPI: `/data-insights/kpi/edit-kpi/${KPI_NAME}`,
|
||||
|
||||
SETTINGS_EDIT_CUSTOM_LOGO_CONFIG: `/settings/OpenMetadata/customLogo/edit-custom-logo-configuration`,
|
||||
SETTINGS_EDIT_CUSTOM_LOGIN_CONFIG: `/settings/OpenMetadata/customLogo/edit-custom-login-configuration`,
|
||||
|
||||
CUSTOMIZE_PAGE: `/customize-page/:fqn/:pageFqn`,
|
||||
};
|
||||
|
||||
@ -186,5 +186,6 @@ export const addDBTIngestionGuide = [
|
||||
|
||||
export const EMAIL_CONFIG_SERVICE_CATEGORY = 'EmailConfiguration';
|
||||
export const CUSTOM_LOGO_CONFIG_SERVICE_CATEGORY = 'CustomLogoConfiguration';
|
||||
export const CUSTOM_LOGIN_CONFIG_SERVICE_CATEGORY = 'CustomLoginConfiguration';
|
||||
export const CUSTOM_PROPERTY_CATEGORY = 'CustomProperty';
|
||||
export const OPEN_METADATA = 'OpenMetadata';
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
"accept": "Akzeptieren",
|
||||
"accept-suggestion": "Vorschlag akzeptieren",
|
||||
"access": "Zugriff",
|
||||
"access-block-time": "Access block time",
|
||||
"accessed": "Accessed",
|
||||
"account": "Konto",
|
||||
"account-email": "Konto-E-Mail",
|
||||
@ -410,6 +411,7 @@
|
||||
"extend-open-meta-data": "Extend OpenMetadata",
|
||||
"failed": "Fehlgeschlagen",
|
||||
"failure-context": "Fehlerkontext",
|
||||
"favicon-url": "Favicon URL",
|
||||
"feature": "Funktion",
|
||||
"feature-lowercase": "funktion",
|
||||
"feature-plural": "funktionen",
|
||||
@ -535,6 +537,7 @@
|
||||
"july": "Juli",
|
||||
"jump-to-end": "Zum Ende springen",
|
||||
"june": "Juni",
|
||||
"jwt-token-expiry-time": "JWT token expiry time",
|
||||
"jwt-uppercase": "JWT",
|
||||
"keyword-lowercase-plural": "Schlüsselwörter",
|
||||
"kill": "Beenden",
|
||||
@ -580,6 +583,7 @@
|
||||
"log-viewer": "Protokollanzeige",
|
||||
"logged-in-user-lowercase": "Angemeldeter Benutzer",
|
||||
"login": "Anmelden",
|
||||
"login-configuration": "Login Configuration",
|
||||
"logo-url": "URL des Logos",
|
||||
"logout": "Abmelden",
|
||||
"machine-learning": "Machine Learning",
|
||||
@ -595,6 +599,7 @@
|
||||
"market-place": "Marketplace",
|
||||
"matches": "Entspricht",
|
||||
"max": "Maximal",
|
||||
"max-login-fail-attampt-plural": "Max login fail attampts",
|
||||
"maximum-size-lowercase": "Maximale Größe",
|
||||
"may": "Mai",
|
||||
"mean": "Durchschnitt",
|
||||
@ -640,6 +645,7 @@
|
||||
"most-active-user": "Aktivste Benutzer",
|
||||
"most-recent-session": "Aktuellste Sitzung",
|
||||
"move-the-entity": "{{entity}} verschieben",
|
||||
"ms": "Milliseconds",
|
||||
"ms-team-plural": "MS-Teams",
|
||||
"mutually-exclusive": "Gegenseitig ausschließend",
|
||||
"my-data": "Meine Daten",
|
||||
@ -1147,6 +1153,7 @@
|
||||
"your-entity": "Ihre {{entity}}"
|
||||
},
|
||||
"message": {
|
||||
"access-block-time-message": "Access will be blocked for milliseconds after max failed login attapmts performed.",
|
||||
"access-to-collaborate": "Erlauben Sie jedem den freien Zugang, um dem Team beizutreten, Daten anzusehen und zusammenzuarbeiten.",
|
||||
"action-has-been-done-but-deploy-successfully": "{{action}} wurde erfolgreich durchgeführt und bereitgestellt.",
|
||||
"action-has-been-done-but-failed-to-deploy": "{{action}} wurde durchgeführt, aber die Bereitstellung ist fehlgeschlagen.",
|
||||
@ -1223,6 +1230,7 @@
|
||||
"create-or-update-email-account-for-bot": "Die Änderung der Kontaktemail aktualisiert oder erstellt einen neuen Bot-Benutzer.",
|
||||
"created-this-task-lowercase": "hat diese Aufgabe erstellt",
|
||||
"custom-classification-name-dbt-tags": "Benutzerdefinierter OpenMetadata-Klassifikationsname für dbt-Tags ",
|
||||
"custom-favicon-url-path-message": "URL path for the favicon icon.",
|
||||
"custom-logo-configuration-message": "Konfigurieren Sie das Anwendungslogo und das Monogramm.",
|
||||
"custom-logo-url-path-message": "URL-Pfad für das Anmeldeseitenlogo.",
|
||||
"custom-monogram-url-path-message": "URL-Pfad für das Navbar-Logo.",
|
||||
@ -1357,6 +1365,7 @@
|
||||
"invalid-object-key": "Ungültiger Objektschlüssel. Muss mit einem Buchstaben, einem Unterstrich oder einem Dollarzeichen beginnen, gefolgt von Buchstaben, Unterstrichen, Dollarzeichen oder Ziffern.",
|
||||
"invalid-property-name": "Ungültiger Eigenschaftsname.",
|
||||
"jwt-token": "Das von Ihnen generierte Token, das zum Zugriff auf die OpenMetadata-API verwendet werden kann.",
|
||||
"jwt-token-expiry-time-message": "JWT token expiry timer in milliseconds.",
|
||||
"kill-ingestion-warning": "Wenn Sie diese Erfassung abbrechen, werden alle laufenden und wartenden Workflows gestoppt und als fehlgeschlagen markiert.",
|
||||
"kill-successfully": "Erfolgreich laufende Workflows für {{entity}} gestoppt.",
|
||||
"kpi-subtitle": "Identifizieren Sie die wichtigsten Leistungskennzahlen (KPIs), die den Gesundheitszustand Ihrer Datenressourcen am besten widerspiegeln.",
|
||||
@ -1368,6 +1377,7 @@
|
||||
"lineage-data-is-not-available-for-deleted-entities": "Verbindungsdaten sind für gelöschte Entitäten nicht verfügbar.",
|
||||
"lineage-ingestion-description": "Die Verbindungsdaten-Erfassung kann konfiguriert und bereitgestellt werden, nachdem eine Metadaten-Erfassung eingerichtet wurde. Der Verbindungsdaten-Erfassungsworkflow ruft den Abfrageverlauf ab, analysiert Abfragen wie CREATE, INSERT, MERGE usw. und bereitet die Verbindung zwischen den beteiligten Entitäten vor. Die Verbindungsdaten-Erfassung kann nur eine Pipeline für einen Datenbankdienst haben. Definieren Sie die Dauer des Abfrageprotokolls (in Tagen) und die Ergebnisgrenze, um zu starten.",
|
||||
"list-of-strings-regex-patterns-csv": "Geben Sie eine Liste von Zeichenfolgen/Regex-Mustern als durch Kommas getrennte Werte ein.",
|
||||
"login-fail-attamp-message": "Allowed attampt on consicutive failed login to application.",
|
||||
"logout-confirmation": "Sind Sie sicher, dass Sie sich abmelden möchten?",
|
||||
"made-announcement-for-entity": "hat eine Ankündigung für {{entity}} gemacht.",
|
||||
"make-an-announcement": "Machen Sie eine Ankündigung!",
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
"accept": "Accept",
|
||||
"accept-suggestion": "Accept Suggestion",
|
||||
"access": "Access",
|
||||
"access-block-time": "Access block time",
|
||||
"accessed": "Accessed",
|
||||
"account": "Account",
|
||||
"account-email": "Account email",
|
||||
@ -410,6 +411,7 @@
|
||||
"extend-open-meta-data": "Extend OpenMetadata",
|
||||
"failed": "Failed",
|
||||
"failure-context": "Failure Context",
|
||||
"favicon-url": "Favicon URL",
|
||||
"feature": "Feature",
|
||||
"feature-lowercase": "feature",
|
||||
"feature-plural": "Features",
|
||||
@ -535,6 +537,7 @@
|
||||
"july": "July",
|
||||
"jump-to-end": "Jump to End",
|
||||
"june": "June",
|
||||
"jwt-token-expiry-time": "JWT token expiry time",
|
||||
"jwt-uppercase": "JWT",
|
||||
"keyword-lowercase-plural": "keywords",
|
||||
"kill": "Kill",
|
||||
@ -580,6 +583,7 @@
|
||||
"log-viewer": "Log Viewer",
|
||||
"logged-in-user-lowercase": "logged-in user",
|
||||
"login": "Login",
|
||||
"login-configuration": "Login Configuration",
|
||||
"logo-url": "Logo URL",
|
||||
"logout": "Logout",
|
||||
"machine-learning": "Machine Learning",
|
||||
@ -595,6 +599,7 @@
|
||||
"market-place": "Marketplace",
|
||||
"matches": "Matches",
|
||||
"max": "Max",
|
||||
"max-login-fail-attampt-plural": "Max login fail attampts",
|
||||
"maximum-size-lowercase": "maximum size",
|
||||
"may": "May",
|
||||
"mean": "Mean",
|
||||
@ -640,6 +645,7 @@
|
||||
"most-active-user": "Most Active User",
|
||||
"most-recent-session": "Most Recent Session",
|
||||
"move-the-entity": "Move the {{entity}}",
|
||||
"ms": "Milliseconds",
|
||||
"ms-team-plural": "MS Teams",
|
||||
"mutually-exclusive": "Mutually Exclusive",
|
||||
"my-data": "My Data",
|
||||
@ -1147,6 +1153,7 @@
|
||||
"your-entity": "Your {{entity}}"
|
||||
},
|
||||
"message": {
|
||||
"access-block-time-message": "Access will be blocked for milliseconds after max failed login attapmts performed.",
|
||||
"access-to-collaborate": "Allow open access for anyone to join the team, view data, and collaborate.",
|
||||
"action-has-been-done-but-deploy-successfully": "has been {{action}} and deployed successfully",
|
||||
"action-has-been-done-but-failed-to-deploy": "has been {{action}}, but failed to deploy",
|
||||
@ -1223,7 +1230,8 @@
|
||||
"create-or-update-email-account-for-bot": "Changing the account email will update or create a new bot user.",
|
||||
"created-this-task-lowercase": "created this task",
|
||||
"custom-classification-name-dbt-tags": "Custom OpenMetadata Classification name for dbt tags ",
|
||||
"custom-logo-configuration-message": "Configure The Application Logo and Monogram.",
|
||||
"custom-favicon-url-path-message": "URL path for the favicon icon.",
|
||||
"custom-logo-configuration-message": "Configure The Application Logo, Monogram and favicon icon.",
|
||||
"custom-logo-url-path-message": "URL path for the login page logo.",
|
||||
"custom-monogram-url-path-message": "URL path for the navbar logo.",
|
||||
"custom-property-name-validation": "Name must start with lower case with no space, underscore, or dots.",
|
||||
@ -1357,6 +1365,7 @@
|
||||
"invalid-object-key": "Invalid object key. Must start with a letter, underscore, or dollar sign, followed by letters, underscores, dollar signs, or digits.",
|
||||
"invalid-property-name": "Invalid Property Name",
|
||||
"jwt-token": "Token you have generated that can be used to access the OpenMetadata API.",
|
||||
"jwt-token-expiry-time-message": "JWT token expiry timer in milliseconds.",
|
||||
"kill-ingestion-warning": "Once you kill this Ingestion, all running and queued workflows will be stopped and marked as Failed.",
|
||||
"kill-successfully": "Successfully killed running workflows for",
|
||||
"kpi-subtitle": "Identify the Key Performance Indicators (KPI) that best reflect the health of your data assets.",
|
||||
@ -1368,6 +1377,7 @@
|
||||
"lineage-data-is-not-available-for-deleted-entities": "Lineage data is not available for deleted entities.",
|
||||
"lineage-ingestion-description": "Lineage ingestion can be configured and deployed after a metadata ingestion has been set up. The lineage ingestion workflow obtains the query history, parses CREATE, INSERT, MERGE... queries and prepares the lineage between the involved entities. The lineage ingestion can have only one pipeline for a database service. Define the Query Log Duration (in days) and Result Limit to start.",
|
||||
"list-of-strings-regex-patterns-csv": "Enter a list of strings/regex patterns as a comma separated value",
|
||||
"login-fail-attamp-message": "Allowed attampt on consicutive failed login to application.",
|
||||
"logout-confirmation": "Are you sure you want to logout?",
|
||||
"made-announcement-for-entity": "made an announcement for {{entity}}",
|
||||
"make-an-announcement": "Make an announcement!",
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
"accept": "Accept",
|
||||
"accept-suggestion": "Aceptar sugerencia",
|
||||
"access": "Acceso",
|
||||
"access-block-time": "Access block time",
|
||||
"accessed": "Accessed",
|
||||
"account": "Cuenta",
|
||||
"account-email": "Correo electrónico de la cuenta",
|
||||
@ -410,6 +411,7 @@
|
||||
"extend-open-meta-data": "Extend OpenMetadata",
|
||||
"failed": "Falló",
|
||||
"failure-context": "Contexto del error",
|
||||
"favicon-url": "Favicon URL",
|
||||
"feature": "Funcionalidad",
|
||||
"feature-lowercase": "funcionalidad",
|
||||
"feature-plural": "Funcionalidades",
|
||||
@ -535,6 +537,7 @@
|
||||
"july": "Julio",
|
||||
"jump-to-end": "Saltar al final",
|
||||
"june": "Junio",
|
||||
"jwt-token-expiry-time": "JWT token expiry time",
|
||||
"jwt-uppercase": "JWT",
|
||||
"keyword-lowercase-plural": "palabras clave",
|
||||
"kill": "Eliminar",
|
||||
@ -580,6 +583,7 @@
|
||||
"log-viewer": "Log Viewer",
|
||||
"logged-in-user-lowercase": "usuario conectado",
|
||||
"login": "Iniciar sesión",
|
||||
"login-configuration": "Login Configuration",
|
||||
"logo-url": "Logo URL",
|
||||
"logout": "Cerrar sesión",
|
||||
"machine-learning": "Machine Learning",
|
||||
@ -595,6 +599,7 @@
|
||||
"market-place": "Marketplace",
|
||||
"matches": "Coincide",
|
||||
"max": "Máx",
|
||||
"max-login-fail-attampt-plural": "Max login fail attampts",
|
||||
"maximum-size-lowercase": "tamaño máximo",
|
||||
"may": "Mayo",
|
||||
"mean": "Media",
|
||||
@ -640,6 +645,7 @@
|
||||
"most-active-user": "Usuario Más Activo",
|
||||
"most-recent-session": "Sesión Más Reciente",
|
||||
"move-the-entity": "Mover la {{entity}}",
|
||||
"ms": "Milliseconds",
|
||||
"ms-team-plural": "Equipos de MS",
|
||||
"mutually-exclusive": "Mutuamente Exclusivo",
|
||||
"my-data": "Mis Datos",
|
||||
@ -1147,6 +1153,7 @@
|
||||
"your-entity": "Tu {{entity}}"
|
||||
},
|
||||
"message": {
|
||||
"access-block-time-message": "Access will be blocked for milliseconds after max failed login attapmts performed.",
|
||||
"access-to-collaborate": "Permitir el acceso abierto para que cualquier persona se una al equipo, vea datos y colabore.",
|
||||
"action-has-been-done-but-deploy-successfully": "se ha {{action}} y se ha deployado correctamente",
|
||||
"action-has-been-done-but-failed-to-deploy": "se ha {{action}}, pero no se ha podido deployar",
|
||||
@ -1223,6 +1230,7 @@
|
||||
"create-or-update-email-account-for-bot": "Cambiar el correo electrónico de la cuenta actualizará o creará un nuevo bot.",
|
||||
"created-this-task-lowercase": "creó esta tarea",
|
||||
"custom-classification-name-dbt-tags": "Nombre personalizado de clasificación de OpenMetadata para tags de dbt",
|
||||
"custom-favicon-url-path-message": "URL path for the favicon icon.",
|
||||
"custom-logo-configuration-message": "Configure The Application Logo and Monogram.",
|
||||
"custom-logo-url-path-message": "URL path for the login page logo.",
|
||||
"custom-monogram-url-path-message": "URL path for the navbar logo.",
|
||||
@ -1357,6 +1365,7 @@
|
||||
"invalid-object-key": "Invalid object key. Must start with a letter, underscore, or dollar sign, followed by letters, underscores, dollar signs, or digits.",
|
||||
"invalid-property-name": "Nombre de propiedad no válido",
|
||||
"jwt-token": "Token que ha generado que se puede utilizar para acceder a la API de OpenMetadata.",
|
||||
"jwt-token-expiry-time-message": "JWT token expiry timer in milliseconds.",
|
||||
"kill-ingestion-warning": "Una vez que se detenga esta ingestión, se detendrán y marcarán como fallidas todos los flujos de trabajo en ejecución y en cola.",
|
||||
"kill-successfully": "Se detuvieron con éxito los flujos de trabajo en ejecución para",
|
||||
"kpi-subtitle": "Identifica los Indicadores Clave de Rendimiento (KPI) que reflejan mejor la salud de tus activos de datos.",
|
||||
@ -1368,6 +1377,7 @@
|
||||
"lineage-data-is-not-available-for-deleted-entities": "Los datos de linaje no están disponibles para las entidades eliminadas.",
|
||||
"lineage-ingestion-description": "La ingesta de linaje se puede configurar y implementar después de que se haya establecido una ingesta de metadatos. El workflow de ingesta de linaje obtiene el historial de consultas, analiza las consultas CREATE, INSERT, MERGE, etc. y prepara el linaje entre las entidades involucradas. La ingesta de linaje solo puede tener un workflow para un servicio de base de datos. Defina la duración del registro de consultas (en días) y el límite de resultados para comenzar.",
|
||||
"list-of-strings-regex-patterns-csv": "Ingrese una lista de cadenas/patrones regex como un valor separado por comas",
|
||||
"login-fail-attamp-message": "Allowed attampt on consicutive failed login to application.",
|
||||
"logout-confirmation": "Are you sure you want to logout?",
|
||||
"made-announcement-for-entity": "hizo un anuncio para {{entity}}",
|
||||
"make-an-announcement": "¡Haz un anuncio!",
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
"accept": "Accepter",
|
||||
"accept-suggestion": "Accepter la Suggestion",
|
||||
"access": "Accès",
|
||||
"access-block-time": "Access block time",
|
||||
"accessed": "Accessed",
|
||||
"account": "Compte",
|
||||
"account-email": "Compte email",
|
||||
@ -410,6 +411,7 @@
|
||||
"extend-open-meta-data": "Extend OpenMetadata",
|
||||
"failed": "Échec",
|
||||
"failure-context": "Contexte de l'Échec",
|
||||
"favicon-url": "Favicon URL",
|
||||
"feature": "Fonctionnalité",
|
||||
"feature-lowercase": "fonctionnalité",
|
||||
"feature-plural": "fonctionnalités",
|
||||
@ -535,6 +537,7 @@
|
||||
"july": "Juillet",
|
||||
"jump-to-end": "Aller à la Fin",
|
||||
"june": "Juin",
|
||||
"jwt-token-expiry-time": "JWT token expiry time",
|
||||
"jwt-uppercase": "JWT",
|
||||
"keyword-lowercase-plural": "mots-clés",
|
||||
"kill": "Arrêter",
|
||||
@ -580,6 +583,7 @@
|
||||
"log-viewer": "Visionneuse de Journal",
|
||||
"logged-in-user-lowercase": "Utilisateur Connecté",
|
||||
"login": "Se Connecter",
|
||||
"login-configuration": "Login Configuration",
|
||||
"logo-url": "URL du Logo",
|
||||
"logout": "Se Déconnecter",
|
||||
"machine-learning": "Machine Learning",
|
||||
@ -595,6 +599,7 @@
|
||||
"market-place": "Marketplace",
|
||||
"matches": "Correspond",
|
||||
"max": "Max",
|
||||
"max-login-fail-attampt-plural": "Max login fail attampts",
|
||||
"maximum-size-lowercase": "taille maximum",
|
||||
"may": "Mai",
|
||||
"mean": "Moyenne",
|
||||
@ -640,6 +645,7 @@
|
||||
"most-active-user": "Utilisateurs les plus Actifs",
|
||||
"most-recent-session": "Session la Plus Récente",
|
||||
"move-the-entity": "Déplacer {{entity}}",
|
||||
"ms": "Milliseconds",
|
||||
"ms-team-plural": "Équipes MS",
|
||||
"mutually-exclusive": "Mutuellement Exclusif",
|
||||
"my-data": "Mes Données",
|
||||
@ -1147,6 +1153,7 @@
|
||||
"your-entity": "Votre {{entity}}"
|
||||
},
|
||||
"message": {
|
||||
"access-block-time-message": "Access will be blocked for milliseconds after max failed login attapmts performed.",
|
||||
"access-to-collaborate": "Permettre l'accès ouvert à l'équipe. Tout le monde pourra rejoindre l'équipe, voir les données, et collaborer",
|
||||
"action-has-been-done-but-deploy-successfully": "{{action}} avec succès et déployé avec succès",
|
||||
"action-has-been-done-but-failed-to-deploy": "{{action}} avec succès, mais n'a pu être déployé",
|
||||
@ -1223,6 +1230,7 @@
|
||||
"create-or-update-email-account-for-bot": "Changer l'email créera un nouveau ou mettra à jour l'agent numérique",
|
||||
"created-this-task-lowercase": "a créé cette tâche",
|
||||
"custom-classification-name-dbt-tags": "Nom personnalisé de la classification OpenMetadata pour les tags dbt ",
|
||||
"custom-favicon-url-path-message": "URL path for the favicon icon.",
|
||||
"custom-logo-configuration-message": "Configure The Application Logo and Monogram.",
|
||||
"custom-logo-url-path-message": "URL path for the login page logo.",
|
||||
"custom-monogram-url-path-message": "URL path for the navbar logo.",
|
||||
@ -1357,6 +1365,7 @@
|
||||
"invalid-object-key": "Invalid object key. Must start with a letter, underscore, or dollar sign, followed by letters, underscores, dollar signs, or digits.",
|
||||
"invalid-property-name": "Nom de propriété non valide",
|
||||
"jwt-token": "Le Jeton que vous avez généré peut être utilisé pour accéder à l’API OpenMetadata.",
|
||||
"jwt-token-expiry-time-message": "JWT token expiry timer in milliseconds.",
|
||||
"kill-ingestion-warning": "Une fois que vous avez interrompu cette Ingestion, tous les workflows en cours d'éxécutions et en files d'attente seront arrêtés et marqués comme aillant échoué.",
|
||||
"kill-successfully": "Workflow a été interrompu avec succès pour",
|
||||
"kpi-subtitle": "Identifier les indicateurs de performance clés (KPI) qui reflètent le mieux la santé de vos actifs de données.",
|
||||
@ -1368,6 +1377,7 @@
|
||||
"lineage-data-is-not-available-for-deleted-entities": "Traçabilité des données n'est pas disponible pour les entités supprimées.",
|
||||
"lineage-ingestion-description": "Traçabilité de l'ingestion peut être configurée et déployée après une ingestion de métadonnées a été mis en place. Le flux de travail d'ingestion de la lignée obtient l'historique des requêtes, analyse CREATE, INSERT, MERGE... requêtes et prépare la lignée entre les entités impliquées. L'ingestion de la lignée peut avoir un seul pipeline pour un service de base de données. Définir la durée du journal de requêtes (en jours) et le nombre de résultats pour démarrer.",
|
||||
"list-of-strings-regex-patterns-csv": "Entrer une liste de chaînes / motifs regex comme une valeur séparée par des virgules",
|
||||
"login-fail-attamp-message": "Allowed attampt on consicutive failed login to application.",
|
||||
"logout-confirmation": "Are you sure you want to logout?",
|
||||
"made-announcement-for-entity": "a fait une annonce pour {{entity}}",
|
||||
"make-an-announcement": "Faire une annonce",
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
"accept": "Accept",
|
||||
"accept-suggestion": "提案を受け入れる",
|
||||
"access": "アクセス",
|
||||
"access-block-time": "Access block time",
|
||||
"accessed": "Accessed",
|
||||
"account": "アカウント",
|
||||
"account-email": "アカウントのEmail",
|
||||
@ -410,6 +411,7 @@
|
||||
"extend-open-meta-data": "Extend OpenMetadata",
|
||||
"failed": "失敗",
|
||||
"failure-context": "Failure Context",
|
||||
"favicon-url": "Favicon URL",
|
||||
"feature": "Feature",
|
||||
"feature-lowercase": "feature",
|
||||
"feature-plural": "Features",
|
||||
@ -535,6 +537,7 @@
|
||||
"july": "7月",
|
||||
"jump-to-end": "最後に移動",
|
||||
"june": "6月",
|
||||
"jwt-token-expiry-time": "JWT token expiry time",
|
||||
"jwt-uppercase": "JWT",
|
||||
"keyword-lowercase-plural": "キーワード",
|
||||
"kill": "終了",
|
||||
@ -580,6 +583,7 @@
|
||||
"log-viewer": "Log Viewer",
|
||||
"logged-in-user-lowercase": "logged-in user",
|
||||
"login": "ログイン",
|
||||
"login-configuration": "Login Configuration",
|
||||
"logo-url": "Logo URL",
|
||||
"logout": "ログアウト",
|
||||
"machine-learning": "Machine Learning",
|
||||
@ -595,6 +599,7 @@
|
||||
"market-place": "Marketplace",
|
||||
"matches": "マッチ",
|
||||
"max": "最大",
|
||||
"max-login-fail-attampt-plural": "Max login fail attampts",
|
||||
"maximum-size-lowercase": "最大サイズ",
|
||||
"may": "3月",
|
||||
"mean": "Mean",
|
||||
@ -640,6 +645,7 @@
|
||||
"most-active-user": "最もアクティブなユーザ",
|
||||
"most-recent-session": "最近のセッション",
|
||||
"move-the-entity": "Move the {{entity}}",
|
||||
"ms": "Milliseconds",
|
||||
"ms-team-plural": "MS Teams",
|
||||
"mutually-exclusive": "Mutually Exclusive",
|
||||
"my-data": "マイデータ",
|
||||
@ -1147,6 +1153,7 @@
|
||||
"your-entity": "あなたの{{entity}}"
|
||||
},
|
||||
"message": {
|
||||
"access-block-time-message": "Access will be blocked for milliseconds after max failed login attapmts performed.",
|
||||
"access-to-collaborate": "Allow open access for anyone to join the team, view data, and collaborate.",
|
||||
"action-has-been-done-but-deploy-successfully": "has been {{action}} and deployed successfully",
|
||||
"action-has-been-done-but-failed-to-deploy": "has been {{action}}, but failed to deploy",
|
||||
@ -1223,6 +1230,7 @@
|
||||
"create-or-update-email-account-for-bot": "Changing the account email will update or create a new bot user.",
|
||||
"created-this-task-lowercase": "このタスクを作成する",
|
||||
"custom-classification-name-dbt-tags": "Custom OpenMetadata Classification name for dbt tags ",
|
||||
"custom-favicon-url-path-message": "URL path for the favicon icon.",
|
||||
"custom-logo-configuration-message": "Configure The Application Logo and Monogram.",
|
||||
"custom-logo-url-path-message": "URL path for the login page logo.",
|
||||
"custom-monogram-url-path-message": "URL path for the navbar logo.",
|
||||
@ -1357,6 +1365,7 @@
|
||||
"invalid-object-key": "Invalid object key. Must start with a letter, underscore, or dollar sign, followed by letters, underscores, dollar signs, or digits.",
|
||||
"invalid-property-name": "無効なプロパティ名",
|
||||
"jwt-token": "Token you have generated that can be used to access the OpenMetadata API.",
|
||||
"jwt-token-expiry-time-message": "JWT token expiry timer in milliseconds.",
|
||||
"kill-ingestion-warning": "Once you kill this Ingestion, all running and queued workflows will be stopped and marked as Failed.",
|
||||
"kill-successfully": "Successfully killed running workflows for",
|
||||
"kpi-subtitle": "Identify the Key Performance Indicators (KPI) that best reflect the health of your data assets.",
|
||||
@ -1368,6 +1377,7 @@
|
||||
"lineage-data-is-not-available-for-deleted-entities": "削除されたエンティティのリネージ情報は利用できません。",
|
||||
"lineage-ingestion-description": "Lineage ingestion can be configured and deployed after a metadata ingestion has been set up. The lineage ingestion workflow obtains the query history, parses CREATE, INSERT, MERGE... queries and prepares the lineage between the involved entities. The lineage ingestion can have only one pipeline for a database service. Define the Query Log Duration (in days) and Result Limit to start.",
|
||||
"list-of-strings-regex-patterns-csv": "Enter a list of strings/regex patterns as a comma separated value",
|
||||
"login-fail-attamp-message": "Allowed attampt on consicutive failed login to application.",
|
||||
"logout-confirmation": "Are you sure you want to logout?",
|
||||
"made-announcement-for-entity": "{{entity}}に対するお知らせを作成しました。",
|
||||
"make-an-announcement": "お知らせを作成してください!",
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
"accept": "Accept",
|
||||
"accept-suggestion": "Aceitar sugestão",
|
||||
"access": "Acesso",
|
||||
"access-block-time": "Access block time",
|
||||
"accessed": "Accessed",
|
||||
"account": "Conta",
|
||||
"account-email": "E-mail da conta",
|
||||
@ -410,6 +411,7 @@
|
||||
"extend-open-meta-data": "Extend OpenMetadata",
|
||||
"failed": "Falhou",
|
||||
"failure-context": "Contexto da falha",
|
||||
"favicon-url": "Favicon URL",
|
||||
"feature": "Função",
|
||||
"feature-lowercase": "Função",
|
||||
"feature-plural": "Funções",
|
||||
@ -535,6 +537,7 @@
|
||||
"july": "Julho",
|
||||
"jump-to-end": "Pular para o final",
|
||||
"june": "Junho",
|
||||
"jwt-token-expiry-time": "JWT token expiry time",
|
||||
"jwt-uppercase": "JWT",
|
||||
"keyword-lowercase-plural": "palavras chaves",
|
||||
"kill": "Destruir",
|
||||
@ -580,6 +583,7 @@
|
||||
"log-viewer": "Log Viewer",
|
||||
"logged-in-user-lowercase": "conectar com usuário",
|
||||
"login": "Entrar",
|
||||
"login-configuration": "Login Configuration",
|
||||
"logo-url": "Logo URL",
|
||||
"logout": "Sair",
|
||||
"machine-learning": "Machine Learning",
|
||||
@ -595,6 +599,7 @@
|
||||
"market-place": "Marketplace",
|
||||
"matches": "Combinar",
|
||||
"max": "Max",
|
||||
"max-login-fail-attampt-plural": "Max login fail attampts",
|
||||
"maximum-size-lowercase": "tamanho máximo",
|
||||
"may": "Maio",
|
||||
"mean": "Média",
|
||||
@ -640,6 +645,7 @@
|
||||
"most-active-user": "Usuário mais ativo",
|
||||
"most-recent-session": "Sessão mais recente",
|
||||
"move-the-entity": "Mover a {{entity}}",
|
||||
"ms": "Milliseconds",
|
||||
"ms-team-plural": "MS Teams",
|
||||
"mutually-exclusive": "Mutualmente exclusivo",
|
||||
"my-data": "Meus dados",
|
||||
@ -1147,6 +1153,7 @@
|
||||
"your-entity": "Sua {{entity}}"
|
||||
},
|
||||
"message": {
|
||||
"access-block-time-message": "Access will be blocked for milliseconds after max failed login attapmts performed.",
|
||||
"access-to-collaborate": "Permite acesso aberto para qualquer pessoa ingressar na equipe, visualizar dados e colaborar.",
|
||||
"action-has-been-done-but-deploy-successfully": "foi {{action}} e implantado com sucesso",
|
||||
"action-has-been-done-but-failed-to-deploy": "foi {{action}}, mas falhou ao implantar",
|
||||
@ -1223,6 +1230,7 @@
|
||||
"create-or-update-email-account-for-bot": "Alterar o e-mail da conta atualizará ou criará um novo usuário de bot.",
|
||||
"created-this-task-lowercase": "criou esta tarefa",
|
||||
"custom-classification-name-dbt-tags": "Nome personalizado da Classificação OpenMetadata para tags dbt",
|
||||
"custom-favicon-url-path-message": "URL path for the favicon icon.",
|
||||
"custom-logo-configuration-message": "Configure The Application Logo and Monogram.",
|
||||
"custom-logo-url-path-message": "URL path for the login page logo.",
|
||||
"custom-monogram-url-path-message": "URL path for the navbar logo.",
|
||||
@ -1357,6 +1365,7 @@
|
||||
"invalid-object-key": "Invalid object key. Must start with a letter, underscore, or dollar sign, followed by letters, underscores, dollar signs, or digits.",
|
||||
"invalid-property-name": "Nome de propriedade inválido",
|
||||
"jwt-token": "Token que você gerou que pode ser usado para acessar a API do OpenMetadata.",
|
||||
"jwt-token-expiry-time-message": "JWT token expiry timer in milliseconds.",
|
||||
"kill-ingestion-warning": "Uma vez que você interromper esta Ingestão, todos os fluxos de trabalho em execução e em fila serão interrompidos e marcados como Falha.",
|
||||
"kill-successfully": "Fluxos de trabalho em execução interrompidos com sucesso para",
|
||||
"kpi-subtitle": "Identifique os Indicadores Chave de Desempenho (KPI) que melhor refletem a saúde dos seus ativos de dados.",
|
||||
@ -1368,6 +1377,7 @@
|
||||
"lineage-data-is-not-available-for-deleted-entities": "Os dados de linhagem não estão disponíveis para entidades excluídas.",
|
||||
"lineage-ingestion-description": "A ingestão de linhagem pode ser configurada e implantada após a configuração da ingestão de metadados. O fluxo de trabalho de ingestão de linhagem obtém o histórico de consultas, analisa as consultas CREATE, INSERT, MERGE ... e prepara a linhagem entre as entidades envolvidas. A ingestão de linhagem pode ter apenas um pipeline para um serviço de banco de dados. Defina a Duração do Log de Consulta (em dias) e o Limite de Resultado para iniciar.",
|
||||
"list-of-strings-regex-patterns-csv": "Digite uma lista de padrões de strings/regex como um valor separado por vírgula",
|
||||
"login-fail-attamp-message": "Allowed attampt on consicutive failed login to application.",
|
||||
"logout-confirmation": "Are you sure you want to logout?",
|
||||
"made-announcement-for-entity": "fez um anúncio para {{entity}}",
|
||||
"make-an-announcement": "Faça um anúncio!",
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
"accept": "Принять",
|
||||
"accept-suggestion": "Согласовать предложение",
|
||||
"access": "Доступ",
|
||||
"access-block-time": "Access block time",
|
||||
"accessed": "Accessed",
|
||||
"account": "Аккаунт",
|
||||
"account-email": "Адрес электронной почты",
|
||||
@ -410,6 +411,7 @@
|
||||
"extend-open-meta-data": "Extend OpenMetadata",
|
||||
"failed": "Неуспешно",
|
||||
"failure-context": "Контекст отказа",
|
||||
"favicon-url": "Favicon URL",
|
||||
"feature": "Свойство",
|
||||
"feature-lowercase": "свойство",
|
||||
"feature-plural": "Свойства",
|
||||
@ -535,6 +537,7 @@
|
||||
"july": "Июль",
|
||||
"jump-to-end": "Перейти к концу",
|
||||
"june": "Июнь",
|
||||
"jwt-token-expiry-time": "JWT token expiry time",
|
||||
"jwt-uppercase": "JWT",
|
||||
"keyword-lowercase-plural": "ключевые слова",
|
||||
"kill": "Уничтожить",
|
||||
@ -580,6 +583,7 @@
|
||||
"log-viewer": "Журнал просмотров",
|
||||
"logged-in-user-lowercase": "авторизованный пользователь",
|
||||
"login": "Логин",
|
||||
"login-configuration": "Login Configuration",
|
||||
"logo-url": "URL-адрес логотипа",
|
||||
"logout": "Выйти",
|
||||
"machine-learning": "Machine Learning",
|
||||
@ -595,6 +599,7 @@
|
||||
"market-place": "Marketplace",
|
||||
"matches": "Совпадения",
|
||||
"max": "Максимум",
|
||||
"max-login-fail-attampt-plural": "Max login fail attampts",
|
||||
"maximum-size-lowercase": "максимальный размер",
|
||||
"may": "Май",
|
||||
"mean": "Среднее",
|
||||
@ -640,6 +645,7 @@
|
||||
"most-active-user": "Самый активный пользователь",
|
||||
"most-recent-session": "Последний сеанс",
|
||||
"move-the-entity": "Переместите {{entity}}",
|
||||
"ms": "Milliseconds",
|
||||
"ms-team-plural": "MS Команды",
|
||||
"mutually-exclusive": "Единичный выбор",
|
||||
"my-data": "Мои данные",
|
||||
@ -1147,6 +1153,7 @@
|
||||
"your-entity": "Ваш {{entity}}"
|
||||
},
|
||||
"message": {
|
||||
"access-block-time-message": "Access will be blocked for milliseconds after max failed login attapmts performed.",
|
||||
"access-to-collaborate": "Разрешить открытый доступ для всех, кто может присоединиться к команде, просматривать данные и сотрудничать.",
|
||||
"action-has-been-done-but-deploy-successfully": "было выполнено {{action}} и успешно развернуто",
|
||||
"action-has-been-done-but-failed-to-deploy": "было {{action}}, но не удалось развернуть",
|
||||
@ -1223,6 +1230,7 @@
|
||||
"create-or-update-email-account-for-bot": "Изменение адреса электронной почты учетной записи приведет к обновлению или созданию нового пользователя-бота.",
|
||||
"created-this-task-lowercase": "Задача создана",
|
||||
"custom-classification-name-dbt-tags": "Пользовательское имя классификации OpenMetadata для тегов dbt",
|
||||
"custom-favicon-url-path-message": "URL path for the favicon icon.",
|
||||
"custom-logo-configuration-message": "Настройте логотип приложения и монограмму.",
|
||||
"custom-logo-url-path-message": "Путь URL для логотипа страницы входа.",
|
||||
"custom-monogram-url-path-message": "Путь URL для логотипа панели навигации.",
|
||||
@ -1357,6 +1365,7 @@
|
||||
"invalid-object-key": "Неверный ключ объекта. Должен начинаться с буквы, знака подчеркивания или знака доллара, за которыми следуют буквы, знаки подчеркивания, знаки доллара или цифры.",
|
||||
"invalid-property-name": "Недопустимое имя свойства",
|
||||
"jwt-token": "Сгенерированный вами токен, который можно использовать для доступа к API OpenMetadata.",
|
||||
"jwt-token-expiry-time-message": "JWT token expiry timer in milliseconds.",
|
||||
"kill-ingestion-warning": "Как только вы завершите это действие, все запущенные рабочие процессы и процессы, находящиеся в очереди, будут остановлены и помечены как неудавшиеся.",
|
||||
"kill-successfully": "Успешно завершены рабочие процессы для",
|
||||
"kpi-subtitle": "Определите ключевые показатели эффективности (KPI), которые лучше всего отражают состояние ваших объектов данных.",
|
||||
@ -1368,6 +1377,7 @@
|
||||
"lineage-data-is-not-available-for-deleted-entities": "Данные о происхождении недоступны для удаленных сущностей.",
|
||||
"lineage-ingestion-description": "Прием данных о происхождении можно настроить и развернуть после настройки приема метаданных. Рабочий процесс приема происхождения получает историю запросов, анализирует запросы CREATE, INSERT, MERGE... и подготавливает происхождение между вовлеченными сущностями. У приема происхождения может быть только один конвейер для службы базы данных. Определите продолжительность журнала запросов (в днях) и лимит результатов для запуска.",
|
||||
"list-of-strings-regex-patterns-csv": "Введите список строк/шаблонов регулярных выражений в виде значения, разделенного запятыми.",
|
||||
"login-fail-attamp-message": "Allowed attampt on consicutive failed login to application.",
|
||||
"logout-confirmation": "Вы уверены, что хотите выйти из системы?",
|
||||
"made-announcement-for-entity": "сделано объявление для {{entity}}",
|
||||
"make-an-announcement": "Сделайте объявление!",
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
"accept": "接受",
|
||||
"accept-suggestion": "接受建议",
|
||||
"access": "访问",
|
||||
"access-block-time": "Access block time",
|
||||
"accessed": "Accessed",
|
||||
"account": "帐号",
|
||||
"account-email": "帐号邮箱",
|
||||
@ -410,6 +411,7 @@
|
||||
"extend-open-meta-data": "Extend OpenMetadata",
|
||||
"failed": "失败",
|
||||
"failure-context": "失败上下文",
|
||||
"favicon-url": "Favicon URL",
|
||||
"feature": "特点",
|
||||
"feature-lowercase": "特点",
|
||||
"feature-plural": "特点",
|
||||
@ -535,6 +537,7 @@
|
||||
"july": "七月",
|
||||
"jump-to-end": "跳到终点",
|
||||
"june": "六月",
|
||||
"jwt-token-expiry-time": "JWT token expiry time",
|
||||
"jwt-uppercase": "JWT",
|
||||
"keyword-lowercase-plural": "关键词",
|
||||
"kill": "终止",
|
||||
@ -580,6 +583,7 @@
|
||||
"log-viewer": "日志查看器",
|
||||
"logged-in-user-lowercase": "已登录用户",
|
||||
"login": "登录",
|
||||
"login-configuration": "Login Configuration",
|
||||
"logo-url": "Logo URL",
|
||||
"logout": "退出",
|
||||
"machine-learning": "Machine Learning",
|
||||
@ -595,6 +599,7 @@
|
||||
"market-place": "Marketplace",
|
||||
"matches": "匹配",
|
||||
"max": "最大值",
|
||||
"max-login-fail-attampt-plural": "Max login fail attampts",
|
||||
"maximum-size-lowercase": "最大",
|
||||
"may": "五月",
|
||||
"mean": "平均值",
|
||||
@ -640,6 +645,7 @@
|
||||
"most-active-user": "最活跃用户",
|
||||
"most-recent-session": "最近的会话",
|
||||
"move-the-entity": "移动{{entity}}",
|
||||
"ms": "Milliseconds",
|
||||
"ms-team-plural": "MS Teams",
|
||||
"mutually-exclusive": "互斥的",
|
||||
"my-data": "我的数据",
|
||||
@ -1147,6 +1153,7 @@
|
||||
"your-entity": "您的{{entity}}"
|
||||
},
|
||||
"message": {
|
||||
"access-block-time-message": "Access will be blocked for milliseconds after max failed login attapmts performed.",
|
||||
"access-to-collaborate": "允许任何人加入团队,查看数据并协作",
|
||||
"action-has-been-done-but-deploy-successfully": "{{action}}已完成并成功部署",
|
||||
"action-has-been-done-but-failed-to-deploy": "{{action}}已完成,但未能部署",
|
||||
@ -1223,6 +1230,7 @@
|
||||
"create-or-update-email-account-for-bot": "更改帐号电子邮箱将更新或创建一个新的机器人用户",
|
||||
"created-this-task-lowercase": "创建了此任务",
|
||||
"custom-classification-name-dbt-tags": "dbt 标签的自定义 OpenMetadata 分类名称",
|
||||
"custom-favicon-url-path-message": "URL path for the favicon icon.",
|
||||
"custom-logo-configuration-message": "配置系统的 Logo",
|
||||
"custom-logo-url-path-message": "登录页 Logo 指向的 URL 地址",
|
||||
"custom-monogram-url-path-message": "导航栏 Logo 指向的 URL 地址",
|
||||
@ -1357,6 +1365,7 @@
|
||||
"invalid-object-key": "无效的对象键名,命名首字母必须由字母、下划线、美元符号开始,再跟随字母、下划线、美元符号或数字",
|
||||
"invalid-property-name": "无效属性名称",
|
||||
"jwt-token": "您生成的,用于访问 OpenMetadata API 的令牌",
|
||||
"jwt-token-expiry-time-message": "JWT token expiry timer in milliseconds.",
|
||||
"kill-ingestion-warning": "一旦您终止此提取工作流,所有正在运行和排队的工作流任务都将停止并标记为失败",
|
||||
"kill-successfully": "成功终止运行中的工作流",
|
||||
"kpi-subtitle": "确定最能反映数据资产健康状况的关键绩效指标 (KPI)",
|
||||
@ -1368,6 +1377,7 @@
|
||||
"lineage-data-is-not-available-for-deleted-entities": "已删除的实体的血缘数据不可用",
|
||||
"lineage-ingestion-description": "在设置元数据提取后,可以配置并部署血缘提取。血缘提取工作流获取查询历史记录,解析 CREATE、INSERT、MERGE... 查询,并整理相关实体之间的血缘。一个数据库服务只能定义一个血缘提取工作流。定义查询日志持续时间(天数)和结果限制即可开始。",
|
||||
"list-of-strings-regex-patterns-csv": "以逗号分隔的值的形式输入字符串/正则表达式列表",
|
||||
"login-fail-attamp-message": "Allowed attampt on consicutive failed login to application.",
|
||||
"logout-confirmation": "您确定要注销登录吗?",
|
||||
"made-announcement-for-entity": "为{{entity}}发布了公告",
|
||||
"make-an-announcement": "发布公告",
|
||||
|
||||
@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright 2023 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { Button, Col, Form, Row } from 'antd';
|
||||
import { AxiosError } from 'axios';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import ResizablePanels from '../../../components/common/ResizablePanels/ResizablePanels';
|
||||
import ServiceDocPanel from '../../../components/common/ServiceDocPanel/ServiceDocPanel';
|
||||
import TitleBreadcrumb from '../../../components/common/title-breadcrumb/title-breadcrumb.component';
|
||||
import Loader from '../../../components/Loader/Loader';
|
||||
import { VALIDATION_MESSAGES } from '../../../constants/constants';
|
||||
import {
|
||||
GlobalSettingOptions,
|
||||
GlobalSettingsMenuCategory,
|
||||
} from '../../../constants/GlobalSettings.constants';
|
||||
import {
|
||||
CUSTOM_LOGIN_CONFIG_SERVICE_CATEGORY,
|
||||
OPEN_METADATA,
|
||||
} from '../../../constants/service-guide.constant';
|
||||
import { ServiceCategory } from '../../../enums/service.enum';
|
||||
import { LoginConfiguration } from '../../../generated/configuration/loginConfiguration';
|
||||
import { Settings, SettingType } from '../../../generated/settings/settings';
|
||||
import { FieldProp, FieldTypes } from '../../../interface/FormUtils.interface';
|
||||
import {
|
||||
getLoginConfig,
|
||||
updateSettingsConfig,
|
||||
} from '../../../rest/settingConfigAPI';
|
||||
import { generateFormFields } from '../../../utils/formUtils';
|
||||
import { getSettingPath } from '../../../utils/RouterUtils';
|
||||
import { showErrorToast, showSuccessToast } from '../../../utils/ToastUtils';
|
||||
|
||||
const EditLoginConfiguration = () => {
|
||||
const { t } = useTranslation();
|
||||
const history = useHistory();
|
||||
const [form] = Form.useForm<LoginConfiguration>();
|
||||
const [activeField, setActiveField] = useState<string>('');
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [updating, setUpdating] = useState<boolean>(false);
|
||||
|
||||
const fetchCustomLogoConfig = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
const data = await getLoginConfig();
|
||||
|
||||
form.setFieldsValue({ ...(data ?? {}) });
|
||||
} catch (error) {
|
||||
showErrorToast(error as AxiosError);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const breadcrumb = useMemo(
|
||||
() => [
|
||||
{
|
||||
name: t('label.setting-plural'),
|
||||
url: getSettingPath(),
|
||||
},
|
||||
{
|
||||
name: t('label.login-configuration'),
|
||||
url: getSettingPath(
|
||||
GlobalSettingsMenuCategory.OPEN_METADATA,
|
||||
GlobalSettingOptions.LOGIN_CONFIGURATION
|
||||
),
|
||||
},
|
||||
{
|
||||
name: t('label.edit-entity', {
|
||||
entity: t('label.login-configuration'),
|
||||
}),
|
||||
url: '',
|
||||
},
|
||||
],
|
||||
[]
|
||||
);
|
||||
|
||||
const formFields: FieldProp[] = [
|
||||
{
|
||||
name: 'maxLoginFailAttempts',
|
||||
label: t('label.max-login-fail-attampt-plural'),
|
||||
type: FieldTypes.NUMBER,
|
||||
required: false,
|
||||
id: 'root/maxLoginFailAttempts',
|
||||
props: {
|
||||
'data-testid': 'maxLoginFailAttempts',
|
||||
size: 'default',
|
||||
style: { width: '100%' },
|
||||
autoFocus: true,
|
||||
},
|
||||
rules: [{ min: 0, type: 'number' }],
|
||||
},
|
||||
{
|
||||
name: 'accessBlockTime',
|
||||
label: t('label.access-block-time'),
|
||||
type: FieldTypes.NUMBER,
|
||||
required: false,
|
||||
id: 'root/accessBlockTime',
|
||||
props: {
|
||||
'data-testid': 'accessBlockTime',
|
||||
size: 'default',
|
||||
style: { width: '100%' },
|
||||
},
|
||||
rules: [{ min: 0, type: 'number' }],
|
||||
},
|
||||
{
|
||||
name: 'jwtTokenExpiryTime',
|
||||
label: t('label.jwt-token-expiry-time'),
|
||||
type: FieldTypes.NUMBER,
|
||||
required: false,
|
||||
id: 'root/jwtTokenExpiryTime',
|
||||
props: {
|
||||
'data-testid': 'jwtTokenExpiryTime',
|
||||
size: 'default',
|
||||
style: { width: '100%' },
|
||||
},
|
||||
rules: [{ min: 0, type: 'number' }],
|
||||
},
|
||||
];
|
||||
|
||||
const handleGoBack = () => history.goBack();
|
||||
|
||||
const handleSubmit = async (configValues: LoginConfiguration) => {
|
||||
try {
|
||||
setUpdating(true);
|
||||
const configData = {
|
||||
config_type: SettingType.LoginConfiguration,
|
||||
config_value: configValues,
|
||||
};
|
||||
await updateSettingsConfig(configData as Settings);
|
||||
showSuccessToast(
|
||||
t('server.update-entity-success', {
|
||||
entity: t('label.login-configuration'),
|
||||
})
|
||||
);
|
||||
handleGoBack();
|
||||
} catch (error) {
|
||||
showErrorToast(error as AxiosError);
|
||||
} finally {
|
||||
setUpdating(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchCustomLogoConfig();
|
||||
}, []);
|
||||
|
||||
const firstPanelChildren = (
|
||||
<div className="max-width-md w-9/10 service-form-container">
|
||||
<TitleBreadcrumb titleLinks={breadcrumb} />
|
||||
<Form
|
||||
className="m-t-md"
|
||||
data-testid="custom-login-config-form"
|
||||
form={form}
|
||||
layout="vertical"
|
||||
validateMessages={VALIDATION_MESSAGES}
|
||||
onFinish={handleSubmit}
|
||||
onFocus={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setActiveField(e.target.id);
|
||||
}}>
|
||||
{generateFormFields(formFields)}
|
||||
<Row justify="end">
|
||||
<Col>
|
||||
<Button
|
||||
data-testid="cancel-button"
|
||||
type="link"
|
||||
onClick={handleGoBack}>
|
||||
{t('label.cancel')}
|
||||
</Button>
|
||||
</Col>
|
||||
<Col>
|
||||
<Button
|
||||
data-testid="save-button"
|
||||
htmlType="submit"
|
||||
loading={updating}
|
||||
type="primary">
|
||||
{t('label.save')}
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
|
||||
const secondPanelChildren = (
|
||||
<ServiceDocPanel
|
||||
activeField={activeField}
|
||||
serviceName={CUSTOM_LOGIN_CONFIG_SERVICE_CATEGORY}
|
||||
serviceType={OPEN_METADATA as ServiceCategory}
|
||||
/>
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
fetchCustomLogoConfig();
|
||||
}, []);
|
||||
|
||||
if (loading) {
|
||||
return <Loader />;
|
||||
}
|
||||
|
||||
return (
|
||||
<ResizablePanels
|
||||
firstPanel={{ children: firstPanelChildren, minWidth: 700, flex: 0.7 }}
|
||||
pageTitle={t('label.edit-entity', { entity: t('label.service') })}
|
||||
secondPanel={{
|
||||
children: secondPanelChildren,
|
||||
className: 'service-doc-panel',
|
||||
minWidth: 60,
|
||||
overlay: {
|
||||
displayThreshold: 200,
|
||||
header: t('label.setup-guide'),
|
||||
rotation: 'counter-clockwise',
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default EditLoginConfiguration;
|
||||
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright 2023 Collate.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import Icon, { InfoCircleOutlined } from '@ant-design/icons';
|
||||
import { Button, Col, Row, Tooltip, Typography } from 'antd';
|
||||
import { AxiosError } from 'axios';
|
||||
import React, { useEffect, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { ReactComponent as IconEdit } from '../../../assets/svg/edit-new.svg';
|
||||
import { useAuthContext } from '../../../components/authentication/auth-provider/AuthProvider';
|
||||
import PageHeader from '../../../components/header/PageHeader.component';
|
||||
import Loader from '../../../components/Loader/Loader';
|
||||
import {
|
||||
GRAYED_OUT_COLOR,
|
||||
NO_DATA_PLACEHOLDER,
|
||||
ROUTES,
|
||||
} from '../../../constants/constants';
|
||||
import { LoginConfiguration } from '../../../generated/configuration/loginConfiguration';
|
||||
import { AuthProvider } from '../../../generated/settings/settings';
|
||||
import { getLoginConfig } from '../../../rest/settingConfigAPI';
|
||||
import { showErrorToast } from '../../../utils/ToastUtils';
|
||||
|
||||
const LoginConfigurationPage = () => {
|
||||
const { t } = useTranslation();
|
||||
const { authConfig } = useAuthContext();
|
||||
const history = useHistory();
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [loginConfig, setLoginConfig] = useState<LoginConfiguration>();
|
||||
|
||||
const isBasicAuth = useMemo(() => {
|
||||
return (
|
||||
authConfig?.provider === AuthProvider.Basic ||
|
||||
authConfig?.provider === AuthProvider.LDAP
|
||||
);
|
||||
}, [authConfig]);
|
||||
|
||||
const fetchLoginConfig = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
|
||||
const loginConfig = await getLoginConfig();
|
||||
|
||||
setLoginConfig(loginConfig);
|
||||
} catch (error) {
|
||||
showErrorToast(error as AxiosError);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleEditClick = () => {
|
||||
history.push(ROUTES.SETTINGS_EDIT_CUSTOM_LOGIN_CONFIG);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isBasicAuth) {
|
||||
fetchLoginConfig();
|
||||
}
|
||||
}, [isBasicAuth]);
|
||||
|
||||
if (loading) {
|
||||
return <Loader />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Row gutter={[16, 16]}>
|
||||
<Col span={24}>
|
||||
<Row align="middle" justify="space-between">
|
||||
<Col>
|
||||
<PageHeader
|
||||
data={{
|
||||
header: 'Login',
|
||||
subHeader:
|
||||
'Login configuration such as failed attampts or expiry timer.',
|
||||
}}
|
||||
/>
|
||||
</Col>
|
||||
<Col>
|
||||
<Button
|
||||
data-testid="edit-button"
|
||||
icon={<Icon component={IconEdit} size={12} />}
|
||||
onClick={handleEditClick}>
|
||||
{t('label.edit')}
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Row align="middle">
|
||||
<Col span={24}>
|
||||
<Typography.Text className="m-0 text-grey-muted">
|
||||
{t('label.max-login-fail-attampt-plural')}
|
||||
<Tooltip
|
||||
placement="top"
|
||||
title={t('message.login-fail-attamp-message')}
|
||||
trigger="hover">
|
||||
<InfoCircleOutlined
|
||||
className="m-x-xss"
|
||||
data-testid="max-login-fail-attampts-url-info"
|
||||
style={{ color: GRAYED_OUT_COLOR }}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Typography.Text>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Typography.Text data-testid="max-login-fail-attampts">
|
||||
{loginConfig?.maxLoginFailAttempts ?? NO_DATA_PLACEHOLDER}
|
||||
</Typography.Text>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Row align="middle">
|
||||
<Col span={24}>
|
||||
<Typography.Text className="m-0 text-grey-muted">
|
||||
{t('label.access-block-time')}
|
||||
<Tooltip
|
||||
placement="top"
|
||||
title={t('message.access-block-time-message')}
|
||||
trigger="hover">
|
||||
<InfoCircleOutlined
|
||||
className="m-x-xss"
|
||||
data-testid="access-block-time-info"
|
||||
style={{ color: GRAYED_OUT_COLOR }}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Typography.Text>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Typography.Text data-testid="access-block-time">
|
||||
{loginConfig?.accessBlockTime ?? NO_DATA_PLACEHOLDER}
|
||||
</Typography.Text>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Row align="middle">
|
||||
<Col span={24}>
|
||||
<Typography.Text className="m-0 text-grey-muted">
|
||||
{t('label.jwt-token-expiry-time')}
|
||||
<Tooltip
|
||||
placement="top"
|
||||
title={t('message.jwt-token-expiry-time-message')}
|
||||
trigger="hover">
|
||||
<InfoCircleOutlined
|
||||
className="m-x-xss"
|
||||
data-testid="jwt-token-expiry-time-info"
|
||||
style={{ color: GRAYED_OUT_COLOR }}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Typography.Text>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Typography.Text data-testid="jwt-token-expiry-time">
|
||||
{loginConfig?.jwtTokenExpiryTime ?? NO_DATA_PLACEHOLDER}{' '}
|
||||
{t('label.ms')}
|
||||
</Typography.Text>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
};
|
||||
|
||||
export default LoginConfigurationPage;
|
||||
@ -22,10 +22,14 @@ import { ReactComponent as IconEdit } from '../../assets/svg/edit-new.svg';
|
||||
import ErrorPlaceHolder from '../../components/common/error-with-placeholder/ErrorPlaceHolder';
|
||||
import PageHeader from '../../components/header/PageHeader.component';
|
||||
import Loader from '../../components/Loader/Loader';
|
||||
import { GRAYED_OUT_COLOR, ROUTES } from '../../constants/constants';
|
||||
import {
|
||||
GRAYED_OUT_COLOR,
|
||||
NO_DATA_PLACEHOLDER,
|
||||
ROUTES,
|
||||
} from '../../constants/constants';
|
||||
import { CUSTOM_LOGO_DOCS } from '../../constants/docs.constants';
|
||||
import { ERROR_PLACEHOLDER_TYPE } from '../../enums/common.enum';
|
||||
import { LogoConfiguration } from '../../generated/configuration/applicationConfiguration';
|
||||
import { LogoConfiguration } from '../../generated/configuration/logoConfiguration';
|
||||
import { SettingType } from '../../generated/settings/settings';
|
||||
import { getSettingsConfigFromConfigType } from '../../rest/settingConfigAPI';
|
||||
import { showErrorToast } from '../../utils/ToastUtils';
|
||||
@ -33,7 +37,6 @@ import { showErrorToast } from '../../utils/ToastUtils';
|
||||
const CustomLogoConfigSettingsPage = () => {
|
||||
const { t } = useTranslation();
|
||||
const history = useHistory();
|
||||
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [config, setConfig] = useState<LogoConfiguration>();
|
||||
|
||||
@ -52,6 +55,7 @@ const CustomLogoConfigSettingsPage = () => {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleEditClick = () => {
|
||||
history.push(ROUTES.SETTINGS_EDIT_CUSTOM_LOGO_CONFIG);
|
||||
};
|
||||
@ -120,7 +124,7 @@ const CustomLogoConfigSettingsPage = () => {
|
||||
<Col span={24}>
|
||||
<Typography.Text data-testid="logo-url">
|
||||
{isEmpty(config?.customLogoUrlPath)
|
||||
? '--'
|
||||
? NO_DATA_PLACEHOLDER
|
||||
: config?.customLogoUrlPath}
|
||||
</Typography.Text>
|
||||
</Col>
|
||||
@ -146,12 +150,38 @@ const CustomLogoConfigSettingsPage = () => {
|
||||
<Col span={24}>
|
||||
<Typography.Text data-testid="monogram-url">
|
||||
{isEmpty(config?.customMonogramUrlPath)
|
||||
? '--'
|
||||
? NO_DATA_PLACEHOLDER
|
||||
: config?.customMonogramUrlPath}
|
||||
</Typography.Text>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col span={12}>
|
||||
<Row align="middle">
|
||||
<Col span={24}>
|
||||
<Typography.Text className="m-0 text-grey-muted">
|
||||
{t('label.favicon-url')}
|
||||
<Tooltip
|
||||
placement="top"
|
||||
title={t('message.custom-favicon-url-path-message')}
|
||||
trigger="hover">
|
||||
<InfoCircleOutlined
|
||||
className="m-x-xss"
|
||||
data-testid="favicon-url-info"
|
||||
style={{ color: GRAYED_OUT_COLOR }}
|
||||
/>
|
||||
</Tooltip>
|
||||
</Typography.Text>
|
||||
</Col>
|
||||
<Col span={24}>
|
||||
<Typography.Text data-testid="favicon-url">
|
||||
{isEmpty(config?.customFaviconUrlPath)
|
||||
? NO_DATA_PLACEHOLDER
|
||||
: config?.customFaviconUrlPath}
|
||||
</Typography.Text>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@ -28,7 +28,7 @@ import {
|
||||
OPEN_METADATA,
|
||||
} from '../../constants/service-guide.constant';
|
||||
import { ServiceCategory } from '../../enums/service.enum';
|
||||
import { LogoConfiguration } from '../../generated/configuration/applicationConfiguration';
|
||||
import { LogoConfiguration } from '../../generated/configuration/logoConfiguration';
|
||||
import { Settings, SettingType } from '../../generated/settings/settings';
|
||||
import { FieldProp, FieldTypes } from '../../interface/FormUtils.interface';
|
||||
import {
|
||||
@ -95,6 +95,7 @@ const EditCustomLogoConfig = () => {
|
||||
id: 'root/customLogoUrlPath',
|
||||
props: {
|
||||
'data-testid': 'customLogoUrlPath',
|
||||
autoFocus: true,
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
@ -123,6 +124,24 @@ const EditCustomLogoConfig = () => {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'customFaviconUrlPath',
|
||||
label: t('label.favicon-url'),
|
||||
type: FieldTypes.TEXT,
|
||||
required: false,
|
||||
id: 'root/customFaviconUrlPath',
|
||||
props: {
|
||||
'data-testid': 'customFaviconUrlPath',
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
type: 'url',
|
||||
message: t('message.entity-is-not-valid-url', {
|
||||
entity: t('label.favicon-url'),
|
||||
}),
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const handleGoBack = () => history.goBack();
|
||||
|
||||
@ -16,7 +16,6 @@ import { Edge } from '../components/Entity/EntityLineage/EntityLineage.interface
|
||||
import { ExploreSearchIndex } from '../components/Explore/explore.interface';
|
||||
import { WILD_CARD_CHAR } from '../constants/char.constants';
|
||||
import { SearchIndex } from '../enums/search.enum';
|
||||
import { ApplicationConfiguration } from '../generated/configuration/applicationConfiguration';
|
||||
import { AuthenticationConfiguration } from '../generated/configuration/authenticationConfiguration';
|
||||
import { AuthorizerConfiguration } from '../generated/configuration/authorizerConfiguration';
|
||||
import { PipelineServiceClientConfiguration } from '../generated/configuration/pipelineServiceClientConfiguration';
|
||||
@ -63,13 +62,6 @@ export const fetchAuthenticationConfig = async () => {
|
||||
|
||||
return response.data;
|
||||
};
|
||||
export const getApplicationConfig = async () => {
|
||||
const response = await APIClient.get<ApplicationConfiguration>(
|
||||
'/system/config/applicationConfig'
|
||||
);
|
||||
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const fetchAuthorizerConfig = async () => {
|
||||
const response = await APIClient.get<AuthorizerConfiguration>(
|
||||
|
||||
@ -13,7 +13,8 @@
|
||||
|
||||
import { AxiosResponse } from 'axios';
|
||||
import axiosClient from '.';
|
||||
import { LogoConfiguration } from '../generated/configuration/applicationConfiguration';
|
||||
import { LoginConfiguration } from '../generated/configuration/loginConfiguration';
|
||||
import { LogoConfiguration } from '../generated/configuration/logoConfiguration';
|
||||
import { Settings, SettingType } from '../generated/settings/settings';
|
||||
|
||||
export const getSettingsConfigFromConfigType = async (
|
||||
@ -39,3 +40,11 @@ export const getCustomLogoConfig = async () => {
|
||||
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const getLoginConfig = async () => {
|
||||
const response = await axiosClient.get<LoginConfiguration>(
|
||||
`system/config/loginConfig`
|
||||
);
|
||||
|
||||
return response.data;
|
||||
};
|
||||
|
||||
@ -273,6 +273,12 @@ export const getGlobalSettingsMenuWithPermission = (
|
||||
key: 'openMetadata.customLogo',
|
||||
icon: <CustomLogoIcon className="w-4 side-panel-icons" />,
|
||||
},
|
||||
{
|
||||
label: i18next.t('label.login-configuration'),
|
||||
isProtected: Boolean(isAdminUser),
|
||||
key: 'openMetadata.loginConfiguration',
|
||||
icon: <CustomLogoIcon className="w-4 side-panel-icons" />,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
@ -93,10 +93,10 @@ export const getField = (field: FieldProp) => {
|
||||
case FieldTypes.NUMBER:
|
||||
fieldElement = (
|
||||
<InputNumber
|
||||
{...props}
|
||||
id={id}
|
||||
placeholder={placeholder}
|
||||
size="small"
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user