Compare commits
11 Commits
Author | SHA1 | Date | |
---|---|---|---|
70e3fb8de6 | |||
9cf75da732 | |||
2cd266caff | |||
28036f1da5 | |||
0dacf2fe30 | |||
32f5ef5e5c | |||
98d91bbde7 | |||
7a92a75d83 | |||
f5556a02fc | |||
1050f4d928 | |||
9276b08f4b |
13
CHANGELOG.md
13
CHANGELOG.md
@ -1,3 +1,16 @@
|
||||
## **1.2.0** (2021-06-22)
|
||||
|
||||
- Generate kcContext automatically :rocket:
|
||||
|
||||
### **1.1.6** (2021-06-21)
|
||||
|
||||
- Fix: Alert messages sometimes includes HTML that is not rendered
|
||||
- Update dist
|
||||
|
||||
### **1.1.5** (2021-06-15)
|
||||
|
||||
- #11: Provide socials in the register
|
||||
|
||||
### **1.1.4** (2021-06-15)
|
||||
|
||||
- Merge pull request #12 from InseeFrLab/email-typo
|
||||
|
@ -271,6 +271,10 @@ Then to load your own therms of services using [like this](https://github.com/ga
|
||||
|
||||
# Some pages still have the default theme. Why?
|
||||
|
||||
**NEW in v1.2 it is now much more easy to add support for custom pages since the
|
||||
Keycloak context is now automatically converted into a JavaScript object (kcContext).
|
||||
In v2 (coming soon) it won't be required to fork for adding support for custom pages.**
|
||||
|
||||
This project only support the most common user facing pages of Keycloak login.
|
||||
[Here](https://user-images.githubusercontent.com/6702424/116787906-227fe700-aaa7-11eb-92ee-22e7673717c2.png) is the complete list of pages (you get them after running `yarn test`)
|
||||
and [here](https://github.com/InseeFrLab/keycloakify/tree/main/src/lib/components) are the pages currently implemented by this module.
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "keycloakify",
|
||||
"version": "1.1.4",
|
||||
"version": "1.2.0",
|
||||
"description": "Keycloak theme generator for Reacts app",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -1,26 +0,0 @@
|
||||
|
||||
var es = /&(?:amp|#38|lt|#60|gt|#62|apos|#39|quot|#34);/g;
|
||||
|
||||
var unes = {
|
||||
'&': '&',
|
||||
'&': '&',
|
||||
'<': '<',
|
||||
'<': '<',
|
||||
'>': '>',
|
||||
'>': '>',
|
||||
''': "'",
|
||||
''': "'",
|
||||
'"': '"',
|
||||
'"': '"'
|
||||
};
|
||||
var cape = function (m) { return unes[m]; };
|
||||
|
||||
Object.defineProperty(
|
||||
String,
|
||||
"htmlUnescape",
|
||||
{
|
||||
"value": function (un) {
|
||||
return String.prototype.replace.call(un, es, cape);
|
||||
}
|
||||
}
|
||||
);
|
@ -1,263 +1,194 @@
|
||||
<script>const _=
|
||||
{
|
||||
"url": {
|
||||
"loginAction": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${url.loginAction?no_esc}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"resourcesPath": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${url.resourcesPath?no_esc}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"resourcesCommonPath": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${url.resourcesCommonPath?no_esc}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"loginRestartFlowUrl": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${url.loginRestartFlowUrl?no_esc}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"loginUrl": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${url.loginUrl?no_esc}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})()
|
||||
},
|
||||
"realm": {
|
||||
"displayName": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${realm.displayName!''}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"displayNameHtml": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${realm.displayNameHtml!''}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"internationalizationEnabled": (function (){
|
||||
|
||||
<#attempt>
|
||||
return ${realm.internationalizationEnabled?c};
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"registrationEmailAsUsername": (function (){
|
||||
|
||||
<#attempt>
|
||||
return ${realm.registrationEmailAsUsername?c};
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})()
|
||||
},
|
||||
"locale": (function (){
|
||||
<#macro objectToJson object depth>
|
||||
<@compress>
|
||||
|
||||
<#local isHash = false>
|
||||
<#attempt>
|
||||
<#if realm.internationalizationEnabled>
|
||||
|
||||
return {
|
||||
"supported": (function(){
|
||||
|
||||
var out= [];
|
||||
|
||||
<#attempt>
|
||||
<#list locale.supported as lng>
|
||||
out.push({
|
||||
"url": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${lng.url?no_esc}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"label": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${lng.label}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"languageTag": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${lng.languageTag}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})()
|
||||
});
|
||||
</#list>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
return out;
|
||||
|
||||
})(),
|
||||
"current": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${locale.current}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})()
|
||||
};
|
||||
|
||||
</#if>
|
||||
<#local isHash = object?is_hash || object?is_hash_ex>
|
||||
<#recover>
|
||||
/* can't evaluate if object is hash */
|
||||
undefined
|
||||
<#return>
|
||||
</#attempt>
|
||||
<#if isHash>
|
||||
|
||||
})(),
|
||||
"auth": (function (){
|
||||
|
||||
<#attempt>
|
||||
<#if auth?has_content>
|
||||
|
||||
var out= {
|
||||
"showUsername": (function (){
|
||||
|
||||
<#attempt>
|
||||
return ${auth.showUsername()?c};
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"showResetCredentials": (function (){
|
||||
|
||||
<#attempt>
|
||||
return ${auth.showResetCredentials()?c};
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"showTryAnotherWayLink": (function(){
|
||||
|
||||
<#attempt>
|
||||
return ${auth.showTryAnotherWayLink()?c};
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})()
|
||||
};
|
||||
<#local keys = "">
|
||||
|
||||
<#attempt>
|
||||
<#if auth.showUsername() && !auth.showResetCredentials()>
|
||||
Object.assign(
|
||||
out,
|
||||
{
|
||||
"attemptedUsername": (function (){
|
||||
<#attempt>
|
||||
return "${auth.attemptedUsername}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})()
|
||||
}
|
||||
);
|
||||
</#if>
|
||||
<#local keys = object?keys>
|
||||
<#recover>
|
||||
/* can't list keys of object */
|
||||
undefined
|
||||
<#return>
|
||||
</#attempt>
|
||||
|
||||
return out;
|
||||
{${'\n'}
|
||||
|
||||
/* <#list keys as key> ${key} </#list> */
|
||||
|
||||
<#list keys as key>
|
||||
|
||||
<#if key == "class">
|
||||
/* skipping "class" property of object */
|
||||
<#continue>
|
||||
</#if>
|
||||
|
||||
<#local value = "">
|
||||
|
||||
<#attempt>
|
||||
<#local value = object[key]>
|
||||
<#recover>
|
||||
/* couldn't dereference ${key} of object */
|
||||
<#continue>
|
||||
</#attempt>
|
||||
|
||||
<#if depth gt 4>
|
||||
/* Avoid calling recustively too many times depth: ${depth}, key: ${key} */
|
||||
<#continue>
|
||||
</#if>
|
||||
|
||||
"${key}": <@objectToJson object=value depth=depth+1/>,
|
||||
|
||||
</#list>
|
||||
|
||||
}${'\n'}
|
||||
|
||||
<#return>
|
||||
|
||||
</#if>
|
||||
|
||||
|
||||
<#local isMethod = "">
|
||||
<#attempt>
|
||||
<#local isMethod = object?is_method>
|
||||
<#recover>
|
||||
/* can't test if object is a method */
|
||||
undefined
|
||||
<#return>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"scripts": (function(){
|
||||
<#if isMethod>
|
||||
undefined
|
||||
<#return>
|
||||
</#if>
|
||||
|
||||
|
||||
|
||||
<#local isBoolean = "">
|
||||
<#attempt>
|
||||
<#local isBoolean = object?is_boolean>
|
||||
<#recover>
|
||||
/* can't test if object is a boolean */
|
||||
undefined
|
||||
<#return>
|
||||
</#attempt>
|
||||
|
||||
<#if isBoolean>
|
||||
${object?c}
|
||||
<#return>
|
||||
</#if>
|
||||
|
||||
|
||||
<#local isEnumerable = "">
|
||||
<#attempt>
|
||||
<#local isEnumerable = object?is_enumerable>
|
||||
<#recover>
|
||||
/* can't test if object is enumerable */
|
||||
undefined
|
||||
<#return>
|
||||
</#attempt>
|
||||
|
||||
<#if isEnumerable>
|
||||
|
||||
[${'\n'}
|
||||
|
||||
<#list object as item>
|
||||
|
||||
<@objectToJson object=item depth=depth+1/>,
|
||||
|
||||
</#list>
|
||||
|
||||
]${'\n'}
|
||||
|
||||
<#return>
|
||||
</#if>
|
||||
|
||||
var out = [];
|
||||
|
||||
<#attempt>
|
||||
<#if scripts??>
|
||||
<#attempt>
|
||||
<#list scripts as script>
|
||||
out.push((function (){
|
||||
"${object?no_esc}"
|
||||
<#recover>
|
||||
/* couldn't convert into string non hash, non method, non boolean, non enumerable object */
|
||||
undefined;
|
||||
<#return>
|
||||
</#attempt>
|
||||
|
||||
|
||||
</@compress>
|
||||
</#macro>
|
||||
|
||||
(()=>{
|
||||
|
||||
//Removing all the undefined
|
||||
const obj = JSON.parse(JSON.stringify(<@objectToJson object=.data_model depth=0 />));
|
||||
|
||||
//Freemarker values that can't be automatically converted into a JavaScript object.
|
||||
Object.deepAssign(
|
||||
obj,
|
||||
{
|
||||
"messagesPerField": {
|
||||
"printIfExists": function (key, x) {
|
||||
switch(key){
|
||||
case "userLabel": return (function (){
|
||||
<#attempt>
|
||||
return "${script}";
|
||||
return "${messagesPerField.printIfExists('userLabel','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})();
|
||||
case "username": return (function (){
|
||||
<#attempt>
|
||||
return "${messagesPerField.printIfExists('username','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})();
|
||||
case "email": return (function (){
|
||||
<#attempt>
|
||||
return "${messagesPerField.printIfExists('email','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})();
|
||||
case "firstName": return (function (){
|
||||
<#attempt>
|
||||
return "${messagesPerField.printIfExists('firstName','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})();
|
||||
case "lastName": return (function (){
|
||||
<#attempt>
|
||||
return "${messagesPerField.printIfExists('lastName','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})();
|
||||
case "password": return (function (){
|
||||
<#attempt>
|
||||
return "${messagesPerField.printIfExists('password','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})();
|
||||
case "password-confirm": return (function (){
|
||||
<#attempt>
|
||||
return "${messagesPerField.printIfExists('password-confirm','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})();
|
||||
}
|
||||
}
|
||||
},
|
||||
"msg": function(){ throw new Error("use import { useKcMessage } from 'keycloakify'"); },
|
||||
}
|
||||
);
|
||||
|
||||
})());
|
||||
</#list>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
</#if>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
return obj;
|
||||
|
||||
return out;
|
||||
})()
|
||||
|
||||
})(),
|
||||
"message": (function (){
|
||||
|
||||
<#attempt>
|
||||
<#if message?has_content>
|
||||
|
||||
return {
|
||||
"type": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${message.type}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"summary": (function (){
|
||||
|
||||
<#attempt>
|
||||
return String.htmlUnescape("${message.summary}");
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})()
|
||||
};
|
||||
|
||||
</#if>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"isAppInitiatedAction": (function (){
|
||||
|
||||
<#attempt>
|
||||
<#if isAppInitiatedAction??>
|
||||
return true;
|
||||
</#if>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
return false;
|
||||
|
||||
})()
|
||||
}
|
||||
</script>
|
@ -1,23 +0,0 @@
|
||||
<script>const _=
|
||||
{
|
||||
"client": (function (){
|
||||
|
||||
<#attempt>
|
||||
<#if client??>
|
||||
return {
|
||||
"baseUrl": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${(client.baseUrl!'')?no_esc}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})()
|
||||
};
|
||||
</#if>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})()
|
||||
}
|
||||
</script>
|
@ -12,10 +12,10 @@ import { objectKeys } from "evt/tools/typeSafety/objectKeys";
|
||||
import { ftlValuesGlobalName } from "../ftlValuesGlobalName";
|
||||
|
||||
export const pageIds = [
|
||||
"login.ftl", "register.ftl", "info.ftl",
|
||||
"error.ftl", "login-reset-password.ftl",
|
||||
"login.ftl", "register.ftl", "info.ftl",
|
||||
"error.ftl", "login-reset-password.ftl",
|
||||
"login-verify-email.ftl", "terms.ftl",
|
||||
"login-otp.ftl", "login-update-profile.ftl",
|
||||
"login-otp.ftl", "login-update-profile.ftl",
|
||||
"login-idp-link-confirm.ftl"
|
||||
] as const;
|
||||
|
||||
@ -26,17 +26,6 @@ function loadAdjacentFile(fileBasename: string) {
|
||||
.toString("utf8");
|
||||
};
|
||||
|
||||
function loadFtlFile(ftlFileBasename: PageId | "common.ftl") {
|
||||
try {
|
||||
|
||||
return loadAdjacentFile(ftlFileBasename)
|
||||
.match(/^<script>const _=((?:.|\n)+)<\/script>[\n]?$/)![1];
|
||||
|
||||
} catch {
|
||||
return "{}";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function generateFtlFilesCodeFactory(
|
||||
params: {
|
||||
@ -100,8 +89,9 @@ export function generateFtlFilesCodeFactory(
|
||||
);
|
||||
|
||||
//FTL is no valid html, we can't insert with cheerio, we put placeholder for injecting later.
|
||||
const ftlCommonPlaceholders = {
|
||||
'{ "x": "vIdLqMeOed9sdLdIdOxdK0d" }': loadFtlFile("common.ftl"),
|
||||
const ftlPlaceholders = {
|
||||
'{ "x": "vIdLqMeOed9sdLdIdOxdK0d" }': loadAdjacentFile("common.ftl")
|
||||
.match(/^<script>const _=((?:.|\n)+)<\/script>[\n]?$/)![1],
|
||||
'<!-- xIdLqMeOedErIdLsPdNdI9dSlxI -->':
|
||||
[
|
||||
'<#if scripts??>',
|
||||
@ -126,23 +116,19 @@ export function generateFtlFilesCodeFactory(
|
||||
'</style>',
|
||||
''
|
||||
]),
|
||||
...["Object.deepAssign.js", "String.htmlUnescape.js"].map(
|
||||
fileBasename => [
|
||||
"<script>",
|
||||
loadAdjacentFile(fileBasename),
|
||||
"</script>"
|
||||
].join("\n")
|
||||
),
|
||||
"<script>",
|
||||
loadAdjacentFile("Object.deepAssign.js"),
|
||||
"</script>",
|
||||
'<script>',
|
||||
` window.${ftlValuesGlobalName}= Object.assign(`,
|
||||
` {},`,
|
||||
` ${objectKeys(ftlCommonPlaceholders)[0]}`,
|
||||
` ${objectKeys(ftlPlaceholders)[0]}`,
|
||||
' );',
|
||||
'</script>',
|
||||
'',
|
||||
pageSpecificCodePlaceholder,
|
||||
'',
|
||||
objectKeys(ftlCommonPlaceholders)[1]
|
||||
objectKeys(ftlPlaceholders)[1]
|
||||
].join("\n"),
|
||||
);
|
||||
|
||||
@ -158,11 +144,6 @@ export function generateFtlFilesCodeFactory(
|
||||
|
||||
const $ = cheerio.load(partiallyFixedIndexHtmlCode);
|
||||
|
||||
const ftlPlaceholders = {
|
||||
'{ "x": "kxOlLqMeOed9sdLdIdOxd444" }': loadFtlFile(pageId),
|
||||
...ftlCommonPlaceholders
|
||||
};
|
||||
|
||||
let ftlCode = $.html()
|
||||
.replace(
|
||||
pageSpecificCodePlaceholder,
|
||||
@ -172,10 +153,6 @@ export function generateFtlFilesCodeFactory(
|
||||
` window.${ftlValuesGlobalName},`,
|
||||
` { "pageId": "${pageId}" }`,
|
||||
' );',
|
||||
` Object.deepAssign(`,
|
||||
` window.${ftlValuesGlobalName},`,
|
||||
` ${objectKeys(ftlPlaceholders)[0]}`,
|
||||
' );',
|
||||
'</script>'
|
||||
].join("\n")
|
||||
);
|
||||
|
@ -1,82 +0,0 @@
|
||||
<script>const _=
|
||||
{
|
||||
"messageHeader": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${messageHeader!''}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"requiredActions": (function (){
|
||||
|
||||
<#attempt>
|
||||
<#if requiredActions??>
|
||||
|
||||
var out =[];
|
||||
|
||||
<#attempt>
|
||||
<#list requiredActions>
|
||||
<#attempt>
|
||||
<#items as reqActionItem>
|
||||
out.push((function (){
|
||||
|
||||
<#attempt>
|
||||
return "${reqActionItem}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})());
|
||||
</#items>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
</#list>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
return out;
|
||||
|
||||
</#if>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"skipLink": (function (){
|
||||
|
||||
<#attempt>
|
||||
<#if skipLink??>
|
||||
return true;
|
||||
</#if>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
return false;
|
||||
|
||||
})(),
|
||||
"pageRedirectUri": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${(pageRedirectUri!'')?no_esc}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"actionUri": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${(actionUri!'')?no_esc}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"client": {
|
||||
"baseUrl": (function(){
|
||||
|
||||
<#attempt>
|
||||
return "${(client.baseUrl!'')?no_esc}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})()
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,11 +0,0 @@
|
||||
<script>const _=
|
||||
{
|
||||
"idpAlias": (function (){
|
||||
<#attempt>
|
||||
return "${idpAlias}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
return "";
|
||||
})()
|
||||
}
|
||||
</script>
|
@ -1,37 +0,0 @@
|
||||
<script>const _=
|
||||
{
|
||||
"otpLogin": {
|
||||
"userOtpCredentials": (function(){
|
||||
|
||||
var out = [];
|
||||
|
||||
<#attempt>
|
||||
<#list otpLogin.userOtpCredentials as otpCredential>
|
||||
out.push({
|
||||
"id": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${otpCredential.id}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"userLabel": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${otpCredential.userLabel}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})()
|
||||
});
|
||||
</#list>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
return out;
|
||||
|
||||
})()
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,14 +0,0 @@
|
||||
<script>const _=
|
||||
{
|
||||
"realm": {
|
||||
"loginWithEmailAllowed": (function (){
|
||||
|
||||
<#attempt>
|
||||
return ${realm.loginWithEmailAllowed?c};
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})()
|
||||
}
|
||||
}
|
||||
</script>
|
@ -1,67 +0,0 @@
|
||||
<script>const _=
|
||||
{
|
||||
"user": {
|
||||
"editUsernameAllowed": (function (){
|
||||
<#attempt>
|
||||
return ${user.editUsernameAllowed?c};
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})(),
|
||||
"username": (function (){
|
||||
<#attempt>
|
||||
return "${user.username!''}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})(),
|
||||
"email": (function (){
|
||||
<#attempt>
|
||||
return "${user.email!''}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})(),
|
||||
"firstName": (function (){
|
||||
<#attempt>
|
||||
return "${user.firstName!''}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})(),
|
||||
"lastName": (function (){
|
||||
<#attempt>
|
||||
return "${user.lastName!''}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})()
|
||||
},
|
||||
"messagesPerField": {
|
||||
"printIfExists": function (key, x) {
|
||||
switch(key){
|
||||
case "username": return (function (){
|
||||
<#attempt>
|
||||
return "${messagesPerField.printIfExists('username','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})();
|
||||
case "email": return (function (){
|
||||
<#attempt>
|
||||
return "${messagesPerField.printIfExists('email','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})();
|
||||
case "firstName": return (function (){
|
||||
<#attempt>
|
||||
return "${messagesPerField.printIfExists('firstName','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})();
|
||||
case "lastName": return (function (){
|
||||
<#attempt>
|
||||
return "${messagesPerField.printIfExists('lastName','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
@ -1,160 +0,0 @@
|
||||
<script>const _=
|
||||
{
|
||||
"url": {
|
||||
"loginResetCredentialsUrl": (function (){
|
||||
<#attempt>
|
||||
return "${url.loginResetCredentialsUrl?no_esc}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})(),
|
||||
"registrationUrl": (function (){
|
||||
<#attempt>
|
||||
return "${url.registrationUrl?no_esc}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})()
|
||||
},
|
||||
"realm": {
|
||||
"loginWithEmailAllowed": (function(){
|
||||
<#attempt>
|
||||
return ${realm.loginWithEmailAllowed?c};
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})(),
|
||||
"rememberMe": (function (){
|
||||
<#attempt>
|
||||
return ${realm.rememberMe?c};
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})(),
|
||||
"password": (function (){
|
||||
<#attempt>
|
||||
return ${realm.password?c};
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})(),
|
||||
"resetPasswordAllowed": (function (){
|
||||
<#attempt>
|
||||
return ${realm.resetPasswordAllowed?c};
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})(),
|
||||
"registrationAllowed": (function (){
|
||||
<#attempt>
|
||||
return ${realm.registrationAllowed?c};
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})()
|
||||
},
|
||||
"auth": (function (){
|
||||
|
||||
<#attempt>
|
||||
<#if auth?has_content>
|
||||
|
||||
return {
|
||||
"selectedCredential": (function (){
|
||||
<#attempt>
|
||||
return "${auth.selectedCredential!''}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})()
|
||||
};
|
||||
|
||||
</#if>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"social": {
|
||||
"displayInfo": (function (){
|
||||
<#attempt>
|
||||
return ${social.displayInfo?c};
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})(),
|
||||
"providers": (()=>{
|
||||
|
||||
<#attempt>
|
||||
<#if social.providers??>
|
||||
|
||||
var out= [];
|
||||
|
||||
<#attempt>
|
||||
<#list social.providers as p>
|
||||
out.push({
|
||||
"loginUrl": (function (){
|
||||
<#attempt>
|
||||
return "${p.loginUrl?no_esc}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})(),
|
||||
"alias": (function (){
|
||||
<#attempt>
|
||||
return "${p.alias}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})(),
|
||||
"providerId": (function (){
|
||||
<#attempt>
|
||||
return "${p.providerId}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})(),
|
||||
"displayName": (function (){
|
||||
<#attempt>
|
||||
return "${p.displayName}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})()
|
||||
});
|
||||
</#list>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
return out;
|
||||
|
||||
</#if>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})()
|
||||
},
|
||||
"usernameEditDisabled": (function () {
|
||||
|
||||
<#attempt>
|
||||
<#if usernameEditDisabled??>
|
||||
return true;
|
||||
</#if>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
return false;
|
||||
|
||||
})(),
|
||||
"login": {
|
||||
"username": (function (){
|
||||
<#attempt>
|
||||
return "${login.username!''}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
})(),
|
||||
"rememberMe": (function (){
|
||||
<#attempt>
|
||||
<#if login.rememberMe??>
|
||||
return true;
|
||||
</#if>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
return false;
|
||||
})()
|
||||
},
|
||||
"registrationDisabled": (function (){
|
||||
<#attempt>
|
||||
<#if registrationDisabled??>
|
||||
return true;
|
||||
</#if>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
return false;
|
||||
})()
|
||||
}
|
||||
</script>
|
@ -1,189 +0,0 @@
|
||||
<script>const _=
|
||||
{
|
||||
"url": {
|
||||
"registrationAction": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${url.registrationAction?no_esc}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})()
|
||||
},
|
||||
"messagesPerField": {
|
||||
"printIfExists": function (key, x) {
|
||||
switch(key){
|
||||
case "userLabel": return (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${messagesPerField.printIfExists('userLabel','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})();
|
||||
case "username": return (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${messagesPerField.printIfExists('username','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})();
|
||||
case "email": return (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${messagesPerField.printIfExists('email','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})();
|
||||
case "firstName": return (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${messagesPerField.printIfExists('firstName','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})();
|
||||
case "lastName": return (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${messagesPerField.printIfExists('lastName','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})();
|
||||
case "password": return (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${messagesPerField.printIfExists('password','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})();
|
||||
case "password-confirm": return (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${messagesPerField.printIfExists('password-confirm','1')}" ? x : undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})();
|
||||
}
|
||||
}
|
||||
},
|
||||
"register": {
|
||||
"formData": {
|
||||
"firstName": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${register.formData.firstName!''}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"displayName": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${register.formData.displayName!''}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"lastName": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${register.formData.lastName!''}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"email": (function(){
|
||||
|
||||
<#attempt>
|
||||
return "${register.formData.email!''}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"username": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${register.formData.username!''}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})()
|
||||
}
|
||||
},
|
||||
"passwordRequired": (function (){
|
||||
|
||||
<#attempt>
|
||||
<#if passwordRequired??>
|
||||
return true;
|
||||
</#if>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
return false;
|
||||
|
||||
})(),
|
||||
"recaptchaRequired": (function (){
|
||||
|
||||
<#attempt>
|
||||
<#if passwordRequired??>
|
||||
return true;
|
||||
</#if>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
return false;
|
||||
|
||||
})(),
|
||||
"recaptchaSiteKey": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${recaptchaSiteKey!''}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"authorizedMailDomains": (function (){
|
||||
|
||||
<#attempt>
|
||||
return "${authorizedMailDomains!''}" || undefined;
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})(),
|
||||
"authorizedMailDomains": (function(){
|
||||
|
||||
var out = undefined;
|
||||
|
||||
<#attempt>
|
||||
<#if authorizedMailDomains??>
|
||||
|
||||
out = [];
|
||||
|
||||
<#attempt>
|
||||
<#list authorizedMailDomains as authorizedMailDomain>
|
||||
out.push((function (){
|
||||
|
||||
<#attempt>
|
||||
return "${authorizedMailDomain}";
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
})());
|
||||
</#list>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
</#if>
|
||||
<#recover>
|
||||
</#attempt>
|
||||
|
||||
return out;
|
||||
|
||||
})(),
|
||||
}
|
||||
</script>
|
@ -269,7 +269,10 @@ export const Template = memo((props: TemplateProps) => {
|
||||
{message.type === "warning" && <span className={cx(props.kcFeedbackWarningIcon)}></span>}
|
||||
{message.type === "error" && <span className={cx(props.kcFeedbackErrorIcon)}></span>}
|
||||
{message.type === "info" && <span className={cx(props.kcFeedbackInfoIcon)}></span>}
|
||||
<span className="kc-feedback-text">{message.summary}</span>
|
||||
<span
|
||||
className="kc-feedback-text"
|
||||
dangerouslySetInnerHTML={{ "__html": message.summary }}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
{formNode}
|
||||
|
@ -9,6 +9,13 @@ import ReactMarkdown from "react-markdown";
|
||||
|
||||
export type MessageKey = keyof typeof kcMessages["en"];
|
||||
|
||||
/**
|
||||
* When the language is switched the page is reloaded, this may appear
|
||||
* as a bug as you might notice that the language successfully switch before
|
||||
* reload.
|
||||
* However we need to tell Keycloak that the user have changed the language
|
||||
* during login so we can retrieve the "local" field of the JWT encoded accessToken.
|
||||
*/
|
||||
export function useKcMessage() {
|
||||
|
||||
const { kcLanguageTag } = useKcLanguageTag();
|
||||
|
@ -130,6 +130,15 @@ export declare namespace KcContext {
|
||||
* (https://github.com/micedre/keycloak-mail-whitelisting)
|
||||
*/
|
||||
authorizedMailDomains?: string[];
|
||||
social: {
|
||||
displayInfo: boolean;
|
||||
providers?: {
|
||||
loginUrl: string;
|
||||
alias: string;
|
||||
providerId: string;
|
||||
displayName: string;
|
||||
}[]
|
||||
};
|
||||
};
|
||||
|
||||
export type Info = Common & {
|
||||
|
@ -168,7 +168,10 @@ export const kcRegisterContext: KcContext.Register = {
|
||||
"*.yet-another-example.com",
|
||||
"*.example.com",
|
||||
"hello-world.com"
|
||||
]
|
||||
],
|
||||
"social": {
|
||||
"displayInfo": true
|
||||
},
|
||||
};
|
||||
|
||||
export const kcInfoContext: KcContext.Info = {
|
||||
|
33
yarn.lock
33
yarn.lock
@ -43,9 +43,9 @@
|
||||
"@babel/helper-plugin-utils" "^7.14.5"
|
||||
|
||||
"@babel/runtime@^7.13.10", "@babel/runtime@^7.7.2":
|
||||
version "7.14.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.5.tgz#665450911c6031af38f81db530f387ec04cd9a98"
|
||||
integrity sha512-121rumjddw9c3NCQ55KGkyE1h/nzWhU/owjhw0l4mQrkzz4x9SGS1X8gFLraHwX7td3Yo4QTL+qj0NcIzN87BA==
|
||||
version "7.14.6"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d"
|
||||
integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
@ -322,9 +322,9 @@ concat-map@0.0.1:
|
||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
|
||||
convert-source-map@^1.5.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442"
|
||||
integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369"
|
||||
integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==
|
||||
dependencies:
|
||||
safe-buffer "~5.1.1"
|
||||
|
||||
@ -770,7 +770,7 @@ micromark@~2.11.0:
|
||||
debug "^4.0.0"
|
||||
parse-entities "^2.0.0"
|
||||
|
||||
minimal-polyfills@^2.1.5, minimal-polyfills@^2.1.6, minimal-polyfills@^2.2.1:
|
||||
minimal-polyfills@^2.1.5, minimal-polyfills@^2.1.6:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/minimal-polyfills/-/minimal-polyfills-2.2.1.tgz#7249d7ece666d3b4e1ec1c1b8f949eb9d44e2308"
|
||||
integrity sha512-WLmHQrsZob4rVYf8yHapZPNJZ3sspGa/sN8abuSD59b0FifDEE7HMfLUi24z7mPZqTpBXy4Svp+iGvAmclCmXg==
|
||||
@ -894,13 +894,12 @@ path@^0.12.7:
|
||||
util "^0.10.3"
|
||||
|
||||
powerhooks@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/powerhooks/-/powerhooks-0.1.1.tgz#5ce825d595673a5c6f86b227e0fcaca1972bd90d"
|
||||
integrity sha512-I8bzTU/uRUyeTkeyAR54g862pwMcAX/ErN3xqdUt7n28riqv93N0Cm900018bNRKBq8ovnb+VxOQ+MXJwhkUOA==
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/powerhooks/-/powerhooks-0.1.4.tgz#82aae8dae5485a154d3ce4e89342a2d68cb2a413"
|
||||
integrity sha512-ig47hJIW/b75gCS3l2EtK8NVAduNVd9vem8IvaWkuPuZIP4mbDAy4Rc0/hvjXVUPs9OzK7jc/zIQika3tTacYg==
|
||||
dependencies:
|
||||
evt "2.0.0-beta.15"
|
||||
memoizee "^0.4.15"
|
||||
minimal-polyfills "^2.2.1"
|
||||
resize-observer-polyfill "^1.5.1"
|
||||
tsafe "^0.1.0"
|
||||
|
||||
@ -1150,9 +1149,9 @@ type@^2.0.0:
|
||||
integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw==
|
||||
|
||||
typescript@^4.2.3:
|
||||
version "4.3.2"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.2.tgz#399ab18aac45802d6f2498de5054fcbbe716a805"
|
||||
integrity sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.4.tgz#3f85b986945bcf31071decdd96cf8bfa65f9dcbc"
|
||||
integrity sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew==
|
||||
|
||||
unified@^9.0.0:
|
||||
version "9.2.1"
|
||||
@ -1265,9 +1264,9 @@ yaml@^1.7.2:
|
||||
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
|
||||
|
||||
yargs-parser@^20.2.2:
|
||||
version "20.2.7"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a"
|
||||
integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==
|
||||
version "20.2.9"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
|
||||
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
|
||||
|
||||
yargs@^16.1.0:
|
||||
version "16.2.0"
|
||||
|
Reference in New Issue
Block a user