remove setErrorText and replace it with proper error text & notifs
This commit is contained in:
parent
886ca8a240
commit
0695adec71
|
@ -60,23 +60,3 @@ export function addClipboardNotifications(clipboard: ClipboardJS, timeout = 1000
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function setErrorText(text: string): void {
|
|
||||||
const errorTextElement = document.querySelector("#errorText");
|
|
||||||
if (errorTextElement) {
|
|
||||||
/* eslint-disable @typescript-eslint/no-unnecessary-type-assertion */
|
|
||||||
const p = document.querySelector("#errorText") as HTMLParagraphElement;
|
|
||||||
p.innerText = `Error: ${text}`;
|
|
||||||
/* eslint-enable @typescript-eslint/no-unnecessary-type-assertion */
|
|
||||||
}
|
|
||||||
UIkit.notification({
|
|
||||||
message: `Error: ${text}`,
|
|
||||||
status: "danger",
|
|
||||||
pos: "top-center",
|
|
||||||
timeout: 2000,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function notImplemented(): void {
|
|
||||||
setErrorText(i18next.t("not_implemented"));
|
|
||||||
}
|
|
||||||
|
|
63
src/ui/elements/ErrorMessage.tsx
Normal file
63
src/ui/elements/ErrorMessage.tsx
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
import { Component, createRef } from "preact";
|
||||||
|
import UIkit from "uikit";
|
||||||
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
type ErrorMessageState = {
|
||||||
|
errorMessage: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Use only when a error text element can't be used
|
||||||
|
// e.g inside componentDidMount
|
||||||
|
export function sendErrorNotification(errorMessage: string) {
|
||||||
|
UIkit.notification({
|
||||||
|
message: `Error: ${errorMessage}`,
|
||||||
|
status: "danger",
|
||||||
|
pos: "top-center",
|
||||||
|
timeout: 2000,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function notImplementedNotification(): void {
|
||||||
|
sendErrorNotification(i18next.t("not_implemented"));
|
||||||
|
}
|
||||||
|
|
||||||
|
export class ErrorMessage extends Component<unknown, ErrorMessageState> {
|
||||||
|
public setErrorMessage(errorMessage: string) {
|
||||||
|
this.setState({
|
||||||
|
errorMessage: `Error: ${errorMessage}`,
|
||||||
|
});
|
||||||
|
|
||||||
|
sendErrorNotification(errorMessage);
|
||||||
|
|
||||||
|
// make browser focus on the change.
|
||||||
|
this.errorMessageRef.current.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public clear() {
|
||||||
|
this.setState({ errorMessage: "" });
|
||||||
|
}
|
||||||
|
|
||||||
|
errorMessageRef = createRef<HTMLParagraphElement>();
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<p
|
||||||
|
ref={this.errorMessageRef}
|
||||||
|
{
|
||||||
|
...[] /* keeping for backwards compatability with seterrorMessage*/
|
||||||
|
}
|
||||||
|
{
|
||||||
|
...[] /* TODO: remove when finished removing all references to seterrorMessage */
|
||||||
|
}
|
||||||
|
id="errorMessage"
|
||||||
|
class="uk-text-danger"
|
||||||
|
{
|
||||||
|
...[] /* makes screenreaders read out changes to this element's content*/
|
||||||
|
}
|
||||||
|
aria-live="assertive"
|
||||||
|
>
|
||||||
|
{this.state.errorMessage || ""}
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ import { DefaultPageProps } from "../../../types/DefaultPageProps";
|
||||||
import { Grid, GridSizes } from "../../elements/Grid";
|
import { Grid, GridSizes } from "../../elements/Grid";
|
||||||
import { PageTitle } from "../../elements/PageTitle";
|
import { PageTitle } from "../../elements/PageTitle";
|
||||||
import { Tile } from "../../elements/Tile";
|
import { Tile } from "../../elements/Tile";
|
||||||
import { notImplemented } from "../../../pageUtils";
|
import { notImplementedNotification } from "../../elements/ErrorMessage";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -23,19 +23,19 @@ export class AccessHomePage extends Component<DefaultPageProps> {
|
||||||
title={i18next.t("access_entities_title")}
|
title={i18next.t("access_entities_title")}
|
||||||
description={i18next.t("access_entities_description")}
|
description={i18next.t("access_entities_description")}
|
||||||
icon="user"
|
icon="user"
|
||||||
onclick={async () => notImplemented()}
|
onclick={async () => notImplementedNotification()}
|
||||||
/>
|
/>
|
||||||
<Tile
|
<Tile
|
||||||
title={i18next.t("access_groups_title")}
|
title={i18next.t("access_groups_title")}
|
||||||
description={i18next.t("access_groups_description")}
|
description={i18next.t("access_groups_description")}
|
||||||
icon="users"
|
icon="users"
|
||||||
onclick={async () => notImplemented()}
|
onclick={async () => notImplementedNotification()}
|
||||||
/>
|
/>
|
||||||
<Tile
|
<Tile
|
||||||
title={i18next.t("access_leases_title")}
|
title={i18next.t("access_leases_title")}
|
||||||
description={i18next.t("access_leases_description")}
|
description={i18next.t("access_leases_description")}
|
||||||
icon="unlock"
|
icon="unlock"
|
||||||
onclick={async () => notImplemented()}
|
onclick={async () => notImplementedNotification()}
|
||||||
/>
|
/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { Component, JSX } from "preact";
|
||||||
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
import { PageTitle } from "../../../elements/PageTitle";
|
import { PageTitle } from "../../../elements/PageTitle";
|
||||||
import { authViewConfigURL, userPassUserListURL } from "../../pageLinks";
|
import { authViewConfigURL, userPassUserListURL } from "../../pageLinks";
|
||||||
import { notImplemented } from "../../../../pageUtils";
|
import { notImplementedNotification, sendErrorNotification } from "../../../elements/ErrorMessage";
|
||||||
import { objectToMap } from "../../../../utils";
|
import { objectToMap } from "../../../../utils";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
@ -46,7 +46,7 @@ export function AuthListElement(props: AuthListElementProps): JSX.Element {
|
||||||
<Button
|
<Button
|
||||||
text={i18next.t("auth_home_edit_config")}
|
text={i18next.t("auth_home_edit_config")}
|
||||||
color="primary"
|
color="primary"
|
||||||
onClick={notImplemented}
|
onClick={notImplementedNotification}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -55,8 +55,13 @@ export function AuthListElement(props: AuthListElementProps): JSX.Element {
|
||||||
|
|
||||||
export class AuthHome extends Component<DefaultPageProps, { authList: Map<string, AuthMethod> }> {
|
export class AuthHome extends Component<DefaultPageProps, { authList: Map<string, AuthMethod> }> {
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const authList = objectToMap(await this.props.api.listAuth()) as Map<string, AuthMethod>;
|
try {
|
||||||
this.setState({ authList });
|
const authList = objectToMap(await this.props.api.listAuth()) as Map<string, AuthMethod>;
|
||||||
|
this.setState({ authList });
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
if (!this.state.authList) return;
|
if (!this.state.authList) return;
|
||||||
|
|
|
@ -4,18 +4,27 @@ import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
import { HeaderAndContent } from "../../../elements/HeaderAndContent";
|
import { HeaderAndContent } from "../../../elements/HeaderAndContent";
|
||||||
import { PageTitle } from "../../../elements/PageTitle";
|
import { PageTitle } from "../../../elements/PageTitle";
|
||||||
import { objectToMap, toStr } from "../../../../utils";
|
import { objectToMap, toStr } from "../../../../utils";
|
||||||
|
import { sendErrorNotification } from "../../../elements/ErrorMessage";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class AuthViewConfig extends Component<DefaultPageProps, { authMethod: AuthMethod }> {
|
export class AuthViewConfig extends Component<DefaultPageProps, { authMethod: AuthMethod }> {
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
const authList = objectToMap(await this.props.api.listAuth()) as Map<string, AuthMethod>;
|
try {
|
||||||
const authMethod = authList.get(baseMount + "/");
|
const authList = objectToMap(await this.props.api.listAuth()) as Map<string, AuthMethod>;
|
||||||
this.setState({ authMethod: authMethod });
|
const authMethod = authList.get(baseMount + "/");
|
||||||
|
this.setState({ authMethod: authMethod });
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.state.authMethod) return;
|
if (!this.state.authMethod) return;
|
||||||
|
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
|
|
||||||
const authMethod = this.state.authMethod;
|
const authMethod = this.state.authMethod;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
import { Button } from "../../../../elements/Button";
|
import { Button } from "../../../../elements/Button";
|
||||||
import { Component } from "preact";
|
import { Component, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../../../../elements/ErrorMessage";
|
||||||
|
import { Margin } from "../../../../elements/Margin";
|
||||||
import { PageTitle } from "../../../../elements/PageTitle";
|
import { PageTitle } from "../../../../elements/PageTitle";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { userPassUserListURL } from "../../../pageLinks";
|
import { userPassUserListURL } from "../../../pageLinks";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class UserPassUserDelete extends Component<DefaultPageProps> {
|
export class UserPassUserDelete extends Component<DefaultPageProps> {
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
const user = this.props.matches["user"];
|
const user = this.props.matches["user"];
|
||||||
|
@ -16,12 +20,22 @@ export class UserPassUserDelete extends Component<DefaultPageProps> {
|
||||||
<PageTitle title={i18next.t("userpass_user_delete_title")} />
|
<PageTitle title={i18next.t("userpass_user_delete_title")} />
|
||||||
<div>
|
<div>
|
||||||
<h5>{i18next.t("userpass_user_delete_text")}</h5>
|
<h5>{i18next.t("userpass_user_delete_text")}</h5>
|
||||||
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
text={i18next.t("common_delete")}
|
text={i18next.t("common_delete")}
|
||||||
color="danger"
|
color="danger"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await this.props.api.deleteUserPassUser(baseMount, user);
|
try {
|
||||||
route(userPassUserListURL(baseMount));
|
await this.props.api.deleteUserPassUser(baseMount, user);
|
||||||
|
route(userPassUserListURL(baseMount));
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Button } from "../../../../elements/Button";
|
import { Button } from "../../../../elements/Button";
|
||||||
import { Component } from "preact";
|
import { Component, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage, sendErrorNotification } from "../../../../elements/ErrorMessage";
|
||||||
import { Form } from "../../../../elements/Form";
|
import { Form } from "../../../../elements/Form";
|
||||||
import { InputWithTitle } from "../../../../elements/InputWithTitle";
|
import { InputWithTitle } from "../../../../elements/InputWithTitle";
|
||||||
import { Margin } from "../../../../elements/Margin";
|
import { Margin } from "../../../../elements/Margin";
|
||||||
|
@ -8,7 +9,6 @@ import { MarginInline } from "../../../../elements/MarginInline";
|
||||||
import { PageTitle } from "../../../../elements/PageTitle";
|
import { PageTitle } from "../../../../elements/PageTitle";
|
||||||
import { UserType } from "../../../../../api/types/user";
|
import { UserType } from "../../../../../api/types/user";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { setErrorText } from "../../../../../pageUtils";
|
|
||||||
import { toStr } from "../../../../../utils";
|
import { toStr } from "../../../../../utils";
|
||||||
import { userPassUserViewURL } from "../../../pageLinks";
|
import { userPassUserViewURL } from "../../../pageLinks";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
@ -16,12 +16,19 @@ import i18next from "i18next";
|
||||||
const removeEmptyStrings = (arr: string[]) => arr.filter((e) => e.length > 0);
|
const removeEmptyStrings = (arr: string[]) => arr.filter((e) => e.length > 0);
|
||||||
|
|
||||||
export class UserPassUserEdit extends Component<DefaultPageProps, { user_data: UserType }> {
|
export class UserPassUserEdit extends Component<DefaultPageProps, { user_data: UserType }> {
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
const user = this.props.matches["user"];
|
const user = this.props.matches["user"];
|
||||||
|
|
||||||
const user_data = await this.props.api.getUserPassUser(baseMount, user);
|
try {
|
||||||
this.setState({ user_data });
|
const user_data = await this.props.api.getUserPassUser(baseMount, user);
|
||||||
|
this.setState({ user_data });
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -111,7 +118,11 @@ export class UserPassUserEdit extends Component<DefaultPageProps, { user_data: U
|
||||||
value={toStr(user_data.token_ttl)}
|
value={toStr(user_data.token_ttl)}
|
||||||
/>
|
/>
|
||||||
</InputWithTitle>
|
</InputWithTitle>
|
||||||
<p class="uk-text-danger" id="errorText" />
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<MarginInline>
|
<MarginInline>
|
||||||
<Button text={i18next.t("common_edit")} color="primary" type="submit" />
|
<Button text={i18next.t("common_edit")} color="primary" type="submit" />
|
||||||
</MarginInline>
|
</MarginInline>
|
||||||
|
@ -134,7 +145,9 @@ export class UserPassUserEdit extends Component<DefaultPageProps, { user_data: U
|
||||||
token_policies: removeEmptyStrings(String(data.get("policies")).split(",")),
|
token_policies: removeEmptyStrings(String(data.get("policies")).split(",")),
|
||||||
token_ttl: parseInt(data.get("initial_ttl") as string, 10),
|
token_ttl: parseInt(data.get("initial_ttl") as string, 10),
|
||||||
};
|
};
|
||||||
|
|
||||||
const password = data.get("password") as string;
|
const password = data.get("password") as string;
|
||||||
|
|
||||||
if (password.length > 0) {
|
if (password.length > 0) {
|
||||||
apiData.password = password;
|
apiData.password = password;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +157,7 @@ export class UserPassUserEdit extends Component<DefaultPageProps, { user_data: U
|
||||||
route(userPassUserViewURL(baseMount, user));
|
route(userPassUserViewURL(baseMount, user));
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
setErrorText(error.message);
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
import { Button } from "../../../../elements/Button";
|
import { Button } from "../../../../elements/Button";
|
||||||
import { Component } from "preact";
|
import { Component, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../../../../elements/ErrorMessage";
|
||||||
import { Form } from "../../../../elements/Form";
|
import { Form } from "../../../../elements/Form";
|
||||||
import { Margin } from "../../../../elements/Margin";
|
import { Margin } from "../../../../elements/Margin";
|
||||||
import { MarginInline } from "../../../../elements/MarginInline";
|
import { MarginInline } from "../../../../elements/MarginInline";
|
||||||
import { PageTitle } from "../../../../elements/PageTitle";
|
import { PageTitle } from "../../../../elements/PageTitle";
|
||||||
import { UserType } from "../../../../../api/types/user";
|
import { UserType } from "../../../../../api/types/user";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { setErrorText } from "../../../../../pageUtils";
|
|
||||||
import { userPassUserViewURL } from "../../../pageLinks";
|
import { userPassUserViewURL } from "../../../pageLinks";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class UserPassUserNew extends Component<DefaultPageProps> {
|
export class UserPassUserNew extends Component<DefaultPageProps> {
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -33,7 +35,11 @@ export class UserPassUserNew extends Component<DefaultPageProps> {
|
||||||
placeholder={i18next.t("common_password")}
|
placeholder={i18next.t("common_password")}
|
||||||
/>
|
/>
|
||||||
</Margin>
|
</Margin>
|
||||||
<p class="uk-text-danger" id="errorText" />
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<MarginInline>
|
<MarginInline>
|
||||||
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
||||||
</MarginInline>
|
</MarginInline>
|
||||||
|
@ -56,7 +62,7 @@ export class UserPassUserNew extends Component<DefaultPageProps> {
|
||||||
route(userPassUserViewURL(baseMount, data.get("username") as string));
|
route(userPassUserViewURL(baseMount, data.get("username") as string));
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
setErrorText(error.message);
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { HeaderAndContent } from "../../../../elements/HeaderAndContent";
|
||||||
import { Margin } from "../../../../elements/Margin";
|
import { Margin } from "../../../../elements/Margin";
|
||||||
import { PageTitle } from "../../../../elements/PageTitle";
|
import { PageTitle } from "../../../../elements/PageTitle";
|
||||||
import { UserType } from "../../../../../api/types/user";
|
import { UserType } from "../../../../../api/types/user";
|
||||||
|
import { sendErrorNotification } from "../../../../elements/ErrorMessage";
|
||||||
import { toStr } from "../../../../../utils";
|
import { toStr } from "../../../../../utils";
|
||||||
import { userPassUserDeleteURL, userPassUserEditURL } from "../../../pageLinks";
|
import { userPassUserDeleteURL, userPassUserEditURL } from "../../../pageLinks";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
@ -14,14 +15,20 @@ export class UserPassUserView extends Component<DefaultPageProps, { user_data: U
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
const user = this.props.matches["user"];
|
const user = this.props.matches["user"];
|
||||||
|
|
||||||
const user_data = await this.props.api.getUserPassUser(baseMount, user);
|
try {
|
||||||
this.setState({ user_data });
|
const user_data = await this.props.api.getUserPassUser(baseMount, user);
|
||||||
|
this.setState({ user_data });
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.state.user_data) return;
|
if (!this.state.user_data) return;
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
const user = this.props.matches["user"];
|
const user = this.props.matches["user"];
|
||||||
|
|
||||||
const user_data = this.state.user_data;
|
const user_data = this.state.user_data;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -4,14 +4,21 @@ import { DefaultPageProps } from "../../../../../types/DefaultPageProps";
|
||||||
import { Margin } from "../../../../elements/Margin";
|
import { Margin } from "../../../../elements/Margin";
|
||||||
import { PageTitle } from "../../../../elements/PageTitle";
|
import { PageTitle } from "../../../../elements/PageTitle";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
|
import { sendErrorNotification } from "../../../../elements/ErrorMessage";
|
||||||
import { userPassUserNewURL, userPassUserViewURL } from "../../../pageLinks";
|
import { userPassUserNewURL, userPassUserViewURL } from "../../../pageLinks";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class UserPassUsersList extends Component<DefaultPageProps, { users: string[] }> {
|
export class UserPassUsersList extends Component<DefaultPageProps, { users: string[] }> {
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
const users = await this.props.api.listUserPassUsers(baseMount);
|
|
||||||
this.setState({ users });
|
try {
|
||||||
|
const users = await this.props.api.listUserPassUsers(baseMount);
|
||||||
|
this.setState({ users });
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -5,8 +5,9 @@ import { Margin } from "../elements/Margin";
|
||||||
import { PageTitle } from "../elements/PageTitle";
|
import { PageTitle } from "../elements/PageTitle";
|
||||||
import { Tile } from "../elements/Tile";
|
import { Tile } from "../elements/Tile";
|
||||||
import { TokenInfo } from "../../api/types/token";
|
import { TokenInfo } from "../../api/types/token";
|
||||||
import { pageChecks, setErrorText } from "../../pageUtils";
|
import { pageChecks } from "../../pageUtils";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
|
import { sendErrorNotification } from "../elements/ErrorMessage";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
type HomeState = {
|
type HomeState = {
|
||||||
|
@ -17,18 +18,31 @@ type HomeState = {
|
||||||
|
|
||||||
export class Home extends Component<DefaultPageProps, HomeState> {
|
export class Home extends Component<DefaultPageProps, HomeState> {
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
|
// Always call pageChecks on /home
|
||||||
if (await pageChecks("/home", this.props.api, this.props.settings)) return;
|
if (await pageChecks("/home", this.props.api, this.props.settings)) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.populateState();
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async populateState() {
|
||||||
|
// Check if logged in otherise redirect to /login
|
||||||
let selfTokenInfo: TokenInfo;
|
let selfTokenInfo: TokenInfo;
|
||||||
try {
|
try {
|
||||||
selfTokenInfo = await this.props.api.lookupSelf();
|
selfTokenInfo = await this.props.api.lookupSelf();
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
setErrorText(error.message);
|
|
||||||
if (error.message == "permission denied") {
|
if (error.message == "permission denied") {
|
||||||
this.props.settings.token = "";
|
this.props.settings.token = "";
|
||||||
route("/login", true);
|
route("/login", true);
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ export class Login extends Component<DefaultPageProps> {
|
||||||
<a>{i18next.t("log_in_with_username")}</a>
|
<a>{i18next.t("log_in_with_username")}</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p id="errorText" class="uk-text-danger" />
|
|
||||||
<ul class="uk-switcher uk-margin switcher-container">
|
<ul class="uk-switcher uk-margin switcher-container">
|
||||||
<li>
|
<li>
|
||||||
<TokenLoginForm {...this.props} />
|
<TokenLoginForm {...this.props} />
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
import { Button } from "../elements/Button";
|
import { Button } from "../elements/Button";
|
||||||
import { Component, JSX } from "preact";
|
import { Component, JSX, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../elements/ErrorMessage";
|
||||||
import { Form } from "../elements/Form";
|
import { Form } from "../elements/Form";
|
||||||
import { Margin } from "../elements/Margin";
|
import { Margin } from "../elements/Margin";
|
||||||
import { MarginInline } from "../elements/MarginInline";
|
import { MarginInline } from "../elements/MarginInline";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { setErrorText } from "../../pageUtils";
|
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class TokenLoginForm extends Component<DefaultPageProps> {
|
export class TokenLoginForm extends Component<DefaultPageProps> {
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
render(): JSX.Element {
|
render(): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<Form onSubmit={(data) => this.onSubmit(data)}>
|
<Form onSubmit={(data) => this.onSubmit(data)}>
|
||||||
|
@ -22,6 +24,11 @@ export class TokenLoginForm extends Component<DefaultPageProps> {
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</Margin>
|
</Margin>
|
||||||
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<MarginInline>
|
<MarginInline>
|
||||||
<Button text={i18next.t("log_in_btn")} color="primary" type="submit" />
|
<Button text={i18next.t("log_in_btn")} color="primary" type="submit" />
|
||||||
</MarginInline>
|
</MarginInline>
|
||||||
|
@ -31,6 +38,9 @@ export class TokenLoginForm extends Component<DefaultPageProps> {
|
||||||
|
|
||||||
async onSubmit(data: FormData): Promise<void> {
|
async onSubmit(data: FormData): Promise<void> {
|
||||||
const token = data.get("token");
|
const token = data.get("token");
|
||||||
|
|
||||||
|
const previousToken = this.props.settings.token;
|
||||||
|
|
||||||
this.props.settings.token = token as string;
|
this.props.settings.token = token as string;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -39,11 +49,18 @@ export class TokenLoginForm extends Component<DefaultPageProps> {
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
document.querySelector("#tokenInput").classList.add("uk-form-danger");
|
document.querySelector("#tokenInput").classList.add("uk-form-danger");
|
||||||
|
|
||||||
|
let errorMessage: string;
|
||||||
|
|
||||||
if (error.message == "permission denied") {
|
if (error.message == "permission denied") {
|
||||||
setErrorText(i18next.t("log_in_token_login_error"));
|
errorMessage = i18next.t("log_in_token_login_error");
|
||||||
} else {
|
} else {
|
||||||
setErrorText(error.message);
|
errorMessage = error.message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.errorMessageRef.current.setErrorMessage(errorMessage);
|
||||||
|
|
||||||
|
this.props.settings.token = previousToken;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
import { Button } from "../elements/Button";
|
import { Button } from "../elements/Button";
|
||||||
import { Component, JSX } from "preact";
|
import { Component, JSX, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../elements/ErrorMessage";
|
||||||
import { Form } from "../elements/Form";
|
import { Form } from "../elements/Form";
|
||||||
import { Margin } from "../elements/Margin";
|
import { Margin } from "../elements/Margin";
|
||||||
import { MarginInline } from "../elements/MarginInline";
|
import { MarginInline } from "../elements/MarginInline";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { setErrorText } from "../../pageUtils";
|
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class UsernameLoginForm extends Component<DefaultPageProps> {
|
export class UsernameLoginForm extends Component<DefaultPageProps> {
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
render(): JSX.Element {
|
render(): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<Form onSubmit={(data) => this.onSubmit(data)}>
|
<Form onSubmit={(data) => this.onSubmit(data)}>
|
||||||
|
@ -32,6 +34,11 @@ export class UsernameLoginForm extends Component<DefaultPageProps> {
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</Margin>
|
</Margin>
|
||||||
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<MarginInline>
|
<MarginInline>
|
||||||
<Button text={i18next.t("log_in_btn")} color="primary" type="submit" />
|
<Button text={i18next.t("log_in_btn")} color="primary" type="submit" />
|
||||||
</MarginInline>
|
</MarginInline>
|
||||||
|
@ -40,6 +47,8 @@ export class UsernameLoginForm extends Component<DefaultPageProps> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async onSubmit(data: FormData): Promise<void> {
|
async onSubmit(data: FormData): Promise<void> {
|
||||||
|
const previousToken = this.props.settings.token;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await this.props.api.usernameLogin(
|
const res = await this.props.api.usernameLogin(
|
||||||
data.get("username") as string,
|
data.get("username") as string,
|
||||||
|
@ -51,7 +60,8 @@ export class UsernameLoginForm extends Component<DefaultPageProps> {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
document.querySelector("#usernameInput").classList.add("uk-form-danger");
|
document.querySelector("#usernameInput").classList.add("uk-form-danger");
|
||||||
document.querySelector("#passwordInput").classList.add("uk-form-danger");
|
document.querySelector("#passwordInput").classList.add("uk-form-danger");
|
||||||
setErrorText(error.message);
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
|
this.props.settings.token = previousToken;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import { Button } from "../elements/Button";
|
import { Button } from "../elements/Button";
|
||||||
import { Component, JSX, createRef } from "preact";
|
import { Component, JSX, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../elements/ErrorMessage";
|
||||||
|
import { Margin } from "../elements/Margin";
|
||||||
import { PageTitle } from "../elements/PageTitle";
|
import { PageTitle } from "../elements/PageTitle";
|
||||||
import { addClipboardNotifications, setErrorText } from "../../pageUtils";
|
import { addClipboardNotifications } from "../../pageUtils";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import ClipboardJS from "clipboard";
|
import ClipboardJS from "clipboard";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
@ -36,9 +38,7 @@ export class Me extends Component<DefaultPageProps, MeState> {
|
||||||
this.state = this.defaultState;
|
this.state = this.defaultState;
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
this.setState(this.defaultState);
|
|
||||||
}
|
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
let canSealVault = false;
|
let canSealVault = false;
|
||||||
|
@ -55,13 +55,20 @@ export class Me extends Component<DefaultPageProps, MeState> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
themeSelectRef = createRef<HTMLSelectElement>();
|
componentWillUnmount() {
|
||||||
|
this.setState(this.defaultState);
|
||||||
|
}
|
||||||
|
|
||||||
render(): JSX.Element {
|
render(): JSX.Element {
|
||||||
return (
|
return (
|
||||||
this.state.loaded && (
|
this.state.loaded && (
|
||||||
<>
|
<>
|
||||||
<PageTitle title={i18next.t("me_page_title")} />
|
<PageTitle title={i18next.t("me_page_title")} />
|
||||||
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<ul class="uk-nav">
|
<ul class="uk-nav">
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
|
@ -84,7 +91,7 @@ export class Me extends Component<DefaultPageProps, MeState> {
|
||||||
route("/");
|
route("/");
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
setErrorText(error.message);
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
@ -95,8 +102,13 @@ export class Me extends Component<DefaultPageProps, MeState> {
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await this.props.api.sealVault();
|
try {
|
||||||
route("/unseal", true);
|
await this.props.api.sealVault();
|
||||||
|
route("/unseal", true);
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{i18next.t("me_seal_vault_btn")}
|
{i18next.t("me_seal_vault_btn")}
|
||||||
|
|
|
@ -5,18 +5,24 @@ import { Margin } from "../../elements/Margin";
|
||||||
import { PageTitle } from "../../elements/PageTitle";
|
import { PageTitle } from "../../elements/PageTitle";
|
||||||
import { policyNewURL, policyViewURL } from "../pageLinks";
|
import { policyNewURL, policyViewURL } from "../pageLinks";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
|
import { sendErrorNotification } from "../../elements/ErrorMessage";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class PoliciesHome extends Component<DefaultPageProps, { policies: string[] }> {
|
export class PoliciesHome extends Component<DefaultPageProps, { policies: string[] }> {
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
let policies = await this.props.api.getPolicies();
|
try {
|
||||||
policies = policies.sort();
|
let policies = await this.props.api.getPolicies();
|
||||||
policies = policies.filter(function (policy_name) {
|
policies = policies.sort();
|
||||||
return policy_name !== "root";
|
policies = policies.filter(function (policy_name) {
|
||||||
});
|
return policy_name !== "root";
|
||||||
this.setState({
|
});
|
||||||
policies: policies,
|
this.setState({
|
||||||
});
|
policies: policies,
|
||||||
|
});
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -1,12 +1,26 @@
|
||||||
import { Button } from "../../elements/Button";
|
import { Button } from "../../elements/Button";
|
||||||
import { Component } from "preact";
|
import { Component, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../../elements/ErrorMessage";
|
||||||
|
import { Margin } from "../../elements/Margin";
|
||||||
import { PageTitle } from "../../elements/PageTitle";
|
import { PageTitle } from "../../elements/PageTitle";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { setErrorText } from "../../../pageUtils";
|
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class PolicyDelete extends Component<DefaultPageProps> {
|
export class PolicyDelete extends Component<DefaultPageProps> {
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
|
async onDelete() {
|
||||||
|
const policyName = this.props.matches["policyName"];
|
||||||
|
try {
|
||||||
|
await this.props.api.deletePolicy(policyName);
|
||||||
|
route("/policies");
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const policyName = this.props.matches["policyName"];
|
const policyName = this.props.matches["policyName"];
|
||||||
return (
|
return (
|
||||||
|
@ -14,18 +28,15 @@ export class PolicyDelete extends Component<DefaultPageProps> {
|
||||||
<PageTitle title={i18next.t("policy_delete_title", { policy: policyName })} />
|
<PageTitle title={i18next.t("policy_delete_title", { policy: policyName })} />
|
||||||
<div>
|
<div>
|
||||||
<h5>{i18next.t("policy_delete_text")}</h5>
|
<h5>{i18next.t("policy_delete_text")}</h5>
|
||||||
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
text={i18next.t("common_delete")}
|
text={i18next.t("common_delete")}
|
||||||
color="danger"
|
color="danger"
|
||||||
onClick={async () => {
|
onClick={async () => await this.onDelete()}
|
||||||
try {
|
|
||||||
await this.props.api.deletePolicy(policyName);
|
|
||||||
route("/policies");
|
|
||||||
} catch (e: unknown) {
|
|
||||||
const error = e as Error;
|
|
||||||
setErrorText(error.message);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -1,28 +1,30 @@
|
||||||
import { Button } from "../../elements/Button";
|
import { Button } from "../../elements/Button";
|
||||||
import { CodeEditor } from "../../elements/CodeEditor";
|
import { CodeEditor } from "../../elements/CodeEditor";
|
||||||
import { Component, JSX } from "preact";
|
import { Component, JSX, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage, sendErrorNotification } from "../../elements/ErrorMessage";
|
||||||
import { Margin } from "../../elements/Margin";
|
import { Margin } from "../../elements/Margin";
|
||||||
import { MarginInline } from "../../elements/MarginInline";
|
import { MarginInline } from "../../elements/MarginInline";
|
||||||
import { PageTitle } from "../../elements/PageTitle";
|
import { PageTitle } from "../../elements/PageTitle";
|
||||||
import { policyViewURL } from "../pageLinks";
|
import { policyViewURL } from "../pageLinks";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { setErrorText } from "../../../pageUtils";
|
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
type PolicyEditorProps = DefaultPageProps & {
|
type PolicyEditorProps = DefaultPageProps & {
|
||||||
policyName: string;
|
policyName: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type PolicyEditorState =
|
type PolicyEditorStateUnloaded = {
|
||||||
| {
|
dataLoaded: false;
|
||||||
dataLoaded: false;
|
};
|
||||||
}
|
|
||||||
| {
|
type PolicyEditorStateLoaded = {
|
||||||
dataLoaded: true;
|
dataLoaded: true;
|
||||||
policyData: string;
|
policyData: string;
|
||||||
code: string;
|
code: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type PolicyEditorState = PolicyEditorStateUnloaded | PolicyEditorStateLoaded;
|
||||||
|
|
||||||
export class PolicyEditor extends Component<PolicyEditorProps, PolicyEditorState> {
|
export class PolicyEditor extends Component<PolicyEditorProps, PolicyEditorState> {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -32,6 +34,19 @@ export class PolicyEditor extends Component<PolicyEditorProps, PolicyEditorState
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
|
async componentDidMount() {
|
||||||
|
if (!this.state.dataLoaded) {
|
||||||
|
try {
|
||||||
|
await this.loadData();
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async editorSave(): Promise<void> {
|
async editorSave(): Promise<void> {
|
||||||
if (!this.state.dataLoaded) return;
|
if (!this.state.dataLoaded) return;
|
||||||
|
|
||||||
|
@ -40,16 +55,10 @@ export class PolicyEditor extends Component<PolicyEditorProps, PolicyEditorState
|
||||||
route(policyViewURL(this.props.policyName));
|
route(policyViewURL(this.props.policyName));
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
setErrorText(error.message);
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onCodeUpdate(code: string): void {
|
|
||||||
this.setState({
|
|
||||||
code: code,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async loadData(): Promise<void> {
|
async loadData(): Promise<void> {
|
||||||
const policyData = await this.props.api.getPolicy(this.props.policyName);
|
const policyData = await this.props.api.getPolicy(this.props.policyName);
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -60,12 +69,6 @@ export class PolicyEditor extends Component<PolicyEditorProps, PolicyEditorState
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount(): void {
|
|
||||||
if (!this.state.dataLoaded) {
|
|
||||||
void this.loadData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render(): JSX.Element {
|
render(): JSX.Element {
|
||||||
if (!this.state.dataLoaded) {
|
if (!this.state.dataLoaded) {
|
||||||
return <p>{i18next.t("content_loading")}</p>;
|
return <p>{i18next.t("content_loading")}</p>;
|
||||||
|
@ -73,13 +76,18 @@ export class PolicyEditor extends Component<PolicyEditorProps, PolicyEditorState
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<p class="uk-text-danger" id="errorText" />
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<Margin>
|
<Margin>
|
||||||
<CodeEditor
|
<CodeEditor
|
||||||
language="hcl"
|
language="hcl"
|
||||||
tabSize={2}
|
tabSize={2}
|
||||||
code={this.state.policyData}
|
code={this.state.policyData}
|
||||||
onUpdate={(code) => this.onCodeUpdate(code)}
|
onUpdate={(code) => {
|
||||||
|
this.setState({ code: code });
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Margin>
|
</Margin>
|
||||||
<MarginInline>
|
<MarginInline>
|
||||||
|
@ -101,11 +109,7 @@ export class PolicyEdit extends Component<DefaultPageProps> {
|
||||||
<>
|
<>
|
||||||
<PageTitle title={i18next.t("policy_edit_title", { policy: policyName })} />
|
<PageTitle title={i18next.t("policy_edit_title", { policy: policyName })} />
|
||||||
<div>
|
<div>
|
||||||
<PolicyEditor
|
<PolicyEditor {...this.props} policyName={policyName} />
|
||||||
settings={this.props.settings}
|
|
||||||
api={this.props.api}
|
|
||||||
policyName={policyName}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,37 +1,50 @@
|
||||||
import { Button } from "../../elements/Button";
|
import { Button } from "../../elements/Button";
|
||||||
import { Component } from "preact";
|
import { Component, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../../elements/ErrorMessage";
|
||||||
import { Form } from "../../elements/Form";
|
import { Form } from "../../elements/Form";
|
||||||
import { Margin } from "../../elements/Margin";
|
import { Margin } from "../../elements/Margin";
|
||||||
import { PageTitle } from "../../elements/PageTitle";
|
import { PageTitle } from "../../elements/PageTitle";
|
||||||
import { policyViewURL } from "../pageLinks";
|
import { policyViewURL } from "../pageLinks";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { setErrorText } from "../../../pageUtils";
|
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class PolicyNew extends Component<DefaultPageProps> {
|
export class PolicyNew extends Component<DefaultPageProps> {
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
|
async onFormSubmit(formData: FormData) {
|
||||||
|
const name = formData.get("name") as string;
|
||||||
|
|
||||||
|
let policies: string[] = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
policies = await this.props.api.getPolicies();
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (policies.includes(name)) {
|
||||||
|
this.errorMessageRef.current.setErrorMessage(i18next.t("policy_new_already_exists"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.props.api.createOrUpdatePolicy(name, " ");
|
||||||
|
route(policyViewURL(name));
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<PageTitle title={i18next.t("policy_new_title")} />
|
<PageTitle title={i18next.t("policy_new_title")} />
|
||||||
<div>
|
<div>
|
||||||
<Form
|
<Form onSubmit={async (formData) => await this.onFormSubmit(formData)}>
|
||||||
onSubmit={async (formData) => {
|
|
||||||
const name = formData.get("name") as string;
|
|
||||||
if ((await this.props.api.getPolicies()).includes(name)) {
|
|
||||||
setErrorText(i18next.t("policy_new_already_exists"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.props.api.createOrUpdatePolicy(name, " ");
|
|
||||||
route(policyViewURL(name));
|
|
||||||
} catch (e: unknown) {
|
|
||||||
const error = e as Error;
|
|
||||||
setErrorText(error.message);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Margin>
|
<Margin>
|
||||||
<input
|
<input
|
||||||
class="uk-input uk-form-width-medium"
|
class="uk-input uk-form-width-medium"
|
||||||
|
@ -40,7 +53,11 @@ export class PolicyNew extends Component<DefaultPageProps> {
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</Margin>
|
</Margin>
|
||||||
<p class="uk-text-danger" id="errorText" />
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { DefaultPageProps } from "../../../types/DefaultPageProps";
|
||||||
import { Margin } from "../../elements/Margin";
|
import { Margin } from "../../elements/Margin";
|
||||||
import { PageTitle } from "../../elements/PageTitle";
|
import { PageTitle } from "../../elements/PageTitle";
|
||||||
import { policyDeleteURL, policyEditURL } from "../pageLinks";
|
import { policyDeleteURL, policyEditURL } from "../pageLinks";
|
||||||
|
import { sendErrorNotification } from "../../elements/ErrorMessage";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class PolicyView extends Component<
|
export class PolicyView extends Component<
|
||||||
|
@ -13,11 +14,16 @@ export class PolicyView extends Component<
|
||||||
> {
|
> {
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const policyName = this.props.matches["policyName"];
|
const policyName = this.props.matches["policyName"];
|
||||||
const policy = await this.props.api.getPolicy(policyName);
|
try {
|
||||||
this.setState({
|
const policy = await this.props.api.getPolicy(policyName);
|
||||||
policy,
|
this.setState({
|
||||||
policyName,
|
policy,
|
||||||
});
|
policyName,
|
||||||
|
});
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -61,6 +61,7 @@ export class PasswordGenerator extends Component<DefaultPageProps, PasswordGener
|
||||||
alphabet: passwordOptionsDefault.alphabet,
|
alphabet: passwordOptionsDefault.alphabet,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
passwordLengthSlider = createRef<HTMLInputElement>();
|
passwordLengthSlider = createRef<HTMLInputElement>();
|
||||||
alphabetSelector = createRef<HTMLSelectElement>();
|
alphabetSelector = createRef<HTMLSelectElement>();
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
import { Button } from "../../elements/Button";
|
import { Button } from "../../elements/Button";
|
||||||
import { Component } from "preact";
|
import { Component, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../../elements/ErrorMessage";
|
||||||
import { Form } from "../../elements/Form";
|
import { Form } from "../../elements/Form";
|
||||||
|
import { Margin } from "../../elements/Margin";
|
||||||
import { MarginInline } from "../../elements/MarginInline";
|
import { MarginInline } from "../../elements/MarginInline";
|
||||||
import { PageTitle } from "../../elements/PageTitle";
|
import { PageTitle } from "../../elements/PageTitle";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { setErrorText } from "../../../pageUtils";
|
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class DeleteSecretsEngine extends Component<DefaultPageProps> {
|
export class DeleteSecretsEngine extends Component<DefaultPageProps> {
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -22,7 +25,9 @@ export class DeleteSecretsEngine extends Component<DefaultPageProps> {
|
||||||
>
|
>
|
||||||
<p>{i18next.t("delete_secrets_engine_message")}</p>
|
<p>{i18next.t("delete_secrets_engine_message")}</p>
|
||||||
|
|
||||||
<p class="uk-text-danger" id="errorText" />
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<MarginInline>
|
<MarginInline>
|
||||||
<Button text={i18next.t("common_delete")} color="danger" type="submit" />
|
<Button text={i18next.t("common_delete")} color="danger" type="submit" />
|
||||||
|
@ -38,7 +43,7 @@ export class DeleteSecretsEngine extends Component<DefaultPageProps> {
|
||||||
route("/secrets");
|
route("/secrets");
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
setErrorText(error.message);
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
import { Button } from "../../../elements/Button";
|
import { Button } from "../../../elements/Button";
|
||||||
import { Component } from "preact";
|
import { Component, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../../../elements/ErrorMessage";
|
||||||
|
import { Margin } from "../../../elements/Margin";
|
||||||
import { SecretTitleElement } from "../SecretTitleElement";
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import { kvListURL, kvViewURL } from "../../pageLinks";
|
import { kvListURL, kvViewURL } from "../../pageLinks";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class KeyValueDelete extends Component<DefaultPageProps> {
|
export class KeyValueDelete extends Component<DefaultPageProps> {
|
||||||
render() {
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
|
async onDelete() {
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
const secretPath = this.props.matches["secretPath"].split("/");
|
const secretPath = this.props.matches["secretPath"].split("/");
|
||||||
const item = this.props.matches["item"];
|
const item = this.props.matches["item"];
|
||||||
|
@ -20,6 +24,20 @@ export class KeyValueDelete extends Component<DefaultPageProps> {
|
||||||
? kvListURL(baseMount, secretPath)
|
? kvListURL(baseMount, secretPath)
|
||||||
: kvViewURL(baseMount, secretPath, item, "null");
|
: kvViewURL(baseMount, secretPath, item, "null");
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.props.api.deleteSecret(baseMount, secretPath, item, version);
|
||||||
|
route(buttonRoute);
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const baseMount = this.props.matches["baseMount"];
|
||||||
|
const secretPath = this.props.matches["secretPath"].split("/");
|
||||||
|
const item = this.props.matches["item"];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SecretTitleElement
|
<SecretTitleElement
|
||||||
|
@ -31,13 +49,15 @@ export class KeyValueDelete extends Component<DefaultPageProps> {
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<h5>{i18next.t("kv_delete_text")}</h5>
|
<h5>{i18next.t("kv_delete_text")}</h5>
|
||||||
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
text={i18next.t("common_delete")}
|
text={i18next.t("common_delete")}
|
||||||
color="danger"
|
color="danger"
|
||||||
onClick={async () => {
|
onClick={async () => this.onDelete()}
|
||||||
await this.props.api.deleteSecret(baseMount, secretPath, item, version);
|
|
||||||
route(buttonRoute);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|
|
@ -2,7 +2,9 @@ import { Button } from "../../../elements/Button";
|
||||||
import { CodeEditor } from "../../../elements/CodeEditor";
|
import { CodeEditor } from "../../../elements/CodeEditor";
|
||||||
import { Component, JSX, createRef } from "preact";
|
import { Component, JSX, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage, sendErrorNotification } from "../../../elements/ErrorMessage";
|
||||||
import { InputWithTitle } from "../../../elements/InputWithTitle";
|
import { InputWithTitle } from "../../../elements/InputWithTitle";
|
||||||
|
import { Margin } from "../../../elements/Margin";
|
||||||
import { SecretTitleElement } from "../SecretTitleElement";
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import {
|
import {
|
||||||
SupportedLanguages,
|
SupportedLanguages,
|
||||||
|
@ -10,7 +12,6 @@ import {
|
||||||
parseData,
|
parseData,
|
||||||
toPrismCode,
|
toPrismCode,
|
||||||
} from "../../../../utils/dataInterchange";
|
} from "../../../../utils/dataInterchange";
|
||||||
import { setErrorText } from "../../../../pageUtils";
|
|
||||||
import { sortedObjectMap } from "../../../../utils";
|
import { sortedObjectMap } from "../../../../utils";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -41,30 +42,18 @@ export class KVEditor extends Component<KVEditProps, KVEditState> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async editorSave(): Promise<void> {
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
if (!this.state.dataLoaded) return;
|
|
||||||
const editorContent = this.state.code;
|
|
||||||
|
|
||||||
try {
|
async componentDidMount() {
|
||||||
parseData(editorContent, this.state.syntax);
|
this.setState({ syntax: this.props.settings.kvEditorDefaultLanguage });
|
||||||
} catch {
|
if (!this.state.dataLoaded) {
|
||||||
setErrorText(i18next.t("kv_sec_edit_invalid_data_err"));
|
try {
|
||||||
return;
|
await this.loadData();
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.props.api.createOrUpdateSecret(
|
|
||||||
this.props.baseMount,
|
|
||||||
this.props.secretPath.map((e) => e + "/"),
|
|
||||||
this.props.secretItem,
|
|
||||||
parseData(editorContent, this.state.syntax),
|
|
||||||
);
|
|
||||||
window.history.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
onCodeUpdate(code: string): void {
|
|
||||||
this.setState({
|
|
||||||
code: code,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadData() {
|
async loadData() {
|
||||||
|
@ -80,10 +69,28 @@ export class KVEditor extends Component<KVEditProps, KVEditState> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentDidMount() {
|
async editorSave(): Promise<void> {
|
||||||
this.setState({ syntax: this.props.settings.kvEditorDefaultLanguage });
|
if (!this.state.dataLoaded) return;
|
||||||
if (!this.state.dataLoaded) {
|
const editorContent = this.state.code;
|
||||||
await this.loadData();
|
|
||||||
|
try {
|
||||||
|
parseData(editorContent, this.state.syntax);
|
||||||
|
} catch {
|
||||||
|
this.errorMessageRef.current.setErrorMessage(i18next.t("kv_sec_edit_invalid_data_err"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.props.api.createOrUpdateSecret(
|
||||||
|
this.props.baseMount,
|
||||||
|
this.props.secretPath.map((e) => e + "/"),
|
||||||
|
this.props.secretItem,
|
||||||
|
parseData(editorContent, this.state.syntax),
|
||||||
|
);
|
||||||
|
window.history.back();
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,13 +130,20 @@ export class KVEditor extends Component<KVEditProps, KVEditState> {
|
||||||
})}
|
})}
|
||||||
</select>
|
</select>
|
||||||
</InputWithTitle>
|
</InputWithTitle>
|
||||||
<p class="uk-text-danger" id="errorText" />
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<CodeEditor
|
<CodeEditor
|
||||||
language={toPrismCode(this.state.syntax)}
|
language={toPrismCode(this.state.syntax)}
|
||||||
tabSize={this.props.settings.kvEditorIndent}
|
tabSize={this.props.settings.kvEditorIndent}
|
||||||
code={this.getStringKVData(this.state.kvData)}
|
code={this.getStringKVData(this.state.kvData)}
|
||||||
onUpdate={(code) => this.onCodeUpdate(code)}
|
onUpdate={(code) => {
|
||||||
|
this.setState({ code });
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button text={i18next.t("common_edit")} color="primary" onClick={() => this.editorSave()} />
|
<Button text={i18next.t("common_edit")} color="primary" onClick={() => this.editorSave()} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { DoesNotExistError } from "../../../../types/internalErrors";
|
||||||
import { SecretTitleElement } from "../SecretTitleElement";
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import { delSecretsEngineURL, kvListURL, kvNewURL, kvViewURL } from "../../pageLinks";
|
import { delSecretsEngineURL, kvListURL, kvNewURL, kvViewURL } from "../../pageLinks";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { setErrorText } from "../../../../pageUtils";
|
import { sendErrorNotification } from "../../../elements/ErrorMessage";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export type KVKeysListProps = DefaultPageProps & {
|
export type KVKeysListProps = DefaultPageProps & {
|
||||||
|
@ -47,6 +47,15 @@ export class KVKeysList extends Component<KVKeysListProps, KVKeysListState> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async componentDidMount() {
|
||||||
|
try {
|
||||||
|
await this.loadData();
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async loadData(): Promise<void> {
|
async loadData(): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const keys = await this.props.api.getSecrets(this.props.baseMount, this.props.secretPath);
|
const keys = await this.props.api.getSecrets(this.props.baseMount, this.props.secretPath);
|
||||||
|
@ -64,7 +73,7 @@ export class KVKeysList extends Component<KVKeysListProps, KVKeysListState> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
setErrorText(error.message);
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -86,10 +95,6 @@ export class KVKeysList extends Component<KVKeysListProps, KVKeysListState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount(): void {
|
|
||||||
void this.loadData();
|
|
||||||
}
|
|
||||||
|
|
||||||
searchBarRef = createRef();
|
searchBarRef = createRef();
|
||||||
|
|
||||||
render(): JSX.Element {
|
render(): JSX.Element {
|
||||||
|
@ -143,15 +148,20 @@ export class KeyValueList extends Component<DefaultPageProps, KeyValueListState>
|
||||||
|
|
||||||
const mountsPath = "/sys/mounts/" + baseMount;
|
const mountsPath = "/sys/mounts/" + baseMount;
|
||||||
const currentPath = baseMount + secretPath.join();
|
const currentPath = baseMount + secretPath.join();
|
||||||
const caps = await this.props.api.getCapabilitiesPath([mountsPath, currentPath]);
|
|
||||||
|
|
||||||
const mount = await this.props.api.getMount(baseMount);
|
try {
|
||||||
|
const caps = await this.props.api.getCapabilitiesPath([mountsPath, currentPath]);
|
||||||
|
const mount = await this.props.api.getMount(baseMount);
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
mountCaps: caps[mountsPath],
|
mountCaps: caps[mountsPath],
|
||||||
pathCaps: caps[currentPath],
|
pathCaps: caps[currentPath],
|
||||||
mountType: mount.type,
|
mountType: mount.type,
|
||||||
});
|
});
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -1,15 +1,41 @@
|
||||||
import { Button } from "../../../elements/Button";
|
import { Button } from "../../../elements/Button";
|
||||||
import { Component } from "preact";
|
import { Component, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../../../elements/ErrorMessage";
|
||||||
import { Form } from "../../../elements/Form";
|
import { Form } from "../../../elements/Form";
|
||||||
import { Margin } from "../../../elements/Margin";
|
import { Margin } from "../../../elements/Margin";
|
||||||
import { SecretTitleElement } from "../SecretTitleElement";
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import { kvViewURL } from "../../pageLinks";
|
import { kvViewURL } from "../../pageLinks";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { setErrorText } from "../../../../pageUtils";
|
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class KeyValueNew extends Component<DefaultPageProps> {
|
export class KeyValueNew extends Component<DefaultPageProps> {
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
|
async newKVSecretHandleForm(
|
||||||
|
formData: FormData,
|
||||||
|
baseMount: string,
|
||||||
|
secretPath: string[],
|
||||||
|
): Promise<void> {
|
||||||
|
const path = formData.get("path") as string;
|
||||||
|
|
||||||
|
let keyData: Record<string, unknown> = {};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const mountInfo = await this.props.api.getMount(baseMount);
|
||||||
|
if (mountInfo.options.version == "1") {
|
||||||
|
// Can't have a empty secret on KV V1
|
||||||
|
keyData = { placeholder_on_kv1: "placeholder_on_kv1" };
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.props.api.createOrUpdateSecret(baseMount, secretPath, path, keyData);
|
||||||
|
route(kvViewURL(baseMount, secretPath, path));
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
const secretPath = (this.props.matches["secretPath"] || "").split("/");
|
const secretPath = (this.props.matches["secretPath"] || "").split("/");
|
||||||
|
@ -36,35 +62,15 @@ export class KeyValueNew extends Component<DefaultPageProps> {
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</Margin>
|
</Margin>
|
||||||
<p class="uk-text-danger" id="errorText" />
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
||||||
</Form>
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async newKVSecretHandleForm(
|
|
||||||
formData: FormData,
|
|
||||||
baseMount: string,
|
|
||||||
secretPath: string[],
|
|
||||||
): Promise<void> {
|
|
||||||
const path = formData.get("path") as string;
|
|
||||||
|
|
||||||
let keyData: Record<string, unknown> = {};
|
|
||||||
|
|
||||||
const mountInfo = await this.props.api.getMount(baseMount);
|
|
||||||
if (mountInfo.options.version == "1") {
|
|
||||||
// Can't have a empty secret on KV V1
|
|
||||||
keyData = { placeholder_on_kv1: "placeholder_on_kv1" };
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
await this.props.api.createOrUpdateSecret(baseMount, secretPath, path, keyData);
|
|
||||||
route(kvViewURL(baseMount, secretPath, path));
|
|
||||||
} catch (e: unknown) {
|
|
||||||
const error = e as Error;
|
|
||||||
setErrorText(error.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import { kvViewURL } from "../../pageLinks";
|
import { kvViewURL } from "../../pageLinks";
|
||||||
import { objectToMap } from "../../../../utils";
|
import { objectToMap } from "../../../../utils";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
|
import { sendErrorNotification } from "../../../elements/ErrorMessage";
|
||||||
|
|
||||||
export class KeyValueVersions extends Component<DefaultPageProps, { versions: string[] }> {
|
export class KeyValueVersions extends Component<DefaultPageProps, { versions: string[] }> {
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
|
@ -11,11 +12,16 @@ export class KeyValueVersions extends Component<DefaultPageProps, { versions: st
|
||||||
const secretPath = this.props.matches["secretPath"].split("/");
|
const secretPath = this.props.matches["secretPath"].split("/");
|
||||||
const secretItem = this.props.matches["item"];
|
const secretItem = this.props.matches["item"];
|
||||||
|
|
||||||
const metadata = await this.props.api.getSecretMetadata(baseMount, secretPath, secretItem);
|
try {
|
||||||
|
const metadata = await this.props.api.getSecretMetadata(baseMount, secretPath, secretItem);
|
||||||
|
|
||||||
const versions = Array.from(objectToMap(metadata.versions).keys());
|
const versions = Array.from(objectToMap(metadata.versions).keys());
|
||||||
|
|
||||||
this.setState({ versions });
|
this.setState({ versions });
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { InputWithTitle } from "../../../elements/InputWithTitle";
|
||||||
import { SecretTitleElement } from "../SecretTitleElement";
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import { SupportedLanguages, dumpData, toPrismCode } from "../../../../utils/dataInterchange";
|
import { SupportedLanguages, dumpData, toPrismCode } from "../../../../utils/dataInterchange";
|
||||||
import { kvDeleteURL, kvEditURL, kvVersionsURL } from "../../pageLinks";
|
import { kvDeleteURL, kvEditURL, kvVersionsURL } from "../../pageLinks";
|
||||||
|
import { sendErrorNotification } from "../../../elements/ErrorMessage";
|
||||||
import { sortedObjectMap } from "../../../../utils";
|
import { sortedObjectMap } from "../../../../utils";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ export class KVSecretNormalVew extends Component<KVSecretViewDataProps> {
|
||||||
{Array.from(this.props.data).map((data: [string, unknown]) => {
|
{Array.from(this.props.data).map((data: [string, unknown]) => {
|
||||||
const key = data[0];
|
const key = data[0];
|
||||||
const value = data[1] as string;
|
const value = data[1] as string;
|
||||||
console.log(this.props.settings.kvHideKeyValues);
|
|
||||||
return (
|
return (
|
||||||
<Grid size={GridSizes.NORMAL}>
|
<Grid size={GridSizes.NORMAL}>
|
||||||
<CopyableInputBox text={key} copyable />
|
<CopyableInputBox text={key} copyable />
|
||||||
|
@ -105,6 +106,15 @@ type KeyValueViewState = {
|
||||||
|
|
||||||
export class KeyValueView extends Component<DefaultPageProps, KeyValueViewState> {
|
export class KeyValueView extends Component<DefaultPageProps, KeyValueViewState> {
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
|
try {
|
||||||
|
await this.getKVViewData();
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getKVViewData() {
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
const secretPath = this.props.matches["secretPath"].split("/");
|
const secretPath = this.props.matches["secretPath"].split("/");
|
||||||
const secretItem = this.props.matches["item"];
|
const secretItem = this.props.matches["item"];
|
||||||
|
@ -129,6 +139,8 @@ export class KeyValueView extends Component<DefaultPageProps, KeyValueViewState>
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e == DoesNotExistError) {
|
if (e == DoesNotExistError) {
|
||||||
secretInfo = null;
|
secretInfo = null;
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
import { Button } from "../../../elements/Button";
|
import { Button } from "../../../elements/Button";
|
||||||
import { Component } from "preact";
|
import { Component, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../../../elements/ErrorMessage";
|
||||||
import { Form } from "../../../elements/Form";
|
import { Form } from "../../../elements/Form";
|
||||||
import { Margin } from "../../../elements/Margin";
|
import { Margin } from "../../../elements/Margin";
|
||||||
import { MarginInline } from "../../../elements/MarginInline";
|
import { MarginInline } from "../../../elements/MarginInline";
|
||||||
import { PageTitle } from "../../../elements/PageTitle";
|
import { PageTitle } from "../../../elements/PageTitle";
|
||||||
import { kvListURL } from "../../pageLinks";
|
import { kvListURL } from "../../pageLinks";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { setErrorText } from "../../../../pageUtils";
|
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class NewKVEngine extends Component<DefaultPageProps> {
|
export class NewKVEngine extends Component<DefaultPageProps> {
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -35,7 +37,11 @@ export class NewKVEngine extends Component<DefaultPageProps> {
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</Margin>
|
</Margin>
|
||||||
<p class="uk-text-danger" id="errorText" />
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<MarginInline>
|
<MarginInline>
|
||||||
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
||||||
</MarginInline>
|
</MarginInline>
|
||||||
|
@ -59,7 +65,7 @@ export class NewKVEngine extends Component<DefaultPageProps> {
|
||||||
route(kvListURL(name, []));
|
route(kvListURL(name, []));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
setErrorText(error.message);
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
import { Button } from "../../../elements/Button";
|
import { Button } from "../../../elements/Button";
|
||||||
import { Component } from "preact";
|
import { Component, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../../../elements/ErrorMessage";
|
||||||
import { Form } from "../../../elements/Form";
|
import { Form } from "../../../elements/Form";
|
||||||
import { Margin } from "../../../elements/Margin";
|
import { Margin } from "../../../elements/Margin";
|
||||||
import { MarginInline } from "../../../elements/MarginInline";
|
import { MarginInline } from "../../../elements/MarginInline";
|
||||||
import { PageTitle } from "../../../elements/PageTitle";
|
import { PageTitle } from "../../../elements/PageTitle";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { setErrorText } from "../../../../pageUtils";
|
|
||||||
import { totpListURL } from "../../pageLinks";
|
import { totpListURL } from "../../pageLinks";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class NewTOTPEngine extends Component<DefaultPageProps> {
|
export class NewTOTPEngine extends Component<DefaultPageProps> {
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -25,7 +27,11 @@ export class NewTOTPEngine extends Component<DefaultPageProps> {
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</Margin>
|
</Margin>
|
||||||
<p class="uk-text-danger" id="errorText" />
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<MarginInline>
|
<MarginInline>
|
||||||
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
||||||
</MarginInline>
|
</MarginInline>
|
||||||
|
@ -46,7 +52,7 @@ export class NewTOTPEngine extends Component<DefaultPageProps> {
|
||||||
route(totpListURL(name));
|
route(totpListURL(name));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
setErrorText(error.message);
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
import { Button } from "../../../elements/Button";
|
import { Button } from "../../../elements/Button";
|
||||||
import { Component } from "preact";
|
import { Component, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../../../elements/ErrorMessage";
|
||||||
import { Form } from "../../../elements/Form";
|
import { Form } from "../../../elements/Form";
|
||||||
import { Margin } from "../../../elements/Margin";
|
import { Margin } from "../../../elements/Margin";
|
||||||
import { MarginInline } from "../../../elements/MarginInline";
|
import { MarginInline } from "../../../elements/MarginInline";
|
||||||
import { PageTitle } from "../../../elements/PageTitle";
|
import { PageTitle } from "../../../elements/PageTitle";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { setErrorText } from "../../../../pageUtils";
|
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class NewTransitEngine extends Component<DefaultPageProps> {
|
export class NewTransitEngine extends Component<DefaultPageProps> {
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -24,7 +26,11 @@ export class NewTransitEngine extends Component<DefaultPageProps> {
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</Margin>
|
</Margin>
|
||||||
<p class="uk-text-danger" id="errorText" />
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<MarginInline>
|
<MarginInline>
|
||||||
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
||||||
</MarginInline>
|
</MarginInline>
|
||||||
|
@ -45,7 +51,7 @@ export class NewTransitEngine extends Component<DefaultPageProps> {
|
||||||
route("/secrets/transit/list/" + name + "/");
|
route("/secrets/transit/list/" + name + "/");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
setErrorText(error.message);
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { Component, JSX } from "preact";
|
||||||
import { DefaultPageProps } from "../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../types/DefaultPageProps";
|
||||||
import { MountType } from "../../../api/types/mount";
|
import { MountType } from "../../../api/types/mount";
|
||||||
import { PageTitle } from "../../elements/PageTitle";
|
import { PageTitle } from "../../elements/PageTitle";
|
||||||
|
import { sendErrorNotification } from "../../elements/ErrorMessage";
|
||||||
import { sortedObjectMap } from "../../../utils";
|
import { sortedObjectMap } from "../../../utils";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -57,14 +58,19 @@ type SecretsState = {
|
||||||
|
|
||||||
export class Secrets extends Component<DefaultPageProps, SecretsState> {
|
export class Secrets extends Component<DefaultPageProps, SecretsState> {
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const mountsCapabilities = await this.props.api.getCapsPath("/sys/mounts");
|
try {
|
||||||
const mounts = await this.props.api.getMounts();
|
const mountsCapabilities = await this.props.api.getCapsPath("/sys/mounts");
|
||||||
// sort it by secretPath so it's in alphabetical order consistantly.
|
const mounts = await this.props.api.getMounts();
|
||||||
const mountsMap = sortedObjectMap(mounts);
|
// sort it by secretPath so it's in alphabetical order consistantly.
|
||||||
this.setState({
|
const mountsMap = sortedObjectMap(mounts);
|
||||||
capabilities: mountsCapabilities,
|
this.setState({
|
||||||
mountsMap: mountsMap as Map<string, MountType>,
|
capabilities: mountsCapabilities,
|
||||||
});
|
mountsMap: mountsMap as Map<string, MountType>,
|
||||||
|
});
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
import { Button } from "../../../elements/Button";
|
import { Button } from "../../../elements/Button";
|
||||||
import { Component } from "preact";
|
import { Component, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../../../elements/ErrorMessage";
|
||||||
|
import { Margin } from "../../../elements/Margin";
|
||||||
import { SecretTitleElement } from "../SecretTitleElement";
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { totpListURL } from "../../pageLinks";
|
import { totpListURL } from "../../pageLinks";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class TOTPDelete extends Component<DefaultPageProps> {
|
export class TOTPDelete extends Component<DefaultPageProps> {
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -18,14 +22,24 @@ export class TOTPDelete extends Component<DefaultPageProps> {
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<h5>{i18next.t("totp_delete_text")}</h5>
|
<h5>{i18next.t("totp_delete_text")}</h5>
|
||||||
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
text={i18next.t("common_delete")}
|
text={i18next.t("common_delete")}
|
||||||
color="danger"
|
color="danger"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
const item = this.props.matches["item"];
|
const item = this.props.matches["item"];
|
||||||
await this.props.api.deleteTOTP(baseMount, item);
|
try {
|
||||||
route(totpListURL(baseMount));
|
await this.props.api.deleteTOTP(baseMount, item);
|
||||||
|
route(totpListURL(baseMount));
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { CapabilitiesType } from "../../../../api/types/capabilities";
|
||||||
import { Component, JSX } from "preact";
|
import { Component, JSX } from "preact";
|
||||||
import { CopyableInputBox } from "../../../elements/CopyableInputBox";
|
import { CopyableInputBox } from "../../../elements/CopyableInputBox";
|
||||||
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
import { DoesNotExistError } from "../../../../types/internalErrors";
|
|
||||||
import { Grid, GridSizes } from "../../../elements/Grid";
|
import { Grid, GridSizes } from "../../../elements/Grid";
|
||||||
import { MarginInline } from "../../../elements/MarginInline";
|
import { MarginInline } from "../../../elements/MarginInline";
|
||||||
import { SecretTitleElement } from "../SecretTitleElement";
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
|
@ -14,7 +13,7 @@ import {
|
||||||
totpNewURL,
|
totpNewURL,
|
||||||
} from "../../pageLinks";
|
} from "../../pageLinks";
|
||||||
import { removeDoubleSlash } from "../../../../utils";
|
import { removeDoubleSlash } from "../../../../utils";
|
||||||
import { setErrorText } from "../../../../pageUtils";
|
import { sendErrorNotification } from "../../../elements/ErrorMessage";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
type TOTPGridItemProps = DefaultPageProps & {
|
type TOTPGridItemProps = DefaultPageProps & {
|
||||||
|
@ -87,42 +86,36 @@ export class TOTPList extends Component<DefaultPageProps, TOTPListState> {
|
||||||
|
|
||||||
refresher: number;
|
refresher: number;
|
||||||
|
|
||||||
async componentDidMount() {
|
async doApiFetches() {
|
||||||
const api = this.props.api;
|
const api = this.props.api;
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
const mountsPath = "/sys/mounts/" + baseMount;
|
const mountsPath = "/sys/mounts/" + baseMount;
|
||||||
|
|
||||||
const caps = await api.getCapabilitiesPath([mountsPath, baseMount]);
|
const caps = await api.getCapabilitiesPath([mountsPath, baseMount]);
|
||||||
|
|
||||||
let totpItems: TOTPItem[] = [];
|
let totpItems: TOTPItem[] = [];
|
||||||
|
|
||||||
try {
|
const totpKeys = await api.getTOTPKeys(baseMount);
|
||||||
const totpKeys = await api.getTOTPKeys(baseMount);
|
|
||||||
|
|
||||||
const totpKeyPermissions = await Promise.all(
|
const totpKeyPermissions = await Promise.all(
|
||||||
Array.from(
|
Array.from(
|
||||||
totpKeys.map(async (key) => {
|
totpKeys.map(async (key) => {
|
||||||
const totpCaps = await api.getCapsPath(removeDoubleSlash(baseMount + "/code/" + key));
|
const totpCaps = await api.getCapsPath(removeDoubleSlash(baseMount + "/code/" + key));
|
||||||
return { key: key, caps: totpCaps };
|
return { key: key, caps: totpCaps };
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
totpItems = Array.from(
|
|
||||||
totpKeyPermissions.map((keyData) => {
|
|
||||||
// Filter out all non-readable totp keys.
|
|
||||||
if (!keyData.caps.includes("read")) return;
|
|
||||||
return {
|
|
||||||
totpKey: keyData.key,
|
|
||||||
canDelete: keyData.caps.includes("delete"),
|
|
||||||
};
|
|
||||||
}),
|
}),
|
||||||
);
|
),
|
||||||
} catch (e: unknown) {
|
);
|
||||||
const error = e as Error;
|
|
||||||
if (error != DoesNotExistError) {
|
totpItems = Array.from(
|
||||||
setErrorText(error.message);
|
totpKeyPermissions.map((keyData) => {
|
||||||
}
|
// Filter out all non-readable totp keys.
|
||||||
}
|
if (!keyData.caps.includes("read")) return;
|
||||||
|
return {
|
||||||
|
totpKey: keyData.key,
|
||||||
|
canDelete: keyData.caps.includes("delete"),
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
capabilities: caps,
|
capabilities: caps,
|
||||||
|
@ -130,6 +123,15 @@ export class TOTPList extends Component<DefaultPageProps, TOTPListState> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async componentDidMount() {
|
||||||
|
try {
|
||||||
|
await this.doApiFetches();
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.state.capabilities) return;
|
if (!this.state.capabilities) return;
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import { Button } from "../../../elements/Button";
|
import { Button } from "../../../elements/Button";
|
||||||
import { Component, JSX, createRef } from "preact";
|
import { Component, JSX, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../../../elements/ErrorMessage";
|
||||||
import { Form } from "../../../elements/Form";
|
import { Form } from "../../../elements/Form";
|
||||||
import { Margin } from "../../../elements/Margin";
|
import { Margin } from "../../../elements/Margin";
|
||||||
import { MarginInline } from "../../../elements/MarginInline";
|
import { MarginInline } from "../../../elements/MarginInline";
|
||||||
import { QRScanner } from "../../../elements/QRScanner";
|
import { QRScanner } from "../../../elements/QRScanner";
|
||||||
import { SecretTitleElement } from "../SecretTitleElement";
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { setErrorText } from "../../../../pageUtils";
|
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
function replaceAll(str: string, replace: string, replaceWith: string): string {
|
function replaceAll(str: string, replace: string, replaceWith: string): string {
|
||||||
|
@ -31,6 +31,7 @@ export class TOTPNewForm extends Component<
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
uriInputRef = createRef<HTMLInputElement>();
|
uriInputRef = createRef<HTMLInputElement>();
|
||||||
|
|
||||||
async onSubmit(data: FormData): Promise<void> {
|
async onSubmit(data: FormData): Promise<void> {
|
||||||
|
@ -46,7 +47,7 @@ export class TOTPNewForm extends Component<
|
||||||
route("/secrets/totp/list/" + this.props.baseMount);
|
route("/secrets/totp/list/" + this.props.baseMount);
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
setErrorText(`API Error: ${error.message}`);
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +87,8 @@ export class TOTPNewForm extends Component<
|
||||||
/>
|
/>
|
||||||
</Margin>
|
</Margin>
|
||||||
|
|
||||||
|
{/* TODO: please redo this to be more like Unseal page qr mode */}
|
||||||
|
|
||||||
{this.state.qrMode && (
|
{this.state.qrMode && (
|
||||||
<QRScanner
|
<QRScanner
|
||||||
onScan={(uri) => {
|
onScan={(uri) => {
|
||||||
|
@ -109,7 +112,9 @@ export class TOTPNewForm extends Component<
|
||||||
/>
|
/>
|
||||||
</MarginInline>
|
</MarginInline>
|
||||||
|
|
||||||
<p id="errorText" class="uk-text-danger" />
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<MarginInline>
|
<MarginInline>
|
||||||
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { Button } from "../../../elements/Button";
|
||||||
import { Component, JSX, createRef } from "preact";
|
import { Component, JSX, createRef } from "preact";
|
||||||
import { CopyableInputBox } from "../../../elements/CopyableInputBox";
|
import { CopyableInputBox } from "../../../elements/CopyableInputBox";
|
||||||
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../../../elements/ErrorMessage";
|
||||||
import { Form } from "../../../elements/Form";
|
import { Form } from "../../../elements/Form";
|
||||||
import { InputWithTitle } from "../../../elements/InputWithTitle";
|
import { InputWithTitle } from "../../../elements/InputWithTitle";
|
||||||
import { Margin } from "../../../elements/Margin";
|
import { Margin } from "../../../elements/Margin";
|
||||||
|
@ -9,7 +10,6 @@ import { MarginInline } from "../../../elements/MarginInline";
|
||||||
import { NewTOTPResp } from "../../../../api/types/totp";
|
import { NewTOTPResp } from "../../../../api/types/totp";
|
||||||
import { SecretTitleElement } from "../SecretTitleElement";
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { setErrorText } from "../../../../pageUtils";
|
|
||||||
import { totpListURL } from "../../pageLinks";
|
import { totpListURL } from "../../pageLinks";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ export class TOTPNewGeneratedForm extends Component<
|
||||||
{ baseMount: string } & DefaultPageProps,
|
{ baseMount: string } & DefaultPageProps,
|
||||||
{ exportedData: NewTOTPResp }
|
{ exportedData: NewTOTPResp }
|
||||||
> {
|
> {
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
uriInputRef = createRef<HTMLInputElement>();
|
uriInputRef = createRef<HTMLInputElement>();
|
||||||
|
|
||||||
render(): JSX.Element {
|
render(): JSX.Element {
|
||||||
|
@ -93,7 +94,9 @@ export class TOTPNewGeneratedForm extends Component<
|
||||||
</InputWithTitle>
|
</InputWithTitle>
|
||||||
</Margin>
|
</Margin>
|
||||||
|
|
||||||
<p id="errorText" class="uk-text-danger" />
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<MarginInline>
|
<MarginInline>
|
||||||
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
||||||
|
@ -140,7 +143,7 @@ export class TOTPNewGeneratedForm extends Component<
|
||||||
}
|
}
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
setErrorText(`API Error: ${error.message}`);
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
import { Button } from "../../../elements/Button";
|
import { Button } from "../../../elements/Button";
|
||||||
import { Component } from "preact";
|
import { Component, createRef } from "preact";
|
||||||
import { CopyableBox } from "../../../elements/CopyableBox";
|
import { CopyableBox } from "../../../elements/CopyableBox";
|
||||||
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../../../elements/ErrorMessage";
|
||||||
import { FileUploadInput } from "../../../elements/FileUploadInput";
|
import { FileUploadInput } from "../../../elements/FileUploadInput";
|
||||||
import { Form } from "../../../elements/Form";
|
import { Form } from "../../../elements/Form";
|
||||||
import { InputWithTitle } from "../../../elements/InputWithTitle";
|
import { InputWithTitle } from "../../../elements/InputWithTitle";
|
||||||
import { Margin } from "../../../elements/Margin";
|
import { Margin } from "../../../elements/Margin";
|
||||||
import { SecretTitleElement } from "../SecretTitleElement";
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import { fileToBase64 } from "../../../../htmlUtils";
|
import { fileToBase64 } from "../../../../htmlUtils";
|
||||||
import { setErrorText } from "../../../../pageUtils";
|
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class TransitDecrypt extends Component<DefaultPageProps, { plaintext: string }> {
|
export class TransitDecrypt extends Component<DefaultPageProps, { plaintext: string }> {
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
const secretItem = this.props.matches["secretItem"];
|
const secretItem = this.props.matches["secretItem"];
|
||||||
|
@ -43,7 +45,11 @@ export class TransitDecrypt extends Component<DefaultPageProps, { plaintext: str
|
||||||
<InputWithTitle title={i18next.t("transit_decrypt_decode_checkbox")}>
|
<InputWithTitle title={i18next.t("transit_decrypt_decode_checkbox")}>
|
||||||
<input class="uk-checkbox" name="decodeBase64Checkbox" type="checkbox" />
|
<input class="uk-checkbox" name="decodeBase64Checkbox" type="checkbox" />
|
||||||
</InputWithTitle>
|
</InputWithTitle>
|
||||||
<p class="uk-text-danger" id="errorText" />
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<Button text={i18next.t("transit_decrypt")} color="primary" type="submit" />
|
<Button text={i18next.t("transit_decrypt")} color="primary" type="submit" />
|
||||||
</Form>
|
</Form>
|
||||||
</>
|
</>
|
||||||
|
@ -74,6 +80,7 @@ export class TransitDecrypt extends Component<DefaultPageProps, { plaintext: str
|
||||||
|
|
||||||
const ciphertext_file = data.get("ciphertext_file") as File;
|
const ciphertext_file = data.get("ciphertext_file") as File;
|
||||||
if (ciphertext_file.size > 0) {
|
if (ciphertext_file.size > 0) {
|
||||||
|
// TODO: please stop using atob
|
||||||
ciphertext = atob(
|
ciphertext = atob(
|
||||||
(await fileToBase64(ciphertext_file)).replace("data:text/plain;base64,", ""),
|
(await fileToBase64(ciphertext_file)).replace("data:text/plain;base64,", ""),
|
||||||
);
|
);
|
||||||
|
@ -92,7 +99,7 @@ export class TransitDecrypt extends Component<DefaultPageProps, { plaintext: str
|
||||||
this.setState({ plaintext: plaintext });
|
this.setState({ plaintext: plaintext });
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
setErrorText(`API Error: ${error.message}`);
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
import { Button } from "../../../elements/Button";
|
import { Button } from "../../../elements/Button";
|
||||||
import { Component } from "preact";
|
import { Component, createRef } from "preact";
|
||||||
import { CopyableBox } from "../../../elements/CopyableBox";
|
import { CopyableBox } from "../../../elements/CopyableBox";
|
||||||
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../../../elements/ErrorMessage";
|
||||||
import { FileUploadInput } from "../../../elements/FileUploadInput";
|
import { FileUploadInput } from "../../../elements/FileUploadInput";
|
||||||
import { Form } from "../../../elements/Form";
|
import { Form } from "../../../elements/Form";
|
||||||
import { InputWithTitle } from "../../../elements/InputWithTitle";
|
import { InputWithTitle } from "../../../elements/InputWithTitle";
|
||||||
import { Margin } from "../../../elements/Margin";
|
import { Margin } from "../../../elements/Margin";
|
||||||
import { SecretTitleElement } from "../SecretTitleElement";
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import { fileToBase64 } from "../../../../htmlUtils";
|
import { fileToBase64 } from "../../../../htmlUtils";
|
||||||
import { setErrorText } from "../../../../pageUtils";
|
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class TransitEncrypt extends Component<DefaultPageProps, { ciphertext: string }> {
|
export class TransitEncrypt extends Component<DefaultPageProps, { ciphertext: string }> {
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
const secretItem = this.props.matches["secretItem"];
|
const secretItem = this.props.matches["secretItem"];
|
||||||
|
@ -43,7 +45,11 @@ export class TransitEncrypt extends Component<DefaultPageProps, { ciphertext: st
|
||||||
<InputWithTitle title={i18next.t("transit_encrypt_already_encoded_checkbox")}>
|
<InputWithTitle title={i18next.t("transit_encrypt_already_encoded_checkbox")}>
|
||||||
<input class="uk-checkbox" name="base64Checkbox" type="checkbox" />
|
<input class="uk-checkbox" name="base64Checkbox" type="checkbox" />
|
||||||
</InputWithTitle>
|
</InputWithTitle>
|
||||||
<p class="uk-text-danger" id="errorText" />
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<Button text={i18next.t("transit_encrypt")} color="primary" type="submit" />
|
<Button text={i18next.t("transit_encrypt")} color="primary" type="submit" />
|
||||||
</Form>
|
</Form>
|
||||||
</>
|
</>
|
||||||
|
@ -87,7 +93,7 @@ export class TransitEncrypt extends Component<DefaultPageProps, { ciphertext: st
|
||||||
this.setState({ ciphertext: res.ciphertext });
|
this.setState({ ciphertext: res.ciphertext });
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
setErrorText(`API Error: ${error.message}`);
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
import { SecretTitleElement } from "../SecretTitleElement";
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import { delSecretsEngineURL, transitNewSecretURL, transitViewSecretURL } from "../../pageLinks";
|
import { delSecretsEngineURL, transitNewSecretURL, transitViewSecretURL } from "../../pageLinks";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
|
import { sendErrorNotification } from "../../../elements/ErrorMessage";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
type TransitViewListState = {
|
type TransitViewListState = {
|
||||||
|
@ -26,25 +27,21 @@ export class TransitViewListItem extends Component<
|
||||||
|
|
||||||
timer: unknown;
|
timer: unknown;
|
||||||
|
|
||||||
getTransitKeys(): void {
|
async getTransitKeys() {
|
||||||
void this.props.api
|
const transitKeys = await this.props.api.getTransitKeys(this.props.baseMount);
|
||||||
.getTransitKeys(this.props.baseMount)
|
this.setState({
|
||||||
.then((keys) => {
|
contentLoaded: true,
|
||||||
this.setState({
|
transitKeysList: transitKeys,
|
||||||
contentLoaded: true,
|
});
|
||||||
transitKeysList: keys,
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch((_) => {
|
|
||||||
this.setState({
|
|
||||||
contentLoaded: true,
|
|
||||||
transitKeysList: [],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount(): void {
|
async componentDidMount() {
|
||||||
this.getTransitKeys();
|
try {
|
||||||
|
await this.getTransitKeys();
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): JSX.Element {
|
render(): JSX.Element {
|
||||||
|
@ -79,8 +76,13 @@ export class TransitList extends Component<DefaultPageProps, { caps: Capabilitie
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
const mountsPath = "/sys/mounts/" + baseMount;
|
const mountsPath = "/sys/mounts/" + baseMount;
|
||||||
|
|
||||||
const caps = await this.props.api.getCapabilitiesPath([mountsPath, baseMount]);
|
try {
|
||||||
this.setState({ caps });
|
const caps = await this.props.api.getCapabilitiesPath([mountsPath, baseMount]);
|
||||||
|
this.setState({ caps });
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -1,21 +1,21 @@
|
||||||
import { Button } from "../../../elements/Button";
|
import { Button } from "../../../elements/Button";
|
||||||
import { Component } from "preact";
|
import { Component, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../../../elements/ErrorMessage";
|
||||||
import { Form } from "../../../elements/Form";
|
import { Form } from "../../../elements/Form";
|
||||||
import { Margin } from "../../../elements/Margin";
|
import { Margin } from "../../../elements/Margin";
|
||||||
import { MarginInline } from "../../../elements/MarginInline";
|
import { MarginInline } from "../../../elements/MarginInline";
|
||||||
import { SecretTitleElement } from "../SecretTitleElement";
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { setErrorText } from "../../../../pageUtils";
|
|
||||||
import { transitViewSecretURL } from "../../pageLinks";
|
import { transitViewSecretURL } from "../../pageLinks";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class TransitNew extends Component<DefaultPageProps> {
|
export class TransitNew extends Component<DefaultPageProps> {
|
||||||
constructor() {
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
super();
|
|
||||||
}
|
|
||||||
render() {
|
render() {
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<SecretTitleElement
|
<SecretTitleElement
|
||||||
|
@ -57,7 +57,11 @@ export class TransitNew extends Component<DefaultPageProps> {
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
</Margin>
|
</Margin>
|
||||||
<p class="uk-text-danger" id="errorText" />
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<MarginInline>
|
<MarginInline>
|
||||||
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
<Button text={i18next.t("common_create")} color="primary" type="submit" />
|
||||||
</MarginInline>
|
</MarginInline>
|
||||||
|
@ -80,7 +84,7 @@ export class TransitNew extends Component<DefaultPageProps> {
|
||||||
route(transitViewSecretURL(baseMount, name));
|
route(transitViewSecretURL(baseMount, name));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
setErrorText(error.message);
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import { Button } from "../../../elements/Button";
|
import { Button } from "../../../elements/Button";
|
||||||
import { Component } from "preact";
|
import { Component, createRef } from "preact";
|
||||||
import { CopyableBox } from "../../../elements/CopyableBox";
|
import { CopyableBox } from "../../../elements/CopyableBox";
|
||||||
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage, sendErrorNotification } from "../../../elements/ErrorMessage";
|
||||||
import { Form } from "../../../elements/Form";
|
import { Form } from "../../../elements/Form";
|
||||||
import { Margin } from "../../../elements/Margin";
|
import { Margin } from "../../../elements/Margin";
|
||||||
import { SecretTitleElement } from "../SecretTitleElement";
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import { TransitKeyType } from "../../../../api/types/transit";
|
import { TransitKeyType } from "../../../../api/types/transit";
|
||||||
import { objectToMap } from "../../../../utils";
|
import { objectToMap } from "../../../../utils";
|
||||||
import { setErrorText } from "../../../../pageUtils";
|
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
type versionOption = { version: string; label: string };
|
type versionOption = { version: string; label: string };
|
||||||
|
@ -18,12 +18,19 @@ type TransitRewrapState = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export class TransitRewrap extends Component<DefaultPageProps, TransitRewrapState> {
|
export class TransitRewrap extends Component<DefaultPageProps, TransitRewrapState> {
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
const secretItem = this.props.matches["secretItem"];
|
const secretItem = this.props.matches["secretItem"];
|
||||||
this.setState({
|
|
||||||
transitKey: await this.props.api.getTransitKey(baseMount, secretItem),
|
try {
|
||||||
});
|
const transitKey = await this.props.api.getTransitKey(baseMount, secretItem);
|
||||||
|
this.setState({ transitKey });
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
@ -83,7 +90,11 @@ export class TransitRewrap extends Component<DefaultPageProps, TransitRewrapStat
|
||||||
placeholder={i18next.t("transit_rewrap_input_placeholder")}
|
placeholder={i18next.t("transit_rewrap_input_placeholder")}
|
||||||
/>
|
/>
|
||||||
</Margin>
|
</Margin>
|
||||||
<p class="uk-text-danger" id="errorText" />
|
|
||||||
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<Button text={i18next.t("transit_rewrap")} color="primary" type="submit" />
|
<Button text={i18next.t("transit_rewrap")} color="primary" type="submit" />
|
||||||
</Form>
|
</Form>
|
||||||
</>
|
</>
|
||||||
|
@ -115,7 +126,7 @@ export class TransitRewrap extends Component<DefaultPageProps, TransitRewrapStat
|
||||||
this.setState({ ciphertext: res.ciphertext });
|
this.setState({ ciphertext: res.ciphertext });
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
setErrorText(`API Error: ${error.message}`);
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import { Tile } from "../../../elements/Tile";
|
import { Tile } from "../../../elements/Tile";
|
||||||
import { TransitKeyType } from "../../../../api/types/transit";
|
import { TransitKeyType } from "../../../../api/types/transit";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
|
import { sendErrorNotification } from "../../../elements/ErrorMessage";
|
||||||
import {
|
import {
|
||||||
transitDecryptSecretURL,
|
transitDecryptSecretURL,
|
||||||
transitEncryptSecretURL,
|
transitEncryptSecretURL,
|
||||||
|
@ -16,8 +17,14 @@ export class TransitView extends Component<DefaultPageProps, { transitKey: Trans
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const baseMount = this.props.matches["baseMount"];
|
const baseMount = this.props.matches["baseMount"];
|
||||||
const secretItem = this.props.matches["secretItem"];
|
const secretItem = this.props.matches["secretItem"];
|
||||||
const transitKey = await this.props.api.getTransitKey(baseMount, secretItem);
|
|
||||||
this.setState({ transitKey });
|
try {
|
||||||
|
const transitKey = await this.props.api.getTransitKey(baseMount, secretItem);
|
||||||
|
this.setState({ transitKey });
|
||||||
|
} catch (e) {
|
||||||
|
const error = e as Error;
|
||||||
|
sendErrorNotification(error.message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -14,9 +14,6 @@ import { route } from "preact-router";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
export class SetLanguage extends Component<DefaultPageProps> {
|
export class SetLanguage extends Component<DefaultPageProps> {
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -22,7 +22,7 @@ export class SetVaultURL extends Component<DefaultPageProps> {
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</Margin>
|
</Margin>
|
||||||
<p id="errorText" class="uk-text-danger" />
|
|
||||||
<Margin>
|
<Margin>
|
||||||
<Button text={i18next.t("set_vault_url_set_btn")} color="primary" type="submit" />
|
<Button text={i18next.t("set_vault_url_set_btn")} color="primary" type="submit" />
|
||||||
</Margin>
|
</Margin>
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import { Button } from "../elements/Button";
|
import { Button } from "../elements/Button";
|
||||||
import { Component, JSX } from "preact";
|
import { Component, JSX, createRef } from "preact";
|
||||||
import { DefaultPageProps } from "../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../types/DefaultPageProps";
|
||||||
|
import { ErrorMessage } from "../elements/ErrorMessage";
|
||||||
|
import { Margin } from "../elements/Margin";
|
||||||
import { PageTitle } from "../elements/PageTitle";
|
import { PageTitle } from "../elements/PageTitle";
|
||||||
import { UnsealForm } from "./Unseal_Form";
|
import { UnsealForm } from "./Unseal_Form";
|
||||||
import { UnsealQR } from "./Unseal_QR";
|
import { UnsealQR } from "./Unseal_QR";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { setErrorText } from "../../pageUtils";
|
|
||||||
import { toStr } from "../../utils";
|
import { toStr } from "../../utils";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ export class Unseal extends Component<DefaultPageProps, UnsealPageState> {
|
||||||
this.updateStateWithSealStatus();
|
this.updateStateWithSealStatus();
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const error = e as Error;
|
const error = e as Error;
|
||||||
setErrorText(error.message);
|
this.errorMessageRef.current.setErrorMessage(error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +67,8 @@ export class Unseal extends Component<DefaultPageProps, UnsealPageState> {
|
||||||
this.setState({ timer: timer });
|
this.setState({ timer: timer });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errorMessageRef = createRef<ErrorMessage>();
|
||||||
|
|
||||||
render(): JSX.Element {
|
render(): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -77,7 +80,9 @@ export class Unseal extends Component<DefaultPageProps, UnsealPageState> {
|
||||||
max={this.state.keys_needed}
|
max={this.state.keys_needed}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<p id="errorText" class="uk-text-danger uk-margin-top" />
|
<Margin>
|
||||||
|
<ErrorMessage ref={this.errorMessageRef} />
|
||||||
|
</Margin>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
{i18next.t("unseal_keys_progress", {
|
{i18next.t("unseal_keys_progress", {
|
||||||
|
|
Loading…
Reference in a new issue