Files
authentik/web/src/flow/sources/plex/PlexLoginInit.ts
T
Jens L. 0021e5fa25 web/flows: fix bottom padding when loading challenge (#15372)
* web/flows: fix bottom padding when loading challenge

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* add base class that does layout for login cards

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* ok actually rework the whole thing

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix leftover div

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix other stages

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* better declare loading state

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* format

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix tests

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2025-07-03 22:07:22 +02:00

96 lines
3.8 KiB
TypeScript

import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { parseAPIResponseError } from "@goauthentik/common/errors/network";
import { PlexAPIClient, popupCenterScreen } from "@goauthentik/common/helpers/plex";
import "@goauthentik/elements/EmptyState";
import { showAPIErrorMessage } from "@goauthentik/elements/messages/MessageContainer";
import "@goauthentik/flow/components/ak-flow-card.js";
import { BaseStage } from "@goauthentik/flow/stages/base";
import { msg } from "@lit/localize";
import { CSSResult } from "lit";
import { TemplateResult, html } from "lit";
import { customElement, state } from "lit/decorators.js";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
import PFDivider from "@patternfly/patternfly/components/Divider/divider.css";
import PFForm from "@patternfly/patternfly/components/Form/form.css";
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
import PFTitle from "@patternfly/patternfly/components/Title/title.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import {
PlexAuthenticationChallenge,
PlexAuthenticationChallengeResponseRequest,
} from "@goauthentik/api";
import { SourcesApi } from "@goauthentik/api";
@customElement("ak-flow-source-plex")
export class PlexLoginInit extends BaseStage<
PlexAuthenticationChallenge,
PlexAuthenticationChallengeResponseRequest
> {
@state()
authUrl?: string;
static get styles(): CSSResult[] {
return [PFBase, PFLogin, PFForm, PFFormControl, PFButton, PFTitle, PFDivider];
}
async firstUpdated(): Promise<void> {
const authInfo = await PlexAPIClient.getPin(this.challenge?.clientId || "");
this.authUrl = authInfo.authUrl;
const authWindow = await popupCenterScreen(authInfo.authUrl, "plex auth", 550, 700);
PlexAPIClient.pinPoll(this.challenge?.clientId || "", authInfo.pin.id).then((token) => {
authWindow?.close();
new SourcesApi(DEFAULT_CONFIG)
.sourcesPlexRedeemTokenCreate({
plexTokenRedeemRequest: {
plexToken: token,
},
slug: this.challenge?.slug || "",
})
.then((redirectChallenge) => {
window.location.assign(redirectChallenge.to);
})
.catch(async (error: unknown) => {
return parseAPIResponseError(error)
.then(showAPIErrorMessage)
.then(() => {
setTimeout(() => {
window.location.assign("/");
}, 5000);
});
});
});
}
render(): TemplateResult {
return html`<ak-flow-card .challenge=${this.challenge}>
<span slot="title">${msg("Authenticating with Plex...")}</span>
<form class="pf-c-form">
<ak-empty-state loading
><span>${msg("Waiting for authentication...")}></span>
</ak-empty-state>
<hr class="pf-c-divider" />
<p>${msg("If no Plex popup opens, click the button below.")}</p>
<button
class="pf-c-button pf-m-block pf-m-primary"
type="button"
@click=${() => {
window.open(this.authUrl, "_blank");
}}
>
${msg("Open login")}
</button>
</form>
</ak-flow-card>`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ak-flow-source-plex": PlexLoginInit;
}
}