@ -5,6 +5,7 @@ import { join as pathJoin } from "path";
|
|||||||
import { objectKeys } from "tsafe/objectKeys";
|
import { objectKeys } from "tsafe/objectKeys";
|
||||||
import { ftlValuesGlobalName } from "../ftlValuesGlobalName";
|
import { ftlValuesGlobalName } from "../ftlValuesGlobalName";
|
||||||
|
|
||||||
|
// https://github.com/keycloak/keycloak/blob/main/services/src/main/java/org/keycloak/forms/login/freemarker/Templates.java
|
||||||
export const pageIds = [
|
export const pageIds = [
|
||||||
"login.ftl",
|
"login.ftl",
|
||||||
"register.ftl",
|
"register.ftl",
|
||||||
@ -21,6 +22,7 @@ export const pageIds = [
|
|||||||
"login-idp-link-email.ftl",
|
"login-idp-link-email.ftl",
|
||||||
"login-page-expired.ftl",
|
"login-page-expired.ftl",
|
||||||
"login-config-totp.ftl",
|
"login-config-totp.ftl",
|
||||||
|
"logout-confirm.ftl",
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export type PageId = typeof pageIds[number];
|
export type PageId = typeof pageIds[number];
|
||||||
|
@ -16,6 +16,7 @@ import { LoginIdpLinkConfirm } from "./LoginIdpLinkConfirm";
|
|||||||
import { LoginPageExpired } from "./LoginPageExpired";
|
import { LoginPageExpired } from "./LoginPageExpired";
|
||||||
import { LoginIdpLinkEmail } from "./LoginIdpLinkEmail";
|
import { LoginIdpLinkEmail } from "./LoginIdpLinkEmail";
|
||||||
import { LoginConfigTotp } from "./LoginConfigTotp";
|
import { LoginConfigTotp } from "./LoginConfigTotp";
|
||||||
|
import { LogoutConfirm } from "./LogoutConfirm";
|
||||||
|
|
||||||
export const KcApp = memo(({ kcContext, ...props }: { kcContext: KcContextBase } & KcProps) => {
|
export const KcApp = memo(({ kcContext, ...props }: { kcContext: KcContextBase } & KcProps) => {
|
||||||
switch (kcContext.pageId) {
|
switch (kcContext.pageId) {
|
||||||
@ -49,5 +50,7 @@ export const KcApp = memo(({ kcContext, ...props }: { kcContext: KcContextBase }
|
|||||||
return <LoginPageExpired {...{ kcContext, ...props }} />;
|
return <LoginPageExpired {...{ kcContext, ...props }} />;
|
||||||
case "login-config-totp.ftl":
|
case "login-config-totp.ftl":
|
||||||
return <LoginConfigTotp {...{ kcContext, ...props }} />;
|
return <LoginConfigTotp {...{ kcContext, ...props }} />;
|
||||||
|
case "logout-confirm.ftl":
|
||||||
|
return <LogoutConfirm {...{ kcContext, ...props }} />;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
61
src/lib/components/LogoutConfirm.tsx
Normal file
61
src/lib/components/LogoutConfirm.tsx
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
import { memo } from "react";
|
||||||
|
import { useCssAndCx } from "tss-react";
|
||||||
|
|
||||||
|
import { Template } from "./Template";
|
||||||
|
import type { KcProps } from "./KcProps";
|
||||||
|
import type { KcContextBase } from "../getKcContext/KcContextBase";
|
||||||
|
import { getMsg } from "../i18n";
|
||||||
|
|
||||||
|
export const LogoutConfirm = memo(({ kcContext, ...props }: { kcContext: KcContextBase.LogoutConfirm } & KcProps) => {
|
||||||
|
const { url, client, logoutConfirm } = kcContext;
|
||||||
|
|
||||||
|
const { cx } = useCssAndCx();
|
||||||
|
|
||||||
|
const { msg, msgStr } = getMsg(kcContext);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Template
|
||||||
|
{...{ kcContext, ...props }}
|
||||||
|
doFetchDefaultThemeResources={true}
|
||||||
|
displayMessage={false}
|
||||||
|
headerNode={msg("logoutConfirmTitle")}
|
||||||
|
formNode={
|
||||||
|
<>
|
||||||
|
<div id="kc-logout-confirm" className="content-area">
|
||||||
|
<p className="instruction">{msg("logoutConfirmHeader")}</p>
|
||||||
|
<form className="form-actions" action={url.logoutConfirmAction} method="POST">
|
||||||
|
<input type="hidden" name="session_code" value={logoutConfirm.code} />
|
||||||
|
<div className={cx(props.kcFormGroupClass)}>
|
||||||
|
<div id="kc-form-options">
|
||||||
|
<div className={cx(props.kcFormOptionsWrapperClass)}></div>
|
||||||
|
</div>
|
||||||
|
<div id="kc-form-buttons" className={cx(props.kcFormGroupClass)}>
|
||||||
|
<input
|
||||||
|
tabIndex={4}
|
||||||
|
className={cx(
|
||||||
|
props.kcButtonClass,
|
||||||
|
props.kcButtonPrimaryClass,
|
||||||
|
props.kcButtonBlockClass,
|
||||||
|
props.kcButtonLargeClass,
|
||||||
|
)}
|
||||||
|
name="confirmLogout"
|
||||||
|
id="kc-logout"
|
||||||
|
type="submit"
|
||||||
|
value={msgStr("doLogout")}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div id="kc-info-message">
|
||||||
|
{!logoutConfirm.skipLink && client.baseUrl && (
|
||||||
|
<p>
|
||||||
|
<a href={client.baseUrl} dangerouslySetInnerHTML={{ __html: msgStr("backToApplication") }} />
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
@ -25,7 +25,8 @@ export type KcContextBase =
|
|||||||
| KcContextBase.LoginIdpLinkConfirm
|
| KcContextBase.LoginIdpLinkConfirm
|
||||||
| KcContextBase.LoginIdpLinkEmail
|
| KcContextBase.LoginIdpLinkEmail
|
||||||
| KcContextBase.LoginPageExpired
|
| KcContextBase.LoginPageExpired
|
||||||
| KcContextBase.LoginConfigTotp;
|
| KcContextBase.LoginConfigTotp
|
||||||
|
| KcContextBase.LogoutConfirm;
|
||||||
|
|
||||||
export declare namespace KcContextBase {
|
export declare namespace KcContextBase {
|
||||||
export type Common = {
|
export type Common = {
|
||||||
@ -256,6 +257,20 @@ export declare namespace KcContextBase {
|
|||||||
otpCredentials: { id: string; userLabel: string }[];
|
otpCredentials: { id: string; userLabel: string }[];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type LogoutConfirm = Common & {
|
||||||
|
pageId: "logout-confirm.ftl";
|
||||||
|
url: {
|
||||||
|
logoutConfirmAction: string;
|
||||||
|
};
|
||||||
|
client: {
|
||||||
|
baseUrl?: string;
|
||||||
|
};
|
||||||
|
logoutConfirm: {
|
||||||
|
code: string;
|
||||||
|
skipLink?: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Attribute = {
|
export type Attribute = {
|
||||||
|
@ -411,4 +411,17 @@ export const kcContextMocks: KcContextBase[] = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
id<KcContextBase.LogoutConfirm>({
|
||||||
|
...kcContextCommonMock,
|
||||||
|
"pageId": "logout-confirm.ftl",
|
||||||
|
"url": {
|
||||||
|
...kcContextCommonMock.url,
|
||||||
|
"logoutConfirmAction": "Continuer?",
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"clientId": "myApp",
|
||||||
|
"baseUrl": "#",
|
||||||
|
},
|
||||||
|
"logoutConfirm": { "code": "123", skipLink: false },
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
|
@ -20,11 +20,14 @@ export const kcMessages = {
|
|||||||
"fr": {
|
"fr": {
|
||||||
...kcMessagesBase["fr"],
|
...kcMessagesBase["fr"],
|
||||||
/* spell-checker: disable */
|
/* spell-checker: disable */
|
||||||
"shouldBeEqual": "{0} doit être egale à {1}",
|
"shouldBeEqual": "{0} doit être égal à {1}",
|
||||||
"shouldBeDifferent": "{0} doit être différent de {1}",
|
"shouldBeDifferent": "{0} doit être différent de {1}",
|
||||||
"shouldMatchPattern": "Dois respecter le schéma: `/{0}/`",
|
"shouldMatchPattern": "Dois respecter le schéma: `/{0}/`",
|
||||||
"mustBeAnInteger": "Doit être un nombre entiers",
|
"mustBeAnInteger": "Doit être un nombre entier",
|
||||||
"notAValidOption": "N'est pas une option valide",
|
"notAValidOption": "N'est pas une option valide",
|
||||||
|
"logoutConfirmTitle": "Déconnexion",
|
||||||
|
"logoutConfirmHeader": "Êtes-vous sûr(e) de vouloir vous déconnecter ?",
|
||||||
|
"doLogout": "Se déconnecter",
|
||||||
/* spell-checker: enable */
|
/* spell-checker: enable */
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user