Skip to content

Commit b4449d7

Browse files
committed
Add Federated Identity screen
1 parent 35841d7 commit b4449d7

File tree

5 files changed

+81
-3
lines changed

5 files changed

+81
-3
lines changed

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "ubuntukr-keycloakify-theme",
33
"homepage": "https://github.com/ubuntu-kr/ubuntukr-keycloakify-theme",
4-
"version": "0.0.5",
4+
"version": "0.0.6",
55
"description": "Keycloak theme for Ubuntu Korea",
66
"repository": {
77
"type": "git",
@@ -26,7 +26,8 @@
2626
"extraLoginPages": [
2727
],
2828
"extraAccountPages": [
29-
"sessions.ftl"
29+
"sessions.ftl",
30+
"federatedIdentity.ftl"
3031
],
3132
"keycloakVersionDefaultAssets": "21.0.1"
3233
},

src/account/KcApp.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const Password = lazy(() => import("./pages/Password"));
1313
const MyExtraPage1 = lazy(() => import("./pages/MyExtraPage1"));
1414
const MyExtraPage2 = lazy(() => import("./pages/MyExtraPage2"));
1515
const Sessions = lazy(() => import("./pages/Sessions"));
16+
const FederatedIdentity = lazy(() => import("./pages/FederatedIdentity"));
1617
const Fallback = lazy(()=> import("keycloakify/account"));
1718

1819
const classes: PageProps<any, any>["classes"] = {
@@ -38,6 +39,7 @@ export default function App(props: { kcContext: KcContext; }) {
3839
case "my-extra-page-1.ftl": return <MyExtraPage1 {...{ kcContext, i18n, Template, classes }} doUseDefaultCss={true} />;
3940
case "my-extra-page-2.ftl": return <MyExtraPage2 {...{ kcContext, i18n, Template, classes }} doUseDefaultCss={true} />;
4041
case "sessions.ftl": return <Sessions {...{ kcContext, i18n, Template, classes }} doUseDefaultCss={true} />;
42+
case "federatedIdentity.ftl" : return <FederatedIdentity {...{ kcContext, i18n, Template, classes }} doUseDefaultCss={true} />;
4143
default: return <Fallback {...{ kcContext, i18n, classes }} Template={Template} doUseDefaultCss={true} />;
4244
}
4345
})()}

src/account/i18n.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export const { useI18n } = createUseI18n({
55
"ko": {
66
"account":"계정",
77
"authenticator":"인증기",
8-
"federatedIdentity":"소셜 로그인",
8+
"federatedIdentity":"통합 인증",
99
"sessions":"세션",
1010
"applications":"애플리케이션",
1111
"log":"로그",
@@ -34,6 +34,9 @@ export const { useI18n } = createUseI18n({
3434
"clients": "클라이언트",
3535
"doLogOutAllSessions": "모든 세션 로그아웃",
3636

37+
"federatedIdentitiesHtmlTitle": "통합 인증",
38+
"doRemove": "삭제",
39+
"doAdd": "추가",
3740
}
3841
});
3942

src/account/kcContext.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,19 @@ export type KcContextExtension =
1616
clients: string[];
1717
}[];
1818
}
19+
}
20+
| {
21+
pageId: "federatedIdentity.ftl";
22+
stateChecker: string;
23+
federatedIdentity: {
24+
identities: {
25+
userName: string;
26+
displayName: string;
27+
providerId: string;
28+
connected: boolean;
29+
}[];
30+
removeLinkPossible: boolean;
31+
}
1932
};
2033

2134
export const { kcContext } = getKcContext<KcContextExtension>({
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { clsx } from "keycloakify/tools/clsx";
2+
import type { PageProps } from "keycloakify/account/pages/PageProps";
3+
import { useGetClassName } from "keycloakify/account/lib/useGetClassName";
4+
import type { KcContext } from "../kcContext";
5+
import type { I18n } from "../i18n";
6+
import { Form, Button, Input, Card, Col, Row } from "@canonical/react-components";
7+
8+
export default function FederatedIdentity(props: PageProps<Extract<KcContext, { pageId: "federatedIdentity.ftl" }>, I18n>) {
9+
const { kcContext, i18n, doUseDefaultCss, Template, classes } = props;
10+
11+
const { getClassName } = useGetClassName({
12+
doUseDefaultCss,
13+
"classes": {
14+
...classes,
15+
"kcBodyClass": clsx(classes?.kcBodyClass, "user")
16+
}
17+
});
18+
19+
const { url, realm, messagesPerField, stateChecker, federatedIdentity } = kcContext;
20+
21+
const { msg, msgStr } = i18n;
22+
23+
return (
24+
<Template {...{ kcContext, i18n, doUseDefaultCss, classes }} active="social">
25+
26+
<h2>{msg("federatedIdentitiesHtmlTitle")}</h2>
27+
<Row>
28+
{federatedIdentity.identities.map((identity, index) => (
29+
<Col size={4}>
30+
<Card title={identity.displayName}>
31+
<h4>{identity.userName}</h4>
32+
{identity.connected && federatedIdentity.removeLinkPossible ? (
33+
<Form action={url.socialUrl} method="post">
34+
<input type="hidden" id="stateChecker" name="stateChecker" value={stateChecker} />
35+
<input type="hidden" id="action" name="action" value="remove" />
36+
<input type="hidden" id="providerId" name="providerId" value={identity.providerId!} />
37+
<Button hasIcon id={`remove-link-${identity.providerId!}`} appearance="negative">
38+
<i className="p-icon--delete"></i>
39+
<span>{msg("doRemove")}</span>
40+
</Button>
41+
</Form>
42+
) : (
43+
<Form action={url.socialUrl} method="post">
44+
<input type="hidden" id="stateChecker" name="stateChecker" value={stateChecker} />
45+
<input type="hidden" id="action" name="action" value="add" />
46+
<input type="hidden" id="providerId" name="providerId" value={identity.providerId!} />
47+
<Button hasIcon id={`remove-link-${identity.providerId!}`} appearance="positive">
48+
<i className="p-icon--plus"></i>
49+
<span>{msg("doAdd")}</span>
50+
</Button>
51+
</Form>
52+
)}
53+
</Card>
54+
</Col>
55+
))}
56+
</Row>
57+
</Template>
58+
);
59+
}

0 commit comments

Comments
 (0)