Files
authentik/web/src/elements/buttons/TokenCopyButton.ts
Jens Langhammer 11334cf638 web: re-cleanup imports not being absolute
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
2022-09-06 19:02:40 +02:00

120 lines
4.8 KiB
TypeScript

import { DEFAULT_CONFIG } from "@goauthentik/web/api/Config";
import { ERROR_CLASS, SECONDARY_CLASS, SUCCESS_CLASS } from "@goauthentik/web/constants";
import { PFSize } from "@goauthentik/web/elements/Spinner";
import { ActionButton } from "@goauthentik/web/elements/buttons/ActionButton";
import { MessageLevel } from "@goauthentik/web/elements/messages/Message";
import { showMessage } from "@goauthentik/web/elements/messages/MessageContainer";
import { TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { CoreApi, ResponseError } from "@goauthentik/api";
@customElement("ak-token-copy-button")
export class TokenCopyButton extends ActionButton {
@property()
identifier?: string;
@property()
buttonClass: string = SECONDARY_CLASS;
apiRequest: () => Promise<unknown> = () => {
this.setLoading();
if (!this.identifier) {
return Promise.reject();
}
return new CoreApi(DEFAULT_CONFIG)
.coreTokensViewKeyRetrieve({
identifier: this.identifier,
})
.then((token) => {
if (!token.key) {
return Promise.reject();
}
setTimeout(() => {
this.buttonClass = SECONDARY_CLASS;
}, 1500);
this.buttonClass = SUCCESS_CLASS;
return token.key;
})
.catch((err: Error | ResponseError | undefined) => {
this.buttonClass = ERROR_CLASS;
if (!(err instanceof ResponseError)) {
setTimeout(() => {
this.buttonClass = SECONDARY_CLASS;
}, 1500);
throw err;
}
return err.response.json().then((errResp) => {
setTimeout(() => {
this.buttonClass = SECONDARY_CLASS;
}, 1500);
throw new Error(errResp["detail"]);
});
});
};
render(): TemplateResult {
return html`<button
class="pf-c-button pf-m-progress ${this.classList.toString()}"
@click=${() => {
if (this.isRunning === true) {
return;
}
this.setLoading();
// 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
// ClipboardItem, so now there's two implementations
if (
navigator.userAgent.includes("Safari") &&
!navigator.userAgent.includes("Chrome")
) {
navigator.clipboard.write([
new ClipboardItem({
"text/plain": (this.callAction() as Promise<string>)
.then((key: string) => {
this.setDone(SUCCESS_CLASS);
return new Blob([key], {
type: "text/plain",
});
})
.catch((err: Error) => {
this.setDone(ERROR_CLASS);
throw err;
}),
}),
]);
} else {
(this.callAction() as Promise<string>)
.then((key: string) => {
navigator.clipboard.writeText(key).then(() => {
this.setDone(SUCCESS_CLASS);
});
})
.catch((err: ResponseError | Error) => {
if (!(err instanceof ResponseError)) {
showMessage({
level: MessageLevel.error,
message: err.message,
});
return;
}
return err.response.json().then((errResp) => {
this.setDone(ERROR_CLASS);
throw new Error(errResp["detail"]);
});
});
}
}}
>
${this.isRunning
? html`<span class="pf-c-button__progress">
<ak-spinner size=${PFSize.Medium}></ak-spinner>
</span>`
: ""}
<slot></slot>
</button>`;
}
}