web: isolate clipboard handling (#7229)
We would like to use the clipboard for more than just the token copy button. This commit enables that by separating the "Write to Clipboard" and "Write to Notifications" routines into separate functions, putting "writeToClipboard" into the utilities collection, and clarifying what happens when a custom presses the TokenCopy button.
This commit is contained in:
parent
92d170d065
commit
7e536515c6
|
@ -1,12 +1,14 @@
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { MessageLevel } from "@goauthentik/common/messages";
|
import { MessageLevel } from "@goauthentik/common/messages";
|
||||||
import { showMessage } from "@goauthentik/elements/messages/MessageContainer";
|
import { showMessage } from "@goauthentik/elements/messages/MessageContainer";
|
||||||
import { isSafari } from "@goauthentik/elements/utils/isSafari";
|
import { writeToClipboard } from "@goauthentik/elements/utils/writeToClipboard";
|
||||||
|
|
||||||
|
import { msg } from "@lit/localize";
|
||||||
import { customElement, property } from "lit/decorators.js";
|
import { customElement, property } from "lit/decorators.js";
|
||||||
|
|
||||||
import { CoreApi, ResponseError, TokenView } from "@goauthentik/api";
|
import { CoreApi, ResponseError, TokenView } from "@goauthentik/api";
|
||||||
|
|
||||||
|
import { APIMessage } from "../../messages/Message";
|
||||||
import BaseTaskButton from "../SpinnerButton/BaseTaskButton";
|
import BaseTaskButton from "../SpinnerButton/BaseTaskButton";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -51,35 +53,26 @@ export class TokenCopyButton extends BaseTaskButton {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onSuccess(token: unknown) {
|
async onSuccess(token: unknown) {
|
||||||
super.onSuccess(token);
|
super.onSuccess(token);
|
||||||
if (!isTokenView(token)) {
|
if (!isTokenView(token)) {
|
||||||
throw new Error(`Unrecognized return from server: ${token}`);
|
throw new Error(`Unrecognized return from server: ${token}`);
|
||||||
}
|
}
|
||||||
|
const wroteToClipboard = await writeToClipboard(token.key as string);
|
||||||
// Insecure origins may not have access to the clipboard. Show a message instead.
|
const info: Pick<APIMessage, "message" | "description"> = wroteToClipboard
|
||||||
if (!navigator.clipboard) {
|
? {
|
||||||
showMessage({
|
message: msg("The token has been copied to your clipboard"),
|
||||||
level: MessageLevel.info,
|
}
|
||||||
message: token.key as string,
|
: {
|
||||||
});
|
message: token.key,
|
||||||
return;
|
description: msg(
|
||||||
}
|
"The token was displayed because authentik does not have permission to write to the clipboard",
|
||||||
|
),
|
||||||
// Safari only allows navigator.clipboard.write with native clipboard items.
|
};
|
||||||
if (isSafari()) {
|
showMessage({
|
||||||
navigator.clipboard.write([
|
level: MessageLevel.info,
|
||||||
new ClipboardItem({
|
...info,
|
||||||
"text/plain": new Blob([token.key as string], {
|
});
|
||||||
type: "text/plain",
|
|
||||||
}),
|
|
||||||
}),
|
|
||||||
]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default behavior: write the token to the clipboard.
|
|
||||||
navigator.clipboard.writeText(token.key as string);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async onError(error: unknown) {
|
async onError(error: unknown) {
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
import { isSafari } from "./isSafari";
|
||||||
|
|
||||||
|
export async function writeToClipboard(message: string) {
|
||||||
|
if (!navigator.clipboard) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Safari only allows navigator.clipboard.write with native clipboard items.
|
||||||
|
try {
|
||||||
|
if (isSafari()) {
|
||||||
|
await navigator.clipboard.write([
|
||||||
|
new ClipboardItem({
|
||||||
|
"text/plain": new Blob([message], {
|
||||||
|
type: "text/plain",
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
await navigator.clipboard.writeText(message);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (_) {
|
||||||
|
/* no op */
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
Reference in New Issue