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:
		| @ -62,7 +62,7 @@ export class PlexSourceForm extends ModelForm<PlexSource, string> { | ||||
|     send = async (data: PlexSource): Promise<PlexSource> => { | ||||
|         data.plexToken = this.plexToken || ""; | ||||
|         let source: PlexSource; | ||||
|         if (this.instance) { | ||||
|         if (this.instance?.pk) { | ||||
|             source = await new SourcesApi(DEFAULT_CONFIG).sourcesPlexUpdate({ | ||||
|                 slug: this.instance.slug, | ||||
|                 plexSourceRequest: data, | ||||
| @ -95,7 +95,7 @@ export class PlexSourceForm extends ModelForm<PlexSource, string> { | ||||
|  | ||||
|     async doAuth(): Promise<void> { | ||||
|         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) => { | ||||
|             authWindow?.close(); | ||||
|             this.plexToken = token; | ||||
|  | ||||
| @ -23,15 +23,24 @@ export const DEFAULT_HEADERS = { | ||||
|     "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, | ||||
|         left = (screen.width - w) / 2; | ||||
|     const popup = window.open( | ||||
|         url, | ||||
|         title, | ||||
|         `scrollbars=yes,width=${w},height=${h},top=${top},left=${left}`, | ||||
|     ); | ||||
|     return popup; | ||||
|     return new Promise((resolve) => { | ||||
|         setTimeout(() => { | ||||
|             const popup = window.open( | ||||
|                 url, | ||||
|                 title, | ||||
|                 `scrollbars=yes,width=${w},height=${h},top=${top},left=${left}`, | ||||
|             ); | ||||
|             resolve(popup); | ||||
|         }); | ||||
|     }); | ||||
| } | ||||
|  | ||||
| export class PlexAPIClient { | ||||
|  | ||||
| @ -8,7 +8,7 @@ import { t } from "@lingui/macro"; | ||||
|  | ||||
| import { CSSResult } 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 PFButton from "@patternfly/patternfly/components/Button/button.css"; | ||||
| @ -30,13 +30,17 @@ export class PlexLoginInit extends BaseStage< | ||||
|     PlexAuthenticationChallenge, | ||||
|     PlexAuthenticationChallengeResponseRequest | ||||
| > { | ||||
|     @state() | ||||
|     authUrl?: string; | ||||
|  | ||||
|     static get styles(): CSSResult[] { | ||||
|         return [PFBase, PFLogin, PFForm, PFFormControl, PFButton, PFTitle, AKGlobal]; | ||||
|     } | ||||
|  | ||||
|     async firstUpdated(): Promise<void> { | ||||
|         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) => { | ||||
|             authWindow?.close(); | ||||
|             new SourcesApi(DEFAULT_CONFIG) | ||||
| @ -69,7 +73,19 @@ export class PlexLoginInit extends BaseStage< | ||||
|             </header> | ||||
|             <div class="pf-c-login__main-body"> | ||||
|                 <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> | ||||
|             </div> | ||||
|             <footer class="pf-c-login__main-footer"> | ||||
|  | ||||
| @ -23,7 +23,7 @@ export class SourceSettingsPlex extends BaseUserSettings { | ||||
|  | ||||
|     async doPlex(): Promise<void> { | ||||
|         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) => { | ||||
|             authWindow?.close(); | ||||
|             new SourcesApi(DEFAULT_CONFIG).sourcesPlexRedeemTokenAuthenticatedCreate({ | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Bastien Rivière
					Bastien Rivière