Feat sml-post-form.ftl #277
This commit is contained in:
@ -21,7 +21,8 @@ export const loginThemePageIds = [
|
||||
"update-user-profile.ftl",
|
||||
"idp-review-user-profile.ftl",
|
||||
"update-email.ftl",
|
||||
"select-authenticator.ftl"
|
||||
"select-authenticator.ftl",
|
||||
"saml-post-form.ftl"
|
||||
] as const;
|
||||
|
||||
export const accountThemePageIds = ["password.ftl", "account.ftl"] as const;
|
||||
|
@ -27,6 +27,7 @@ const UpdateUserProfile = lazy(() => import("keycloakify/login/pages/UpdateUserP
|
||||
const IdpReviewUserProfile = lazy(() => import("keycloakify/login/pages/IdpReviewUserProfile"));
|
||||
const UpdateEmail = lazy(() => import("keycloakify/login/pages/UpdateEmail"));
|
||||
const SelectAuthenticator = lazy(() => import("keycloakify/login/pages/SelectAuthenticator"));
|
||||
const SamlPostForm = lazy(() => import("keycloakify/login/pages/SamlPostForm"));
|
||||
|
||||
export default function Fallback(props: PageProps<KcContext, I18n>) {
|
||||
const { kcContext, ...rest } = props;
|
||||
@ -81,6 +82,8 @@ export default function Fallback(props: PageProps<KcContext, I18n>) {
|
||||
return <UpdateEmail kcContext={kcContext} {...rest} />;
|
||||
case "select-authenticator.ftl":
|
||||
return <SelectAuthenticator kcContext={kcContext} {...rest} />;
|
||||
case "saml-post-form.ftl":
|
||||
return <SamlPostForm kcContext={kcContext} {...rest} />;
|
||||
}
|
||||
assert<Equals<typeof kcContext, never>>(false);
|
||||
})()}
|
||||
|
@ -32,7 +32,8 @@ export type KcContext =
|
||||
| KcContext.UpdateUserProfile
|
||||
| KcContext.IdpReviewUserProfile
|
||||
| KcContext.UpdateEmail
|
||||
| KcContext.SelectAuthenticator;
|
||||
| KcContext.SelectAuthenticator
|
||||
| KcContext.SamlPostForm;
|
||||
|
||||
export declare namespace KcContext {
|
||||
export type Common = {
|
||||
@ -85,6 +86,16 @@ export declare namespace KcContext {
|
||||
};
|
||||
};
|
||||
|
||||
export type SamlPostForm = Common & {
|
||||
pageId: "saml-post-form.ftl";
|
||||
samlPost: {
|
||||
url: string;
|
||||
SAMLRequest?: string;
|
||||
SAMLResponse?: string;
|
||||
RelayState?: string;
|
||||
};
|
||||
};
|
||||
|
||||
export type Login = Common & {
|
||||
pageId: "login.ftl";
|
||||
url: {
|
||||
@ -543,4 +554,13 @@ export declare namespace Validators {
|
||||
};
|
||||
}
|
||||
|
||||
assert<Equals<KcContext["pageId"], LoginThemePageId>>();
|
||||
{
|
||||
type Got = KcContext["pageId"];
|
||||
type Expected = LoginThemePageId;
|
||||
|
||||
type OnlyInGot = Exclude<Got, Expected>;
|
||||
type OnlyInExpected = Exclude<Expected, Got>;
|
||||
|
||||
assert<Equals<OnlyInGot, never>>();
|
||||
assert<Equals<OnlyInExpected, never>>();
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ import type { KcContext, Attribute } from "./KcContext";
|
||||
import { resourcesCommonDirPathRelativeToPublicDir, resourcesDirPathRelativeToPublicDir } from "keycloakify/bin/mockTestingResourcesPath";
|
||||
import { pathJoin } from "keycloakify/bin/tools/pathJoin";
|
||||
import { id } from "tsafe/id";
|
||||
import { assert, type Equals } from "tsafe/assert";
|
||||
import type { LoginThemePageId } from "keycloakify/bin/keycloakify/generateFtl";
|
||||
|
||||
const PUBLIC_URL = process.env["PUBLIC_URL"] ?? "/";
|
||||
|
||||
@ -243,7 +245,7 @@ const loginUrl = {
|
||||
"registrationUrl": "/auth/realms/myrealm/login-actions/registration?client_id=account&tab_id=HoAx28ja4xg"
|
||||
};
|
||||
|
||||
export const kcContextMocks: KcContext[] = [
|
||||
export const kcContextMocks = [
|
||||
id<KcContext.Login>({
|
||||
...kcContextCommonMock,
|
||||
"pageId": "login.ftl",
|
||||
@ -519,5 +521,27 @@ export const kcContextMocks: KcContext[] = [
|
||||
}
|
||||
]
|
||||
}
|
||||
}),
|
||||
id<KcContext.SamlPostForm>({
|
||||
...kcContextCommonMock,
|
||||
pageId: "saml-post-form.ftl",
|
||||
"samlPost": {
|
||||
"url": "https://saml-post-url"
|
||||
}
|
||||
}),
|
||||
id<KcContext.LoginPageExpired>({
|
||||
...kcContextCommonMock,
|
||||
pageId: "login-page-expired.ftl"
|
||||
})
|
||||
];
|
||||
|
||||
{
|
||||
type Got = (typeof kcContextMocks)[number]["pageId"];
|
||||
type Expected = LoginThemePageId;
|
||||
|
||||
type OnlyInGot = Exclude<Got, Expected>;
|
||||
type OnlyInExpected = Exclude<Expected, Got>;
|
||||
|
||||
assert<Equals<OnlyInGot, never>>();
|
||||
assert<Equals<OnlyInExpected, never>>();
|
||||
}
|
||||
|
@ -14,7 +14,9 @@ export default function RegisterUserProfile(props: PageProps<Extract<KcContext,
|
||||
classes
|
||||
});
|
||||
|
||||
const { url, messagesPerField, recaptchaRequired, recaptchaSiteKey } = kcContext;
|
||||
const { url, messagesPerField, recaptchaRequired, recaptchaSiteKey, realm } = kcContext;
|
||||
|
||||
realm.registrationEmailAsUsername;
|
||||
|
||||
const { msg, msgStr } = i18n;
|
||||
|
||||
|
27
src/login/pages/SamlPostForm.tsx
Normal file
27
src/login/pages/SamlPostForm.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import type { PageProps } from "keycloakify/login/pages/PageProps";
|
||||
import type { KcContext } from "../kcContext";
|
||||
import type { I18n } from "../i18n";
|
||||
|
||||
export default function SamlPostForm(props: PageProps<Extract<KcContext, { pageId: "saml-post-form.ftl" }>, I18n>) {
|
||||
const { kcContext, i18n, doUseDefaultCss, Template, classes } = props;
|
||||
|
||||
const { msgStr, msg } = i18n;
|
||||
|
||||
const { samlPost } = kcContext;
|
||||
|
||||
return (
|
||||
<Template {...{ kcContext, i18n, doUseDefaultCss, classes }} displayMessage={false} headerNode={msg("saml.post-form.title")}>
|
||||
<script dangerouslySetInnerHTML={{ "__html": `window.onload = function() {document.forms[0].submit()};` }} />
|
||||
<p>{msg("saml.post-form.message")}</p>
|
||||
<form name="saml-post-binding" method="post" action={samlPost.url}>
|
||||
{samlPost.SAMLRequest && <input type="hidden" name="SAMLRequest" value={samlPost.SAMLRequest} />}
|
||||
{samlPost.SAMLResponse && <input type="hidden" name="SAMLResponse" value={samlPost.SAMLResponse} />}
|
||||
{samlPost.RelayState && <input type="hidden" name="RelayState" value={samlPost.RelayState} />}
|
||||
<noscript>
|
||||
<p>{msg("saml.post-form.js-disabled")}</p>
|
||||
<input type="submit" value={msgStr("doContinue")} />
|
||||
</noscript>
|
||||
</form>
|
||||
</Template>
|
||||
);
|
||||
}
|
24
stories/login/pages/SamlPostForm.stories.tsx
Normal file
24
stories/login/pages/SamlPostForm.stories.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
import React from "react";
|
||||
import type { ComponentMeta } from "@storybook/react";
|
||||
import { createPageStory } from "../createPageStory";
|
||||
|
||||
const pageId = "saml-post-form.ftl";
|
||||
|
||||
const { PageStory } = createPageStory({ pageId });
|
||||
|
||||
const meta: ComponentMeta<any> = {
|
||||
title: `login/${pageId}`,
|
||||
component: PageStory,
|
||||
parameters: {
|
||||
viewMode: "story",
|
||||
previewTabs: {
|
||||
"storybook/docs/panel": {
|
||||
"hidden": true
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
export const Default = () => <PageStory />;
|
Reference in New Issue
Block a user