import "@goauthentik/admin/common/ak-flow-search/ak-source-flow-search"; import { iconHelperText, placeholderHelperText } from "@goauthentik/admin/helperText"; import { BaseSourceForm } from "@goauthentik/admin/sources/BaseSourceForm"; import { UserMatchingModeToLabel } from "@goauthentik/admin/sources/oauth/utils"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { PlexAPIClient, PlexResource, popupCenterScreen } from "@goauthentik/common/helpers/plex"; import { ascii_letters, digits, first, randomString } from "@goauthentik/common/utils"; import { CapabilitiesEnum, WithCapabilitiesConfig, } from "@goauthentik/elements/Interface/capabilitiesProvider"; import "@goauthentik/elements/forms/FormGroup"; import "@goauthentik/elements/forms/HorizontalFormElement"; import "@goauthentik/elements/forms/SearchSelect"; import { msg } from "@lit/localize"; import { TemplateResult, html } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import { ifDefined } from "lit/directives/if-defined.js"; import { FlowsInstancesListDesignationEnum, PlexSource, SourcesApi, UserMatchingModeEnum, } from "@goauthentik/api"; @customElement("ak-source-plex-form") export class PlexSourceForm extends WithCapabilitiesConfig(BaseSourceForm) { async loadInstance(pk: string): Promise { const source = await new SourcesApi(DEFAULT_CONFIG).sourcesPlexRetrieve({ slug: pk, }); this.plexToken = source.plexToken; this.loadServers(); this.clearIcon = false; return source; } @state() clearIcon = false; @property() plexToken?: string; @property({ attribute: false }) plexResources?: PlexResource[]; get defaultInstance(): PlexSource | undefined { return { clientId: randomString(40, ascii_letters + digits), } as PlexSource; } async send(data: PlexSource): Promise { data.plexToken = this.plexToken || ""; let source: PlexSource; if (this.instance?.pk) { source = await new SourcesApi(DEFAULT_CONFIG).sourcesPlexUpdate({ slug: this.instance.slug, plexSourceRequest: data, }); } else { source = await new SourcesApi(DEFAULT_CONFIG).sourcesPlexCreate({ plexSourceRequest: data, }); } if (this.can(CapabilitiesEnum.CanSaveMedia)) { const icon = this.getFormFiles()["icon"]; if (icon || this.clearIcon) { await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconCreate({ slug: source.slug, file: icon, clear: this.clearIcon, }); } } else { await new SourcesApi(DEFAULT_CONFIG).sourcesAllSetIconUrlCreate({ slug: source.slug, filePathRequest: { url: data.icon || "", }, }); } return source; } async doAuth(): Promise { const authInfo = await PlexAPIClient.getPin(this.instance?.clientId || ""); 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; this.loadServers(); }); } async loadServers(): Promise { if (!this.plexToken) { return; } this.plexResources = await new PlexAPIClient(this.plexToken).getServers(); } renderSettings(): TemplateResult { if (!this.plexToken) { return html` `; } return html`

${msg( "Select which server a user has to be a member of to be allowed to authenticate.", )}

${msg("Hold control/command to select multiple items.")}

`; } renderForm(): TemplateResult { return html`

${placeholderHelperText}

${this.can(CapabilitiesEnum.CanSaveMedia) ? html` ${this.instance?.icon ? html`

${msg("Currently set to:")} ${this.instance?.icon}

` : html``}
${this.instance?.icon ? html`

${msg("Delete currently set icon.")}

` : html``}` : html`

${iconHelperText}

`} ${msg("Protocol settings")}
${this.renderSettings()}
${msg("Flow settings")}

${msg("Flow to use when authenticating existing users.")}

${msg("Flow to use when enrolling new users.")}

`; } }