KEYCLOAK-7123: l10n dropdowns (#5170)

* KEYCLOAK-7196: Add kc_locale to keycloak.js

* KEYCLOAK-7123: Localization dropdowns

* Update keycloak-service to latest keycloak.js
This commit is contained in:
Stan Silvert 2018-04-25 15:04:12 -04:00 committed by GitHub
parent fe2ae6ec68
commit 35154db50f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 577 additions and 534 deletions

View file

@ -89,9 +89,7 @@ public class AccountConsole {
map.put("authUrl", session.getContext().getContextPath());
map.put("baseUrl", session.getContext().getContextPath() + "/realms/" + realm.getName() + "/account");
map.put("realm", realm.getName());
map.put("isRegistrationEmailAsUsername", realm.isRegistrationEmailAsUsername());
map.put("isEditUserNameAllowed", realm.isEditUsernameAllowed());
map.put("realm", realm);
map.put("resourceUrl", Urls.themeRoot(baseUri).getPath() + "/account/" + theme.getName());
map.put("resourceVersion", Version.RESOURCES_VERSION);
@ -108,7 +106,7 @@ public class AccountConsole {
Properties messages = theme.getMessages(locale);
map.put("msg", new MessageFormatterMethod(locale, messages));
map.put("msgJSON", messagesToJsonString(messages));
map.put("supportedLocales", supportedLocales(messages));
map.put("properties", theme.getProperties());
FreeMarkerUtil freeMarkerUtil = new FreeMarkerUtil();
@ -119,6 +117,15 @@ public class AccountConsole {
}
}
private Map<String, String> supportedLocales(Properties messages) throws IOException {
Map<String, String> supportedLocales = new HashMap<>();
for (String l : realm.getSupportedLocales()) {
String label = messages.getProperty("locale_" + l, l);
supportedLocales.put(l, label);
}
return supportedLocales;
}
private String messagesToJsonString(Properties props) {
if (props == null) return "";

View file

@ -4,6 +4,7 @@ doLogOutAllSessions=Log out all sessions
doRemove=Remove
doAdd=Add
doSignOut=Sign Out
doLogIn=Log In
editAccountHtmlTitle=Edit Account
personalInfoHtmlTitle=Personal Info
@ -210,18 +211,18 @@ permissionRequestion=Permission Requestion
permission=Permission
shares=share(s)
locale_ca=Catal\u00E0
locale_ca=Catal\u00e0
locale_de=Deutsch
locale_en=English
locale_es=Espa\u00F1ol
locale_es=Espa\u00f1ol
locale_fr=Fran\u00e7ais
locale_it=Italian
locale_ja=\u65E5\u672C\u8A9E
locale_ja=\u65e5\u672c\u8a9e
locale_nl=Nederlands
locale_no=Norsk
locale_lt=Lietuvi\u0173
locale_pt-BR=Portugu\u00EAs (Brasil)
locale_ru=\u0420\u0443\u0441\u0441\u043A\u0438\u0439
locale_sk=Sloven\u010Dina
locale_pt-BR=Portugu\u00eas (Brasil)
locale_ru=\u0420\u0443\u0441\u0441\u043a\u0438\u0439
locale_sk=Sloven\u010dina
locale_sv=Svenska
locale_zh-CN=\u4e2d\u6587\u7b80\u4f53

View file

@ -6,10 +6,16 @@
<script>
var authUrl = '${authUrl}';
var baseUrl = '${baseUrl}';
var realm = '${realm}';
var realm = '${realm.name}';
var resourceUrl = '${resourceUrl}';
var isRegistrationEmailAsUsername = ${isRegistrationEmailAsUsername?c};
var isEditUserNameAllowed = ${isEditUserNameAllowed?c};
var isRegistrationEmailAsUsername = ${realm.registrationEmailAsUsername?c};
var isEditUserNameAllowed = ${realm.editUsernameAllowed?c};
var isInternationalizationEnabled = ${realm.internationalizationEnabled?c};
var availableLocales = [];
<#list supportedLocales as locale, label>
availableLocales.push({locale : '${locale}', label : '${label}'});
</#list>
<#if referrer??>
var referrer = '${referrer}';
@ -67,7 +73,7 @@
<script src="${authUrl}/js/keycloak.js"></script>
<script>
var keycloak = Keycloak('${authUrl}/realms/${realm}/account/keycloak.json');
var keycloak = Keycloak('${authUrl}/realms/${realm.name}/account/keycloak.json');
keycloak.init({onLoad: 'check-sso'}).success(function(authenticated) {
var loadjs = function (url,loadListener) {
const script = document.createElement("script");
@ -128,27 +134,15 @@
we are unable to localize the button's message. Not sure what to do about that yet.
-->
<ul class="nav navbar-nav navbar-right navbar-iconic">
<li><button id="signInButton" style="visibility:hidden" onclick="keycloak.login();" class="btn btn-primary btn-lg btn-sign" type="button">Log In</button></li>
<li><button id="signInButton" style="visibility:hidden" onclick="keycloak.login();" class="btn btn-primary btn-lg btn-sign" type="button">${msg("doLogIn")}</button></li>
<li class="dropdown">
<a href="#0" class="dropdown-toggle nav-item-iconic" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
${msg("locale_en")} <span class="caret"></span>
${msg("locale_" + locale)} <span class="caret"></span>
</a>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
<li><a href="#">${msg("locale_ca")}</a></li>
<li><a href="#">${msg("locale_de")}</a></li>
<li><a href="#">${msg("locale_en")}</a></li>
<li><a href="#">${msg("locale_es")}</a></li>
<li><a href="#">${msg("locale_fr")}</a></li>
<li><a href="#">${msg("locale_it")}</a></li>
<li><a href="#">${msg("locale_ja")}</a></li>
<li><a href="#">${msg("locale_nl")}</a></li>
<li><a href="#">${msg("locale_no")}</a></li>
<li><a href="#">${msg("locale_lt")}</a></li>
<li><a href="#">${msg("locale_pt-BR")}</a></li>
<li><a href="#">${msg("locale_ru")}</a></li>
<li><a href="#">${msg("locale_sk")}</a></li>
<li><a href="#">${msg("locale_sv")}</a></li>
<li><a href="#">${msg("locale_zh-CN")}</a></li>
<#list supportedLocales as locale, label>
<li><a href="${baseUrl}/?kc_locale=${locale}">${label}</a></li>
</#list>
</ul>
</li>
</ul>

View file

@ -1,7 +1,7 @@
/*
* MIT License
*
* Copyright 2017 Andy Hanson
* Copyright 2017 Brett Epps <https://github.com/eppsilon>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction, including
@ -29,7 +29,7 @@ export = Keycloak;
declare function Keycloak(config?: string|{}): Keycloak.KeycloakInstance;
declare namespace Keycloak {
type KeycloakAdapterName = 'cordova'|'default';
type KeycloakAdapterName = 'cordova'|'default' | any;
type KeycloakOnLoad = 'login-required'|'check-sso';
type KeycloakResponseMode = 'query'|'fragment';
type KeycloakResponseType = 'code'|'id_token token'|'code id_token token';
@ -39,6 +39,15 @@ declare namespace Keycloak {
/**
* @private Undocumented.
*/
useNonce?: boolean;
/**
* Allows to use different adapter:
*
* - {string} default - using browser api for redirects
* - {string} cordova - using cordova plugins
* - {function} - allows to provide custom function as adapter.
*/
adapter?: KeycloakAdapterName;
/**
@ -78,7 +87,7 @@ declare namespace Keycloak {
* Set the interval to check login state (in seconds).
* @default 5
*/
checkLoginIframeInterval?: boolean;
checkLoginIframeInterval?: number;
/**
* Set the OpenID Connect response mode to send to Keycloak upon login.
@ -141,9 +150,17 @@ declare namespace Keycloak {
idpHint?: string;
/**
* Specifies the desired locale for the UI.
* Sets the 'ui_locales' query param in compliance with section 3.1.2.1
* of the OIDC 1.0 specification.
*/
locale?: string;
/**
* Specifies the desired Keycloak locale for the UI. This differs from
* the locale param in that it tells the Keycloak server to set a cookie and update
* the user's profile to a new preferred locale.
*/
kcLocale?: string;
}
type KeycloakPromiseCallback<T> = (result: T) => void;

View file

@ -51,6 +51,8 @@
adapter = loadAdapter('cordova');
} else if (initOptions && initOptions.adapter === 'default') {
adapter = loadAdapter();
} else if (initOptions && typeof initOptions.adapter === "object") {
adapter = initOptions.adapter;
} else {
if (window.Cordova || window.cordova) {
adapter = loadAdapter('cordova');
@ -281,6 +283,10 @@
url += '&ui_locales=' + encodeURIComponent(options.locale);
}
if (options && options.kcLocale) {
url += '&kc_locale=' + encodeURIComponent(options.kcLocale);
}
return url;
}
@ -464,6 +470,10 @@
} else {
console.warn('[KEYCLOAK] Failed to refresh token');
if (req.status == 400) {
kc.clearToken();
}
kc.onAuthRefreshError && kc.onAuthRefreshError();
for (var p = refreshQueue.pop(); p != null; p = refreshQueue.pop()) {
p.setError(true);

View file

@ -28,6 +28,12 @@
</a>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu2">
<li><a href="#" (click)="logout()">{{'doSignOut' | translate}}</a></li>
<li class="dropdown-submenu pull-left">
<a class="test" tabindex="-1" href="#">Change language</a>
<ul class="dropdown-menu">
<li *ngFor="let locale of availableLocales" (click)="changeLocale(locale.locale)"><a tabindex="-1" href="#">{{ locale.label }}</a></li>
</ul>
</li>
</ul>
</li>
</ul>

View file

@ -24,6 +24,7 @@ declare const resourceUrl: string;
declare const baseUrl: string;
declare const referrer: string;
declare const referrer_uri: string;
declare const availableLocales: Array<Object>;
@Component({
selector: 'app-top-nav',
@ -34,10 +35,13 @@ export class TopNavComponent implements OnInit {
@Input() showSideNav: String;
public resourceUrl: string = resourceUrl;
public availableLocales: Array<Object> = availableLocales;
private referrer: Referrer;
constructor(private keycloakService: KeycloakService, translateUtil: TranslateUtil, private respSvc: ResponsivenessService) {
constructor(private keycloakService: KeycloakService,
translateUtil: TranslateUtil,
private respSvc: ResponsivenessService) {
this.referrer = new Referrer(translateUtil);
}
@ -52,4 +56,8 @@ export class TopNavComponent implements OnInit {
this.keycloakService.logout(baseUrl);
}
private changeLocale(newLocale: string) {
this.keycloakService.login({kcLocale: newLocale });
}
}