diff --git a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.6.0.xml b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.6.0.xml
index 24902d56da..9d6e545b5a 100644
--- a/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.6.0.xml
+++ b/connections/jpa-liquibase/src/main/resources/META-INF/jpa-changelog-1.6.0.xml
@@ -8,6 +8,10 @@
+
+
+
+
diff --git a/core/src/main/java/org/keycloak/representations/idm/ClientRepresentation.java b/core/src/main/java/org/keycloak/representations/idm/ClientRepresentation.java
index 020445e406..7ad8c6e443 100755
--- a/core/src/main/java/org/keycloak/representations/idm/ClientRepresentation.java
+++ b/core/src/main/java/org/keycloak/representations/idm/ClientRepresentation.java
@@ -11,6 +11,7 @@ public class ClientRepresentation {
protected String id;
protected String clientId;
protected String name;
+ protected String rootUrl;
protected String adminUrl;
protected String baseUrl;
protected Boolean surrogateAuthRequired;
@@ -74,6 +75,14 @@ public class ClientRepresentation {
this.surrogateAuthRequired = surrogateAuthRequired;
}
+ public String getRootUrl() {
+ return rootUrl;
+ }
+
+ public void setRootUrl(String rootUrl) {
+ this.rootUrl = rootUrl;
+ }
+
public String getAdminUrl() {
return adminUrl;
}
diff --git a/docbook/reference/en/en-US/modules/server-installation.xml b/docbook/reference/en/en-US/modules/server-installation.xml
index 6b39bf664f..c702020844 100755
--- a/docbook/reference/en/en-US/modules/server-installation.xml
+++ b/docbook/reference/en/en-US/modules/server-installation.xml
@@ -843,27 +843,25 @@ All configuration options are optional. Default value for directory is Installing Keycloak Server as Root Context
- The Keycloak server can be installed as the default web application. This way, instead of referencing
- the server as http://mydomain.com/auth, it would be
- http://mydomain.com/.
+ The Keycloak server can be installed as the default web application. In doing so, the server can be referenced at http://mydomain.com/ instead of http://mydomain.com/auth.
- To do this, you need to add a default-web-module attribute in the Undertow subystem in standalone.xml.
+ To do this, add the default-web-module attribute in the Undertow subystem in standalone.xml.
+
-
+
]]>
- main-auth-server is the name of the Keycloak server as defined in the Keycloak subsystem.
+ keycloak-server.war is the runtime name of the Keycloak server application. Note that the WAR file does not exist as a file. If its name changes (ie. keycloak-server.war) in the future, find its new name from the Keycloak log entry with runtime-name:.
- If you have already run your server before changing to the root context then your database
- will contain references to the old /auth context. And, your clients may also have incorrect
+ If you have run your server before altering the root context, your database
+ will contain references to the old /auth context. Your clients may also have incorrect
references. To fix this on the server side, you will need to export
your database to json, make corrections, and then import. Client-side keycloak.json
files will need to be updated manually as well.
diff --git a/docbook/reference/en/en-US/modules/themes.xml b/docbook/reference/en/en-US/modules/themes.xml
index cd59f382ad..10b2417a46 100755
--- a/docbook/reference/en/en-US/modules/themes.xml
+++ b/docbook/reference/en/en-US/modules/themes.xml
@@ -181,6 +181,12 @@ import=common/keycloak
messages/messages.properties inside your theme folder and add the following content:
username=Your Username
+
+ For the admin console, there is a second resource bundle named admin-messages.properties.
+ This resource bundle is converted to JSON and shipped to the console to be processed by
+ angular-translate. It is found in the same directory as messages.properties and can be overridden
+ in the same way as described above.
+ Modifying HTML
diff --git a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java
index 35081ce7b9..a4b3771761 100755
--- a/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java
+++ b/forms/account-freemarker/src/main/java/org/keycloak/account/freemarker/FreeMarkerAccountProvider.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * 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.
+ */
package org.keycloak.account.freemarker;
import java.io.IOException;
@@ -197,7 +213,10 @@ public class FreeMarkerAccountProvider implements AccountProvider {
String result = freeMarker.processTemplate(attributes, Templates.getTemplate(page), theme);
Response.ResponseBuilder builder = Response.status(status).type(MediaType.TEXT_HTML).entity(result);
BrowserSecurityHeaderSetup.headers(builder, realm);
- LocaleHelper.updateLocaleCookie(builder, locale, realm, uriInfo, Urls.localeCookiePath(baseUri,realm.getName()));
+
+ String keycloakLocaleCookiePath = Urls.localeCookiePath(baseUri, realm.getName());
+
+ LocaleHelper.updateLocaleCookie(builder, locale, realm, uriInfo, keycloakLocaleCookiePath);
return builder.build();
} catch (FreeMarkerException e) {
logger.error("Failed to process template", e);
@@ -209,7 +228,7 @@ public class FreeMarkerAccountProvider implements AccountProvider {
this.passwordSet = passwordSet;
return this;
}
-
+
protected void setMessage(MessageType type, String message, Object... parameters) {
messageType = type;
messages = new ArrayList<>();
@@ -225,7 +244,7 @@ public class FreeMarkerAccountProvider implements AccountProvider {
return message.getMessage();
}
}
-
+
@Override
public AccountProvider setErrors(List messages) {
this.messageType = MessageType.ERROR;
diff --git a/forms/common-freemarker/src/main/java/org/keycloak/freemarker/ExtendingThemeManager.java b/forms/common-freemarker/src/main/java/org/keycloak/freemarker/ExtendingThemeManager.java
index 0e98f1147f..020d349150 100644
--- a/forms/common-freemarker/src/main/java/org/keycloak/freemarker/ExtendingThemeManager.java
+++ b/forms/common-freemarker/src/main/java/org/keycloak/freemarker/ExtendingThemeManager.java
@@ -224,10 +224,15 @@ public class ExtendingThemeManager implements ThemeProvider {
@Override
public Properties getMessages(Locale locale) throws IOException {
+ return getMessages("messages", locale);
+ }
+
+ @Override
+ public Properties getMessages(String baseBundlename, Locale locale) throws IOException {
Properties messages = new Properties();
ListIterator itr = themes.listIterator(themes.size());
while (itr.hasPrevious()) {
- Properties m = itr.previous().getMessages(locale);
+ Properties m = itr.previous().getMessages(baseBundlename, locale);
if (m != null) {
messages.putAll(m);
}
diff --git a/forms/common-freemarker/src/main/java/org/keycloak/freemarker/LocaleHelper.java b/forms/common-freemarker/src/main/java/org/keycloak/freemarker/LocaleHelper.java
index 9f1aafe4e4..14f7f6c6aa 100644
--- a/forms/common-freemarker/src/main/java/org/keycloak/freemarker/LocaleHelper.java
+++ b/forms/common-freemarker/src/main/java/org/keycloak/freemarker/LocaleHelper.java
@@ -1,6 +1,21 @@
+/*
+ * Copyright 2015 Red Hat Inc. and/or its affiliates and other contributors
+ * as indicated by the @author tags. All rights reserved.
+ *
+ * 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.
+ */
package org.keycloak.freemarker;
-import org.jboss.logging.Logger;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserModel;
@@ -38,7 +53,7 @@ public class LocaleHelper {
return locale;
}
}
-
+
//1. Locale cookie
if(httpHeaders != null && httpHeaders.getCookies().containsKey(LOCALE_COOKIE)){
String localeString = httpHeaders.getCookies().get(LOCALE_COOKIE).getValue();
@@ -89,7 +104,11 @@ public class LocaleHelper {
return Locale.ENGLISH;
}
- public static void updateLocaleCookie(Response.ResponseBuilder builder, Locale locale, RealmModel realm, UriInfo uriInfo, String path) {
+ public static void updateLocaleCookie(Response.ResponseBuilder builder,
+ Locale locale,
+ RealmModel realm,
+ UriInfo uriInfo,
+ String path) {
if (locale == null) {
return;
}
diff --git a/forms/common-freemarker/src/main/java/org/keycloak/freemarker/Theme.java b/forms/common-freemarker/src/main/java/org/keycloak/freemarker/Theme.java
index 6a12a49f00..43107ce723 100644
--- a/forms/common-freemarker/src/main/java/org/keycloak/freemarker/Theme.java
+++ b/forms/common-freemarker/src/main/java/org/keycloak/freemarker/Theme.java
@@ -29,8 +29,27 @@ public interface Theme {
public InputStream getResourceAsStream(String path) throws IOException;
+ /**
+ * Same as getMessages(baseBundlename, locale), but uses a default baseBundlename
+ * such as "messages".
+ *
+ * @param locale The locale of the desired message bundle.
+ * @return The localized messages from the bundle.
+ * @throws IOException If bundle can not be read.
+ */
public Properties getMessages(Locale locale) throws IOException;
+ /**
+ * Retrieve localized messages from a message bundle.
+ *
+ * @param baseBundlename The base name of the bundle, such as "messages" in
+ * messages_en.properties.
+ * @param locale The locale of the desired message bundle.
+ * @return The localized messages from the bundle.
+ * @throws IOException If bundle can not be read.
+ */
+ public Properties getMessages(String baseBundlename, Locale locale) throws IOException;
+
public Properties getProperties() throws IOException;
}
diff --git a/forms/common-themes/src/main/java/org/keycloak/theme/ClassLoaderTheme.java b/forms/common-themes/src/main/java/org/keycloak/theme/ClassLoaderTheme.java
index 3e92be880b..68ac7caca1 100755
--- a/forms/common-themes/src/main/java/org/keycloak/theme/ClassLoaderTheme.java
+++ b/forms/common-themes/src/main/java/org/keycloak/theme/ClassLoaderTheme.java
@@ -100,12 +100,17 @@ public class ClassLoaderTheme implements Theme {
@Override
public Properties getMessages(Locale locale) throws IOException {
+ return getMessages("messages", locale);
+ }
+
+ @Override
+ public Properties getMessages(String baseBundlename, Locale locale) throws IOException {
if(locale == null){
return null;
}
Properties m = new Properties();
- URL url = classLoader.getResource(this.messageRoot + "messages_" + locale.toString() + ".properties");
+ URL url = classLoader.getResource(this.messageRoot + baseBundlename + "_" + locale.toString() + ".properties");
if (url != null) {
m.load(url.openStream());
}
diff --git a/forms/common-themes/src/main/java/org/keycloak/theme/FolderTheme.java b/forms/common-themes/src/main/java/org/keycloak/theme/FolderTheme.java
index d1593fe99d..77a65a8e59 100644
--- a/forms/common-themes/src/main/java/org/keycloak/theme/FolderTheme.java
+++ b/forms/common-themes/src/main/java/org/keycloak/theme/FolderTheme.java
@@ -93,13 +93,18 @@ public class FolderTheme implements Theme {
@Override
public Properties getMessages(Locale locale) throws IOException {
+ return getMessages("messages", locale);
+ }
+
+ @Override
+ public Properties getMessages(String baseBundlename, Locale locale) throws IOException {
if(locale == null){
return null;
}
Properties m = new Properties();
- File file = new File(themeDir, "messages" + File.separator + "messages_" + locale.toString() + ".properties");
+ File file = new File(themeDir, "messages" + File.separator + baseBundlename + "_" + locale.toString() + ".properties");
if (file.isFile()) {
m.load(new FileInputStream(file));
}
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/index.ftl b/forms/common-themes/src/main/resources/theme/base/admin/index.ftl
index 1a87bce79d..1584d0d93a 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/index.ftl
+++ b/forms/common-themes/src/main/resources/theme/base/admin/index.ftl
@@ -21,6 +21,10 @@
+
+
+
+
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_de.properties b/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_de.properties
new file mode 100644
index 0000000000..6442e6e05a
--- /dev/null
+++ b/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_de.properties
@@ -0,0 +1,116 @@
+# Common messages
+enabled=de Enabled
+name=de Name
+save=de Save
+cancel=de Cancel
+onText=AN
+offText=AUS
+client=de Client
+clear=de Clear
+
+# Realm settings
+realm-detail.enabled.tooltip=de Users and clients can only access a realm if it's enabled
+registrationAllowed=de User registration
+registrationAllowed.tooltip=de Enable/disable the registration page. A link for registration will show on login page too.
+registrationEmailAsUsername=de Email as username
+registrationEmailAsUsername.tooltip=de If enabled then username field is hidden from registration form and email is used as username for new user.
+editUsernameAllowed=de Edit username
+editUsernameAllowed.tooltip=de If enabled, the username field is editable, readonly otherwise.
+resetPasswordAllowed=de Forget password
+resetPasswordAllowed.tooltip=de Show a link on login page for user to click on when they have forgotten their credentials.
+rememberMe=de Remember Me
+rememberMe.tooltip=de Show checkbox on login page to allow user to remain logged in between browser restarts until session expires.
+verifyEmail=de Verify email
+verifyEmail.tooltip=de Require the user to verify their email address the first time they login.
+sslRequired=de Require SSL
+sslRequired.option.all=de all requests
+sslRequired.option.external=de external requests
+sslRequired.option.none=de none
+sslRequired.tooltip=de Is HTTPS required? 'None' means HTTPS is not required for any client IP address. 'External requests' means localhost and private IP addresses can access without HTTPS. 'All requests' means HTTPS is required for all IP addresses.
+publicKey=de Public key
+gen-new-keys=de Generate new keys
+certificate=de Certificate
+host=de Host
+smtp-host=de SMTP Host
+port=de Port
+smtp-port=de SMTP Port (defaults to 25)
+from=de From
+sender-email-addr=de Sender Email Address
+enable-ssl=de Enable SSL
+enable-start-tls=de Enable StartTLS
+enable-auth=de Enable Authentication
+username=de Username
+login-username=de Login Username
+password=de Password
+login-password=de Login Password
+login-theme=de Login Theme
+select-one=de Select one...
+login-theme.tooltip=de Select theme for login, TOTP, grant, registration, and forgot password pages.
+account-theme=de Account Theme
+account-theme.tooltip=de Select theme for user account management pages.
+admin-console-theme=de Admin Console Theme
+select-theme-admin-console=de Select theme for admin console.
+email-theme=de Email Theme
+select-theme-email=de Select theme for emails that are sent by the server.
+i18n-enabled=de Internationalization Enabled
+supported-locales=de Supported Locales
+supported-locales.placeholder=de Type a locale and enter
+default-locale=de Default Locale
+realm-cache-enabled=de Realm Cache Enabled
+realm-cache-enabled.tooltip=de Enable/disable cache for realm, client and role data.
+user-cache-enabled=de User Cache Enabled
+user-cache-enabled.tooltip=de Enable/disable user and user role mapping cache.
+sso-session-idle=de SSO Session Idle
+seconds=de Seconds
+minutes=de Minutes
+hours=de Hours
+days=de Days
+sso-session-max=de SSO Session Max
+sso-session-idle.tooltip=de Time a session is allowed to be idle before it expires. Tokens and browser sessions are invalidated when a session is expired.
+sso-session-max.tooltip=de Max time before a session is expired. Tokens and browser sessions are invalidated when a session is expired.
+access-token-lifespan=de Access Token Lifespan
+access-token-lifespan.tooltip=de Max time before an access token is expired. This value is recommended to be short relative to the SSO timeout.
+client-login-timeout=de Client login timeout
+client-login-timeout.tooltip=de Max time an client has to finish the access token protocol. This should normally be 1 minute.
+login-timeout=de Login timeout
+login-timeout.tooltip=de Max time a user has to complete a login. This is recommended to be relatively long. 30 minutes or more.
+login-action-timeout=de Login action timeout
+login-action-timeout.tooltip=de Max time a user has to complete login related actions like update password or configure totp. This is recommended to be relatively long. 5 minutes or more.
+headers=de Headers
+brute-force-detection=de Brute Force Detection
+x-frame-options=de X-Frame-Options
+click-label-for-info=de Click on label link for more information. The default value prevents pages from being included via non-origin iframes.
+content-sec-policy=de Content-Security-Policy
+max-login-failures=de Max Login Failures
+max-login-failures.tooltip=de How many failures before wait is triggered.
+wait-increment=de Wait Increment
+wait-increment.tooltip=de When failure threshold has been met, how much time should the user be locked out?
+quick-login-check-millis=de Quick Login Check Milli Seconds
+quick-login-check-millis.tooltip=de If a failure happens concurrently too quickly, lock out the user.
+min-quick-login-wait=de Minimum Quick Login Wait
+min-quick-login-wait.tooltip=de How long to wait after a quick login failure.
+max-wait=de Max Wait
+max-wait.tooltip=de Max time a user will be locked out.
+failure-reset-time=de Failure Reset Time
+failure-reset-time.tooltip=de When will failure count be reset?
+realm-tab-login=de Login
+realm-tab-keys=de Keys
+realm-tab-email=de Email
+realm-tab-themes=de Themes
+realm-tab-cache=de Cache
+realm-tab-tokens=de Tokens
+realm-tab-security-defenses=de Security Defenses
+realm-tab-general=de General
+add-realm=de Add Realm
+
+#Session settings
+realm-sessions=de Realm Sessions
+revocation=de Revocation
+logout-all=de Logout All
+active-sessions=de Active Sessions
+sessions=de Sessions
+not-before=de Not Before
+not-before.tooltip=de Revoke any tokens issued before this date.
+set-to-now=de Set To Now
+push=de Push
+push.tooltip=de For every client that has an admin URL, notify them of the new revocation policy.
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties b/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
new file mode 100644
index 0000000000..be3ef2de22
--- /dev/null
+++ b/forms/common-themes/src/main/resources/theme/base/admin/messages/admin-messages_en.properties
@@ -0,0 +1,116 @@
+# Common messages
+enabled=Enabled
+name=Name
+save=Save
+cancel=Cancel
+onText=ON
+offText=OFF
+client=Client
+clear=Clear
+
+# Realm settings
+realm-detail.enabled.tooltip=Users and clients can only access a realm if it's enabled
+registrationAllowed=User registration
+registrationAllowed.tooltip=Enable/disable the registration page. A link for registration will show on login page too.
+registrationEmailAsUsername=Email as username
+registrationEmailAsUsername.tooltip=If enabled then username field is hidden from registration form and email is used as username for new user.
+editUsernameAllowed=Edit username
+editUsernameAllowed.tooltip=If enabled, the username field is editable, readonly otherwise.
+resetPasswordAllowed=Forget password
+resetPasswordAllowed.tooltip=Show a link on login page for user to click on when they have forgotten their credentials.
+rememberMe=Remember Me
+rememberMe.tooltip=Show checkbox on login page to allow user to remain logged in between browser restarts until session expires.
+verifyEmail=Verify email
+verifyEmail.tooltip=Require the user to verify their email address the first time they login.
+sslRequired=Require SSL
+sslRequired.option.all=all requests
+sslRequired.option.external=external requests
+sslRequired.option.none=none
+sslRequired.tooltip=Is HTTPS required? 'None' means HTTPS is not required for any client IP address. 'External requests' means localhost and private IP addresses can access without HTTPS. 'All requests' means HTTPS is required for all IP addresses.
+publicKey=Public key
+gen-new-keys=Generate new keys
+certificate=Certificate
+host=Host
+smtp-host=SMTP Host
+port=Port
+smtp-port=SMTP Port (defaults to 25)
+from=From
+sender-email-addr=Sender Email Address
+enable-ssl=Enable SSL
+enable-start-tls=Enable StartTLS
+enable-auth=Enable Authentication
+username=Username
+login-username=Login Username
+password=Password
+login-password=Login Password
+login-theme=Login Theme
+select-one=Select one...
+login-theme.tooltip=Select theme for login, TOTP, grant, registration, and forgot password pages.
+account-theme=Account Theme
+account-theme.tooltip=Select theme for user account management pages.
+admin-console-theme=Admin Console Theme
+select-theme-admin-console=Select theme for admin console.
+email-theme=Email Theme
+select-theme-email=Select theme for emails that are sent by the server.
+i18n-enabled=Internationalization Enabled
+supported-locales=Supported Locales
+supported-locales.placeholder=Type a locale and enter
+default-locale=Default Locale
+realm-cache-enabled=Realm Cache Enabled
+realm-cache-enabled.tooltip=Enable/disable cache for realm, client and role data.
+user-cache-enabled=User Cache Enabled
+user-cache-enabled.tooltip=Enable/disable user and user role mapping cache.
+sso-session-idle=SSO Session Idle
+seconds=Seconds
+minutes=Minutes
+hours=Hours
+days=Days
+sso-session-max=SSO Session Max
+sso-session-idle.tooltip=Time a session is allowed to be idle before it expires. Tokens and browser sessions are invalidated when a session is expired.
+sso-session-max.tooltip=Max time before a session is expired. Tokens and browser sessions are invalidated when a session is expired.
+access-token-lifespan=Access Token Lifespan
+access-token-lifespan.tooltip=Max time before an access token is expired. This value is recommended to be short relative to the SSO timeout.
+client-login-timeout=Client login timeout
+client-login-timeout.tooltip=Max time an client has to finish the access token protocol. This should normally be 1 minute.
+login-timeout=Login timeout
+login-timeout.tooltip=Max time a user has to complete a login. This is recommended to be relatively long. 30 minutes or more.
+login-action-timeout=Login action timeout
+login-action-timeout.tooltip=Max time a user has to complete login related actions like update password or configure totp. This is recommended to be relatively long. 5 minutes or more.
+headers=Headers
+brute-force-detection=Brute Force Detection
+x-frame-options=X-Frame-Options
+click-label-for-info=Click on label link for more information. The default value prevents pages from being included via non-origin iframes.
+content-sec-policy=Content-Security-Policy
+max-login-failures=Max Login Failures
+max-login-failures.tooltip=How many failures before wait is triggered.
+wait-increment=Wait Increment
+wait-increment.tooltip=When failure threshold has been met, how much time should the user be locked out?
+quick-login-check-millis=Quick Login Check Milli Seconds
+quick-login-check-millis.tooltip=If a failure happens concurrently too quickly, lock out the user.
+min-quick-login-wait=Minimum Quick Login Wait
+min-quick-login-wait.tooltip=How long to wait after a quick login failure.
+max-wait=Max Wait
+max-wait.tooltip=Max time a user will be locked out.
+failure-reset-time=Failure Reset Time
+failure-reset-time.tooltip=When will failure count be reset?
+realm-tab-login=Login
+realm-tab-keys=Keys
+realm-tab-email=Email
+realm-tab-themes=Themes
+realm-tab-cache=Cache
+realm-tab-tokens=Tokens
+realm-tab-security-defenses=Security Defenses
+realm-tab-general=General
+add-realm=Add Realm
+
+#Session settings
+realm-sessions=Realm Sessions
+revocation=Revocation
+logout-all=Logout All
+active-sessions=Active Sessions
+sessions=Sessions
+not-before=Not Before
+not-before.tooltip=Revoke any tokens issued before this date.
+set-to-now=Set To Now
+push=Push
+push.tooltip=For every client that has an admin URL, notify them of the new revocation policy.
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js
index 756c89e2ac..350f0d0315 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/app.js
@@ -7,7 +7,7 @@ var configUrl = consoleBaseUrl + "/config";
var auth = {};
-var module = angular.module('keycloak', [ 'keycloak.services', 'keycloak.loaders', 'ui.bootstrap', 'ui.select2', 'angularFileUpload' ]);
+var module = angular.module('keycloak', [ 'keycloak.services', 'keycloak.loaders', 'ui.bootstrap', 'ui.select2', 'angularFileUpload', 'pascalprecht.translate', 'ngCookies', 'ngSanitize']);
var resourceRequests = 0;
var loadingTimer = -1;
@@ -52,8 +52,18 @@ module.factory('authInterceptor', function($q, Auth) {
};
});
-
-
+module.config(['$translateProvider', function($translateProvider) {
+ $translateProvider.useSanitizeValueStrategy('sanitizeParameters');
+
+ var locale = auth.authz.idTokenParsed.locale;
+ if (locale !== undefined) {
+ $translateProvider.preferredLanguage(locale);
+ } else {
+ $translateProvider.preferredLanguage('en');
+ }
+
+ $translateProvider.useUrlLoader('messages.json');
+}]);
module.config([ '$routeProvider', function($routeProvider) {
$routeProvider
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js
index ae334e73c6..3cb3e6029f 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/controllers/clients.js
@@ -564,8 +564,6 @@ module.controller('ClientRoleDetailCtrl', function($scope, realm, client, role,
module.controller('ClientImportCtrl', function($scope, $location, $upload, realm, serverInfo, Notifications) {
$scope.realm = realm;
- $scope.configFormats = serverInfo.clientImporters;
- $scope.configFormat = null;
$scope.files = [];
@@ -614,7 +612,6 @@ module.controller('ClientImportCtrl', function($scope, $location, $upload, realm
module.controller('ClientListCtrl', function($scope, realm, clients, Client, serverInfo, $route, Dialog, Notifications) {
$scope.realm = realm;
$scope.clients = clients;
- $scope.importButton = serverInfo.clientImporters.length > 0;
$scope.removeClient = function(client) {
Dialog.confirmDelete(client.clientId, 'client', function() {
@@ -670,7 +667,7 @@ module.controller('ClientInstallationCtrl', function($scope, realm, client, Clie
}
});
-module.controller('ClientDetailCtrl', function($scope, realm, client, $route, serverInfo, Client, $location, Dialog, Notifications) {
+module.controller('ClientDetailCtrl', function($scope, realm, client, $route, serverInfo, Client, ClientDescriptionConverter, $location, $modal, Dialog, Notifications) {
$scope.accessTypes = [
"confidential",
"public",
@@ -709,40 +706,45 @@ module.controller('ClientDetailCtrl', function($scope, realm, client, $route, se
$scope.samlEncrypt = false;
$scope.samlForcePostBinding = false;
$scope.samlForceNameIdFormat = false;
- if (!$scope.create) {
- if (!client.attributes) {
- client.attributes = {};
+
+ function updateProperties() {
+ if (!$scope.client.attributes) {
+ $scope.client.attributes = {};
}
- $scope.client= angular.copy(client);
$scope.accessType = $scope.accessTypes[0];
- if (client.bearerOnly) {
+ if ($scope.client.bearerOnly) {
$scope.accessType = $scope.accessTypes[2];
- } else if (client.publicClient) {
+ } else if ($scope.client.publicClient) {
$scope.accessType = $scope.accessTypes[1];
}
- if (client.protocol) {
- $scope.protocol = $scope.protocols[$scope.protocols.indexOf(client.protocol)];
+ if ($scope.client.protocol) {
+ $scope.protocol = $scope.protocols[$scope.protocols.indexOf($scope.client.protocol)];
} else {
$scope.protocol = $scope.protocols[0];
}
- if (client.attributes['saml.signature.algorithm'] == 'RSA_SHA1') {
+ if ($scope.client.attributes['saml.signature.algorithm'] == 'RSA_SHA1') {
$scope.signatureAlgorithm = $scope.signatureAlgorithms[0];
- } else if (client.attributes['saml.signature.algorithm'] == 'RSA_SHA256') {
+ } else if ($scope.client.attributes['saml.signature.algorithm'] == 'RSA_SHA256') {
$scope.signatureAlgorithm = $scope.signatureAlgorithms[1];
- } else if (client.attributes['saml.signature.algorithm'] == 'RSA_SHA512') {
+ } else if ($scope.client.attributes['saml.signature.algorithm'] == 'RSA_SHA512') {
$scope.signatureAlgorithm = $scope.signatureAlgorithms[2];
- } else if (client.attributes['saml.signature.algorithm'] == 'DSA_SHA1') {
+ } else if ($scope.client.attributes['saml.signature.algorithm'] == 'DSA_SHA1') {
$scope.signatureAlgorithm = $scope.signatureAlgorithms[3];
}
- if (client.attributes['saml_name_id_format'] == 'unspecified') {
+ if ($scope.client.attributes['saml_name_id_format'] == 'unspecified') {
$scope.nameIdFormat = $scope.nameIdFormats[0];
- } else if (client.attributes['saml_name_id_format'] == 'email') {
+ } else if ($scope.client.attributes['saml_name_id_format'] == 'email') {
$scope.nameIdFormat = $scope.nameIdFormats[1];
- } else if (client.attributes['saml_name_id_format'] == 'transient') {
+ } else if ($scope.client.attributes['saml_name_id_format'] == 'transient') {
$scope.nameIdFormat = $scope.nameIdFormats[2];
- } else if (client.attributes['saml_name_id_format'] == 'persistent') {
+ } else if ($scope.client.attributes['saml_name_id_format'] == 'persistent') {
$scope.nameIdFormat = $scope.nameIdFormats[3];
}
+ }
+
+ if (!$scope.create) {
+ $scope.client = angular.copy(client);
+ updateProperties();
} else {
$scope.client = { enabled: true, attributes: {}};
$scope.client.attributes['saml_signature_canonicalization_method'] = $scope.canonicalization[0].value;
@@ -813,6 +815,29 @@ module.controller('ClientDetailCtrl', function($scope, realm, client, $route, se
}
}
+ $scope.importFile = function(fileContent){
+ console.debug(fileContent);
+ ClientDescriptionConverter.save({
+ realm: realm.realm
+ }, fileContent, function (data) {
+ $scope.client = data;
+ updateProperties();
+ $scope.importing = true;
+ });
+ };
+
+ $scope.viewImportDetails = function() {
+ $modal.open({
+ templateUrl: resourceUrl + '/partials/modal/view-object.html',
+ controller: 'JsonModalCtrl',
+ resolve: {
+ object: function () {
+ return $scope.client;
+ }
+ }
+ })
+ };
+
$scope.switchChange = function() {
$scope.changed = true;
}
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js
index d1abe26cd6..8d56c90750 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/js/services.js
@@ -927,6 +927,13 @@ module.factory('Client', function($resource) {
});
});
+module.factory('ClientDescriptionConverter', function($resource) {
+ return $resource(authUrl + '/admin/realms/:realm/client-description-converter', {
+ realm : '@realm'
+ });
+});
+
+
module.factory('ClientInstallation', function($resource) {
var url = authUrl + '/admin/realms/:realm/clients/:client/installation/json';
return {
diff --git a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/brute-force.html b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/brute-force.html
index e26e126c70..33845c0b40 100755
--- a/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/brute-force.html
+++ b/forms/common-themes/src/main/resources/theme/base/admin/resources/partials/brute-force.html
@@ -2,102 +2,102 @@