web: fix authentification with Plex on iOS (#4095)

* web: fix authentification with Plex on iOS

Fixes issue #3822

* fixup

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

* add fallback button

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
Co-authored-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Bastien Rivière 2022-12-01 13:32:00 +01:00 committed by GitHub
parent 46c8db7f4b
commit 93fee5f0e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 13 deletions

View File

@ -62,7 +62,7 @@ export class PlexSourceForm extends ModelForm<PlexSource, string> {
send = async (data: PlexSource): Promise<PlexSource> => { send = async (data: PlexSource): Promise<PlexSource> => {
data.plexToken = this.plexToken || ""; data.plexToken = this.plexToken || "";
let source: PlexSource; let source: PlexSource;
if (this.instance) { if (this.instance?.pk) {
source = await new SourcesApi(DEFAULT_CONFIG).sourcesPlexUpdate({ source = await new SourcesApi(DEFAULT_CONFIG).sourcesPlexUpdate({
slug: this.instance.slug, slug: this.instance.slug,
plexSourceRequest: data, plexSourceRequest: data,
@ -95,7 +95,7 @@ export class PlexSourceForm extends ModelForm<PlexSource, string> {
async doAuth(): Promise<void> { async doAuth(): Promise<void> {
const authInfo = await PlexAPIClient.getPin(this.instance?.clientId || ""); const authInfo = await PlexAPIClient.getPin(this.instance?.clientId || "");
const authWindow = popupCenterScreen(authInfo.authUrl, "plex auth", 550, 700); const authWindow = await popupCenterScreen(authInfo.authUrl, "plex auth", 550, 700);
PlexAPIClient.pinPoll(this.instance?.clientId || "", authInfo.pin.id).then((token) => { PlexAPIClient.pinPoll(this.instance?.clientId || "", authInfo.pin.id).then((token) => {
authWindow?.close(); authWindow?.close();
this.plexToken = token; this.plexToken = token;

View File

@ -23,15 +23,24 @@ export const DEFAULT_HEADERS = {
"X-Plex-Device-Vendor": "goauthentik.io", "X-Plex-Device-Vendor": "goauthentik.io",
}; };
export function popupCenterScreen(url: string, title: string, w: number, h: number): Window | null { export async function popupCenterScreen(
url: string,
title: string,
w: number,
h: number,
): Promise<Window | null> {
const top = (screen.height - h) / 4, const top = (screen.height - h) / 4,
left = (screen.width - w) / 2; left = (screen.width - w) / 2;
const popup = window.open( return new Promise((resolve) => {
url, setTimeout(() => {
title, const popup = window.open(
`scrollbars=yes,width=${w},height=${h},top=${top},left=${left}`, url,
); title,
return popup; `scrollbars=yes,width=${w},height=${h},top=${top},left=${left}`,
);
resolve(popup);
});
});
} }
export class PlexAPIClient { export class PlexAPIClient {

View File

@ -8,7 +8,7 @@ import { t } from "@lingui/macro";
import { CSSResult } from "lit"; import { CSSResult } from "lit";
import { TemplateResult, html } from "lit"; import { TemplateResult, html } from "lit";
import { customElement } from "lit/decorators.js"; import { customElement, state } from "lit/decorators.js";
import AKGlobal from "@goauthentik/common/styles/authentik.css"; import AKGlobal from "@goauthentik/common/styles/authentik.css";
import PFButton from "@patternfly/patternfly/components/Button/button.css"; import PFButton from "@patternfly/patternfly/components/Button/button.css";
@ -30,13 +30,17 @@ export class PlexLoginInit extends BaseStage<
PlexAuthenticationChallenge, PlexAuthenticationChallenge,
PlexAuthenticationChallengeResponseRequest PlexAuthenticationChallengeResponseRequest
> { > {
@state()
authUrl?: string;
static get styles(): CSSResult[] { static get styles(): CSSResult[] {
return [PFBase, PFLogin, PFForm, PFFormControl, PFButton, PFTitle, AKGlobal]; return [PFBase, PFLogin, PFForm, PFFormControl, PFButton, PFTitle, AKGlobal];
} }
async firstUpdated(): Promise<void> { async firstUpdated(): Promise<void> {
const authInfo = await PlexAPIClient.getPin(this.challenge?.clientId || ""); const authInfo = await PlexAPIClient.getPin(this.challenge?.clientId || "");
const authWindow = popupCenterScreen(authInfo.authUrl, "plex auth", 550, 700); this.authUrl = authInfo.authUrl;
const authWindow = await popupCenterScreen(authInfo.authUrl, "plex auth", 550, 700);
PlexAPIClient.pinPoll(this.challenge?.clientId || "", authInfo.pin.id).then((token) => { PlexAPIClient.pinPoll(this.challenge?.clientId || "", authInfo.pin.id).then((token) => {
authWindow?.close(); authWindow?.close();
new SourcesApi(DEFAULT_CONFIG) new SourcesApi(DEFAULT_CONFIG)
@ -69,7 +73,19 @@ export class PlexLoginInit extends BaseStage<
</header> </header>
<div class="pf-c-login__main-body"> <div class="pf-c-login__main-body">
<form class="pf-c-form"> <form class="pf-c-form">
<ak-empty-state ?loading="${true}"> </ak-empty-state> <ak-empty-state ?loading="${true}" header=${t`Waiting for authentication...`}>
</ak-empty-state>
<hr />
<p>${t`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");
}}
>
${t`Open login`}
</button>
</form> </form>
</div> </div>
<footer class="pf-c-login__main-footer"> <footer class="pf-c-login__main-footer">

View File

@ -23,7 +23,7 @@ export class SourceSettingsPlex extends BaseUserSettings {
async doPlex(): Promise<void> { async doPlex(): Promise<void> {
const authInfo = await PlexAPIClient.getPin(this.configureUrl || ""); const authInfo = await PlexAPIClient.getPin(this.configureUrl || "");
const authWindow = popupCenterScreen(authInfo.authUrl, "plex auth", 550, 700); const authWindow = await popupCenterScreen(authInfo.authUrl, "plex auth", 550, 700);
PlexAPIClient.pinPoll(this.configureUrl || "", authInfo.pin.id).then((token) => { PlexAPIClient.pinPoll(this.configureUrl || "", authInfo.pin.id).then((token) => {
authWindow?.close(); authWindow?.close();
new SourcesApi(DEFAULT_CONFIG).sourcesPlexRedeemTokenAuthenticatedCreate({ new SourcesApi(DEFAULT_CONFIG).sourcesPlexRedeemTokenAuthenticatedCreate({