diff --git a/src/helpers/AccountHelper.ts b/src/helpers/AccountHelper.ts index b5f5785..765ad69 100644 --- a/src/helpers/AccountHelper.ts +++ b/src/helpers/AccountHelper.ts @@ -39,6 +39,11 @@ export interface AdminAccountKey { time_add: number; } +export interface AdminResetToken { + token: string; + expire: number; +} + const SESSION_STORAGE_TOKEN = "auth_token"; let currentAccount: AdminAccount | null = null; @@ -150,6 +155,17 @@ export class AccountHelper { }); } + /** + * Generate a access reset token for an admin + * + * @param adminID The id of the target administrator + */ + static async GenerateResetToken(adminID: number): Promise { + return await serverRequest("accounts/generate_reset_token", { + id: adminID, + }); + } + /** * First step of access key enrollment */ diff --git a/src/ui/routes/AccountSettingsRoute.tsx b/src/ui/routes/AccountSettingsRoute.tsx index 947190f..0f797bc 100644 --- a/src/ui/routes/AccountSettingsRoute.tsx +++ b/src/ui/routes/AccountSettingsRoute.tsx @@ -26,6 +26,7 @@ import { AdminAccount, AdminAccountKey, } from "../../helpers/AccountHelper"; +import { CopyToClipboard } from "../../utils/ClipboardUtils"; import { AsyncWidget } from "../widgets/AsyncWidget"; import { input, @@ -192,6 +193,7 @@ export class KeySettingsSection extends React.Component< this.load = this.load.bind(this); this.build = this.build.bind(this); + this.generateResetToken = this.generateResetToken.bind(this); this.registerNewKey = this.registerNewKey.bind(this); this.deleteKey = this.deleteKey.bind(this); } @@ -202,6 +204,27 @@ export class KeySettingsSection extends React.Component< this.setState({ keys: keys }); } + async generateResetToken() { + try { + if ( + !(await matConfirm( + "Do you really want to generate a reset token for this account?" + )) + ) + return; + + const token = await AccountHelper.GenerateResetToken( + this.props.admin.id + ); + + CopyToClipboard(token.token); + snackbar("Reset token was successfully copied to the clipboard!"); + } catch (e) { + console.error(e); + matAlert("Failed to generate a token!"); + } + } + async registerNewKey() { try { const challenge = await AccountHelper.GetKeyRegistrationChallenge(); @@ -297,6 +320,9 @@ export class KeySettingsSection extends React.Component< margin: "5px 10px", }} > +