Compare commits
36 Commits
Author | SHA1 | Date | |
---|---|---|---|
fde03445e4 | |||
070828c516 | |||
1965c30135 | |||
f7bd16cb79 | |||
862ee31f1b | |||
66ead628f3 | |||
e143257b48 | |||
0b68e051e6 | |||
9557145f72 | |||
249877b9c5 | |||
ff2321fde5 | |||
1edd6e4193 | |||
bdde9162d9 | |||
99b4933536 | |||
c5caf7e0da | |||
bcc5308cfb | |||
9fb902db5c | |||
239f98aa9c | |||
f5d0511662 | |||
75582d2a26 | |||
0796b3dedf | |||
662a76bbb6 | |||
a664195625 | |||
e533e127bf | |||
346e3df009 | |||
19ba0873f5 | |||
fb4acc62c4 | |||
fd538e95ca | |||
def2d8b75b | |||
586b28af1c | |||
585c279d10 | |||
51bc65e671 | |||
ff1758cdce | |||
72a3c37e84 | |||
c99cdf5566 | |||
ad339710f1 |
6
.github/workflows/ci.yaml
vendored
6
.github/workflows/ci.yaml
vendored
@ -3,6 +3,7 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- v9
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
@ -129,10 +130,7 @@ jobs:
|
||||
echo "Can't publish on NPM, You must first create a secret called NPM_TOKEN that contains your NPM auth token. https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets"
|
||||
false
|
||||
fi
|
||||
EXTRA_ARGS=""
|
||||
if [ "$IS_PRE_RELEASE" = "true" ]; then
|
||||
EXTRA_ARGS="--tag next"
|
||||
fi
|
||||
EXTRA_ARGS="--tag v9"
|
||||
npm publish $EXTRA_ARGS
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
||||
|
18
README.md
18
README.md
@ -17,9 +17,12 @@
|
||||
<a href="https://github.com/thomasdarimont/awesome-keycloak">
|
||||
<img src="https://awesome.re/mentioned-badge.svg"/>
|
||||
</a>
|
||||
<a href="https://discord.gg/kYFZG7fQmn">
|
||||
<img src="https://img.shields.io/discord/1097708346976505977"/>
|
||||
</a>
|
||||
<p align="center">
|
||||
Check out our discord server!<br/>
|
||||
<a href="https://discord.gg/mJdYJSdcm4">
|
||||
<img src="https://dcbadge.limes.pink/api/server/kYFZG7fQmn"/>
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://www.keycloakify.dev">Home</a>
|
||||
-
|
||||
@ -38,10 +41,13 @@
|
||||
<img width="400" src="https://github.com/keycloakify/keycloakify/assets/6702424/e66d105c-c06f-47d1-8a31-a6ab09da4e80">
|
||||
</p>
|
||||
|
||||
Keycloakify is fully compatible with Keycloak 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, [~~22~~](https://github.com/keycloakify/keycloakify/issues/389#issuecomment-1822509763), **23** [and up](https://github.com/keycloakify/keycloakify/discussions/346#discussioncomment-5889791)!
|
||||
> WARNING: Do not use Keycloakify v9 if you are staring out!
|
||||
> Use the latest release candidate of Keycloakify v10 instead.
|
||||
> `yarn add keycloakify@next` See [npm](https://www.npmjs.com/package/keycloakify?activeTab=versions).
|
||||
|
||||
> NOTE: Keycloak 24 introduces [important changes](https://www.keycloak.org/docs/latest/upgrading/index.html#changes-to-freemarker-templates-to-render-pages-based-on-the-user-profile-and-realm).
|
||||
> We're actively working on incorporating them into Keycloakify.
|
||||
Keycloakify is fully compatible with Keycloak 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, [~~22~~](https://github.com/keycloakify/keycloakify/issues/389#issuecomment-1822509763), 23, 24, 25...[and beyond](https://github.com/keycloakify/keycloakify/discussions/346#discussioncomment-5889791)
|
||||
|
||||
> NOTE: Keycloakify 10 is still in realase-candidate state. [Follow progress](https://github.com/keycloakify/keycloakify/pull/538).
|
||||
|
||||
## Sponsor
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "keycloakify",
|
||||
"version": "9.6.5",
|
||||
"version": "9.7.5",
|
||||
"description": "Create Keycloak themes using React",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -113,7 +113,7 @@
|
||||
"@babel/parser": "^7.22.7",
|
||||
"@babel/types": "^7.22.5",
|
||||
"@octokit/rest": "^18.12.0",
|
||||
"cheerio": "^1.0.0-rc.5",
|
||||
"cheerio": "1.0.0-rc.5",
|
||||
"cli-select": "^1.1.2",
|
||||
"evt": "^2.4.18",
|
||||
"make-fetch-happen": "^11.0.3",
|
||||
|
@ -3,6 +3,7 @@ import type { PageProps } from "keycloakify/account/pages/PageProps";
|
||||
import type { I18n } from "keycloakify/account/i18n";
|
||||
import type { KcContext } from "./kcContext";
|
||||
import { assert, type Equals } from "tsafe/assert";
|
||||
import FederatedIdentity from "./pages/FederatedIdentity";
|
||||
|
||||
const Password = lazy(() => import("keycloakify/account/pages/Password"));
|
||||
const Account = lazy(() => import("keycloakify/account/pages/Account"));
|
||||
@ -30,6 +31,8 @@ export default function Fallback(props: PageProps<KcContext, I18n>) {
|
||||
return <Applications kcContext={kcContext} {...rest} />;
|
||||
case "log.ftl":
|
||||
return <Log kcContext={kcContext} {...rest} />;
|
||||
case "federatedIdentity.ftl":
|
||||
return <FederatedIdentity kcContext={kcContext} {...rest} />;
|
||||
}
|
||||
assert<Equals<typeof kcContext, never>>(false);
|
||||
})()}
|
||||
|
@ -23,7 +23,9 @@ export default function Template(props: TemplateProps<KcContext, I18n>) {
|
||||
`${url.resourcesPath}/css/account.css`
|
||||
],
|
||||
"htmlClassName": getClassName("kcHtmlClass"),
|
||||
"bodyClassName": clsx("admin-console", "user", getClassName("kcBodyClass"))
|
||||
"bodyClassName": clsx("admin-console", "user", getClassName("kcBodyClass")),
|
||||
"htmlLangProperty": locale?.currentLanguageTag,
|
||||
"documentTitle": i18n.msgStr("accountManagementTitle")
|
||||
});
|
||||
|
||||
if (!isReady) {
|
||||
|
@ -3,7 +3,14 @@ import { assert } from "tsafe/assert";
|
||||
import type { Equals } from "tsafe";
|
||||
import { type ThemeType } from "keycloakify/bin/constants";
|
||||
|
||||
export type KcContext = KcContext.Password | KcContext.Account | KcContext.Sessions | KcContext.Totp | KcContext.Applications | KcContext.Log;
|
||||
export type KcContext =
|
||||
| KcContext.Password
|
||||
| KcContext.Account
|
||||
| KcContext.Sessions
|
||||
| KcContext.Totp
|
||||
| KcContext.Applications
|
||||
| KcContext.Log
|
||||
| KcContext.FederatedIdentity;
|
||||
|
||||
export declare namespace KcContext {
|
||||
export type Common = {
|
||||
@ -27,6 +34,7 @@ export declare namespace KcContext {
|
||||
sessionsUrl: string;
|
||||
applicationsUrl: string;
|
||||
logUrl: string;
|
||||
logoutUrl: string;
|
||||
resourceUrl: string;
|
||||
resourcesCommonPath: string;
|
||||
resourcesPath: string;
|
||||
@ -91,15 +99,6 @@ export declare namespace KcContext {
|
||||
username?: string;
|
||||
};
|
||||
properties: Record<string, string | undefined>;
|
||||
sessions: {
|
||||
sessions: {
|
||||
ipAddress: string;
|
||||
started?: any;
|
||||
lastAccess?: any;
|
||||
expires?: any;
|
||||
clients: string[];
|
||||
}[];
|
||||
};
|
||||
};
|
||||
|
||||
export type Password = Common & {
|
||||
@ -126,11 +125,12 @@ export declare namespace KcContext {
|
||||
pageId: "sessions.ftl";
|
||||
sessions: {
|
||||
sessions: {
|
||||
ipAddress: string;
|
||||
started?: any;
|
||||
lastAccess?: any;
|
||||
expires?: any;
|
||||
expires: string;
|
||||
clients: string[];
|
||||
ipAddress: string;
|
||||
started: string;
|
||||
lastAccess: string;
|
||||
id: string;
|
||||
}[];
|
||||
};
|
||||
stateChecker: string;
|
||||
@ -193,12 +193,21 @@ export declare namespace KcContext {
|
||||
stateChecker: string;
|
||||
applications: {
|
||||
applications: {
|
||||
realmRolesAvailable: { name: string; description: string }[];
|
||||
realmRolesAvailable: {
|
||||
name: string;
|
||||
description: string;
|
||||
compositesStream?: Record<string, unknown>;
|
||||
clientRole?: boolean;
|
||||
composite?: boolean;
|
||||
id?: string;
|
||||
containerId?: string;
|
||||
attributes?: Record<string, unknown>;
|
||||
}[];
|
||||
resourceRolesAvailable: Record<
|
||||
string,
|
||||
{
|
||||
roleName: string;
|
||||
roleDescription: string;
|
||||
roleDescription?: string;
|
||||
clientName: string;
|
||||
clientId: string;
|
||||
}[]
|
||||
@ -207,41 +216,44 @@ export declare namespace KcContext {
|
||||
clientScopesGranted: string[];
|
||||
effectiveUrl?: string;
|
||||
client: {
|
||||
consentScreenText: string;
|
||||
surrogateAuthRequired: boolean;
|
||||
bearerOnly: boolean;
|
||||
id: string;
|
||||
protocolMappersStream: Record<string, unknown>;
|
||||
includeInTokenScope: boolean;
|
||||
redirectUris: string[];
|
||||
fullScopeAllowed: boolean;
|
||||
registeredNodes: Record<string, unknown>;
|
||||
enabled: boolean;
|
||||
clientAuthenticatorType: string;
|
||||
realmScopeMappingsStream: Record<string, unknown>;
|
||||
scopeMappingsStream: Record<string, unknown>;
|
||||
displayOnConsentScreen: boolean;
|
||||
clientId: string;
|
||||
rootUrl: string;
|
||||
authenticationFlowBindingOverrides: Record<string, unknown>;
|
||||
standardFlowEnabled: boolean;
|
||||
attributes: Record<string, unknown>;
|
||||
publicClient: boolean;
|
||||
alwaysDisplayInConsole: boolean;
|
||||
attributes: Record<string, unknown>;
|
||||
authenticationFlowBindingOverrides: Record<string, unknown>;
|
||||
baseUrl?: string;
|
||||
bearerOnly: boolean;
|
||||
clientAuthenticatorType: string;
|
||||
clientId: string;
|
||||
consentRequired: boolean;
|
||||
notBefore: string;
|
||||
rolesStream: Record<string, unknown>;
|
||||
protocol: string;
|
||||
dynamicScope: boolean;
|
||||
consentScreenText: string;
|
||||
description: string;
|
||||
directAccessGrantsEnabled: boolean;
|
||||
name: string;
|
||||
serviceAccountsEnabled: boolean;
|
||||
displayOnConsentScreen: boolean;
|
||||
dynamicScope: boolean;
|
||||
enabled: boolean;
|
||||
frontchannelLogout: boolean;
|
||||
nodeReRegistrationTimeout: string;
|
||||
fullScopeAllowed: boolean;
|
||||
id: string;
|
||||
implicitFlowEnabled: boolean;
|
||||
baseUrl: string;
|
||||
webOrigins: string[];
|
||||
includeInTokenScope: boolean;
|
||||
managementUrl: string;
|
||||
name?: string;
|
||||
nodeReRegistrationTimeout: string;
|
||||
notBefore: string;
|
||||
protocol: string;
|
||||
protocolMappersStream: Record<string, unknown>;
|
||||
publicClient: boolean;
|
||||
realm: Record<string, unknown>;
|
||||
realmScopeMappingsStream: Record<string, unknown>;
|
||||
redirectUris: string[];
|
||||
registeredNodes: Record<string, unknown>;
|
||||
rolesStream: Record<string, unknown>;
|
||||
rootUrl?: string;
|
||||
scopeMappingsStream: Record<string, unknown>;
|
||||
secret: string;
|
||||
serviceAccountsEnabled: boolean;
|
||||
standardFlowEnabled: boolean;
|
||||
surrogateAuthRequired: boolean;
|
||||
webOrigins: string[];
|
||||
};
|
||||
}[];
|
||||
};
|
||||
@ -254,11 +266,25 @@ export declare namespace KcContext {
|
||||
date: string | number | Date;
|
||||
event: string;
|
||||
ipAddress: string;
|
||||
client: any;
|
||||
details: any[];
|
||||
client: string;
|
||||
details: { value: string; key: string }[];
|
||||
}[];
|
||||
};
|
||||
};
|
||||
|
||||
export type FederatedIdentity = Common & {
|
||||
pageId: "federatedIdentity.ftl";
|
||||
stateChecker: string;
|
||||
federatedIdentity: {
|
||||
identities: {
|
||||
providerId: string;
|
||||
displayName: string;
|
||||
userName: string;
|
||||
connected: boolean;
|
||||
}[];
|
||||
removeLinkPossible: boolean;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -17,6 +17,7 @@ export const kcContextCommonMock: KcContext.Common = {
|
||||
"resourceUrl": "#",
|
||||
"accountUrl": "#",
|
||||
"applicationsUrl": "#",
|
||||
"logoutUrl": "#",
|
||||
"getLogoutUrl": () => "#",
|
||||
"logUrl": "#",
|
||||
"passwordUrl": "#",
|
||||
@ -156,17 +157,6 @@ export const kcContextCommonMock: KcContext.Common = {
|
||||
"css/account.css img/icon-sidebar-active.png img/logo.png resources-common/node_modules/patternfly/dist/css/patternfly.min.css resources-common/node_modules/patternfly/dist/css/patternfly-additions.min.css resources-common/node_modules/patternfly/dist/css/patternfly-additions.min.css",
|
||||
"kcButtonClass": "btn",
|
||||
"kcButtonDefaultClass": "btn-default"
|
||||
},
|
||||
"sessions": {
|
||||
"sessions": [
|
||||
{
|
||||
"ipAddress": "127.0.0.1",
|
||||
"started": new Date().toString(),
|
||||
"lastAccess": new Date().toString(),
|
||||
"expires": new Date().toString(),
|
||||
"clients": ["Chrome", "Firefox"]
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
@ -200,12 +190,12 @@ export const kcContextMocks: KcContext[] = [
|
||||
"sessions": {
|
||||
"sessions": [
|
||||
{
|
||||
...kcContextCommonMock.sessions,
|
||||
"ipAddress": "127.0.0.1",
|
||||
"started": new Date().toString(),
|
||||
"lastAccess": new Date().toString(),
|
||||
"expires": new Date().toString(),
|
||||
"clients": ["Chrome", "Firefox"]
|
||||
"clients": ["Chrome", "Firefox"],
|
||||
"id": "f8951177-817d-4a70-9c02-86d3c170fe51"
|
||||
}
|
||||
]
|
||||
},
|
||||
@ -246,9 +236,25 @@ export const kcContextMocks: KcContext[] = [
|
||||
"event": "login",
|
||||
"ipAddress": "172.17.0.1",
|
||||
"client": "security-admin-console",
|
||||
"details": ["auth_method = openid-connect, username = admin"]
|
||||
"details": [{ key: "openid-connect", value: "admin" }]
|
||||
}
|
||||
]
|
||||
}
|
||||
}),
|
||||
id<KcContext.FederatedIdentity>({
|
||||
...kcContextCommonMock,
|
||||
"stateChecker": "",
|
||||
"pageId": "federatedIdentity.ftl",
|
||||
"federatedIdentity": {
|
||||
"identities": [
|
||||
{
|
||||
"providerId": "keycloak-oidc",
|
||||
"displayName": "keycloak-oidc",
|
||||
"userName": "John",
|
||||
"connected": true
|
||||
}
|
||||
],
|
||||
"removeLinkPossible": true
|
||||
}
|
||||
})
|
||||
];
|
||||
|
@ -61,10 +61,10 @@ export default function Applications(props: PageProps<Extract<KcContext, { pageI
|
||||
|
||||
<td>
|
||||
{!isArrayWithEmptyObject(application.realmRolesAvailable) &&
|
||||
application.realmRolesAvailable.map(role => (
|
||||
application.realmRolesAvailable.map((role, index) => (
|
||||
<span key={role.name}>
|
||||
{role.description ? advancedMsg(role.description) : advancedMsg(role.name)}
|
||||
{role !== application.realmRolesAvailable[application.realmRolesAvailable.length - 1] && ", "}
|
||||
{index < application.realmRolesAvailable.length - 1 && ", "}
|
||||
</span>
|
||||
))}
|
||||
{!isArrayWithEmptyObject(application.realmRolesAvailable) && application.resourceRolesAvailable && ", "}
|
||||
|
58
src/account/pages/FederatedIdentity.tsx
Normal file
58
src/account/pages/FederatedIdentity.tsx
Normal file
@ -0,0 +1,58 @@
|
||||
import { PageProps } from "keycloakify/account";
|
||||
import { I18n } from "keycloakify/account/i18n";
|
||||
import { KcContext } from "keycloakify/account/kcContext";
|
||||
|
||||
export default function FederatedIdentity(props: PageProps<Extract<KcContext, { pageId: "federatedIdentity.ftl" }>, I18n>) {
|
||||
const { kcContext, i18n, doUseDefaultCss, classes, Template } = props;
|
||||
|
||||
const { url, federatedIdentity, stateChecker } = kcContext;
|
||||
const { msg } = i18n;
|
||||
return (
|
||||
<Template {...{ kcContext, i18n, doUseDefaultCss, classes }} active="federatedIdentity">
|
||||
<div className="main-layout social">
|
||||
<div className="row">
|
||||
<div className="col-md-10">
|
||||
<h2>{msg("federatedIdentitiesHtmlTitle")}</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div id="federated-identities">
|
||||
{federatedIdentity.identities.map(identity => (
|
||||
<div key={identity.providerId} className="row margin-bottom">
|
||||
<div className="col-sm-2 col-md-2">
|
||||
<label htmlFor={identity.providerId} className="control-label">
|
||||
{identity.displayName}
|
||||
</label>
|
||||
</div>
|
||||
<div className="col-sm-5 col-md-5">
|
||||
<input disabled className="form-control" value={identity.userName} />
|
||||
</div>
|
||||
<div className="col-sm-5 col-md-5">
|
||||
{identity.connected ? (
|
||||
federatedIdentity.removeLinkPossible && (
|
||||
<form action={url.socialUrl} method="post" className="form-inline">
|
||||
<input type="hidden" name="stateChecker" value={stateChecker} />
|
||||
<input type="hidden" name="action" value="remove" />
|
||||
<input type="hidden" name="providerId" value={identity.providerId} />
|
||||
<button id={`remove-link-${identity.providerId}`} className="btn btn-default">
|
||||
{msg("doRemove")}
|
||||
</button>
|
||||
</form>
|
||||
)
|
||||
) : (
|
||||
<form action={url.socialUrl} method="post" className="form-inline">
|
||||
<input type="hidden" name="stateChecker" value={stateChecker} />
|
||||
<input type="hidden" name="action" value="add" />
|
||||
<input type="hidden" name="providerId" value={identity.providerId} />
|
||||
<button id={`add-link-${identity.providerId}`} className="btn btn-default">
|
||||
{msg("doAdd")}
|
||||
</button>
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Template>
|
||||
);
|
||||
}
|
@ -2,7 +2,7 @@ import type { PageProps } from "keycloakify/account/pages/PageProps";
|
||||
import type { KcContext } from "../kcContext";
|
||||
import type { I18n } from "../i18n";
|
||||
import { Key } from "react";
|
||||
import { useGetClassName } from "../lib/useGetClassName";
|
||||
import { useGetClassName } from "keycloakify/account/lib/useGetClassName";
|
||||
|
||||
export default function Log(props: PageProps<Extract<KcContext, { pageId: "log.ftl" }>, I18n>) {
|
||||
const { kcContext, i18n, doUseDefaultCss, classes, Template } = props;
|
||||
|
@ -12,12 +12,9 @@ export default function Sessions(props: PageProps<Extract<KcContext, { pageId: "
|
||||
classes
|
||||
});
|
||||
|
||||
console.log({ kcContext });
|
||||
const { url, stateChecker, sessions } = kcContext;
|
||||
|
||||
const { msg } = i18n;
|
||||
console.log({ sdf: kcContext.locale?.supported });
|
||||
console.log({ asdf: "asdf" });
|
||||
return (
|
||||
<Template {...{ kcContext, i18n, doUseDefaultCss, classes }} active="sessions">
|
||||
<div className={getClassName("kcContentWrapperClass")}>
|
||||
|
@ -7,6 +7,7 @@ import { MessageKey } from "keycloakify/account/i18n/i18n";
|
||||
|
||||
export default function Totp(props: PageProps<Extract<KcContext, { pageId: "totp.ftl" }>, I18n>) {
|
||||
const { kcContext, i18n, doUseDefaultCss, Template, classes } = props;
|
||||
|
||||
const { getClassName } = useGetClassName({
|
||||
doUseDefaultCss,
|
||||
classes
|
||||
@ -78,7 +79,7 @@ export default function Totp(props: PageProps<Extract<KcContext, { pageId: "totp
|
||||
<p>{msg("totpStep1")}</p>
|
||||
|
||||
<ul id="kc-totp-supported-apps">
|
||||
{totp.supportedApplications.map(app => (
|
||||
{totp.supportedApplications?.map(app => (
|
||||
<li key={app}>{msg(app as MessageKey)}</li>
|
||||
))}
|
||||
</ul>
|
||||
@ -99,28 +100,26 @@ export default function Totp(props: PageProps<Extract<KcContext, { pageId: "totp
|
||||
</li>
|
||||
<li>
|
||||
<p>{msg("totpManualStep3")}</p>
|
||||
<p>
|
||||
<ul>
|
||||
<li id="kc-totp-type">
|
||||
{msg("totpType")}: {msg(`totp.${totp.policy.type}`)}
|
||||
<ul>
|
||||
<li id="kc-totp-type">
|
||||
{msg("totpType")}: {msg(`totp.${totp.policy.type}`)}
|
||||
</li>
|
||||
<li id="kc-totp-algorithm">
|
||||
{msg("totpAlgorithm")}: {algToKeyUriAlg?.[totp.policy.algorithm] ?? totp.policy.algorithm}
|
||||
</li>
|
||||
<li id="kc-totp-digits">
|
||||
{msg("totpDigits")}: {totp.policy.digits}
|
||||
</li>
|
||||
{totp.policy.type === "totp" ? (
|
||||
<li id="kc-totp-period">
|
||||
{msg("totpInterval")}: {totp.policy.period}
|
||||
</li>
|
||||
<li id="kc-totp-algorithm">
|
||||
{msg("totpAlgorithm")}: {algToKeyUriAlg?.[totp.policy.algorithm] ?? totp.policy.algorithm}
|
||||
) : (
|
||||
<li id="kc-totp-counter">
|
||||
{msg("totpCounter")}: {totp.policy.initialCounter}
|
||||
</li>
|
||||
<li id="kc-totp-digits">
|
||||
{msg("totpDigits")}: {totp.policy.digits}
|
||||
</li>
|
||||
{totp.policy.type === "totp" ? (
|
||||
<li id="kc-totp-period">
|
||||
{msg("totpInterval")}: {totp.policy.period}
|
||||
</li>
|
||||
) : (
|
||||
<li id="kc-totp-counter">
|
||||
{msg("totpCounter")}: {totp.policy.initialCounter}
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
</p>
|
||||
)}
|
||||
</ul>
|
||||
</li>
|
||||
</>
|
||||
) : (
|
||||
|
@ -50,6 +50,19 @@ export async function downloadBuiltinKeycloakTheme(params: { keycloakVersion: st
|
||||
});
|
||||
}
|
||||
|
||||
repatriate_common_resources_from_base_login_theme: {
|
||||
const baseLoginThemeResourceDir = pathJoin(destDirPath, "base", "login", "resources");
|
||||
|
||||
if (!fs.existsSync(baseLoginThemeResourceDir)) {
|
||||
break repatriate_common_resources_from_base_login_theme;
|
||||
}
|
||||
|
||||
transformCodebase({
|
||||
"srcDirPath": baseLoginThemeResourceDir,
|
||||
"destDirPath": pathJoin(destDirPath, "keycloak", "login", "resources")
|
||||
});
|
||||
}
|
||||
|
||||
install_and_move_to_common_resources_generated_in_keycloak_v2: {
|
||||
if (!fs.readFileSync(pathJoin(destDirPath, "keycloak", "login", "theme.properties")).toString("utf8").includes("web_modules")) {
|
||||
break install_and_move_to_common_resources_generated_in_keycloak_v2;
|
||||
@ -191,7 +204,7 @@ export async function downloadBuiltinKeycloakTheme(params: { keycloakVersion: st
|
||||
break remove_unused_lib;
|
||||
}
|
||||
|
||||
const toDeletePerfixes = ["ui-ace", "filesaver", "fileupload", "angular", "ui-ace", "pficon"];
|
||||
const toDeletePerfixes = ["ui-ace", "filesaver", "fileupload", "angular", "ui-ace"];
|
||||
|
||||
transformCodebase({
|
||||
"srcDirPath": libDirPath,
|
||||
|
@ -26,7 +26,7 @@ export function getNpmWorkspaceRootDirPath(params: { reactAppRootDirPath: string
|
||||
const cwd = pathResolve(pathJoin(...[reactAppRootDirPath, ...Array(depth).fill("..")]));
|
||||
|
||||
try {
|
||||
child_process.execSync("npm config get", { cwd: cwd });
|
||||
child_process.execSync("npm config get", { cwd, "stdio": ["pipe", "pipe", "pipe"] });
|
||||
} catch (error) {
|
||||
if (String(error).includes("ENOWORKSPACES")) {
|
||||
assert(cwd !== pathSep, "NPM workspace not found");
|
||||
|
@ -483,6 +483,9 @@
|
||||
) || (
|
||||
["masterAdminClient", "delegateForUpdate", "defaultRole"]?seq_contains(key) &&
|
||||
are_same_path(path, ["realm"])
|
||||
) || (
|
||||
"smtpConfig" == key &&
|
||||
are_same_path(path, ["realm"])
|
||||
) || (
|
||||
"error.ftl" == pageId &&
|
||||
are_same_path(path, ["realm"]) &&
|
||||
|
@ -27,7 +27,15 @@ export const loginThemePageIds = [
|
||||
"saml-post-form.ftl"
|
||||
] as const;
|
||||
|
||||
export const accountThemePageIds = ["password.ftl", "account.ftl", "sessions.ftl", "totp.ftl", "applications.ftl", "log.ftl"] as const;
|
||||
export const accountThemePageIds = [
|
||||
"password.ftl",
|
||||
"account.ftl",
|
||||
"sessions.ftl",
|
||||
"totp.ftl",
|
||||
"applications.ftl",
|
||||
"log.ftl",
|
||||
"federatedIdentity.ftl"
|
||||
] as const;
|
||||
|
||||
export type LoginThemePageId = (typeof loginThemePageIds)[number];
|
||||
export type AccountThemePageId = (typeof accountThemePageIds)[number];
|
||||
|
@ -10,8 +10,11 @@ import { getThemeSrcDirPath } from "../getThemeSrcDirPath";
|
||||
import { getThisCodebaseRootDirPath } from "../tools/getThisCodebaseRootDirPath";
|
||||
import { readThisNpmProjectVersion } from "../tools/readThisNpmProjectVersion";
|
||||
import { keycloakifyBuildOptionsForPostPostBuildScriptEnvName } from "../constants";
|
||||
import { assertNoPnpmDlx } from "../tools/assertNoPnpmDlx";
|
||||
|
||||
export async function main() {
|
||||
assertNoPnpmDlx();
|
||||
|
||||
const buildOptions = readBuildOptions({
|
||||
"processArgv": process.argv.slice(2)
|
||||
});
|
||||
|
14
src/bin/tools/assertNoPnpmDlx.ts
Normal file
14
src/bin/tools/assertNoPnpmDlx.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { sep as pathSep } from "path";
|
||||
|
||||
export function assertNoPnpmDlx() {
|
||||
if (__dirname.includes(`${pathSep}pnpm${pathSep}dlx${pathSep}`)) {
|
||||
console.log(
|
||||
[
|
||||
"Please don't use `pnpm dlx keycloakify`.",
|
||||
"\nUse `npx keycloakify` or `pnpm exec keycloakify` instead since you want to use the",
|
||||
"keycloakify version that is installed in your project and not the latest version on NPM."
|
||||
].join(" ")
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
@ -1,24 +1,19 @@
|
||||
import React from "react";
|
||||
import type { ComponentMeta } from "@storybook/react";
|
||||
import { Meta, StoryObj } from "@storybook/react";
|
||||
import { createPageStory } from "../createPageStory";
|
||||
|
||||
const pageId = "account.ftl";
|
||||
|
||||
const { PageStory } = createPageStory({ pageId });
|
||||
|
||||
const meta: ComponentMeta<any> = {
|
||||
title: `account/${pageId}`,
|
||||
component: PageStory,
|
||||
parameters: {
|
||||
viewMode: "story",
|
||||
previewTabs: {
|
||||
"storybook/docs/panel": {
|
||||
hidden: true
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const meta = {
|
||||
title: "account/Account",
|
||||
component: PageStory
|
||||
} satisfies Meta<typeof PageStory>;
|
||||
export default meta;
|
||||
|
||||
export const Default = () => <PageStory />;
|
||||
type Story = StoryObj<typeof meta>;
|
||||
|
||||
export const Default: Story = {
|
||||
render: () => <PageStory />
|
||||
};
|
||||
|
173
stories/account/pages/Authenticator.stories.tsx
Normal file
173
stories/account/pages/Authenticator.stories.tsx
Normal file
@ -0,0 +1,173 @@
|
||||
import React from "react";
|
||||
import { Meta } from "@storybook/react";
|
||||
import { createPageStory } from "../createPageStory";
|
||||
|
||||
const { PageStory } = createPageStory({
|
||||
pageId: "totp.ftl"
|
||||
});
|
||||
|
||||
const meta = {
|
||||
title: "account/Authenticator",
|
||||
component: PageStory
|
||||
} satisfies Meta<typeof PageStory>;
|
||||
export default meta;
|
||||
|
||||
export const Default = () => (
|
||||
<PageStory
|
||||
kcContext={{
|
||||
totp: {
|
||||
enabled: false,
|
||||
totpSecretEncoded: "HE4W MSTC OBKU CY2M ONXF OV3Q NYYU I3SH",
|
||||
totpSecret: "99fJbpUAcLsnWWpn1DnG",
|
||||
manualUrl: "http://localhost:8080/realms/myrealm/account/totp?mode=manual",
|
||||
totpSecretQrCode:
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAPYAAAD2AQAAAADNaUdlAAACk0lEQVR4Xu2YQY6DMAxFjViw5AjcBC6GBBIXozfJEbpkger53wEKqOpmFvaikQYNeVRyHPvbiejXscp95jp+/D5zHT9+n7kO8qeIFDqKzjJo9dC1wUSPP7yG4IPq41lq9ZK+keLZSwXDGwMhOCZgdX4sBVD1qld+GYg/h6ScreBuIDo5FKfVM7Z8aWs9PB2E2/73DdOlwUrK9Ck+HDnzB7ziR8fjlD/OPI8pVQwCi899TkNw2M+tp9XSLFKPIq2UySIhBB906fCQTicFwiv1EUG6+d+bl4zPIYnUk5oIcS69/evPYStUp6P0dJhD/mhauijcth76mOsfw+GFrbfXKJx7LW2N15kijuWIMCYicLQOCEimDp1c0L8PzCLTs3/d+ZQLyl6VqeSIT9nz25szf2ZybHgC31yrXEQIbqaPjX0k9GqWy0N/nLkagsHWNXR0LZwsR357c0pjC6fm+meu5f6f6oszz/qj7GpYCdHf0LVH/gTgtJ/5bVavPJ9svwnBS9qaqwoHOh3G7Ln++HIIDgpKYpFW00dlkX7ruz836THBWQpzd23/xeDsFVroz15fRjsfMyaC8JX2Y8PZf+VIoKff+uTO6WSIUIfSkrl9/rbfnbPr30R8hnMtXA/98ea5lx4ZlSMgQlMsEnb73XnP+yNl/SuR3/lzTSZHMTirMpMcXjWr0U5Mp/rnzmk/TsXkC2/iKEJ5TRG4DZ5KrP/C0RiVmkp+5I8zN1uh2vv9Vs+bzJ4947Y+bz6wl6ZIcv87ZaU2+6PwnoKdb7VYmrf9Z02MxCmNdmparbVJtrA4nA+e9LgIS6dzfvly7j+4XWIuPJp8iE9PbvkzJHYNabt/o5MP+535t/Hj95nr+PH7zHX8m/8B+RAnloz5pi4AAAAASUVORK5CYII=",
|
||||
policy: {
|
||||
type: "totp"
|
||||
},
|
||||
qrUrl: "http://localhost:8080/realms/myrealm/account/totp?mode=qr",
|
||||
otpCredentials: []
|
||||
},
|
||||
messagesPerField: {},
|
||||
stateChecker: "ihTeSAMfNsobnPjYiktV8DY-5T4sVzVdrEZRdwfMm8Y",
|
||||
realm: {
|
||||
userManagedAccessAllowed: true,
|
||||
internationalizationEnabled: false
|
||||
},
|
||||
url: {
|
||||
totpUrl: "http://localhost:8080/realms/myrealm/account/totp"
|
||||
},
|
||||
keycloakifyVersion: "9.6.1",
|
||||
themeVersion: "1.0.10",
|
||||
themeType: "account",
|
||||
themeName: "keycloakify",
|
||||
pageId: "totp.ftl"
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
export const WithTotpEnabled = () => (
|
||||
<PageStory
|
||||
kcContext={{
|
||||
totp: {
|
||||
enabled: true,
|
||||
totpSecretEncoded: "G55E MZKC JFUD MQLT MFIF EVSB JFLG M6SO",
|
||||
totpSecret: "7zFeBIh6AsaPRVAIVfzN",
|
||||
manualUrl: "http://localhost:8080/realms/myrealm/account/totp?mode=manual",
|
||||
supportedApplications: ["totpAppFreeOTPName", "totpAppMicrosoftAuthenticatorName", "totpAppGoogleName"],
|
||||
totpSecretQrCode:
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAPYAAAD2AQAAAADNaUdlAAACo0lEQVR4Xu2YPY6DMBCFJ6JwyRF8k+RiSCBxsXATjkDpAmX2vTGBwErbbDFTZIps4s8rmfl9RvRPW+W6crYvv66c7cuvK2cjX0Tkho9yW/q5PHSc5QYA62PwXnWqmzrRSUdNL+mygRC8kzQZWhqVO1CRds3YHopnfUkzp2c7ZAY+GIdXywOb0qsdJMXiFn9serYrncxNv/PDkdfUzObk/eNaX368mnl1kML8RH1vFoGzargA1DM/VeWhOpf9+by5iL5Q0NaEUETslHiSIz+dOc4q0tqBrcg7IsnpnZ8BeLmjqjFa4Fps4vlR3484nFHH6OP8o1cTc4I/Q3D4Uqw1TjpkeHqc2R/Rjvb89OUUDAL/CpycOf/o6fUjP505/phrOf8wn+tolsxyD8GZnzyrJSScrNyEcXhHJwrBh2yj2fShPlFB2PQxn935aK1HIB1G1nczm8+P+nbmC7si+zell53a4i97fnhz5Gddxc9iSgLPpPifGn9vDqN0YBL0lpozdx7nd+dDHSiFXkV+NlZO85Efzvzda8yrwkylvlEbhxE4bTJpiCEIkWNHbxD/w/++fJMOVX8p5Q70F0V2EI4LsUWd+ov6Wtgu5aM/OXNIf6jWbKq6zmekA77t88WZr5lXO6vvWaj6kbNo4nv/ceaon0TpYPqrmNJhue/x9+ZKLchbO+cLPrb+aI09BLeob1en2nqkKsUYfOvatSGa/ircmD7i78rNmJoYzXwIKh228z3+ztzef+Cb6S/lSxoWOXM2CO/ZuvlqARtLvX8u1Ie6+d+bd/X9pdS3lrrF/8jPCPytv9AVIbfvddxE4iNFLKL+hH/xCNudKgTvGX/r33ars/y062gQjljfWN8cyKm+f2NPOvqTL//Lvvy6crYvv66c7d/8B/9RFjk6Tp30AAAAAElFTkSuQmCC",
|
||||
policy: {
|
||||
type: "totp",
|
||||
algorithm: "HmacSHA1"
|
||||
},
|
||||
qrUrl: "http://localhost:8080/realms/myrealm/account/totp?mode=qr",
|
||||
otpCredentials: [
|
||||
{
|
||||
id: "7afaaf7d-f2d5-44f5-a966-e5297f0b2b7a",
|
||||
userLabel: "mobile"
|
||||
}
|
||||
]
|
||||
},
|
||||
message: {
|
||||
summary: "Mobile authenticator configured.",
|
||||
type: "success"
|
||||
},
|
||||
url: {
|
||||
totpUrl: "http://localhost:8080/realms/myrealm/account/totp"
|
||||
},
|
||||
messagesPerField: {},
|
||||
stateChecker: "0UvyCNJHRJXmdahtRmn0tTPCU2nwLtWBUfPaaX1qb4g",
|
||||
realm: {
|
||||
userManagedAccessAllowed: true,
|
||||
internationalizationEnabled: false
|
||||
},
|
||||
keycloakifyVersion: "9.6.1",
|
||||
themeVersion: "1.0.10",
|
||||
themeType: "account",
|
||||
themeName: "keycloakify",
|
||||
pageId: "totp.ftl"
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
export const WithManualMode = () => (
|
||||
<PageStory
|
||||
kcContext={{
|
||||
mode: "manual",
|
||||
totp: {
|
||||
enabled: false,
|
||||
totpSecretEncoded: "KZ5H CYTW GBVV ASDE JRXG MMCK HAZU E6TX",
|
||||
totpSecret: "Vzqbv0kPHdLnf0J83Bzw",
|
||||
manualUrl: "http://localhost:8080/realms/myrealm/account/totp?mode=manual",
|
||||
totpSecretQrCode:
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAPYAAAD2AQAAAADNaUdlAAACpklEQVR4Xu2YQa6rMAxFXTFgyBLYSbsxJJC6sb6dZAkdMkDNv8cBStHTm/yBM2ikIpqTgePY1w6W/xyLnWc+x5efZz7Hl59nPgf8aWaXPFl+2ZhbzfWaGPTT3yr4mPPPs8nty4ZeKxfzRQ6q4IO1P8zq0c/iffvqtIlLTfw5psxsK3f7JirjTHDqWpQ3T9fC/fytn2956u32bNJv8RHIyZ/n0MvJh8cpvwJ5GffkQaBNYPo2auCyv30YVmtitm4yu1qT5mtXCR9svsqXeih1/I1IbZHLKniTskxPOvCGSB3Wud2/0Vz+5YH9uHZAvzORUAlXaXmY9FHxyZuWI0L5sfs3lkt1vDTbtVtM8bmovrCT26o/0bxozVAWIY3IuTLpsvk3mDNeRv9QqrJWEp+25Xc01/uMVudHpySiE3PXklN1cLSm8yCgKmuWICUIxip4vqM6Y+kalNX3hJNtz+9orgOXQ60noZPrd/H5u74E86I/pfXXm/obXPvOr2juVW8o9nsTS77T5Ix18CZ71sh+qQ7n3+LzY32J5WptXt291Bdaf8tcVw76Hcvpqr31R3CUOri7Q79r4ap61+5O12XoT1leOrFK+HZ/asga/sr0tz5F85wozWq4aMKcP1DK3f54Ttfv+a0iqG1wCU2H/iGWl156IionQYWmngTpan84H9aGy+8nl7I8J5ejOnjP0SNCC/0/lVpydKyPwZz7u/Xef80ouaRHHt7PP5j74BJFfBpJ3vLp460/wdxtxX5KM6XPMvktJ6/7i+YjvfRS/Gs3za3218LJH5qwzKKf7fzd3fXwEWmkf5WTKS3JN1YRTxKhiY9IC6mzUKmP/g3knL8cqoeUiKvJL/EZyT1/sJ/vg+X7G07e7Q/mf40vP898ji8/z3yO/+b/ANUwOXCzdQgqAAAAAElFTkSuQmCC",
|
||||
policy: {
|
||||
type: "totp",
|
||||
algorithm: "HmacSHA1"
|
||||
},
|
||||
qrUrl: "http://localhost:8080/realms/myrealm/account/totp?mode=qr",
|
||||
otpCredentials: []
|
||||
},
|
||||
messagesPerField: {},
|
||||
stateChecker: "HiBl2ADzLwKwQS813LOEig1Ymm4xpEu_NacYtWJIuHU",
|
||||
realm: {
|
||||
userManagedAccessAllowed: true,
|
||||
internationalizationEnabled: false
|
||||
},
|
||||
url: {
|
||||
totpUrl: "http://localhost:8080/realms/myrealm/account/totp?mode=manual"
|
||||
},
|
||||
keycloakifyVersion: "9.6.1",
|
||||
themeVersion: "1.0.10",
|
||||
themeType: "account",
|
||||
themeName: "keycloakify",
|
||||
pageId: "totp.ftl"
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
export const MoreThanOneTotpProviders = () => (
|
||||
<PageStory
|
||||
kcContext={{
|
||||
totp: {
|
||||
enabled: true,
|
||||
totpSecretEncoded: "G55E MZKC JFUD MQLT MFIF EVSB JFLG M6SO",
|
||||
totpSecret: "7zFeBIh6AsaPRVAIVfzN",
|
||||
manualUrl: "http://localhost:8080/realms/myrealm/account/totp?mode=manual",
|
||||
supportedApplications: ["totpAppFreeOTPName", "totpAppMicrosoftAuthenticatorName", "totpAppGoogleName"],
|
||||
totpSecretQrCode:
|
||||
"iVBORw0KGgoAAAANSUhEUgAAAPYAAAD2AQAAAADNaUdlAAACo0lEQVR4Xu2YPY6DMBCFJ6JwyRF8k+RiSCBxsXATjkDpAmX2vTGBwErbbDFTZIps4s8rmfl9RvRPW+W6crYvv66c7cuvK2cjX0Tkho9yW/q5PHSc5QYA62PwXnWqmzrRSUdNL+mygRC8kzQZWhqVO1CRds3YHopnfUkzp2c7ZAY+GIdXywOb0qsdJMXiFn9serYrncxNv/PDkdfUzObk/eNaX368mnl1kML8RH1vFoGzargA1DM/VeWhOpf9+by5iL5Q0NaEUETslHiSIz+dOc4q0tqBrcg7IsnpnZ8BeLmjqjFa4Fps4vlR3484nFHH6OP8o1cTc4I/Q3D4Uqw1TjpkeHqc2R/Rjvb89OUUDAL/CpycOf/o6fUjP505/phrOf8wn+tolsxyD8GZnzyrJSScrNyEcXhHJwrBh2yj2fShPlFB2PQxn935aK1HIB1G1nczm8+P+nbmC7si+zell53a4i97fnhz5Gddxc9iSgLPpPifGn9vDqN0YBL0lpozdx7nd+dDHSiFXkV+NlZO85Efzvzda8yrwkylvlEbhxE4bTJpiCEIkWNHbxD/w/++fJMOVX8p5Q70F0V2EI4LsUWd+ov6Wtgu5aM/OXNIf6jWbKq6zmekA77t88WZr5lXO6vvWaj6kbNo4nv/ceaon0TpYPqrmNJhue/x9+ZKLchbO+cLPrb+aI09BLeob1en2nqkKsUYfOvatSGa/ircmD7i78rNmJoYzXwIKh228z3+ztzef+Cb6S/lSxoWOXM2CO/ZuvlqARtLvX8u1Ie6+d+bd/X9pdS3lrrF/8jPCPytv9AVIbfvddxE4iNFLKL+hH/xCNudKgTvGX/r33ars/y062gQjljfWN8cyKm+f2NPOvqTL//Lvvy6crYvv66c7d/8B/9RFjk6Tp30AAAAAElFTkSuQmCC",
|
||||
policy: {
|
||||
type: "totp",
|
||||
algorithm: "HmacSHA1"
|
||||
},
|
||||
qrUrl: "http://localhost:8080/realms/myrealm/account/totp?mode=qr",
|
||||
otpCredentials: [
|
||||
{
|
||||
id: "7afaaf7d-f2d5-44f5-a966-e5297f0b2b7a",
|
||||
userLabel: "Samsung S23"
|
||||
},
|
||||
{
|
||||
id: "fbe22500-d979-45a3-9666-84c99e27958e",
|
||||
userLabel: "Apple Iphone 15"
|
||||
}
|
||||
]
|
||||
},
|
||||
url: {
|
||||
totpUrl: "http://localhost:8080/realms/myrealm/account/totp"
|
||||
},
|
||||
messagesPerField: {},
|
||||
stateChecker: "0UvyCNJHRJXmdahtRmn0tTPCU2nwLtWBUfPaaX1qb4g",
|
||||
realm: {
|
||||
userManagedAccessAllowed: true,
|
||||
internationalizationEnabled: false
|
||||
},
|
||||
keycloakifyVersion: "9.6.1",
|
||||
themeVersion: "1.0.10",
|
||||
themeType: "account",
|
||||
themeName: "keycloakify",
|
||||
pageId: "totp.ftl"
|
||||
}}
|
||||
/>
|
||||
);
|
34
stories/account/pages/FederatedIdentity.stories.tsx
Normal file
34
stories/account/pages/FederatedIdentity.stories.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
import React from "react";
|
||||
import { Meta } from "@storybook/react";
|
||||
import { createPageStory } from "../createPageStory";
|
||||
|
||||
const pageId = "federatedIdentity.ftl";
|
||||
|
||||
const { PageStory } = createPageStory({ pageId });
|
||||
|
||||
const meta = {
|
||||
title: "account/FederatedIdentity",
|
||||
component: PageStory
|
||||
} satisfies Meta<typeof PageStory>;
|
||||
|
||||
export default meta;
|
||||
|
||||
export const Default = () => <PageStory />;
|
||||
|
||||
export const NotConnected = () => (
|
||||
<PageStory
|
||||
kcContext={{
|
||||
pageId: "federatedIdentity.ftl",
|
||||
federatedIdentity: {
|
||||
identities: [
|
||||
{
|
||||
providerId: "google",
|
||||
displayName: "keycloak-oidc",
|
||||
connected: false
|
||||
}
|
||||
],
|
||||
removeLinkPossible: true
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
354
stories/account/pages/Log.stories.tsx
Normal file
354
stories/account/pages/Log.stories.tsx
Normal file
@ -0,0 +1,354 @@
|
||||
import React from "react";
|
||||
import { Meta } from "@storybook/react";
|
||||
import { createPageStory } from "../createPageStory";
|
||||
|
||||
const pageId = "log.ftl";
|
||||
|
||||
const { PageStory } = createPageStory({
|
||||
pageId
|
||||
});
|
||||
|
||||
const meta = {
|
||||
title: "account/Log",
|
||||
component: PageStory
|
||||
} satisfies Meta<typeof PageStory>;
|
||||
|
||||
export default meta;
|
||||
|
||||
export const Default = () => (
|
||||
<PageStory
|
||||
kcContext={{
|
||||
log: {
|
||||
events: [
|
||||
{
|
||||
date: "2024-04-26T12:29:08Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [
|
||||
{
|
||||
value: "openid-connect",
|
||||
key: "auth_method"
|
||||
},
|
||||
{
|
||||
value: "john.doe",
|
||||
key: "username"
|
||||
}
|
||||
],
|
||||
event: "login"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T12:10:56Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [
|
||||
{
|
||||
value: "openid-connect",
|
||||
key: "auth_method"
|
||||
},
|
||||
{
|
||||
value: "john.doe",
|
||||
key: "username"
|
||||
}
|
||||
],
|
||||
event: "login"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T11:57:34Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "account",
|
||||
details: [],
|
||||
event: "update totp"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T11:57:21Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "account",
|
||||
details: [],
|
||||
event: "update totp"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T11:56:56Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "account",
|
||||
details: [],
|
||||
event: "remove totp"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T11:56:55Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "account",
|
||||
details: [],
|
||||
event: "remove totp"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T11:56:41Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "account",
|
||||
details: [],
|
||||
event: "update totp"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T11:56:36Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "account",
|
||||
details: [],
|
||||
event: "update totp"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T11:32:54Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [
|
||||
{
|
||||
value: "openid-connect",
|
||||
key: "auth_method"
|
||||
},
|
||||
{
|
||||
value: "john.doe",
|
||||
key: "username"
|
||||
}
|
||||
],
|
||||
event: "login"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T09:42:54Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [
|
||||
{
|
||||
value: "openid-connect",
|
||||
key: "auth_method"
|
||||
},
|
||||
{
|
||||
value: "john.doe",
|
||||
key: "username"
|
||||
}
|
||||
],
|
||||
event: "login"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T09:42:52Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [
|
||||
{
|
||||
value: "openid-connect",
|
||||
key: "auth_method"
|
||||
},
|
||||
{
|
||||
value: "john.doe",
|
||||
key: "username"
|
||||
}
|
||||
],
|
||||
event: "login"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T09:42:40Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [
|
||||
{
|
||||
value: "openid-connect",
|
||||
key: "auth_method"
|
||||
},
|
||||
{
|
||||
value: "john.doe",
|
||||
key: "username"
|
||||
}
|
||||
],
|
||||
event: "login"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T09:42:09Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [
|
||||
{
|
||||
value: "openid-connect",
|
||||
key: "auth_method"
|
||||
},
|
||||
{
|
||||
value: "false",
|
||||
key: "remember_me"
|
||||
},
|
||||
{
|
||||
value: "john.doe",
|
||||
key: "username"
|
||||
}
|
||||
],
|
||||
event: "login"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T09:24:17Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [],
|
||||
event: "logout"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T09:23:54Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [
|
||||
{
|
||||
value: "openid-connect",
|
||||
key: "auth_method"
|
||||
},
|
||||
{
|
||||
value: "john.doe",
|
||||
key: "username"
|
||||
}
|
||||
],
|
||||
event: "login"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T09:23:50Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [
|
||||
{
|
||||
value: "openid-connect",
|
||||
key: "auth_method"
|
||||
},
|
||||
{
|
||||
value: "john.doe",
|
||||
key: "username"
|
||||
}
|
||||
],
|
||||
event: "login"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T09:23:47Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "account",
|
||||
details: [
|
||||
{
|
||||
value: "openid-connect",
|
||||
key: "auth_method"
|
||||
},
|
||||
{
|
||||
value: "john.doe",
|
||||
key: "username"
|
||||
}
|
||||
],
|
||||
event: "login"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T09:23:15Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [],
|
||||
event: "logout"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T09:23:06Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [
|
||||
{
|
||||
value: "openid-connect",
|
||||
key: "auth_method"
|
||||
},
|
||||
{
|
||||
value: "john.doe",
|
||||
key: "username"
|
||||
}
|
||||
],
|
||||
event: "login"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T09:22:53Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [],
|
||||
event: "logout"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T09:21:29Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [
|
||||
{
|
||||
value: "openid-connect",
|
||||
key: "auth_method"
|
||||
},
|
||||
{
|
||||
value: "false",
|
||||
key: "remember_me"
|
||||
},
|
||||
{
|
||||
value: "john.doe",
|
||||
key: "username"
|
||||
}
|
||||
],
|
||||
event: "login"
|
||||
},
|
||||
{
|
||||
date: "2024-04-26T09:17:32Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [
|
||||
{
|
||||
value: "openid-connect",
|
||||
key: "auth_method"
|
||||
},
|
||||
{
|
||||
value: "john.doe",
|
||||
key: "username"
|
||||
}
|
||||
],
|
||||
event: "login"
|
||||
},
|
||||
{
|
||||
date: "2024-04-18T11:19:09Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [
|
||||
{
|
||||
value: "openid-connect",
|
||||
key: "auth_method"
|
||||
},
|
||||
{
|
||||
value: "john.doe",
|
||||
key: "username"
|
||||
}
|
||||
],
|
||||
event: "login"
|
||||
},
|
||||
{
|
||||
date: "2024-04-18T11:18:50Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "keycloakify-frontend",
|
||||
details: [
|
||||
{
|
||||
value: "openid-connect",
|
||||
key: "auth_method"
|
||||
},
|
||||
{
|
||||
value: "john.doe",
|
||||
key: "username"
|
||||
}
|
||||
],
|
||||
event: "login"
|
||||
},
|
||||
{
|
||||
date: "2024-04-18T11:18:24Z",
|
||||
ipAddress: "127.0.0.1",
|
||||
client: "account",
|
||||
details: [
|
||||
{
|
||||
value: "openid-connect",
|
||||
key: "auth_method"
|
||||
},
|
||||
{
|
||||
value: "john.doe",
|
||||
key: "username"
|
||||
}
|
||||
],
|
||||
event: "login"
|
||||
}
|
||||
]
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
@ -1,23 +1,15 @@
|
||||
import React from "react";
|
||||
import type { ComponentMeta } from "@storybook/react";
|
||||
import { Meta } from "@storybook/react";
|
||||
import { createPageStory } from "../createPageStory";
|
||||
|
||||
const pageId = "password.ftl";
|
||||
|
||||
const { PageStory } = createPageStory({ pageId });
|
||||
|
||||
const meta: ComponentMeta<any> = {
|
||||
title: `account/${pageId}`,
|
||||
component: PageStory,
|
||||
parameters: {
|
||||
viewMode: "story",
|
||||
previewTabs: {
|
||||
"storybook/docs/panel": {
|
||||
hidden: true
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const meta = {
|
||||
title: "account/Password",
|
||||
component: PageStory
|
||||
} satisfies Meta<typeof PageStory>;
|
||||
|
||||
export default meta;
|
||||
|
||||
|
@ -1,26 +1,55 @@
|
||||
import React from "react";
|
||||
import type { ComponentMeta } from "@storybook/react";
|
||||
import { Meta } from "@storybook/react";
|
||||
import { createPageStory } from "../createPageStory";
|
||||
|
||||
const pageId = "sessions.ftl";
|
||||
|
||||
const { PageStory } = createPageStory({ pageId });
|
||||
|
||||
const meta: ComponentMeta<any> = {
|
||||
title: `account/${pageId}`,
|
||||
component: PageStory,
|
||||
parameters: {
|
||||
viewMode: "story",
|
||||
previewTabs: {
|
||||
"storybook/docs/panel": {
|
||||
hidden: true
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const meta = {
|
||||
title: "account/Sessions",
|
||||
component: PageStory
|
||||
} satisfies Meta<typeof PageStory>;
|
||||
|
||||
export default meta;
|
||||
|
||||
export const Default = () => <PageStory />;
|
||||
export const Default = () => (
|
||||
<PageStory
|
||||
kcContext={{
|
||||
sessions: {
|
||||
sessions: [
|
||||
{
|
||||
expires: "2024-04-26T18:14:19Z",
|
||||
clients: ["account"],
|
||||
ipAddress: "172.20.0.1",
|
||||
started: "2024-04-26T08:14:19Z",
|
||||
lastAccess: "2024-04-26T08:30:54Z",
|
||||
id: "af835e30-4821-43b1-b4f7-e732d3cc15d2"
|
||||
},
|
||||
{
|
||||
expires: "2024-04-26T18:14:09Z",
|
||||
clients: ["security-admin-console", "account"],
|
||||
ipAddress: "172.20.0.1",
|
||||
started: "2024-04-26T08:14:09Z",
|
||||
lastAccess: "2024-04-26T08:15:14Z",
|
||||
id: "60a9d8b8-617d-441e-8643-08c3fe30e231"
|
||||
}
|
||||
]
|
||||
},
|
||||
stateChecker: "xQ7EOgFrLi4EvnJ8dbXKhwFGWk_bkOp0X89mhilt1os"
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
export const WithMessage = () => <PageStory kcContext={{}} />;
|
||||
export const WithError = () => (
|
||||
<PageStory
|
||||
kcContext={{
|
||||
url: { passwordUrl: "/auth/realms/keycloakify/account/password" },
|
||||
stateChecker: "xQ7EOgFrLi4EvnJ8dbXKhwFGWk_bkOp0X89mhilt1os",
|
||||
message: {
|
||||
summary: "Invalid existing password.",
|
||||
type: "error"
|
||||
}
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
@ -1,23 +1,15 @@
|
||||
import React from "react";
|
||||
import type { ComponentMeta } from "@storybook/react";
|
||||
import { Meta } from "@storybook/react";
|
||||
import { createPageStory } from "../createPageStory";
|
||||
|
||||
const pageId = "totp.ftl";
|
||||
|
||||
const { PageStory } = createPageStory({ pageId });
|
||||
|
||||
const meta: ComponentMeta<any> = {
|
||||
title: `account/${pageId}`,
|
||||
component: PageStory,
|
||||
parameters: {
|
||||
viewMode: "story",
|
||||
previewTabs: {
|
||||
"storybook/docs/panel": {
|
||||
hidden: true
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const meta = {
|
||||
title: "account/Authenticator",
|
||||
component: PageStory
|
||||
} satisfies Meta<typeof PageStory>;
|
||||
|
||||
export default meta;
|
||||
|
||||
|
112
yarn.lock
112
yarn.lock
@ -4744,30 +4744,29 @@ check-error@^1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
|
||||
integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==
|
||||
|
||||
cheerio-select@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4"
|
||||
integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==
|
||||
cheerio-select-tmp@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/cheerio-select-tmp/-/cheerio-select-tmp-0.1.1.tgz#55bbef02a4771710195ad736d5e346763ca4e646"
|
||||
integrity sha512-YYs5JvbpU19VYJyj+F7oYrIE2BOll1/hRU7rEy/5+v9BzkSo3bK81iAeeQEMI92vRIxz677m72UmJUiVwwgjfQ==
|
||||
dependencies:
|
||||
boolbase "^1.0.0"
|
||||
css-select "^5.1.0"
|
||||
css-what "^6.1.0"
|
||||
domelementtype "^2.3.0"
|
||||
domhandler "^5.0.3"
|
||||
domutils "^3.0.1"
|
||||
css-select "^3.1.2"
|
||||
css-what "^4.0.0"
|
||||
domelementtype "^2.1.0"
|
||||
domhandler "^4.0.0"
|
||||
domutils "^2.4.4"
|
||||
|
||||
cheerio@^1.0.0-rc.5:
|
||||
version "1.0.0-rc.12"
|
||||
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.12.tgz#788bf7466506b1c6bf5fae51d24a2c4d62e47683"
|
||||
integrity sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==
|
||||
cheerio@1.0.0-rc.5:
|
||||
version "1.0.0-rc.5"
|
||||
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.5.tgz#88907e1828674e8f9fee375188b27dadd4f0fa2f"
|
||||
integrity sha512-yoqps/VCaZgN4pfXtenwHROTp8NG6/Hlt4Jpz2FEP0ZJQ+ZUkVDd0hAPDNKhj3nakpfPt/CNs57yEtxD1bXQiw==
|
||||
dependencies:
|
||||
cheerio-select "^2.1.0"
|
||||
dom-serializer "^2.0.0"
|
||||
domhandler "^5.0.3"
|
||||
domutils "^3.0.1"
|
||||
htmlparser2 "^8.0.1"
|
||||
parse5 "^7.0.0"
|
||||
parse5-htmlparser2-tree-adapter "^7.0.0"
|
||||
cheerio-select-tmp "^0.1.0"
|
||||
dom-serializer "~1.2.0"
|
||||
domhandler "^4.0.0"
|
||||
entities "~2.1.0"
|
||||
htmlparser2 "^6.0.0"
|
||||
parse5 "^6.0.0"
|
||||
parse5-htmlparser2-tree-adapter "^6.0.0"
|
||||
|
||||
chokidar@^2.1.8:
|
||||
version "2.1.8"
|
||||
@ -5349,6 +5348,17 @@ css-loader@^5.0.1:
|
||||
schema-utils "^3.0.0"
|
||||
semver "^7.3.5"
|
||||
|
||||
css-select@^3.1.2:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/css-select/-/css-select-3.1.2.tgz#d52cbdc6fee379fba97fb0d3925abbd18af2d9d8"
|
||||
integrity sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA==
|
||||
dependencies:
|
||||
boolbase "^1.0.0"
|
||||
css-what "^4.0.0"
|
||||
domhandler "^4.0.0"
|
||||
domutils "^2.4.3"
|
||||
nth-check "^2.0.0"
|
||||
|
||||
css-select@^4.1.3:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b"
|
||||
@ -5360,18 +5370,12 @@ css-select@^4.1.3:
|
||||
domutils "^2.8.0"
|
||||
nth-check "^2.0.1"
|
||||
|
||||
css-select@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6"
|
||||
integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==
|
||||
dependencies:
|
||||
boolbase "^1.0.0"
|
||||
css-what "^6.1.0"
|
||||
domhandler "^5.0.2"
|
||||
domutils "^3.0.1"
|
||||
nth-check "^2.0.1"
|
||||
css-what@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/css-what/-/css-what-4.0.0.tgz#35e73761cab2eeb3d3661126b23d7aa0e8432233"
|
||||
integrity sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A==
|
||||
|
||||
css-what@^6.0.1, css-what@^6.1.0:
|
||||
css-what@^6.0.1:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
|
||||
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
|
||||
@ -5656,6 +5660,15 @@ dom-serializer@^2.0.0:
|
||||
domhandler "^5.0.2"
|
||||
entities "^4.2.0"
|
||||
|
||||
dom-serializer@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.2.0.tgz#3433d9136aeb3c627981daa385fc7f32d27c48f1"
|
||||
integrity sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA==
|
||||
dependencies:
|
||||
domelementtype "^2.0.1"
|
||||
domhandler "^4.0.0"
|
||||
entities "^2.0.0"
|
||||
|
||||
dom-walk@^0.1.0:
|
||||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
|
||||
@ -5666,7 +5679,7 @@ domain-browser@^1.1.1:
|
||||
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
|
||||
integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
|
||||
|
||||
domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0:
|
||||
domelementtype@^2.0.1, domelementtype@^2.1.0, domelementtype@^2.2.0, domelementtype@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
|
||||
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
|
||||
@ -5685,7 +5698,7 @@ domhandler@^5.0, domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3:
|
||||
dependencies:
|
||||
domelementtype "^2.3.0"
|
||||
|
||||
domutils@^2.5.2, domutils@^2.8.0:
|
||||
domutils@^2.4.3, domutils@^2.4.4, domutils@^2.5.2, domutils@^2.8.0:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
|
||||
integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
|
||||
@ -5843,6 +5856,11 @@ entities@^4.2.0, entities@^4.4.0:
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
|
||||
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
|
||||
|
||||
entities@~2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5"
|
||||
integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==
|
||||
|
||||
err-code@^2.0.2:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9"
|
||||
@ -7206,7 +7224,7 @@ html-webpack-plugin@^5.0.0:
|
||||
pretty-error "^4.0.0"
|
||||
tapable "^2.0.0"
|
||||
|
||||
htmlparser2@^6.1.0:
|
||||
htmlparser2@^6.0.0, htmlparser2@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7"
|
||||
integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==
|
||||
@ -7216,7 +7234,7 @@ htmlparser2@^6.1.0:
|
||||
domutils "^2.5.2"
|
||||
entities "^2.0.0"
|
||||
|
||||
htmlparser2@^8.0, htmlparser2@^8.0.1:
|
||||
htmlparser2@^8.0:
|
||||
version "8.0.2"
|
||||
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21"
|
||||
integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==
|
||||
@ -9054,7 +9072,7 @@ npmlog@^5.0.1:
|
||||
gauge "^3.0.0"
|
||||
set-blocking "^2.0.0"
|
||||
|
||||
nth-check@^2.0.1:
|
||||
nth-check@^2.0.0, nth-check@^2.0.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d"
|
||||
integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==
|
||||
@ -9407,26 +9425,18 @@ parse-json@^5.0.0:
|
||||
json-parse-even-better-errors "^2.3.0"
|
||||
lines-and-columns "^1.1.6"
|
||||
|
||||
parse5-htmlparser2-tree-adapter@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1"
|
||||
integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==
|
||||
parse5-htmlparser2-tree-adapter@^6.0.0:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6"
|
||||
integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==
|
||||
dependencies:
|
||||
domhandler "^5.0.2"
|
||||
parse5 "^7.0.0"
|
||||
parse5 "^6.0.1"
|
||||
|
||||
parse5@^6.0.0:
|
||||
parse5@^6.0.0, parse5@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"
|
||||
integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==
|
||||
|
||||
parse5@^7.0.0:
|
||||
version "7.1.2"
|
||||
resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32"
|
||||
integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==
|
||||
dependencies:
|
||||
entities "^4.4.0"
|
||||
|
||||
parseurl@~1.3.2, parseurl@~1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
|
||||
|
Reference in New Issue
Block a user