Add KV secret version viewing again
This commit is contained in:
parent
bfaa43ce3a
commit
a8add31ff1
|
@ -18,7 +18,7 @@ import { SecretMetadataType } from "./types/secret";
|
||||||
import { Settings } from "../settings/Settings";
|
import { Settings } from "../settings/Settings";
|
||||||
import { TokenInfo } from "./types/token";
|
import { TokenInfo } from "./types/token";
|
||||||
import { UserType, UserTypeAPIResp } from "./types/user";
|
import { UserType, UserTypeAPIResp } from "./types/user";
|
||||||
import { removeDoubleSlash } from "../utils";
|
import { getObjectKeys, removeDoubleSlash } from "../utils";
|
||||||
|
|
||||||
async function checkResponse(resp: Response): Promise<void> {
|
async function checkResponse(resp: Response): Promise<void> {
|
||||||
if (resp.ok) return;
|
if (resp.ok) return;
|
||||||
|
@ -352,19 +352,67 @@ export class API {
|
||||||
await checkResponse(resp);
|
await checkResponse(resp);
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteSecret(baseMount: string, secretPath: string[], name: string): Promise<void> {
|
async deleteSecret(
|
||||||
|
baseMount: string,
|
||||||
|
secretPath: string[],
|
||||||
|
name: string,
|
||||||
|
version: string = "null",
|
||||||
|
): Promise<void> {
|
||||||
let secretURL = "";
|
let secretURL = "";
|
||||||
|
|
||||||
|
let request;
|
||||||
|
|
||||||
const mountInfo = await this.getMount(baseMount);
|
const mountInfo = await this.getMount(baseMount);
|
||||||
if (mountInfo.options.version == "2") {
|
const mountVersion = mountInfo.options.version;
|
||||||
secretURL = `/v1/${baseMount}/metadata/${secretPath.join("/")}/${name}`;
|
|
||||||
|
if (mountVersion == "2" && version != "null") {
|
||||||
|
secretURL = `/v1/${baseMount}/delete/${secretPath.join("/")}/${name}`;
|
||||||
|
secretURL = removeDoubleSlash(secretURL).replace(/\/$/, "");
|
||||||
|
request = new Request(this.appendAPIURL(secretURL), {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
...this.getHeaders(),
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ versions: [version] }),
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
secretURL = `/v1/${baseMount}/${secretPath.join("/")}/${name}`;
|
if (mountVersion == "2") {
|
||||||
|
secretURL = `/v1/${baseMount}/metadata/${secretPath.join("/")}/${name}`;
|
||||||
|
} else {
|
||||||
|
secretURL = `/v1/${baseMount}/${secretPath.join("/")}/${name}`;
|
||||||
|
}
|
||||||
|
secretURL = removeDoubleSlash(secretURL).replace(/\/$/, "");
|
||||||
|
request = new Request(this.appendAPIURL(secretURL), {
|
||||||
|
method: "DELETE",
|
||||||
|
headers: this.getHeaders(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
const resp = await fetch(request);
|
||||||
|
await checkResponse(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
async undeleteSecret(
|
||||||
|
baseMount: string,
|
||||||
|
secretPath: string[],
|
||||||
|
name: string,
|
||||||
|
version: string = "null",
|
||||||
|
): Promise<void> {
|
||||||
|
let secretURL = `/v1/${baseMount}/undelete/${secretPath.join("/")}/${name}`;
|
||||||
secretURL = removeDoubleSlash(secretURL).replace(/\/$/, "");
|
secretURL = removeDoubleSlash(secretURL).replace(/\/$/, "");
|
||||||
|
if (version == "null") {
|
||||||
|
const meta = await this.getSecretMetadata(baseMount, secretPath, name);
|
||||||
|
const versions = getObjectKeys(meta.versions);
|
||||||
|
version = String(versions[versions.length - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
const request = new Request(this.appendAPIURL(secretURL), {
|
const request = new Request(this.appendAPIURL(secretURL), {
|
||||||
method: "DELETE",
|
method: "POST",
|
||||||
headers: this.getHeaders(),
|
headers: {
|
||||||
|
...this.getHeaders(),
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ versions: [version] }),
|
||||||
});
|
});
|
||||||
const resp = await fetch(request);
|
const resp = await fetch(request);
|
||||||
await checkResponse(resp);
|
await checkResponse(resp);
|
||||||
|
@ -376,7 +424,7 @@ export class API {
|
||||||
name: string,
|
name: string,
|
||||||
): Promise<Record<string, unknown>> {
|
): Promise<Record<string, unknown>> {
|
||||||
const request = new Request(
|
const request = new Request(
|
||||||
this.appendAPIURL(`/v1/${baseMount}/${secretPath.join("")}/${name}`),
|
this.appendAPIURL(`/v1/${baseMount}/${secretPath.join("/")}/${name}`),
|
||||||
{
|
{
|
||||||
headers: this.getHeaders(),
|
headers: this.getHeaders(),
|
||||||
},
|
},
|
||||||
|
@ -394,10 +442,12 @@ export class API {
|
||||||
baseMount: string,
|
baseMount: string,
|
||||||
secretPath: string[],
|
secretPath: string[],
|
||||||
name: string,
|
name: string,
|
||||||
|
version: string = "null",
|
||||||
): Promise<Record<string, unknown>> {
|
): Promise<Record<string, unknown>> {
|
||||||
let secretURL = "";
|
let secretURL = "";
|
||||||
|
|
||||||
secretURL = `/v1/${baseMount}/data/${secretPath.join("")}/${name}`;
|
secretURL = `/v1/${baseMount}/data/${secretPath.join("/")}/${name}`;
|
||||||
|
if (version != "null") secretURL += `?version=${version}`;
|
||||||
|
|
||||||
const request = new Request(this.appendAPIURL(secretURL), {
|
const request = new Request(this.appendAPIURL(secretURL), {
|
||||||
headers: this.getHeaders(),
|
headers: this.getHeaders(),
|
||||||
|
@ -414,10 +464,11 @@ export class API {
|
||||||
baseMount: string,
|
baseMount: string,
|
||||||
secretPath: string[],
|
secretPath: string[],
|
||||||
name: string,
|
name: string,
|
||||||
|
version: string = "null",
|
||||||
): Promise<Record<string, unknown>> {
|
): Promise<Record<string, unknown>> {
|
||||||
const mountInfo = await this.getMount(baseMount);
|
const mountInfo = await this.getMount(baseMount);
|
||||||
if (mountInfo.options.version == "2") {
|
if (mountInfo.options.version == "2") {
|
||||||
return await this.getSecretKV2(baseMount, secretPath, name);
|
return await this.getSecretKV2(baseMount, secretPath, name, version);
|
||||||
} else {
|
} else {
|
||||||
return await this.getSecretKV1(baseMount, secretPath, name);
|
return await this.getSecretKV1(baseMount, secretPath, name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ import { UserPassUserEdit } from "./ui/pages/Access/Auth/userpass/UserPassUserEd
|
||||||
import { UserPassUserNew } from "./ui/pages/Access/Auth/userpass/UserPassUserNew";
|
import { UserPassUserNew } from "./ui/pages/Access/Auth/userpass/UserPassUserNew";
|
||||||
import { UserPassUserView } from "./ui/pages/Access/Auth/userpass/UserPassUserView";
|
import { UserPassUserView } from "./ui/pages/Access/Auth/userpass/UserPassUserView";
|
||||||
import { UserPassUsersList } from "./ui/pages/Access/Auth/userpass/UserPassUsersList";
|
import { UserPassUsersList } from "./ui/pages/Access/Auth/userpass/UserPassUsersList";
|
||||||
|
import { KeyValueVersions } from "./ui/pages/Secrets/KeyValue/KeyValueVersions";
|
||||||
|
|
||||||
export const Main = () => (
|
export const Main = () => (
|
||||||
<Router>
|
<Router>
|
||||||
|
@ -65,7 +66,12 @@ export const Main = () => (
|
||||||
<KeyValueNew path="/secrets/kv/new/:baseMount/:secretPath*?" settings={settings} api={api} />
|
<KeyValueNew path="/secrets/kv/new/:baseMount/:secretPath*?" settings={settings} api={api} />
|
||||||
<KeyValueList path="/secrets/kv/list/:baseMount/:secretPath*?" settings={settings} api={api} />
|
<KeyValueList path="/secrets/kv/list/:baseMount/:secretPath*?" settings={settings} api={api} />
|
||||||
<KeyValueView
|
<KeyValueView
|
||||||
path="/secrets/kv/view/:item/:baseMount/:secretPath*?"
|
path="/secrets/kv/view/:item/:version/:baseMount/:secretPath*?"
|
||||||
|
settings={settings}
|
||||||
|
api={api}
|
||||||
|
/>
|
||||||
|
<KeyValueVersions
|
||||||
|
path="/secrets/kv/versions/:item/:baseMount/:secretPath*?"
|
||||||
settings={settings}
|
settings={settings}
|
||||||
api={api}
|
api={api}
|
||||||
/>
|
/>
|
||||||
|
@ -75,7 +81,7 @@ export const Main = () => (
|
||||||
api={api}
|
api={api}
|
||||||
/>
|
/>
|
||||||
<KeyValueDelete
|
<KeyValueDelete
|
||||||
path="/secrets/kv/delete/:item/:baseMount/:secretPath*?"
|
path="/secrets/kv/delete/:item/:version/:baseMount/:secretPath*?"
|
||||||
settings={settings}
|
settings={settings}
|
||||||
api={api}
|
api={api}
|
||||||
/>
|
/>
|
||||||
|
@ -83,7 +89,7 @@ export const Main = () => (
|
||||||
<TOTPList path="/secrets/totp/list/:baseMount" settings={settings} api={api} />
|
<TOTPList path="/secrets/totp/list/:baseMount" settings={settings} api={api} />
|
||||||
<TOTPNew path="/secrets/totp/new/:baseMount" settings={settings} api={api} />
|
<TOTPNew path="/secrets/totp/new/:baseMount" settings={settings} api={api} />
|
||||||
<TOTPNewGenerated path="/secrets/totp/new_generated/:baseMount" settings={settings} api={api} />
|
<TOTPNewGenerated path="/secrets/totp/new_generated/:baseMount" settings={settings} api={api} />
|
||||||
<TOTPDelete path="/secrets/totp/delete/:baseMount/:item" settings={settings} api={api} />
|
<TOTPDelete path="/secrets/totp/delete/:version/:baseMount/:item" settings={settings} api={api} />
|
||||||
|
|
||||||
<TransitNew path="/secrets/transit/new/:baseMount" settings={settings} api={api} />
|
<TransitNew path="/secrets/transit/new/:baseMount" settings={settings} api={api} />
|
||||||
<TransitList path="/secrets/transit/list/:baseMount" settings={settings} api={api} />
|
<TransitList path="/secrets/transit/list/:baseMount" settings={settings} api={api} />
|
||||||
|
|
|
@ -2,12 +2,15 @@ import { Component } from "preact";
|
||||||
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
import { SecretTitleElement } from "../SecretTitleElement";
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
import { route } from "preact-router";
|
||||||
|
import { kvListURL, kvViewURL } from "../../pageLinks";
|
||||||
|
|
||||||
export class KeyValueDelete extends Component<DefaultPageProps> {
|
export class KeyValueDelete extends Component<DefaultPageProps> {
|
||||||
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("/");
|
||||||
const item = this.props.matches["item"];
|
const item = this.props.matches["item"];
|
||||||
|
const version = this.props.matches["version"];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -23,8 +26,13 @@ export class KeyValueDelete extends Component<DefaultPageProps> {
|
||||||
<button
|
<button
|
||||||
class="uk-button uk-button-danger"
|
class="uk-button uk-button-danger"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await this.props.api.deleteSecret(baseMount, secretPath, item);
|
await this.props.api.deleteSecret(baseMount, secretPath, item, version);
|
||||||
window.history.back();
|
if (version == "null") {
|
||||||
|
route(kvListURL(baseMount, secretPath))
|
||||||
|
} else {
|
||||||
|
route(kvViewURL(baseMount, secretPath, item, "null"))
|
||||||
|
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{i18next.t("common_delete")}
|
{i18next.t("common_delete")}
|
||||||
|
|
55
src/ui/pages/Secrets/KeyValue/KeyValueVersions.tsx
Normal file
55
src/ui/pages/Secrets/KeyValue/KeyValueVersions.tsx
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import { Component } from "preact";
|
||||||
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
|
import { kvViewURL } from "../../pageLinks";
|
||||||
|
import { route } from "preact-router";
|
||||||
|
import { objectToMap } from "../../../../utils";
|
||||||
|
|
||||||
|
export class KeyValueVersions extends Component<DefaultPageProps, { versions: string[] }> {
|
||||||
|
async componentDidMount() {
|
||||||
|
const baseMount = this.props.matches["baseMount"];
|
||||||
|
const secretPath = this.props.matches["secretPath"].split("/");
|
||||||
|
const secretItem = this.props.matches["item"];
|
||||||
|
|
||||||
|
const metadata = await this.props.api.getSecretMetadata(
|
||||||
|
baseMount,
|
||||||
|
secretPath,
|
||||||
|
secretItem,
|
||||||
|
);
|
||||||
|
|
||||||
|
const versions = Array.from(objectToMap(metadata.versions).keys());
|
||||||
|
|
||||||
|
this.setState({ versions });
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (!this.state.versions) return;
|
||||||
|
const baseMount = this.props.matches["baseMount"];
|
||||||
|
const secretPath = this.props.matches["secretPath"].split("/");
|
||||||
|
const secretItem = this.props.matches["item"];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<SecretTitleElement
|
||||||
|
type="kv"
|
||||||
|
baseMount={baseMount}
|
||||||
|
secretPath={secretPath}
|
||||||
|
item={this.props.matches["item"]}
|
||||||
|
/>
|
||||||
|
<ul class="uk-nav uk-nav-default">
|
||||||
|
{this.state.versions.map((ver) => (
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
onClick={async () => {
|
||||||
|
route(kvViewURL(baseMount, secretPath, secretItem, ver));
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{`v${ver}`}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,10 +4,11 @@ import { CopyableInputBox } from "../../../elements/CopyableInputBox";
|
||||||
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
|
||||||
import { Grid, GridSizes } from "../../../elements/Grid";
|
import { Grid, GridSizes } from "../../../elements/Grid";
|
||||||
import { SecretTitleElement } from "../SecretTitleElement";
|
import { SecretTitleElement } from "../SecretTitleElement";
|
||||||
import { kvDeleteURL, kvEditURL } from "../../pageLinks";
|
import { kvDeleteURL, kvEditURL, kvVersionsURL } from "../../pageLinks";
|
||||||
import { route } from "preact-router";
|
import { route } from "preact-router";
|
||||||
import { sortedObjectMap } from "../../../../utils";
|
import { sortedObjectMap } from "../../../../utils";
|
||||||
import i18next from "i18next";
|
import i18next from "i18next";
|
||||||
|
import { DoesNotExistError } from "../../../../types/internalErrors";
|
||||||
|
|
||||||
export type KVSecretViewProps = {
|
export type KVSecretViewProps = {
|
||||||
kvData: Record<string, unknown>;
|
kvData: Record<string, unknown>;
|
||||||
|
@ -46,6 +47,9 @@ type KeyValueViewState = {
|
||||||
secretItem: string;
|
secretItem: string;
|
||||||
caps: string[];
|
caps: string[];
|
||||||
secretInfo: Record<string, unknown>;
|
secretInfo: Record<string, unknown>;
|
||||||
|
kvVersion: string;
|
||||||
|
isDeleted: boolean;
|
||||||
|
secretVersion: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class KeyValueView extends Component<DefaultPageProps, KeyValueViewState> {
|
export class KeyValueView extends Component<DefaultPageProps, KeyValueViewState> {
|
||||||
|
@ -53,27 +57,43 @@ export class KeyValueView extends Component<DefaultPageProps, KeyValueViewState>
|
||||||
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"];
|
||||||
|
const secretVersion = this.props.matches["version"];
|
||||||
|
|
||||||
const caps = (await this.props.api.getCapabilities(baseMount, secretPath, secretItem))
|
const caps = (await this.props.api.getCapabilities(baseMount, secretPath, secretItem))
|
||||||
.capabilities;
|
.capabilities;
|
||||||
|
|
||||||
const secretPathAPI = secretPath.map((e) => e + "/");
|
const mountInfo = await this.props.api.getMount(baseMount);
|
||||||
// TODO: this is a big hacky, fix when redo how api arguments work
|
let kvVersion = mountInfo.options.version;
|
||||||
secretPathAPI[secretPathAPI.length - 1] = String(secretPathAPI[secretPathAPI.length - 1])
|
|
||||||
.replace("/", "")
|
let secretInfo: Record<string, unknown>;
|
||||||
.toString();
|
|
||||||
|
if (kvVersion == "2") {
|
||||||
|
try {
|
||||||
|
secretInfo = await this.props.api.getSecretKV2(baseMount, secretPath, secretItem, secretVersion);
|
||||||
|
} catch (e) {
|
||||||
|
if (e == DoesNotExistError) {
|
||||||
|
secretInfo = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
secretInfo = await this.props.api.getSecretKV1(baseMount, secretPath, secretItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
let isDeleted = (secretInfo == null) && (kvVersion == "2");
|
||||||
|
|
||||||
const secretInfo = await this.props.api.getSecret(baseMount, secretPathAPI, secretItem);
|
|
||||||
this.setState({
|
this.setState({
|
||||||
baseMount,
|
baseMount,
|
||||||
secretPath,
|
secretPath,
|
||||||
secretItem,
|
secretItem,
|
||||||
caps,
|
caps,
|
||||||
secretInfo,
|
secretInfo,
|
||||||
|
kvVersion,
|
||||||
|
isDeleted,
|
||||||
|
secretVersion,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
if (!this.state.baseMount) return;
|
if (!this.state.secretInfo) return;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -85,19 +105,43 @@ export class KeyValueView extends Component<DefaultPageProps, KeyValueViewState>
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<p id="buttonsBlock">
|
<p id="buttonsBlock">
|
||||||
{this.state.caps.includes("delete") && (
|
{
|
||||||
<button
|
// Delete Button
|
||||||
class="uk-button uk-button-danger"
|
!this.state.isDeleted && this.state.caps.includes("delete") && (
|
||||||
onClick={async () => {
|
<button
|
||||||
route(
|
class="uk-button uk-button-danger"
|
||||||
kvDeleteURL(this.state.baseMount, this.state.secretPath, this.state.secretItem),
|
onClick={() => {
|
||||||
);
|
route(
|
||||||
}}
|
kvDeleteURL(
|
||||||
>
|
this.state.baseMount,
|
||||||
{i18next.t("kv_secret_delete_btn")}
|
this.state.secretPath,
|
||||||
</button>
|
this.state.secretItem,
|
||||||
)}
|
this.state.secretVersion,
|
||||||
{this.state.caps.includes("update") && (
|
),
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{((): string => {
|
||||||
|
// Delete Secret on kv-v1
|
||||||
|
let deleteButtonText = i18next.t("kv_secret_delete_btn");
|
||||||
|
if (this.state.kvVersion == "2" && this.state.secretVersion == "null") {
|
||||||
|
// Delete All
|
||||||
|
deleteButtonText = i18next.t("kv_secret_delete_all_btn");
|
||||||
|
} else if (
|
||||||
|
this.state.kvVersion == "2" &&
|
||||||
|
this.state.secretVersion != "null"
|
||||||
|
) {
|
||||||
|
// Delete Version X
|
||||||
|
deleteButtonText = i18next.t("kv_secret_delete_version_btn", {
|
||||||
|
version: this.state.secretVersion,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return deleteButtonText;
|
||||||
|
})()}
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{this.state.secretVersion == "null" && this.state.caps.includes("update") && (
|
||||||
<button
|
<button
|
||||||
class="uk-button uk-button-primary"
|
class="uk-button uk-button-primary"
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
|
@ -109,9 +153,43 @@ export class KeyValueView extends Component<DefaultPageProps, KeyValueViewState>
|
||||||
{i18next.t("common_edit")}
|
{i18next.t("common_edit")}
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
{!this.state.isDeleted && this.state.kvVersion == "2" && (
|
||||||
|
<button
|
||||||
|
class="uk-button uk-button-secondary"
|
||||||
|
onClick={async () => {
|
||||||
|
route(
|
||||||
|
kvVersionsURL(this.state.baseMount, this.state.secretPath, this.state.secretItem),
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{i18next.t("kv_secret_versions_btn")}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{<KVSecretVew kvData={this.state.secretInfo} />}
|
{!this.state.isDeleted && <KVSecretVew kvData={this.state.secretInfo} />}
|
||||||
|
|
||||||
|
{this.state.isDeleted && (
|
||||||
|
<>
|
||||||
|
<p>{i18next.t("kv_secret_deleted_text")}</p>
|
||||||
|
<button
|
||||||
|
class="uk-button uk-button-primary"
|
||||||
|
onClick={async () => {
|
||||||
|
await this.props.api.undeleteSecret(
|
||||||
|
this.state.baseMount,
|
||||||
|
this.state.secretPath,
|
||||||
|
this.state.secretItem,
|
||||||
|
this.state.secretVersion,
|
||||||
|
);
|
||||||
|
this.setState({});
|
||||||
|
await this.componentDidMount();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{i18next.t("kv_secret_restore_btn")}
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
@ -10,16 +10,20 @@ export function kvNewURL(baseMount: string, secretPath?: string[]): string {
|
||||||
return `/secrets/kv/new/${baseMount}` + (secretPath ? `/${secretPath.join("/")}` : "");
|
return `/secrets/kv/new/${baseMount}` + (secretPath ? `/${secretPath.join("/")}` : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
export function kvDeleteURL(baseMount: string, secretPath: string[], secret: string): string {
|
export function kvDeleteURL(baseMount: string, secretPath: string[], secret: string, version: string = "null"): string {
|
||||||
return `/secrets/kv/delete/${secret}/${baseMount}/${secretPath.join("/")}`;
|
return `/secrets/kv/delete/${secret}/${version}/${baseMount}/${secretPath.join("/")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function kvEditURL(baseMount: string, secretPath: string[], secret: string): string {
|
export function kvEditURL(baseMount: string, secretPath: string[], secret: string): string {
|
||||||
return `/secrets/kv/edit/${secret}/${baseMount}/${secretPath.join("/")}`;
|
return `/secrets/kv/edit/${secret}/${baseMount}/${secretPath.join("/")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function kvViewURL(baseMount: string, secretPath: string[], secret: string): string {
|
export function kvVersionsURL(baseMount: string, secretPath: string[], secret: string): string {
|
||||||
return `/secrets/kv/view/${secret}/${baseMount}/${secretPath.join("/")}`;
|
return `/secrets/kv/versions/${secret}/${baseMount}/${secretPath.join("/")}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function kvViewURL(baseMount: string, secretPath: string[], secret: string, version: string = "null"): string {
|
||||||
|
return `/secrets/kv/view/${secret}/${version}/${baseMount}/${secretPath.join("/")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function kvListURL(baseMount: string, secretPath: string[]): string {
|
export function kvListURL(baseMount: string, secretPath: string[]): string {
|
||||||
|
|
Loading…
Reference in a new issue