Compare commits
81 Commits
Author | SHA1 | Date | |
---|---|---|---|
f766348b87 | |||
82281303d0 | |||
1caa17beb0 | |||
1c4d346f9f | |||
4320efb049 | |||
a756423768 | |||
8525fc74c0 | |||
30c0cc5aa8 | |||
b3bbd7c07d | |||
09d4ba2bb0 | |||
30315027c1 | |||
05acefe70e | |||
6c14758e33 | |||
b93ec20119 | |||
ce04646576 | |||
9282dfe491 | |||
fca6280bcc | |||
cdeb575ec6 | |||
271dbe4fb7 | |||
9a0337114d | |||
2d28f4eb55 | |||
f673927e16 | |||
52896b82a9 | |||
9d53ecb0cd | |||
aec3ac32e5 | |||
f150f1568e | |||
309189c55d | |||
f68c54cd3a | |||
bef8545161 | |||
c21cd14ac2 | |||
275d7f0072 | |||
58c8306cf4 | |||
f782b684ad | |||
092b2a5f52 | |||
42b2d40ad6 | |||
3f6fe6cfc0 | |||
1abf542a74 | |||
c4720ca03d | |||
4316878cce | |||
c180d75a83 | |||
4a040b32c0 | |||
ea330a1eef | |||
2451ba0a77 | |||
2c276a56e5 | |||
708030b8b5 | |||
d5fc0582bc | |||
f9dce82c83 | |||
e82602f994 | |||
1d36395e5a | |||
8f8857bc22 | |||
226247b3b6 | |||
b2ea5014f3 | |||
48bc416aa7 | |||
386e7203b2 | |||
9bdb224631 | |||
dd36aacbee | |||
6b57b1c720 | |||
9e9e6d41ff | |||
5140389502 | |||
fc6328131f | |||
9de0083ca6 | |||
f5231b840d | |||
afb6596c4b | |||
dde9afef92 | |||
6595e9c3cb | |||
c0e3b5fe06 | |||
6b8f3bbc51 | |||
9a5a021e64 | |||
14c05fec8c | |||
eaf7a455cd | |||
55bb21f3ee | |||
f123bc0912 | |||
572eb7b1c0 | |||
2befaff8a8 | |||
437a9ce2d3 | |||
1b967b250a | |||
e221f39e07 | |||
21a8838a24 | |||
fad91ccae0 | |||
825914aa4b | |||
f15c0ecbb0 |
8
.github/workflows/ci.yaml
vendored
8
.github/workflows/ci.yaml
vendored
@ -14,7 +14,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- uses: actions/setup-node@v2.1.3
|
||||
- uses: bahmutov/npm-install@v1
|
||||
- uses: bahmutov/npm-install@v1.8.15
|
||||
- name: If this step fails run 'yarn format' then commit again.
|
||||
run: |
|
||||
PACKAGE_MANAGER=npm
|
||||
@ -25,6 +25,8 @@ jobs:
|
||||
test:
|
||||
runs-on: macos-10.15
|
||||
needs: test_formatting
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
strategy:
|
||||
matrix:
|
||||
node: [ '15', '14' ]
|
||||
@ -39,7 +41,7 @@ jobs:
|
||||
- uses: actions/setup-node@v2.1.3
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
- uses: bahmutov/npm-install@v1
|
||||
- uses: bahmutov/npm-install@v1.8.15
|
||||
- if: steps.step1.outputs.npm_or_yarn == 'yarn'
|
||||
run: |
|
||||
yarn build
|
||||
@ -121,7 +123,7 @@ jobs:
|
||||
with:
|
||||
node-version: '15'
|
||||
registry-url: https://registry.npmjs.org/
|
||||
- uses: bahmutov/npm-install@v1
|
||||
- uses: bahmutov/npm-install@v1.8.15
|
||||
- run: |
|
||||
PACKAGE_MANAGER=npm
|
||||
if [ -f "./yarn.lock" ]; then
|
||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -47,5 +47,5 @@ jspm_packages
|
||||
|
||||
.idea
|
||||
|
||||
/keycloak_theme_email
|
||||
/keycloak_email
|
||||
/build_keycloak
|
91
CHANGELOG.md
91
CHANGELOG.md
@ -1,3 +1,94 @@
|
||||
### **5.6.3** (2022-07-03)
|
||||
|
||||
- update powerhooks
|
||||
|
||||
### **5.6.2** (2022-07-03)
|
||||
|
||||
- Update powerhooks and EVT
|
||||
|
||||
### **5.6.1** (2022-07-03)
|
||||
|
||||
- Merge pull request #128 from Ann2827/pull
|
||||
|
||||
Fix bugs on error.ftl template
|
||||
- fix: bugs on error.ftl template
|
||||
- Merge pull request #52 from InseeFrLab/main
|
||||
|
||||
Update fork
|
||||
|
||||
## **5.6.0** (2022-06-28)
|
||||
|
||||
- Merge pull request #127 from aidangilmore/add-totp-support
|
||||
|
||||
feat: add login-config-totp.ftl page
|
||||
- Fix unknown algorithm name lookup in LoginConfigTotp
|
||||
- Add totp config support
|
||||
|
||||
## **5.5.0** (2022-06-28)
|
||||
|
||||
- Make it possible to redirect to login by repacing the url (should be default in most case)
|
||||
|
||||
### **5.4.7** (2022-06-19)
|
||||
|
||||
- #121
|
||||
- fmt
|
||||
- Create CONTRIBUTING.md
|
||||
- Enable users to link keycloak in their own app
|
||||
|
||||
### **5.4.6** (2022-06-16)
|
||||
|
||||
- Use keycloak 18.0.1 i18n resources #120
|
||||
|
||||
### **5.4.5** (2022-06-14)
|
||||
|
||||
- Merge pull request #119 from dro-sh/fix-locale-on-useFormValidationSlice
|
||||
|
||||
pass locale to getGetErrors to get correct messages
|
||||
- pass locale to getGetErrors to get correct messages
|
||||
|
||||
### **5.4.4** (2022-06-05)
|
||||
|
||||
|
||||
|
||||
### **5.4.3** (2022-06-01)
|
||||
|
||||
|
||||
|
||||
### **5.4.2** (2022-06-01)
|
||||
|
||||
- Prevent rate limite in CI by authenticating
|
||||
|
||||
### **5.4.1** (2022-06-01)
|
||||
|
||||
|
||||
|
||||
## **5.4.0** (2022-05-23)
|
||||
|
||||
- #109
|
||||
|
||||
### **5.3.2** (2022-05-04)
|
||||
|
||||
- Merge pull request #101 from Romcol/bugfix/99
|
||||
|
||||
Issue #99 - Make replace less greedy in remplaceImportFromStatic
|
||||
- [IMP] Issue #99 - Make replace less greedy in remplaceImportFromStatic
|
||||
|
||||
### **5.3.1** (2022-04-29)
|
||||
|
||||
- Comment out missleading informations
|
||||
|
||||
## **5.3.0** (2022-04-28)
|
||||
|
||||
- Rename keycloak_theme_email to keycloak_email (it's shorter)
|
||||
|
||||
## **5.2.0** (2022-04-27)
|
||||
|
||||
- Export KcApp
|
||||
|
||||
## **5.1.0** (2022-04-27)
|
||||
|
||||
- Export kcLanguageTags
|
||||
|
||||
# **5.0.0** (2022-04-27)
|
||||
|
||||
- i18n rebuild from the ground up
|
||||
|
3
CONTRIBUTING.md
Normal file
3
CONTRIBUTING.md
Normal file
@ -0,0 +1,3 @@
|
||||
Looking to contribute? Thank you! PR are more than welcome.
|
||||
|
||||
Please refers to [this documentation page](https://docs.keycloakify.dev/contributing) that will help you get started.
|
15
README.md
15
README.md
@ -12,7 +12,7 @@
|
||||
<img src="https://img.shields.io/bundlephobia/minzip/keycloakify">
|
||||
</a>
|
||||
<a href="https://www.npmjs.com/package/keycloakify">
|
||||
<img src="https://img.shields.io/npm/dw/keycloakify">
|
||||
<img src="https://img.shields.io/npm/dm/keycloakify">
|
||||
</a>
|
||||
<a href="https://github.com/garronej/keycloakify/blob/main/LICENSE">
|
||||
<img src="https://img.shields.io/npm/l/keycloakify">
|
||||
@ -38,6 +38,19 @@
|
||||
|
||||
# Changelog highlights
|
||||
|
||||
## v5.6.0
|
||||
|
||||
Add support for `login-config-totp.ftl` page [#127](https://github.com/InseeFrLab/keycloakify/pull/127).
|
||||
|
||||
## v5.3.0
|
||||
|
||||
Rename `keycloak_theme_email` to `keycloak_email`.
|
||||
If you already had a `keycloak_theme_email` you should rename it `keycloak_email`.
|
||||
|
||||
## v5.0.0
|
||||
|
||||
New i18n system. Import of terms and services have changed. [See example](https://github.com/garronej/keycloakify-demo-app/blob/a5b6a50f24bc25e082931f5ad9ebf47492acd12a/src/index.tsx#L46-L63).
|
||||
|
||||
## v4.10.0
|
||||
|
||||
Add `login-idp-link-email.ftl` page [See PR](https://github.com/InseeFrLab/keycloakify/pull/92).
|
||||
|
18
package.json
18
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "keycloakify",
|
||||
"version": "5.0.0",
|
||||
"version": "5.6.3",
|
||||
"description": "Keycloak theme generator for Reacts app",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -22,7 +22,7 @@
|
||||
},
|
||||
"bin": {
|
||||
"build-keycloak-theme": "dist/bin/build-keycloak-theme/index.js",
|
||||
"create-keycloak-theme-email-directory": "dist/bin/create-keycloak-theme-email-directory.js",
|
||||
"create-keycloak-email-directory": "dist/bin/create-keycloak-email-directory.js",
|
||||
"download-builtin-keycloak-theme": "dist/bin/download-builtin-keycloak-theme.js"
|
||||
},
|
||||
"lint-staged": {
|
||||
@ -57,19 +57,19 @@
|
||||
"homepage": "https://github.com/garronej/keycloakify",
|
||||
"peerDependencies": {
|
||||
"@emotion/react": "^11.4.1",
|
||||
"react": "^16.8.0 || ^17.0.0"
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@emotion/react": "^11.4.1",
|
||||
"@types/memoizee": "^0.4.7",
|
||||
"@types/node": "^17.0.25",
|
||||
"@types/react": "^17.0.0",
|
||||
"@types/react": "18.0.9",
|
||||
"copyfiles": "^2.4.1",
|
||||
"husky": "^4.3.8",
|
||||
"lint-staged": "^11.0.0",
|
||||
"prettier": "^2.3.0",
|
||||
"properties-parser": "^0.3.1",
|
||||
"react": "^17.0.1",
|
||||
"react": "18.1.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"typescript": "^4.2.3"
|
||||
},
|
||||
@ -77,14 +77,14 @@
|
||||
"@octokit/rest": "^18.12.0",
|
||||
"cheerio": "^1.0.0-rc.5",
|
||||
"cli-select": "^1.1.2",
|
||||
"evt": "2.0.0-beta.39",
|
||||
"evt": "2.0.0-beta.45",
|
||||
"memoizee": "^0.4.15",
|
||||
"minimal-polyfills": "^2.2.1",
|
||||
"path-browserify": "^1.0.1",
|
||||
"powerhooks": "^0.14.0",
|
||||
"powerhooks": "^0.20.3",
|
||||
"react-markdown": "^5.0.3",
|
||||
"scripting-tools": "^0.19.13",
|
||||
"tsafe": "^0.9.0",
|
||||
"tss-react": "^3.5.2"
|
||||
"tsafe": "^0.10.0",
|
||||
"tss-react": "^3.7.0"
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ const doUseExternalAssets = process.argv[2]?.toLowerCase() === "--external-asset
|
||||
const parsedPackageJson: ParsedPackageJson = require(pathJoin(reactProjectDirPath, "package.json"));
|
||||
|
||||
export const keycloakThemeBuildingDirPath = pathJoin(reactProjectDirPath, "build_keycloak");
|
||||
export const keycloakThemeEmailDirPath = pathJoin(keycloakThemeBuildingDirPath, "..", "keycloak_theme_email");
|
||||
export const keycloakThemeEmailDirPath = pathJoin(keycloakThemeBuildingDirPath, "..", "keycloak_email");
|
||||
|
||||
function sanitizeThemeName(name: string) {
|
||||
return name
|
||||
@ -106,7 +106,8 @@ export function main() {
|
||||
`✅ Your keycloak theme has been generated and bundled into ./${pathRelative(reactProjectDirPath, jarFilePath)} 🚀`,
|
||||
`It is to be placed in "/opt/keycloak/providers" in the container running a quay.io/keycloak/keycloak Docker image.`,
|
||||
"",
|
||||
"Using Helm (https://github.com/codecentric/helm-charts), edit to reflect:",
|
||||
//TODO: Restore when we find a good Helm chart for Keycloak.
|
||||
//"Using Helm (https://github.com/codecentric/helm-charts), edit to reflect:",
|
||||
"",
|
||||
"value.yaml: ",
|
||||
" extraInitContainers: |",
|
||||
|
@ -30,6 +30,9 @@ ${ftl_object_to_js_code_declaring_an_object(.data_model, [])?no_esc};
|
||||
</#attempt>
|
||||
|
||||
"printIfExists": function (fieldName, x) {
|
||||
<#if !messagesPerField?? >
|
||||
return undefined;
|
||||
</#if>
|
||||
<#list fieldNames as fieldName>
|
||||
if(fieldName === "${fieldName}" ){
|
||||
<#attempt>
|
||||
@ -41,6 +44,9 @@ ${ftl_object_to_js_code_declaring_an_object(.data_model, [])?no_esc};
|
||||
throw new Error("There is no " + fieldName + " field");
|
||||
},
|
||||
"existsError": function (fieldName) {
|
||||
<#if !messagesPerField?? >
|
||||
return false;
|
||||
</#if>
|
||||
<#list fieldNames as fieldName>
|
||||
if(fieldName === "${fieldName}" ){
|
||||
<#attempt>
|
||||
@ -52,6 +58,9 @@ ${ftl_object_to_js_code_declaring_an_object(.data_model, [])?no_esc};
|
||||
throw new Error("There is no " + fieldName + " field");
|
||||
},
|
||||
"get": function (fieldName) {
|
||||
<#if !messagesPerField?? >
|
||||
return '';
|
||||
</#if>
|
||||
<#list fieldNames as fieldName>
|
||||
if(fieldName === "${fieldName}" ){
|
||||
<#attempt>
|
||||
@ -65,6 +74,9 @@ ${ftl_object_to_js_code_declaring_an_object(.data_model, [])?no_esc};
|
||||
throw new Error("There is no " + fieldName + " field");
|
||||
},
|
||||
"exists": function (fieldName) {
|
||||
<#if !messagesPerField?? >
|
||||
return false;
|
||||
</#if>
|
||||
<#list fieldNames as fieldName>
|
||||
if(fieldName === "${fieldName}" ){
|
||||
<#attempt>
|
||||
@ -124,9 +136,11 @@ ${ftl_object_to_js_code_declaring_an_object(.data_model, [])?no_esc};
|
||||
) || (
|
||||
<#-- https://github.com/InseeFrLab/keycloakify/pull/65#issuecomment-991896344 (reports with saml-post-form.ftl) -->
|
||||
<#-- https://github.com/InseeFrLab/keycloakify/issues/91#issue-1212319466 (reports with error.ftl and Kc18) -->
|
||||
<#-- https://github.com/InseeFrLab/keycloakify/issues/109#issuecomment-1134610163 -->
|
||||
key == "loginAction" &&
|
||||
are_same_path(path, ["url"]) &&
|
||||
["saml-post-form.ftl", "error.ftl"]?seq_contains(pageId)
|
||||
["saml-post-form.ftl", "error.ftl", "info.ftl"]?seq_contains(pageId) &&
|
||||
!(auth?has_content && auth.showTryAnotherWayLink())
|
||||
) || (
|
||||
["contextData", "idpConfig", "idp", "authenticationSession"]?seq_contains(key) &&
|
||||
are_same_path(path, ["brokerContext"]) &&
|
||||
@ -135,6 +149,9 @@ ${ftl_object_to_js_code_declaring_an_object(.data_model, [])?no_esc};
|
||||
key == "identityProviderBrokerCtx" &&
|
||||
are_same_path(path, []) &&
|
||||
["login-idp-link-confirm.ftl", "login-idp-link-email.ftl" ]?seq_contains(pageId)
|
||||
) || (
|
||||
["masterAdminClient", "delegateForUpdate", "defaultRole"]?seq_contains(key) &&
|
||||
are_same_path(path, ["realm"])
|
||||
)
|
||||
>
|
||||
<#local out_seq += ["/*If you need '" + key + "' on " + pageId + ", please submit an issue to the Keycloakify repo*/"]>
|
||||
@ -152,7 +169,7 @@ ${ftl_object_to_js_code_declaring_an_object(.data_model, [])?no_esc};
|
||||
</#attempt>
|
||||
|
||||
</#if>
|
||||
|
||||
|
||||
<#attempt>
|
||||
<#if !object[key]??>
|
||||
<#continue>
|
||||
@ -200,6 +217,31 @@ ${ftl_object_to_js_code_declaring_an_object(.data_model, [])?no_esc};
|
||||
</#attempt>
|
||||
|
||||
<#if isMethod>
|
||||
|
||||
<#if are_same_path(path, ["auth", "showUsername"])>
|
||||
<#attempt>
|
||||
<#return auth.showUsername()?c>
|
||||
<#recover>
|
||||
<#return "ABORT: Couldn't evaluate auth.showUsername()">
|
||||
</#attempt>
|
||||
</#if>
|
||||
|
||||
<#if are_same_path(path, ["auth", "showResetCredentials"])>
|
||||
<#attempt>
|
||||
<#return auth.showResetCredentials()?c>
|
||||
<#recover>
|
||||
<#return "ABORT: Couldn't evaluate auth.showResetCredentials()">
|
||||
</#attempt>
|
||||
</#if>
|
||||
|
||||
<#if are_same_path(path, ["auth", "showTryAnotherWayLink"])>
|
||||
<#attempt>
|
||||
<#return auth.showTryAnotherWayLink()?c>
|
||||
<#recover>
|
||||
<#return "ABORT: Couldn't evaluate auth.showTryAnotherWayLink()">
|
||||
</#attempt>
|
||||
</#if>
|
||||
|
||||
<#return "ABORT: It's a method">
|
||||
</#if>
|
||||
|
||||
|
@ -20,6 +20,7 @@ export const pageIds = [
|
||||
"login-idp-link-confirm.ftl",
|
||||
"login-idp-link-email.ftl",
|
||||
"login-page-expired.ftl",
|
||||
"login-config-totp.ftl",
|
||||
] as const;
|
||||
|
||||
export type PageId = typeof pageIds[number];
|
||||
|
@ -88,7 +88,7 @@ export function generateKeycloakThemeResources(params: {
|
||||
console.log(
|
||||
[
|
||||
`Not bundling email template because ${pathBasename(keycloakThemeEmailDirPath)} does not exist`,
|
||||
`To start customizing the email template, run: 👉 npx create-keycloak-theme-email-directory 👈`,
|
||||
`To start customizing the email template, run: 👉 npx create-keycloak-email-directory 👈`,
|
||||
].join("\n"),
|
||||
);
|
||||
doBundleEmailTemplate = false;
|
||||
|
@ -17,12 +17,12 @@ export function replaceImportsFromStaticInJsCode(params: { jsCode: string; urlOr
|
||||
const { jsCode, urlOrigin } = params;
|
||||
|
||||
const fixedJsCode = jsCode
|
||||
.replace(/(\w+\.\w+)\+"static\//g, (...[, group]) =>
|
||||
.replace(/([a-zA-Z]+\.[a-zA-Z]+)\+"static\//g, (...[, group]) =>
|
||||
urlOrigin === undefined
|
||||
? `window.${ftlValuesGlobalName}.url.resourcesPath + "/build/static/`
|
||||
: `("${ftlValuesGlobalName}" in window ? "${urlOrigin}" : "") + ${group} + "static/`,
|
||||
)
|
||||
.replace(/".chunk.css",(\w)+=(\w+\.\w+)\+(\w+),/, (...[, group1, group2, group3]) =>
|
||||
.replace(/".chunk.css",([a-zA-Z])+=([a-zA-Z]+\.[a-zA-Z]+)\+([a-zA-Z]+),/, (...[, group1, group2, group3]) =>
|
||||
urlOrigin === undefined
|
||||
? `".chunk.css",${group1} = window.${ftlValuesGlobalName}.url.resourcesPath + "/build/" + ${group3},`
|
||||
: `".chunk.css",${group1} = ("${ftlValuesGlobalName}" in window ? "${urlOrigin}" : "") + ${group2} + ${group3},`,
|
||||
|
@ -9,7 +9,7 @@ import { rm_rf, rm_r } from "./tools/rm";
|
||||
//@ts-ignore
|
||||
const propertiesParser = require("properties-parser");
|
||||
|
||||
for (const keycloakVersion of ["11.0.3", "15.0.2", "16.1.0"]) {
|
||||
for (const keycloakVersion of ["11.0.3", "15.0.2", "18.0.1"]) {
|
||||
console.log({ keycloakVersion });
|
||||
|
||||
const tmpDirPath = pathJoin(getProjectRoot(), "tmp_xImOef9dOd44");
|
||||
|
@ -60,7 +60,7 @@ const execYarnLink = (params: { targetModuleName?: string; cwd: string }) => {
|
||||
});
|
||||
};
|
||||
|
||||
const testAppNames = ["keycloakify-demo-app"] as const;
|
||||
const testAppNames = [process.argv[2] ?? "keycloakify-demo-app"] as const;
|
||||
|
||||
const getTestAppPath = (testAppName: typeof testAppNames[number]) => pathJoin(keycloakifyDirPath, "..", testAppName);
|
||||
|
||||
|
@ -1,7 +0,0 @@
|
||||
import { Octokit } from "@octokit/rest";
|
||||
|
||||
export function createOctokit(params: { github_token: string }) {
|
||||
const { github_token } = params;
|
||||
|
||||
return new Octokit({ ...(github_token !== "" ? { "auth": github_token } : {}) });
|
||||
}
|
@ -15,6 +15,7 @@ import { LoginUpdateProfile } from "./LoginUpdateProfile";
|
||||
import { LoginIdpLinkConfirm } from "./LoginIdpLinkConfirm";
|
||||
import { LoginPageExpired } from "./LoginPageExpired";
|
||||
import { LoginIdpLinkEmail } from "./LoginIdpLinkEmail";
|
||||
import { LoginConfigTotp } from "./LoginConfigTotp";
|
||||
|
||||
export const KcApp = memo(({ kcContext, ...props }: { kcContext: KcContextBase } & KcProps) => {
|
||||
switch (kcContext.pageId) {
|
||||
@ -46,5 +47,7 @@ export const KcApp = memo(({ kcContext, ...props }: { kcContext: KcContextBase }
|
||||
return <LoginIdpLinkEmail {...{ kcContext, ...props }} />;
|
||||
case "login-page-expired.ftl":
|
||||
return <LoginPageExpired {...{ kcContext, ...props }} />;
|
||||
case "login-config-totp.ftl":
|
||||
return <LoginConfigTotp {...{ kcContext, ...props }} />;
|
||||
}
|
||||
});
|
||||
|
183
src/lib/components/LoginConfigTotp.tsx
Normal file
183
src/lib/components/LoginConfigTotp.tsx
Normal file
@ -0,0 +1,183 @@
|
||||
import { memo } from "react";
|
||||
import { Template } from "./Template";
|
||||
import type { KcProps } from "./KcProps";
|
||||
import type { KcContextBase } from "../getKcContext/KcContextBase";
|
||||
import { getMsg } from "../i18n";
|
||||
import { useCssAndCx } from "tss-react";
|
||||
|
||||
export const LoginConfigTotp = memo(({ kcContext, ...props }: { kcContext: KcContextBase.LoginConfigTotp } & KcProps) => {
|
||||
const { url, isAppInitiatedAction, totp, mode, messagesPerField } = kcContext;
|
||||
|
||||
const { cx } = useCssAndCx();
|
||||
|
||||
const { msg, msgStr } = getMsg(kcContext);
|
||||
const algToKeyUriAlg: Record<KcContextBase.LoginConfigTotp["totp"]["policy"]["algorithm"], string> = {
|
||||
HmacSHA1: "SHA1",
|
||||
HmacSHA256: "SHA256",
|
||||
HmacSHA512: "SHA512",
|
||||
};
|
||||
|
||||
return (
|
||||
<Template
|
||||
{...{ kcContext, ...props }}
|
||||
doFetchDefaultThemeResources={true}
|
||||
headerNode={msg("loginTotpTitle")}
|
||||
formNode={
|
||||
<>
|
||||
<ol id="kc-totp-settings">
|
||||
<li>
|
||||
<p>{msg("loginTotpStep1")}</p>
|
||||
|
||||
<ul id="kc-totp-supported-apps">
|
||||
{totp.policy.supportedApplications.map(app => (
|
||||
<li>{app}</li>
|
||||
))}
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
{mode && mode == "manual" ? (
|
||||
<>
|
||||
<li>
|
||||
<p>{msg("loginTotpManualStep2")}</p>
|
||||
<p>
|
||||
<span id="kc-totp-secret-key">{totp.totpSecretEncoded}</span>
|
||||
</p>
|
||||
<p>
|
||||
<a href={totp.qrUrl} id="mode-barcode">
|
||||
{msg("loginTotpScanBarcode")}
|
||||
</a>
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>{msg("loginTotpManualStep3")}</p>
|
||||
<p>
|
||||
<ul>
|
||||
<li id="kc-totp-type">
|
||||
{msg("loginTotpType")}: {msg(`loginTotp.${totp.policy.type}`)}
|
||||
</li>
|
||||
<li id="kc-totp-algorithm">
|
||||
{msg("loginTotpAlgorithm")}: {algToKeyUriAlg?.[totp.policy.algorithm] ?? totp.policy.algorithm}
|
||||
</li>
|
||||
<li id="kc-totp-digits">
|
||||
{msg("loginTotpDigits")}: {totp.policy.digits}
|
||||
</li>
|
||||
{totp.policy.type === "totp" ? (
|
||||
<li id="kc-totp-period">
|
||||
{msg("loginTotpInterval")}: {totp.policy.period}
|
||||
</li>
|
||||
) : (
|
||||
<li id="kc-totp-counter">
|
||||
{msg("loginTotpCounter")}: {totp.policy.initialCounter}
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</p>
|
||||
</li>
|
||||
</>
|
||||
) : (
|
||||
<li>
|
||||
<p>{msg("loginTotpStep2")}</p>
|
||||
<img id="kc-totp-secret-qr-code" src={`data:image/png;base64, ${totp.totpSecretQrCode}`} alt="Figure: Barcode" />
|
||||
<br />
|
||||
<p>
|
||||
<a href={totp.manualUrl} id="mode-manual">
|
||||
{msg("loginTotpUnableToScan")}
|
||||
</a>
|
||||
</p>
|
||||
</li>
|
||||
)}
|
||||
<li>
|
||||
<p>{msg("loginTotpStep3")}</p>
|
||||
<p>{msg("loginTotpStep3DeviceName")}</p>
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<form action={url.loginAction} className={cx(props.kcFormClass)} id="kc-totp-settings-form" method="post">
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<label htmlFor="totp" className={cx(props.kcLabelClass)}>
|
||||
{msg("authenticatorCode")}
|
||||
</label>{" "}
|
||||
<span className="required">*</span>
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="text"
|
||||
id="totp"
|
||||
name="totp"
|
||||
autoComplete="off"
|
||||
className={cx(props.kcInputClass)}
|
||||
aria-invalid={messagesPerField.existsError("totp")}
|
||||
/>
|
||||
|
||||
{messagesPerField.existsError("totp") && (
|
||||
<span id="input-error-otp-code" className={cx(props.kcInputErrorMessageClass)} aria-live="polite">
|
||||
{messagesPerField.get("totp")}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<input type="hidden" id="totpSecret" name="totpSecret" value={totp.totpSecret} />
|
||||
{mode && <input type="hidden" id="mode" value={mode} />}
|
||||
</div>
|
||||
|
||||
<div className={cx(props.kcFormGroupClass)}>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<label htmlFor="userLabel" className={cx(props.kcLabelClass)}>
|
||||
{msg("loginTotpDeviceName")}
|
||||
</label>{" "}
|
||||
{totp.otpCredentials.length >= 1 && <span className="required">*</span>}
|
||||
</div>
|
||||
<div className={cx(props.kcInputWrapperClass)}>
|
||||
<input
|
||||
type="text"
|
||||
id="userLabel"
|
||||
name="userLabel"
|
||||
autoComplete="off"
|
||||
className={cx(props.kcInputClass)}
|
||||
aria-invalid={messagesPerField.existsError("userLabel")}
|
||||
/>
|
||||
{messagesPerField.existsError("userLabel") && (
|
||||
<span id="input-error-otp-label" className={cx(props.kcInputErrorMessageClass)} aria-live="polite">
|
||||
{messagesPerField.get("userLabel")}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isAppInitiatedAction ? (
|
||||
<>
|
||||
<input
|
||||
type="submit"
|
||||
className={cx(props.kcButtonClass, props.kcButtonPrimaryClass, props.kcButtonLargeClass)}
|
||||
id="saveTOTPBtn"
|
||||
value={msgStr("doSubmit")}
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className={cx(
|
||||
props.kcButtonClass,
|
||||
props.kcButtonDefaultClass,
|
||||
props.kcButtonLargeClass,
|
||||
props.kcButtonLargeClass,
|
||||
)}
|
||||
id="cancelTOTPBtn"
|
||||
name="cancel-aia"
|
||||
value="true"
|
||||
>
|
||||
${msg("doCancel")}
|
||||
</button>
|
||||
</>
|
||||
) : (
|
||||
<input
|
||||
type="submit"
|
||||
className={cx(props.kcButtonClass, props.kcButtonPrimaryClass, props.kcButtonLargeClass)}
|
||||
id="saveTOTPBtn"
|
||||
value={msgStr("doSubmit")}
|
||||
/>
|
||||
)}
|
||||
</form>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
});
|
@ -24,7 +24,8 @@ export type KcContextBase =
|
||||
| KcContextBase.LoginUpdateProfile
|
||||
| KcContextBase.LoginIdpLinkConfirm
|
||||
| KcContextBase.LoginIdpLinkEmail
|
||||
| KcContextBase.LoginPageExpired;
|
||||
| KcContextBase.LoginPageExpired
|
||||
| KcContextBase.LoginConfigTotp;
|
||||
|
||||
export declare namespace KcContextBase {
|
||||
export type Common = {
|
||||
@ -52,9 +53,9 @@ export declare namespace KcContextBase {
|
||||
currentLanguageTag: KcLanguageTag;
|
||||
};
|
||||
auth?: {
|
||||
showUsername: boolean;
|
||||
showResetCredentials: boolean;
|
||||
showTryAnotherWayLink: boolean;
|
||||
showUsername?: boolean;
|
||||
showResetCredentials?: boolean;
|
||||
showTryAnotherWayLink?: boolean;
|
||||
attemptedUsername?: string;
|
||||
};
|
||||
scripts: string[];
|
||||
@ -223,6 +224,34 @@ export declare namespace KcContextBase {
|
||||
export type LoginPageExpired = Common & {
|
||||
pageId: "login-page-expired.ftl";
|
||||
};
|
||||
|
||||
export type LoginConfigTotp = Common & {
|
||||
pageId: "login-config-totp.ftl";
|
||||
mode?: "qr" | "manual" | undefined | null;
|
||||
totp: {
|
||||
totpSecretEncoded: string;
|
||||
qrUrl: string;
|
||||
policy: {
|
||||
supportedApplications: string[];
|
||||
algorithm: "HmacSHA1" | "HmacSHA256" | "HmacSHA512";
|
||||
digits: number;
|
||||
lookAheadWindow: number;
|
||||
} & (
|
||||
| {
|
||||
type: "totp";
|
||||
period: number;
|
||||
}
|
||||
| {
|
||||
type: "hotp";
|
||||
initialCounter: number;
|
||||
}
|
||||
);
|
||||
totpSecretQrCode: string;
|
||||
manualUrl: string;
|
||||
totpSecret: string;
|
||||
otpCredentials: { id: string; userLabel: string }[];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export type Attribute = {
|
||||
|
@ -387,4 +387,25 @@ export const kcContextMocks: KcContextBase[] = [
|
||||
"username": "anUsername",
|
||||
},
|
||||
}),
|
||||
id<KcContextBase.LoginConfigTotp>({
|
||||
...kcContextCommonMock,
|
||||
"pageId": "login-config-totp.ftl",
|
||||
totp: {
|
||||
totpSecretEncoded: "KVVF G2BY N4YX S6LB IUYT K2LH IFYE 4SBV",
|
||||
qrUrl: "#",
|
||||
totpSecretQrCode:
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAPYAAAD2AQAAAADNaUdlAAACM0lEQVR4Xu3OIZJgOQwDUDFd2UxiurLAVnnbHw4YGDKtSiWOn4Gxf81//7r/+q8b4HfLGBZDK9d85NmNR+sB42sXvOYrN5P1DcgYYFTGfOlbzE8gzwy3euweGizw7cfdl34/GRhlkxjKNV+5AebPXPORX1JuB9x8ZfbyyD2y1krWAKsbMq1HnqQDaLfa77p4+MqvzEGSqvSAD/2IHW2yHaigR9tX3m8dDIYGcNf3f+gDpVBZbZU77zyJ6Rlcy+qoTMG887KAPD9hsh6a1Sv3gJUHGHUAxSMzj7zqDDe7Phmt2eG+8UsMxjRGm816MAO+8VMl1R1jGHOrZB/5Zo/WXAPgxixm9Mo96vDGrM1eOto8c4Ax4wF437mifOXlpiPzCnN7Y9l95NnEMxgMY9AAGA8fucH14Y1aVb6N/cqrmyh0BVht7k1e+bU8LK0Cg5vmVq9c5vHIjOfqxDIfeTraNVTwewa4wVe+SW5N+uP1qACeudUZbqGOfA6VZV750Noq2Xx3kpveV44ZelSV1V7KFHzkWyVrrlUwG0Pl9pWnoy3vsQoME6vKI69i5osVgwWzHT7zjmJtMcNUSVn1oYMd7ZodbgowZl45VG0uVuLPUr1yc79uaQBag/mqR34xhlWyHm1prplHboCWdZ4TeZjsK8+dI+jbz1C5hl65mcpgB5dhcj8+dGO+0Ko68+lD37JDD83dpDLzzK+TrQyaVwGj6pUboGV+7+AyN8An/pf84/7rv/4/1l4OCc/1BYMAAAAASUVORK5CYII=",
|
||||
manualUrl: "#",
|
||||
totpSecret: "G4nsI8lQagRMUchH8jEG",
|
||||
otpCredentials: [],
|
||||
policy: {
|
||||
supportedApplications: ["FreeOTP", "Google Authenticator"],
|
||||
algorithm: "HmacSHA1",
|
||||
digits: 6,
|
||||
lookAheadWindow: 1,
|
||||
type: "totp",
|
||||
period: 30,
|
||||
},
|
||||
},
|
||||
}),
|
||||
];
|
||||
|
4732
src/lib/i18n/generated_kcMessages/18.0.1/account.ts
Normal file
4732
src/lib/i18n/generated_kcMessages/18.0.1/account.ts
Normal file
File diff suppressed because it is too large
Load Diff
283
src/lib/i18n/generated_kcMessages/18.0.1/admin.ts
Normal file
283
src/lib/i18n/generated_kcMessages/18.0.1/admin.ts
Normal file
@ -0,0 +1,283 @@
|
||||
//This code was automatically generated by running dist/bin/generate-i18n-messages.js
|
||||
//PLEASE DO NOT EDIT MANUALLY
|
||||
|
||||
/* spell-checker: disable */
|
||||
export const kcMessages = {
|
||||
"ca": {
|
||||
"invalidPasswordHistoryMessage": "Contrasenya incorrecta: no pot ser igual a cap de les últimes {0} contrasenyes.",
|
||||
"invalidPasswordMinDigitsMessage": "Contraseña incorrecta: debe contener al menos {0} caracteres numéricos.",
|
||||
"invalidPasswordMinLengthMessage": "Contrasenya incorrecta: longitud mínima {0}.",
|
||||
"invalidPasswordMinLowerCaseCharsMessage": "Contrasenya incorrecta: ha de contenir almenys {0} lletres minúscules.",
|
||||
"invalidPasswordMinSpecialCharsMessage": "Contrasenya incorrecta: ha de contenir almenys {0} caràcters especials.",
|
||||
"invalidPasswordMinUpperCaseCharsMessage": "Contrasenya incorrecta: ha de contenir almenys {0} lletres majúscules.",
|
||||
"invalidPasswordNotUsernameMessage": "Contrasenya incorrecta: no pot ser igual al nom d'usuari.",
|
||||
"invalidPasswordRegexPatternMessage": "Contrasenya incorrecta: no compleix l'expressió regular.",
|
||||
},
|
||||
"de": {
|
||||
"invalidPasswordMinLengthMessage": "Ungültiges Passwort: muss mindestens {0} Zeichen beinhalten.",
|
||||
"invalidPasswordMinLowerCaseCharsMessage": "Ungültiges Passwort: muss mindestens {0} Kleinbuchstaben beinhalten.",
|
||||
"invalidPasswordMinDigitsMessage": "Ungültiges Passwort: muss mindestens {0} Ziffern beinhalten.",
|
||||
"invalidPasswordMinUpperCaseCharsMessage": "Ungültiges Passwort: muss mindestens {0} Großbuchstaben beinhalten.",
|
||||
"invalidPasswordMinSpecialCharsMessage": "Ungültiges Passwort: muss mindestens {0} Sonderzeichen beinhalten.",
|
||||
"invalidPasswordNotUsernameMessage": "Ungültiges Passwort: darf nicht identisch mit dem Benutzernamen sein.",
|
||||
"invalidPasswordNotEmailMessage": "Ungültiges Passwort: darf nicht identisch mit der E-Mail-Adresse sein.",
|
||||
"invalidPasswordRegexPatternMessage": "Ungültiges Passwort: stimmt nicht mit Regex-Muster überein.",
|
||||
"invalidPasswordHistoryMessage": "Ungültiges Passwort: darf nicht identisch mit einem der letzten {0} Passwörter sein.",
|
||||
"invalidPasswordBlacklistedMessage": "Ungültiges Passwort: Passwort ist zu bekannt und auf der schwarzen Liste.",
|
||||
"invalidPasswordGenericMessage": "Ungültiges Passwort: neues Passwort erfüllt die Passwort-Anforderungen nicht.",
|
||||
},
|
||||
"en": {
|
||||
"invalidPasswordMinLengthMessage": "Invalid password: minimum length {0}.",
|
||||
"invalidPasswordMaxLengthMessage": "Invalid password: maximum length {0}.",
|
||||
"invalidPasswordMinLowerCaseCharsMessage": "Invalid password: must contain at least {0} lower case characters.",
|
||||
"invalidPasswordMinDigitsMessage": "Invalid password: must contain at least {0} numerical digits.",
|
||||
"invalidPasswordMinUpperCaseCharsMessage": "Invalid password: must contain at least {0} upper case characters.",
|
||||
"invalidPasswordMinSpecialCharsMessage": "Invalid password: must contain at least {0} special characters.",
|
||||
"invalidPasswordNotUsernameMessage": "Invalid password: must not be equal to the username.",
|
||||
"invalidPasswordNotEmailMessage": "Invalid password: must not be equal to the email.",
|
||||
"invalidPasswordRegexPatternMessage": "Invalid password: fails to match regex pattern(s).",
|
||||
"invalidPasswordHistoryMessage": "Invalid password: must not be equal to any of last {0} passwords.",
|
||||
"invalidPasswordBlacklistedMessage": "Invalid password: password is blacklisted.",
|
||||
"invalidPasswordGenericMessage": "Invalid password: new password does not match password policies.",
|
||||
"ldapErrorEditModeMandatory": "Edit Mode is mandatory",
|
||||
"ldapErrorInvalidCustomFilter": 'Custom configured LDAP filter does not start with "(" or does not end with ")".',
|
||||
"ldapErrorConnectionTimeoutNotNumber": "Connection Timeout must be a number",
|
||||
"ldapErrorReadTimeoutNotNumber": "Read Timeout must be a number",
|
||||
"ldapErrorMissingClientId": "Client ID needs to be provided in config when Realm Roles Mapping is not used.",
|
||||
"ldapErrorCantPreserveGroupInheritanceWithUIDMembershipType":
|
||||
"Not possible to preserve group inheritance and use UID membership type together.",
|
||||
"ldapErrorCantWriteOnlyForReadOnlyLdap": "Can not set write only when LDAP provider mode is not WRITABLE",
|
||||
"ldapErrorCantWriteOnlyAndReadOnly": "Can not set write-only and read-only together",
|
||||
"ldapErrorCantEnableStartTlsAndConnectionPooling": "Can not enable both StartTLS and connection pooling.",
|
||||
"ldapErrorCantEnableUnsyncedAndImportOff": "Can not disable Importing users when LDAP provider mode is UNSYNCED",
|
||||
"ldapErrorMissingGroupsPathGroup": "Groups path group does not exist - please create the group on specified path first",
|
||||
"ldapErrorValidatePasswordPolicyAvailableForWritableOnly": "Validate Password Policy is applicable only with WRITABLE edit mode",
|
||||
"clientRedirectURIsFragmentError": "Redirect URIs must not contain an URI fragment",
|
||||
"clientRootURLFragmentError": "Root URL must not contain an URL fragment",
|
||||
"clientRootURLIllegalSchemeError": "Root URL uses an illegal scheme",
|
||||
"clientBaseURLIllegalSchemeError": "Base URL uses an illegal scheme",
|
||||
"backchannelLogoutUrlIllegalSchemeError": "Backchannel logout URL uses an illegal scheme",
|
||||
"clientRedirectURIsIllegalSchemeError": "A redirect URI uses an illegal scheme",
|
||||
"clientBaseURLInvalid": "Base URL is not a valid URL",
|
||||
"clientRootURLInvalid": "Root URL is not a valid URL",
|
||||
"clientRedirectURIsInvalid": "A redirect URI is not a valid URI",
|
||||
"backchannelLogoutUrlIsInvalid": "Backchannel logout URL is not a valid URL",
|
||||
"pairwiseMalformedClientRedirectURI": "Client contained an invalid redirect URI.",
|
||||
"pairwiseClientRedirectURIsMissingHost": "Client redirect URIs must contain a valid host component.",
|
||||
"pairwiseClientRedirectURIsMultipleHosts":
|
||||
"Without a configured Sector Identifier URI, client redirect URIs must not contain multiple host components.",
|
||||
"pairwiseMalformedSectorIdentifierURI": "Malformed Sector Identifier URI.",
|
||||
"pairwiseFailedToGetRedirectURIs": "Failed to get redirect URIs from the Sector Identifier URI.",
|
||||
"pairwiseRedirectURIsMismatch": "Client redirect URIs does not match redirect URIs fetched from the Sector Identifier URI.",
|
||||
"duplicatedJwksSettings": 'The "Use JWKS" switch and the switch "Use JWKS URL" cannot be ON at the same time.',
|
||||
"error-invalid-value": "Invalid value.",
|
||||
"error-invalid-blank": "Please specify value.",
|
||||
"error-empty": "Please specify value.",
|
||||
"error-invalid-length": "Attribute {0} must have a length between {1} and {2}.",
|
||||
"error-invalid-length-too-short": "Attribute {0} must have minimal length of {1}.",
|
||||
"error-invalid-length-too-long": "Attribute {0} must have maximal length of {2}.",
|
||||
"error-invalid-email": "Invalid email address.",
|
||||
"error-invalid-number": "Invalid number.",
|
||||
"error-number-out-of-range": "Attribute {0} must be a number between {1} and {2}.",
|
||||
"error-number-out-of-range-too-small": "Attribute {0} must have minimal value of {1}.",
|
||||
"error-number-out-of-range-too-big": "Attribute {0} must have maximal value of {2}.",
|
||||
"error-pattern-no-match": "Invalid value.",
|
||||
"error-invalid-uri": "Invalid URL.",
|
||||
"error-invalid-uri-scheme": "Invalid URL scheme.",
|
||||
"error-invalid-uri-fragment": "Invalid URL fragment.",
|
||||
"error-user-attribute-required": "Please specify attribute {0}.",
|
||||
"error-invalid-date": "Attribute {0} is invalid date.",
|
||||
"error-user-attribute-read-only": "Attribute {0} is read only.",
|
||||
"error-username-invalid-character": "{0} contains invalid character.",
|
||||
"error-person-name-invalid-character": "{0} contains invalid character.",
|
||||
},
|
||||
"es": {
|
||||
"invalidPasswordMinLengthMessage": "Contraseña incorrecta: longitud mínima {0}.",
|
||||
"invalidPasswordMinLowerCaseCharsMessage": "Contraseña incorrecta: debe contener al menos {0} letras minúsculas.",
|
||||
"invalidPasswordMinDigitsMessage": "Contraseña incorrecta: debe contener al menos {0} caracteres numéricos.",
|
||||
"invalidPasswordMinUpperCaseCharsMessage": "Contraseña incorrecta: debe contener al menos {0} letras mayúsculas.",
|
||||
"invalidPasswordMinSpecialCharsMessage": "Contraseña incorrecta: debe contener al menos {0} caracteres especiales.",
|
||||
"invalidPasswordNotUsernameMessage": "Contraseña incorrecta: no puede ser igual al nombre de usuario.",
|
||||
"invalidPasswordRegexPatternMessage": "Contraseña incorrecta: no cumple la expresión regular.",
|
||||
"invalidPasswordHistoryMessage": "Contraseña incorrecta: no puede ser igual a ninguna de las últimas {0} contraseñas.",
|
||||
},
|
||||
"fi": {},
|
||||
"fr": {
|
||||
"invalidPasswordMinLengthMessage": "Mot de passe invalide : longueur minimale requise de {0}.",
|
||||
"invalidPasswordMinLowerCaseCharsMessage": "Mot de passe invalide : doit contenir au moins {0} lettre(s) en minuscule.",
|
||||
"invalidPasswordMinDigitsMessage": "Mot de passe invalide : doit contenir au moins {0} chiffre(s).",
|
||||
"invalidPasswordMinUpperCaseCharsMessage": "Mot de passe invalide : doit contenir au moins {0} lettre(s) en majuscule.",
|
||||
"invalidPasswordMinSpecialCharsMessage": "Mot de passe invalide : doit contenir au moins {0} caractère(s) spéciaux.",
|
||||
"invalidPasswordNotUsernameMessage": "Mot de passe invalide : ne doit pas être identique au nom d'utilisateur.",
|
||||
"invalidPasswordRegexPatternMessage": "Mot de passe invalide : ne valide pas l'expression rationnelle.",
|
||||
"invalidPasswordHistoryMessage": "Mot de passe invalide : ne doit pas être égal aux {0} derniers mot de passe.",
|
||||
},
|
||||
"it": {},
|
||||
"ja": {
|
||||
"invalidPasswordMinLengthMessage": "無効なパスワード: 最小{0}の長さが必要です。",
|
||||
"invalidPasswordMinLowerCaseCharsMessage": "無効なパスワード: 少なくとも{0}文字の小文字を含む必要があります。",
|
||||
"invalidPasswordMinDigitsMessage": "無効なパスワード: 少なくとも{0}文字の数字を含む必要があります。",
|
||||
"invalidPasswordMinUpperCaseCharsMessage": "無効なパスワード: 少なくとも{0}文字の大文字を含む必要があります。",
|
||||
"invalidPasswordMinSpecialCharsMessage": "無効なパスワード: 少なくとも{0}文字の特殊文字を含む必要があります。",
|
||||
"invalidPasswordNotUsernameMessage": "無効なパスワード: ユーザー名と同じパスワードは禁止されています。",
|
||||
"invalidPasswordRegexPatternMessage": "無効なパスワード: 正規表現パターンと一致しません。",
|
||||
"invalidPasswordHistoryMessage": "無効なパスワード: 最近の{0}パスワードのいずれかと同じパスワードは禁止されています。",
|
||||
"invalidPasswordBlacklistedMessage": "無効なパスワード: パスワードがブラックリストに含まれています。",
|
||||
"invalidPasswordGenericMessage": "無効なパスワード: 新しいパスワードはパスワード・ポリシーと一致しません。",
|
||||
"ldapErrorInvalidCustomFilter": "LDAPフィルターのカスタム設定が、「(」から開始または「)」で終了となっていません。",
|
||||
"ldapErrorConnectionTimeoutNotNumber": "接続タイムアウトは数字でなければなりません",
|
||||
"ldapErrorReadTimeoutNotNumber": "読み取りタイムアウトは数字でなければなりません",
|
||||
"ldapErrorMissingClientId": "レルムロール・マッピングを使用しない場合は、クライアントIDは設定内で提供される必要があります。",
|
||||
"ldapErrorCantPreserveGroupInheritanceWithUIDMembershipType":
|
||||
"グループの継承を維持することと、UIDメンバーシップ・タイプを使用することは同時にできません。",
|
||||
"ldapErrorCantWriteOnlyForReadOnlyLdap": "LDAPプロバイダー・モードがWRITABLEではない場合は、write onlyを設定することはできません。",
|
||||
"ldapErrorCantWriteOnlyAndReadOnly": "write-onlyとread-onlyを一緒に設定することはできません。",
|
||||
"ldapErrorCantEnableStartTlsAndConnectionPooling": "StartTLSと接続プーリングの両方を有効にできません。",
|
||||
"clientRedirectURIsFragmentError": "リダイレクトURIにURIフラグメントを含めることはできません。",
|
||||
"clientRootURLFragmentError": "ルートURLにURLフラグメントを含めることはできません。",
|
||||
"pairwiseMalformedClientRedirectURI": "クライアントに無効なリダイレクトURIが含まれていました。",
|
||||
"pairwiseClientRedirectURIsMissingHost": "クライアントのリダイレクトURIには有効なホスト・コンポーネントが含まれている必要があります。",
|
||||
"pairwiseClientRedirectURIsMultipleHosts":
|
||||
"設定されたセレクター識別子URIがない場合は、クライアントのリダイレクトURIは複数のホスト・コンポーネントを含むことはできません。",
|
||||
"pairwiseMalformedSectorIdentifierURI": "不正なセレクター識別子URIです。",
|
||||
"pairwiseFailedToGetRedirectURIs": "セクター識別子URIからリダイレクトURIを取得できませんでした。",
|
||||
"pairwiseRedirectURIsMismatch": "クライアントのリダイレクトURIは、セクター識別子URIからフェッチされたリダイレクトURIと一致しません。",
|
||||
},
|
||||
"lt": {
|
||||
"invalidPasswordMinLengthMessage": "Per trumpas slaptažodis: mažiausias ilgis {0}.",
|
||||
"invalidPasswordMinLowerCaseCharsMessage": "Neteisingas slaptažodis: privaloma įvesti {0} mažąją raidę.",
|
||||
"invalidPasswordMinDigitsMessage": "Neteisingas slaptažodis: privaloma įvesti {0} skaitmenį.",
|
||||
"invalidPasswordMinUpperCaseCharsMessage": "Neteisingas slaptažodis: privaloma įvesti {0} didžiąją raidę.",
|
||||
"invalidPasswordMinSpecialCharsMessage": "Neteisingas slaptažodis: privaloma įvesti {0} specialų simbolį.",
|
||||
"invalidPasswordNotUsernameMessage": "Neteisingas slaptažodis: slaptažodis negali sutapti su naudotojo vardu.",
|
||||
"invalidPasswordRegexPatternMessage": "Neteisingas slaptažodis: slaptažodis netenkina regex taisyklės(ių).",
|
||||
"invalidPasswordHistoryMessage": "Neteisingas slaptažodis: slaptažodis negali sutapti su prieš tai buvusiais {0} slaptažodžiais.",
|
||||
"ldapErrorInvalidCustomFilter": 'Sukonfigūruotas LDAP filtras neprasideda "(" ir nesibaigia ")" simboliais.',
|
||||
"ldapErrorMissingClientId": "Privaloma nurodyti kliento ID kai srities rolių susiejimas nėra nenaudojamas.",
|
||||
"ldapErrorCantPreserveGroupInheritanceWithUIDMembershipType": "Grupių paveldėjimo ir UID narystės tipas kartu negali būti naudojami.",
|
||||
"ldapErrorCantWriteOnlyForReadOnlyLdap": "Negalima nustatyti rašymo rėžimo kuomet LDAP teikėjo rėžimas ne WRITABLE",
|
||||
"ldapErrorCantWriteOnlyAndReadOnly": "Negalima nustatyti tik rašyti ir tik skaityti kartu",
|
||||
"clientRedirectURIsFragmentError": "Nurodykite URI fragmentą, kurio negali būti peradresuojamuose URI adresuose",
|
||||
"clientRootURLFragmentError": "Nurodykite URL fragmentą, kurio negali būti šakniniame URL adrese",
|
||||
"pairwiseMalformedClientRedirectURI": "Klientas pateikė neteisingą nukreipimo nuorodą.",
|
||||
"pairwiseClientRedirectURIsMissingHost": "Kliento nukreipimo nuorodos privalo būti nurodytos su serverio vardo komponentu.",
|
||||
"pairwiseClientRedirectURIsMultipleHosts":
|
||||
"Kuomet nesukonfigūruotas sektoriaus identifikatoriaus URL, kliento nukreipimo nuorodos privalo talpinti ne daugiau kaip vieną skirtingą serverio vardo komponentą.",
|
||||
"pairwiseMalformedSectorIdentifierURI": "Neteisinga sektoriaus identifikatoriaus URI.",
|
||||
"pairwiseFailedToGetRedirectURIs": "Nepavyko gauti nukreipimo nuorodų iš sektoriaus identifikatoriaus URI.",
|
||||
"pairwiseRedirectURIsMismatch": "Kliento nukreipimo nuoroda neatitinka nukreipimo nuorodų iš sektoriaus identifikatoriaus URI.",
|
||||
},
|
||||
"lv": {},
|
||||
"nl": {
|
||||
"invalidPasswordMinLengthMessage": "Ongeldig wachtwoord: de minimale lengte is {0} karakters.",
|
||||
"invalidPasswordMinLowerCaseCharsMessage": "Ongeldig wachtwoord: het moet minstens {0} kleine letters bevatten.",
|
||||
"invalidPasswordMinDigitsMessage": "Ongeldig wachtwoord: het moet minstens {0} getallen bevatten.",
|
||||
"invalidPasswordMinUpperCaseCharsMessage": "Ongeldig wachtwoord: het moet minstens {0} hoofdletters bevatten.",
|
||||
"invalidPasswordMinSpecialCharsMessage": "Ongeldig wachtwoord: het moet minstens {0} speciale karakters bevatten.",
|
||||
"invalidPasswordNotUsernameMessage": "Ongeldig wachtwoord: het mag niet overeenkomen met de gebruikersnaam.",
|
||||
"invalidPasswordRegexPatternMessage": "Ongeldig wachtwoord: het voldoet niet aan het door de beheerder ingestelde patroon.",
|
||||
"invalidPasswordHistoryMessage": "Ongeldig wachtwoord: het mag niet overeen komen met een van de laatste {0} wachtwoorden.",
|
||||
"invalidPasswordGenericMessage": "Ongeldig wachtwoord: het nieuwe wachtwoord voldoet niet aan het wachtwoordbeleid.",
|
||||
"ldapErrorInvalidCustomFilter": 'LDAP filter met aangepaste configuratie start niet met "(" of eindigt niet met ")".',
|
||||
"ldapErrorConnectionTimeoutNotNumber": "Verbindingstimeout moet een getal zijn",
|
||||
"ldapErrorReadTimeoutNotNumber": "Lees-timeout moet een getal zijn",
|
||||
"ldapErrorMissingClientId": "Client ID moet ingesteld zijn als Realm Roles Mapping niet gebruikt wordt.",
|
||||
"ldapErrorCantPreserveGroupInheritanceWithUIDMembershipType": "Kan groepsovererving niet behouden bij UID-lidmaatschapstype.",
|
||||
"ldapErrorCantWriteOnlyForReadOnlyLdap": "Alleen-schrijven niet mogelijk als LDAP provider mode niet WRITABLE is",
|
||||
"ldapErrorCantWriteOnlyAndReadOnly": "Alleen-schrijven en alleen-lezen mogen niet tegelijk ingesteld zijn",
|
||||
"clientRedirectURIsFragmentError": "Redirect URIs mogen geen URI fragment bevatten",
|
||||
"clientRootURLFragmentError": "Root URL mag geen URL fragment bevatten",
|
||||
"pairwiseMalformedClientRedirectURI": "Client heeft een ongeldige redirect URI.",
|
||||
"pairwiseClientRedirectURIsMissingHost": "Client redirect URIs moeten een geldige host-component bevatten.",
|
||||
"pairwiseClientRedirectURIsMultipleHosts":
|
||||
"Zonder een geconfigureerde Sector Identifier URI mogen client redirect URIs niet meerdere host componenten hebben.",
|
||||
"pairwiseMalformedSectorIdentifierURI": "Onjuist notatie in Sector Identifier URI.",
|
||||
"pairwiseFailedToGetRedirectURIs": "Kon geen redirect URIs verkrijgen van de Sector Identifier URI.",
|
||||
"pairwiseRedirectURIsMismatch": "Client redirect URIs komen niet overeen met redict URIs ontvangen van de Sector Identifier URI.",
|
||||
},
|
||||
"no": {
|
||||
"invalidPasswordMinLengthMessage": "Ugyldig passord: minimum lengde {0}.",
|
||||
"invalidPasswordMinLowerCaseCharsMessage": "Ugyldig passord: må inneholde minst {0} små bokstaver.",
|
||||
"invalidPasswordMinDigitsMessage": "Ugyldig passord: må inneholde minst {0} sifre.",
|
||||
"invalidPasswordMinUpperCaseCharsMessage": "Ugyldig passord: må inneholde minst {0} store bokstaver.",
|
||||
"invalidPasswordMinSpecialCharsMessage": "Ugyldig passord: må inneholde minst {0} spesialtegn.",
|
||||
"invalidPasswordNotUsernameMessage": "Ugyldig passord: kan ikke være likt brukernavn.",
|
||||
"invalidPasswordRegexPatternMessage": "Ugyldig passord: tilfredsstiller ikke kravene for passord-mønster.",
|
||||
"invalidPasswordHistoryMessage": "Ugyldig passord: kan ikke være likt noen av de {0} foregående passordene.",
|
||||
"ldapErrorInvalidCustomFilter": 'Tilpasset konfigurasjon av LDAP-filter starter ikke med "(" eller slutter ikke med ")".',
|
||||
"ldapErrorMissingClientId": "KlientID må være tilgjengelig i config når sikkerhetsdomenerollemapping ikke brukes.",
|
||||
"ldapErrorCantPreserveGroupInheritanceWithUIDMembershipType": "Ikke mulig å bevare gruppearv og samtidig bruke UID medlemskapstype.",
|
||||
"ldapErrorCantWriteOnlyForReadOnlyLdap": "Kan ikke sette write-only når LDAP leverandør-modus ikke er WRITABLE",
|
||||
"ldapErrorCantWriteOnlyAndReadOnly": "Kan ikke sette både write-only og read-only",
|
||||
},
|
||||
"pl": {},
|
||||
"pt-BR": {
|
||||
"invalidPasswordMinLengthMessage": "Senha inválida: deve conter ao menos {0} caracteres.",
|
||||
"invalidPasswordMinLowerCaseCharsMessage": "Senha inválida: deve conter ao menos {0} caracteres minúsculos.",
|
||||
"invalidPasswordMinDigitsMessage": "Senha inválida: deve conter ao menos {0} digitos numéricos.",
|
||||
"invalidPasswordMinUpperCaseCharsMessage": "Senha inválida: deve conter ao menos {0} caracteres maiúsculos.",
|
||||
"invalidPasswordMinSpecialCharsMessage": "Senha inválida: deve conter ao menos {0} caracteres especiais.",
|
||||
"invalidPasswordNotUsernameMessage": "Senha inválida: não deve ser igual ao nome de usuário.",
|
||||
"invalidPasswordRegexPatternMessage": "Senha inválida: falha ao passar por padrões.",
|
||||
"invalidPasswordHistoryMessage": "Senha inválida: não deve ser igual às últimas {0} senhas.",
|
||||
"ldapErrorInvalidCustomFilter": 'Filtro LDAP não inicia com "(" ou não termina com ")".',
|
||||
"ldapErrorMissingClientId": "ID do cliente precisa ser definido na configuração quando mapeamentos de Roles do Realm não é utilizado.",
|
||||
"ldapErrorCantPreserveGroupInheritanceWithUIDMembershipType":
|
||||
"Não é possível preservar herança de grupos e usar tipo de associação de UID ao mesmo tempo.",
|
||||
"ldapErrorCantWriteOnlyForReadOnlyLdap": "Não é possível definir modo de somente escrita quando o provedor LDAP não suporta escrita",
|
||||
"ldapErrorCantWriteOnlyAndReadOnly": "Não é possível definir somente escrita e somente leitura ao mesmo tempo",
|
||||
"clientRedirectURIsFragmentError": "URIs de redirecionamento não podem conter fragmentos",
|
||||
"clientRootURLFragmentError": "URL raiz não pode conter fragmentos",
|
||||
},
|
||||
"ru": {
|
||||
"invalidPasswordMinLengthMessage": "Некорректный пароль: длина пароля должна быть не менее {0} символов(а).",
|
||||
"invalidPasswordMinDigitsMessage": "Некорректный пароль: должен содержать не менее {0} цифр(ы).",
|
||||
"invalidPasswordMinLowerCaseCharsMessage": "Некорректный пароль: пароль должен содержать не менее {0} символов(а) в нижнем регистре.",
|
||||
"invalidPasswordMinUpperCaseCharsMessage": "Некорректный пароль: пароль должен содержать не менее {0} символов(а) в верхнем регистре.",
|
||||
"invalidPasswordMinSpecialCharsMessage": "Некорректный пароль: пароль должен содержать не менее {0} спецсимволов(а).",
|
||||
"invalidPasswordNotUsernameMessage": "Некорректный пароль: пароль не должен совпадать с именем пользователя.",
|
||||
"invalidPasswordRegexPatternMessage": "Некорректный пароль: пароль не прошел проверку по регулярному выражению.",
|
||||
"invalidPasswordHistoryMessage": "Некорректный пароль: пароль не должен совпадать с последним(и) {0} паролем(ями).",
|
||||
"invalidPasswordGenericMessage": "Некорректный пароль: новый пароль не соответствует правилам пароля.",
|
||||
"ldapErrorInvalidCustomFilter": 'Сконфигурированный пользователем фильтр LDAP не должен начинаться с "(" или заканчиваться на ")".',
|
||||
"ldapErrorMissingClientId": "Client ID должен быть настроен в конфигурации, если не используется сопоставление ролей в realm.",
|
||||
"ldapErrorCantPreserveGroupInheritanceWithUIDMembershipType": "Не удалось унаследовать группу и использовать членство UID типа вместе.",
|
||||
"ldapErrorCantWriteOnlyForReadOnlyLdap": 'Невозможно установить режим "только на запись", когда LDAP провайдер не в режиме WRITABLE',
|
||||
"ldapErrorCantWriteOnlyAndReadOnly": 'Невозможно одновременно установить режимы "только на чтение" и "только на запись"',
|
||||
"clientRedirectURIsFragmentError": "URI перенаправления не должен содержать фрагмент URI",
|
||||
"clientRootURLFragmentError": "Корневой URL не должен содержать фрагмент URL ",
|
||||
"pairwiseMalformedClientRedirectURI": "Клиент содержит некорректный URI перенаправления.",
|
||||
"pairwiseClientRedirectURIsMissingHost": "URI перенаправления клиента должен содержать корректный компонент хоста.",
|
||||
"pairwiseClientRedirectURIsMultipleHosts":
|
||||
"Без конфигурации по части идентификатора URI, URI перенаправления клиента не может содержать несколько компонентов хоста.",
|
||||
"pairwiseMalformedSectorIdentifierURI": "Искаженная часть идентификатора URI.",
|
||||
"pairwiseFailedToGetRedirectURIs": "Не удалось получить идентификаторы URI перенаправления из части идентификатора URI.",
|
||||
"pairwiseRedirectURIsMismatch": "Клиент URI переадресации не соответствует URI переадресации, полученной из части идентификатора URI.",
|
||||
},
|
||||
"zh-CN": {
|
||||
"invalidPasswordMinLengthMessage": "无效的密码:最短长度 {0}.",
|
||||
"invalidPasswordMinLowerCaseCharsMessage": "无效的密码:至少包含 {0} 小写字母",
|
||||
"invalidPasswordMinDigitsMessage": "无效的密码:至少包含 {0} 个数字",
|
||||
"invalidPasswordMinUpperCaseCharsMessage": "无效的密码:最短长度 {0} 大写字母",
|
||||
"invalidPasswordMinSpecialCharsMessage": "无效的密码:最短长度 {0} 特殊字符",
|
||||
"invalidPasswordNotUsernameMessage": "无效的密码: 不可以与用户名相同",
|
||||
"invalidPasswordRegexPatternMessage": "无效的密码: 无法与正则表达式匹配",
|
||||
"invalidPasswordHistoryMessage": "无效的密码:不能与最后使用的 {0} 个密码相同",
|
||||
"ldapErrorInvalidCustomFilter": '定制的 LDAP过滤器不是以 "(" 开头或以 ")"结尾.',
|
||||
"ldapErrorConnectionTimeoutNotNumber": "Connection Timeout 必须是个数字",
|
||||
"ldapErrorMissingClientId": "当域角色映射未启用时,客户端 ID 需要指定。",
|
||||
"ldapErrorCantPreserveGroupInheritanceWithUIDMembershipType": "无法在使用UID成员类型的同时维护组继承属性。",
|
||||
"ldapErrorCantWriteOnlyForReadOnlyLdap": "当LDAP提供方不是可写模式时,无法设置只写",
|
||||
"ldapErrorCantWriteOnlyAndReadOnly": "无法同时设置只读和只写",
|
||||
"clientRedirectURIsFragmentError": "重定向URL不应包含URI片段",
|
||||
"clientRootURLFragmentError": "根URL 不应包含 URL 片段",
|
||||
"pairwiseMalformedClientRedirectURI": "客户端包含一个无效的重定向URL",
|
||||
"pairwiseClientRedirectURIsMissingHost": "客户端重定向URL需要有一个有效的主机",
|
||||
"pairwiseClientRedirectURIsMultipleHosts":
|
||||
"Without a configured Sector Identifier URI, client redirect URIs must not contain multiple host components.",
|
||||
"pairwiseMalformedSectorIdentifierURI": "Malformed Sector Identifier URI.",
|
||||
"pairwiseFailedToGetRedirectURIs": "无法从服务器获得重定向URL",
|
||||
"pairwiseRedirectURIsMismatch": "客户端的重定向URI与服务器端获取的URI配置不匹配。",
|
||||
},
|
||||
};
|
||||
/* spell-checker: enable */
|
1062
src/lib/i18n/generated_kcMessages/18.0.1/email.ts
Normal file
1062
src/lib/i18n/generated_kcMessages/18.0.1/email.ts
Normal file
File diff suppressed because it is too large
Load Diff
6063
src/lib/i18n/generated_kcMessages/18.0.1/login.ts
Normal file
6063
src/lib/i18n/generated_kcMessages/18.0.1/login.ts
Normal file
File diff suppressed because it is too large
Load Diff
@ -2,8 +2,9 @@ import "minimal-polyfills/Object.fromEntries";
|
||||
//NOTE for later: https://github.com/remarkjs/react-markdown/blob/236182ecf30bd89c1e5a7652acaf8d0bf81e6170/src/renderers.js#L7-L35
|
||||
import ReactMarkdown from "react-markdown";
|
||||
import memoize from "memoizee";
|
||||
import { kcMessages as kcMessagesBase } from "./generated_kcMessages/15.0.2/login";
|
||||
import { kcMessages as kcMessagesBase } from "./generated_kcMessages/18.0.1/login";
|
||||
import { assert } from "tsafe/assert";
|
||||
import type { Equals } from "tsafe";
|
||||
|
||||
export const kcMessages = {
|
||||
...kcMessagesBase,
|
||||
@ -30,6 +31,33 @@ export const kcMessages = {
|
||||
|
||||
export type KcLanguageTag = keyof typeof kcMessages;
|
||||
|
||||
export const kcLanguageTags = [
|
||||
"en",
|
||||
"fr",
|
||||
"ca",
|
||||
"cs",
|
||||
"da",
|
||||
"de",
|
||||
"es",
|
||||
"hu",
|
||||
"it",
|
||||
"ja",
|
||||
"lt",
|
||||
"nl",
|
||||
"no",
|
||||
"pl",
|
||||
"pt-BR",
|
||||
"ru",
|
||||
"sk",
|
||||
"sv",
|
||||
"tr",
|
||||
"zh-CN",
|
||||
"fi",
|
||||
"lv",
|
||||
] as const;
|
||||
|
||||
assert<Equals<KcLanguageTag, typeof kcLanguageTags[number]>>();
|
||||
|
||||
type KcContextLike = { locale?: { currentLanguageTag: KcLanguageTag } };
|
||||
|
||||
export function getCurrentKcLanguageTag(kcContext: KcContextLike) {
|
||||
|
@ -4,6 +4,7 @@ export * from "./i18n";
|
||||
|
||||
export { useDownloadTerms } from "./components/Terms";
|
||||
|
||||
export * from "./components/KcApp";
|
||||
export * from "./components/KcProps";
|
||||
export * from "./keycloakJsAdapter";
|
||||
export * from "./useFormValidationSlice";
|
||||
|
@ -44,8 +44,9 @@ export declare namespace keycloak_js {
|
||||
export function createKeycloakAdapter(params: {
|
||||
keycloakInstance: keycloak_js.KeycloakInstance;
|
||||
transformUrlBeforeRedirect(url: string): string;
|
||||
getRedirectMethod?: () => "overwrite location.href" | "location.replace";
|
||||
}): keycloak_js.KeycloakAdapter {
|
||||
const { keycloakInstance, transformUrlBeforeRedirect } = params;
|
||||
const { keycloakInstance, transformUrlBeforeRedirect, getRedirectMethod = () => "overwrite location.href" } = params;
|
||||
|
||||
const neverResolvingPromise: keycloak_js.KeycloakPromise<void, void> = Object.defineProperties(new Promise(() => {}), {
|
||||
"success": { "value": () => {} },
|
||||
@ -54,25 +55,50 @@ export function createKeycloakAdapter(params: {
|
||||
|
||||
return {
|
||||
"login": options => {
|
||||
window.location.href = transformUrlBeforeRedirect(keycloakInstance.createLoginUrl(options));
|
||||
const newHref = transformUrlBeforeRedirect(keycloakInstance.createLoginUrl(options));
|
||||
switch (getRedirectMethod()) {
|
||||
case "location.replace":
|
||||
window.location.replace(newHref);
|
||||
break;
|
||||
case "overwrite location.href":
|
||||
window.location.href = newHref;
|
||||
break;
|
||||
}
|
||||
return neverResolvingPromise;
|
||||
},
|
||||
"register": options => {
|
||||
const newHref = transformUrlBeforeRedirect(keycloakInstance.createRegisterUrl(options));
|
||||
switch (getRedirectMethod()) {
|
||||
case "location.replace":
|
||||
window.location.replace(newHref);
|
||||
break;
|
||||
case "overwrite location.href":
|
||||
window.location.href = newHref;
|
||||
break;
|
||||
}
|
||||
|
||||
return neverResolvingPromise;
|
||||
},
|
||||
"logout": options => {
|
||||
window.location.replace(transformUrlBeforeRedirect(keycloakInstance.createLogoutUrl(options)));
|
||||
return neverResolvingPromise;
|
||||
},
|
||||
"register": options => {
|
||||
window.location.href = transformUrlBeforeRedirect(keycloakInstance.createRegisterUrl(options));
|
||||
|
||||
return neverResolvingPromise;
|
||||
},
|
||||
"accountManagement": () => {
|
||||
var accountUrl = transformUrlBeforeRedirect(keycloakInstance.createAccountUrl());
|
||||
if (typeof accountUrl !== "undefined") {
|
||||
window.location.href = accountUrl;
|
||||
} else {
|
||||
const accountUrl = transformUrlBeforeRedirect(keycloakInstance.createAccountUrl());
|
||||
|
||||
if (accountUrl === "undefined") {
|
||||
throw new Error("Not supported by the OIDC server");
|
||||
}
|
||||
|
||||
switch (getRedirectMethod()) {
|
||||
case "location.replace":
|
||||
window.location.replace(accountUrl);
|
||||
break;
|
||||
case "overwrite location.href":
|
||||
window.location.href = accountUrl;
|
||||
break;
|
||||
}
|
||||
|
||||
return neverResolvingPromise;
|
||||
},
|
||||
"redirectUri": options => {
|
||||
|
@ -313,6 +313,9 @@ export function useFormValidationSlice(params: {
|
||||
};
|
||||
passwordRequired: boolean;
|
||||
realm: { registrationEmailAsUsername: boolean };
|
||||
locale?: {
|
||||
currentLanguageTag: KcLanguageTag;
|
||||
};
|
||||
};
|
||||
/** NOTE: Try to avoid passing a new ref every render for better performances. */
|
||||
passwordValidators?: Validators;
|
||||
@ -382,6 +385,7 @@ export function useFormValidationSlice(params: {
|
||||
"profile": {
|
||||
"attributes": attributesWithPassword,
|
||||
},
|
||||
"locale": kcContext.locale,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -8,7 +8,7 @@ generateKeycloakThemeResources({
|
||||
"themeName": "keycloakify-demo-app",
|
||||
"reactAppBuildDirPath": pathJoin(sampleReactProjectDirPath, "build"),
|
||||
"keycloakThemeBuildingDirPath": pathJoin(sampleReactProjectDirPath, "build_keycloak_theme"),
|
||||
"keycloakThemeEmailDirPath": pathJoin(sampleReactProjectDirPath, "keycloak_theme_email"),
|
||||
"keycloakThemeEmailDirPath": pathJoin(sampleReactProjectDirPath, "keycloak_email"),
|
||||
"urlPathname": "/keycloakify-demo-app/",
|
||||
"urlOrigin": undefined,
|
||||
"extraPagesId": ["my-custom-page.ftl"],
|
||||
|
Reference in New Issue
Block a user