prepare flow frame

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens Langhammer
2024-03-21 22:23:48 +01:00
parent 828f477548
commit b2f2fd241d
3 changed files with 68 additions and 2 deletions

View File

@ -1,3 +1,4 @@
import { ensureCSSStyleSheet } from "@goauthentik/authentik/elements/utils/ensureCSSStyleSheet";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import {
EVENT_FLOW_ADVANCE,
@ -76,6 +77,9 @@ export class FlowExecutor extends Interface implements StageHost {
@state()
flowInfo?: ContextualFlowInfo;
@state()
frameMode = window !== window.top;
ws: WebsocketClient;
static get styles(): CSSResult[] {
@ -140,6 +144,17 @@ export class FlowExecutor extends Interface implements StageHost {
:host([theme="dark"]) .pf-c-login.sidebar_right .pf-c-list {
color: var(--ak-dark-foreground);
}
/* frame design */
.pf-c-login.frame {
padding: 0;
min-height: initial !important;
}
.pf-c-login.frame .pf-c-login__footer {
flex-grow: 0;
}
.pf-c-login.frame .pf-c-login__footer .pf-c-list {
padding: 0;
}
.pf-c-brand {
padding-top: calc(
var(--pf-c-login__main-footer-links--PaddingTop) +
@ -161,6 +176,19 @@ export class FlowExecutor extends Interface implements StageHost {
constructor() {
super();
if (this.frameMode) {
// PatternFly sets html and body to 100% height, which we don't
// want in this case since the iframe should only take the space it needs
document.adoptedStyleSheets = [
...document.adoptedStyleSheets,
ensureCSSStyleSheet(css`
body,
html {
height: unset !important;
}
`),
];
}
this.ws = new WebsocketClient();
if (window.location.search.includes("inspector")) {
this.inspectorOpen = true;
@ -482,7 +510,26 @@ export class FlowExecutor extends Interface implements StageHost {
}
render(): TemplateResult {
return html` <ak-locale-context>
if (this.frameMode) {
return html`<ak-locale-context>
<div class="pf-c-login frame">
<div class="ak-login-container">
<div class="pf-c-login__main">${this.renderChallengeWrapper()}</div>
<footer class="pf-c-login__footer">
<ul class="pf-c-list pf-m-inline">
<li>
<a
href="https://goauthentik.io?utm_source=authentik&amp;utm_medium=flow"
>${msg("Powered by authentik")}</a
>
</li>
</ul>
</footer>
</div>
</div>
</ak-locale-context>`;
}
return html`<ak-locale-context>
<div class="pf-c-background-image"></div>
<div class="pf-c-page__drawer">
<div class="pf-c-drawer ${this.inspectorOpen ? "pf-m-expanded" : "pf-m-collapsed"}">

View File

@ -12,6 +12,7 @@ import PFTitle from "@patternfly/patternfly/components/Title/title.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { FlowChallengeResponseRequest, RedirectChallenge } from "@goauthentik/api";
import { globalAK } from "@goauthentik/authentik/common/global";
@customElement("ak-stage-redirect")
export class RedirectStage extends BaseStage<RedirectChallenge, FlowChallengeResponseRequest> {
@ -49,8 +50,25 @@ export class RedirectStage extends BaseStage<RedirectChallenge, FlowChallengeRes
"authentik/stages/redirect: redirecting to url from server",
this.challenge.to,
);
window.location.assign(this.challenge.to);
this.startedRedirect = true;
if (this.host.frameMode && window.top) {
try {
window.top.location.assign(this.challenge.to);
} catch {
window.top.postMessage(
{
source: "goauthentik.io",
context: "flow-executor",
component: this.challenge.component,
to: this.challenge.to,
},
globalAK().brand.matchedDomain,
);
}
if (this.challenge.to.startsWith("http")) {
return;
}
}
}
renderLoading(): TemplateResult {

View File

@ -16,6 +16,7 @@ export interface StageHost {
challenge?: unknown;
flowSlug?: string;
loading: boolean;
frameMode: boolean;
submit(payload: unknown, options?: SubmitOptions): Promise<boolean>;
readonly brand?: CurrentBrand;