web/elements: fix copy on insecure origins (#4917)

* web/elements: fix copy on insecure origins

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

* fallback to messages for other clipboard uses

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

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L 2023-03-13 14:18:48 +01:00 committed by GitHub
parent 9219abf84b
commit 61bf73d2f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 0 deletions

View File

@ -2,6 +2,7 @@ import "@goauthentik/admin/providers/RelatedApplicationButton";
import "@goauthentik/admin/providers/saml/SAMLProviderForm"; import "@goauthentik/admin/providers/saml/SAMLProviderForm";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { EVENT_REFRESH } from "@goauthentik/common/constants"; import { EVENT_REFRESH } from "@goauthentik/common/constants";
import { MessageLevel } from "@goauthentik/common/messages";
import { AKElement } from "@goauthentik/elements/Base"; import { AKElement } from "@goauthentik/elements/Base";
import "@goauthentik/elements/CodeMirror"; import "@goauthentik/elements/CodeMirror";
import "@goauthentik/elements/Tabs"; import "@goauthentik/elements/Tabs";
@ -9,6 +10,7 @@ import "@goauthentik/elements/buttons/ActionButton";
import "@goauthentik/elements/buttons/ModalButton"; import "@goauthentik/elements/buttons/ModalButton";
import "@goauthentik/elements/buttons/SpinnerButton"; import "@goauthentik/elements/buttons/SpinnerButton";
import "@goauthentik/elements/events/ObjectChangelog"; import "@goauthentik/elements/events/ObjectChangelog";
import { showMessage } from "@goauthentik/elements/messages/MessageContainer";
import { t } from "@lingui/macro"; import { t } from "@lingui/macro";
@ -101,6 +103,14 @@ export class SAMLProviderViewPage extends AKElement {
<ak-action-button <ak-action-button
class="pf-m-secondary" class="pf-m-secondary"
.apiRequest=${() => { .apiRequest=${() => {
if (!navigator.clipboard) {
return Promise.resolve(
showMessage({
level: MessageLevel.info,
message: this.provider?.urlDownloadMetadata || "",
}),
);
}
return navigator.clipboard.writeText( return navigator.clipboard.writeText(
this.provider?.urlDownloadMetadata || "", this.provider?.urlDownloadMetadata || "",
); );
@ -371,6 +381,15 @@ export class SAMLProviderViewPage extends AKElement {
<ak-action-button <ak-action-button
class="pf-m-secondary" class="pf-m-secondary"
.apiRequest=${() => { .apiRequest=${() => {
if (!navigator.clipboard) {
return Promise.resolve(
showMessage({
level: MessageLevel.info,
message:
this.provider?.urlDownloadMetadata || "",
}),
);
}
return navigator.clipboard.writeText( return navigator.clipboard.writeText(
this.provider?.urlDownloadMetadata || "", this.provider?.urlDownloadMetadata || "",
); );

View File

@ -62,6 +62,23 @@ export class TokenCopyButton extends ActionButton {
return; return;
} }
this.setLoading(); 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 // Because safari is stupid, it only allows navigator.clipboard.write directly
// in the @click handler. // in the @click handler.
// And also chrome is stupid, because it doesn't accept Promises as values for // And also chrome is stupid, because it doesn't accept Promises as values for

View File

@ -82,6 +82,13 @@ export class AuthenticatorTOTPStage extends BaseStage<
@click=${(e: Event) => { @click=${(e: Event) => {
e.preventDefault(); e.preventDefault();
if (!this.challenge?.configUrl) return; if (!this.challenge?.configUrl) return;
if (!navigator.clipboard) {
showMessage({
level: MessageLevel.info,
message: this.challenge?.configUrl,
});
return;
}
navigator.clipboard navigator.clipboard
.writeText(this.challenge?.configUrl) .writeText(this.challenge?.configUrl)
.then(() => { .then(() => {