diff --git a/web/src/admin/providers/saml/SAMLProviderViewPage.ts b/web/src/admin/providers/saml/SAMLProviderViewPage.ts index 62a77f7ac..90255729f 100644 --- a/web/src/admin/providers/saml/SAMLProviderViewPage.ts +++ b/web/src/admin/providers/saml/SAMLProviderViewPage.ts @@ -2,6 +2,7 @@ import "@goauthentik/admin/providers/RelatedApplicationButton"; import "@goauthentik/admin/providers/saml/SAMLProviderForm"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { EVENT_REFRESH } from "@goauthentik/common/constants"; +import { MessageLevel } from "@goauthentik/common/messages"; import { AKElement } from "@goauthentik/elements/Base"; import "@goauthentik/elements/CodeMirror"; import "@goauthentik/elements/Tabs"; @@ -9,6 +10,7 @@ import "@goauthentik/elements/buttons/ActionButton"; import "@goauthentik/elements/buttons/ModalButton"; import "@goauthentik/elements/buttons/SpinnerButton"; import "@goauthentik/elements/events/ObjectChangelog"; +import { showMessage } from "@goauthentik/elements/messages/MessageContainer"; import { t } from "@lingui/macro"; @@ -101,6 +103,14 @@ export class SAMLProviderViewPage extends AKElement { { + if (!navigator.clipboard) { + return Promise.resolve( + showMessage({ + level: MessageLevel.info, + message: this.provider?.urlDownloadMetadata || "", + }), + ); + } return navigator.clipboard.writeText( this.provider?.urlDownloadMetadata || "", ); @@ -371,6 +381,15 @@ export class SAMLProviderViewPage extends AKElement { { + if (!navigator.clipboard) { + return Promise.resolve( + showMessage({ + level: MessageLevel.info, + message: + this.provider?.urlDownloadMetadata || "", + }), + ); + } return navigator.clipboard.writeText( this.provider?.urlDownloadMetadata || "", ); diff --git a/web/src/elements/buttons/TokenCopyButton.ts b/web/src/elements/buttons/TokenCopyButton.ts index 66b717ec1..7104a95ed 100644 --- a/web/src/elements/buttons/TokenCopyButton.ts +++ b/web/src/elements/buttons/TokenCopyButton.ts @@ -62,6 +62,23 @@ export class TokenCopyButton extends ActionButton { return; } this.setLoading(); + // If we're on an insecure origin (non-https and not localhost), we might + // not be able to write to the clipboard, and instead show a message + if (!navigator.clipboard) { + this.callAction() + .then((v) => { + this.setDone(SUCCESS_CLASS); + showMessage({ + level: MessageLevel.info, + message: v as string, + }); + }) + .catch((err: Error) => { + this.setDone(ERROR_CLASS); + throw err; + }); + return; + } // Because safari is stupid, it only allows navigator.clipboard.write directly // in the @click handler. // And also chrome is stupid, because it doesn't accept Promises as values for diff --git a/web/src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts b/web/src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts index 11fe08ea3..1bf3152ad 100644 --- a/web/src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts +++ b/web/src/flow/stages/authenticator_totp/AuthenticatorTOTPStage.ts @@ -82,6 +82,13 @@ export class AuthenticatorTOTPStage extends BaseStage< @click=${(e: Event) => { e.preventDefault(); if (!this.challenge?.configUrl) return; + if (!navigator.clipboard) { + showMessage({ + level: MessageLevel.info, + message: this.challenge?.configUrl, + }); + return; + } navigator.clipboard .writeText(this.challenge?.configUrl) .then(() => {