118 lines
3.6 KiB
TypeScript
118 lines
3.6 KiB
TypeScript
import { Component, JSX, render } from "preact";
|
|
import { DefaultPageProps } from "../../../types/DefaultPageProps";
|
|
import { MountType, getMounts } from "../../../api/sys/getMounts";
|
|
import { Page } from "../../../types/Page";
|
|
import { PageState } from "../../../state/PageState";
|
|
import { PageTitle } from "../../elements/PageTitle";
|
|
import { getCapsPath } from "../../../api/sys/getCapabilities";
|
|
import { prePageChecks } from "../../../pageUtils";
|
|
import { route } from "preact-router";
|
|
import { sortedObjectMap } from "../../../utils";
|
|
import i18next from "i18next";
|
|
|
|
const supportedMountTypes = ["kv", "totp", "transit", "cubbyhole"];
|
|
|
|
export function isSupportedMount(mount: MountType): boolean {
|
|
if (typeof mount != "object") return false;
|
|
if (mount == null) return false;
|
|
if (!("type" in mount)) return false;
|
|
if (!supportedMountTypes.includes(mount.type)) return false;
|
|
return true;
|
|
}
|
|
|
|
export type MountLinkProps = {
|
|
state: PageState;
|
|
mount: MountType;
|
|
baseMount: string;
|
|
};
|
|
|
|
function MountLink(props: MountLinkProps): JSX.Element {
|
|
const mount = props.mount;
|
|
const baseMount = props.baseMount;
|
|
|
|
let linkText = "";
|
|
let mountPathType: string;
|
|
if (mount.type == "kv") {
|
|
linkText = `K/V (v${mount.options.version}) - ${baseMount}`;
|
|
mountPathType = "kv";
|
|
} else if (mount.type == "totp") {
|
|
linkText = `TOTP - ${baseMount}`;
|
|
mountPathType = "totp";
|
|
} else if (mount.type == "transit") {
|
|
linkText = `Transit - ${baseMount}`;
|
|
mountPathType = "transit";
|
|
} else if (mount.type == "cubbyhole") {
|
|
linkText = `Cubbyhole - ${baseMount}`;
|
|
mountPathType = "kv";
|
|
}
|
|
|
|
const link = "/secrets/" + mountPathType + "/list/" + baseMount;
|
|
|
|
return (
|
|
<li>
|
|
<a href={link}>{linkText}</a>
|
|
</li>
|
|
);
|
|
}
|
|
|
|
type SecretsState = {
|
|
mountsMap: Map<string, MountType>;
|
|
capabilities: string[];
|
|
};
|
|
|
|
export class Secrets extends Component<DefaultPageProps, SecretsState> {
|
|
async componentDidMount() {
|
|
if (!(await prePageChecks(this.props.state))) return;
|
|
|
|
const mountsCapabilities = await getCapsPath("/sys/mounts");
|
|
const mounts = await getMounts();
|
|
// sort it by secretPath so it's in alphabetical order consistantly.
|
|
const mountsMap = sortedObjectMap(mounts);
|
|
this.setState({
|
|
capabilities: mountsCapabilities,
|
|
mountsMap: mountsMap as Map<string, MountType>,
|
|
});
|
|
}
|
|
|
|
render() {
|
|
return (
|
|
this.state.mountsMap && (
|
|
<>
|
|
<PageTitle title={i18next.t("secrets_home_page_title")} />
|
|
<div>
|
|
<div>
|
|
<p>
|
|
{this.state.capabilities.includes("sudo") &&
|
|
this.state.capabilities.includes("create") && (
|
|
<button
|
|
class="uk-button uk-button-primary"
|
|
onClick={() => {
|
|
route("/secrets/new_secrets_engine");
|
|
}}
|
|
>
|
|
{i18next.t("secrets_home_new_secrets_engine_button")}
|
|
</button>
|
|
)}
|
|
</p>
|
|
</div>
|
|
<div class="uk-margin-top">
|
|
<ul class="uk-nav uk-nav-default">
|
|
{Array.from(this.state.mountsMap).map((args: [string, MountType]) => {
|
|
const baseMount = args[0];
|
|
const mount = args[1];
|
|
console.log(baseMount, mount);
|
|
if (isSupportedMount(mount)) {
|
|
return (
|
|
<MountLink state={this.props.state} mount={mount} baseMount={baseMount} />
|
|
);
|
|
}
|
|
})}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</>
|
|
)
|
|
);
|
|
}
|
|
}
|