1
0
Fork 0
This commit is contained in:
ChaotiCryptidz 2022-01-07 14:11:14 +00:00
parent 6089fe9501
commit 12eb745d2c
34 changed files with 578 additions and 867 deletions

View file

@ -1,4 +1,4 @@
VaultUI Copyright (2021) (Z & Kitteh)(“Licensor”)
VaultUI Copyright (2022) (ChaotiCryptidz)(“Licensor”)
Hippocratic License Version Number: 2.1.

View file

@ -4,9 +4,9 @@
/* eslint-disable */
import "./scss/main.scss";
import UIkit from 'uikit';
import UIkit from "uikit";
// Don't Sort These!
import Icons from 'uikit/dist/js/uikit-icons';
import Icons from "uikit/dist/js/uikit-icons";
// @ts-ignore
UIkit.use(Icons);
@ -22,7 +22,6 @@ Prism.highlightAll();
import translations from "./translations/index.mjs";
// Actual Imports
import { PageRouter } from "./pagerouter/PageRouter";
import { formatDistance } from "./formatDistance";
import { getSealStatus } from "./api/sys/getSealStatus";
//import { pageList } from "./allPages";

View file

@ -1,4 +1,3 @@
import { PageRouter } from "./pagerouter/PageRouter";
import { PageState } from "./state/PageState";
import { getSealStatus } from "./api/sys/getSealStatus";
import { lookupSelf } from "./api/sys/lookupSelf";

View file

@ -1,6 +0,0 @@
import { PageType } from "./PageType";
export type PageListType = {
getPageIDs(): Promise<string[]>;
getPage(pageID: string): Promise<PageType>;
};

View file

@ -1,99 +0,0 @@
import { PageListType } from "./PageListType";
import { PageType } from "./PageType";
const PageDoesNotExistError = new Error("Page does not exist.");
const PageHasNotBeenSetError = new Error("Page has not been set.");
export type Options = {
pageList: PageListType;
state: unknown;
pageContentElement: HTMLElement;
pageTitleElement: HTMLElement;
resetElementContent?: boolean;
onPageChange: () => void;
};
export class PageRouter {
constructor(options: Options) {
this.pageList = options.pageList;
this.state = options.state;
this.pageContentElement = options.pageContentElement;
this.pageTitleElement = options.pageTitleElement;
this.resetElementContent = (options.resetElementContent || true) == true;
this.onPageChange = options.onPageChange;
}
public onPageChange: () => void;
private pageList: PageListType;
private currentPageID: string;
private currentPage: PageType;
private resetElementContent: boolean;
public state: unknown;
public pageContentElement: HTMLElement;
public pageTitleElement: HTMLElement;
public async getPageIDs(): Promise<string[]> {
return await this.pageList.getPageIDs();
}
public async getCurrentPage(): Promise<PageType> {
return this.currentPage;
}
public async getCurrentPageID(): Promise<string> {
return this.currentPageID;
}
public async setPageContent(content: string | HTMLElement): Promise<void> {
if (typeof content === "string") {
this.pageContentElement.innerHTML = content;
} else {
this.pageContentElement.innerHTML = "";
this.pageContentElement.appendChild(content);
}
}
public async changePage(pageID: string): Promise<void> {
if (!(await this.getPageIDs()).includes(pageID)) throw PageDoesNotExistError;
// Do cleanup on current page.
if (this.currentPage) {
await this.currentPage.cleanup();
}
// Set the current page to the new page
this.currentPageID = pageID;
this.currentPage = await this.pageList.getPage(pageID);
// Dispatch an event saying the page has been changed.
this.onPageChange();
await this.currentPage.setRouterAndState(this, this.state);
// Render the page.
await this.renderPage();
}
public async renderPage(): Promise<void> {
if (!this.currentPage) throw PageHasNotBeenSetError;
if (this.resetElementContent) {
// Reset back to blank.
this.pageContentElement.innerHTML = "";
this.pageTitleElement.innerHTML = "";
}
await Promise.all([this.currentPage.renderPageTitle(), this.currentPage.render()]);
}
public async refresh(): Promise<void> {
await this.renderPage();
}
public async goBack(): Promise<void> {
if (!this.currentPage) throw PageHasNotBeenSetError;
await this.currentPage.goBack();
}
}

View file

@ -1,9 +0,0 @@
import { PageRouter } from "./PageRouter";
export type PageType = {
render(): Promise<void>;
renderPageTitle(): Promise<void>;
goBack(): Promise<void>;
cleanup(): Promise<void>;
setRouterAndState(router: PageRouter, state: unknown): Promise<void>;
};

View file

@ -33,52 +33,68 @@ import { PolicyView } from "./ui/pages/Policies/PolicyView";
import { PolicyNew } from "./ui/pages/Policies/PolicyNew";
import { PolicyDelete } from "./ui/pages/Policies/PolicyDelete";
import { PolicyEdit } from "./ui/pages/Policies/PolicyEdit";
import { AuthHome } from "./ui/pages/Access/Auth/AuthHome";
import { AccessHomePage } from "./ui/pages/Access/AccessHome";
import { AuthViewConfig } from "./ui/pages/Access/Auth/AuthViewConfig";
import { UserPassUsersList } from "./ui/pages/Access/Auth/userpass/UserPassUsersList";
import { UserPassUserDelete } from "./ui/pages/Access/Auth/userpass/UserPassUserDelete";
import { UserPassUserView } from "./ui/pages/Access/Auth/userpass/UserPassUserView";
import { UserPassUserNew } from "./ui/pages/Access/Auth/userpass/UserPassUserNew";
import { UserPassUserEdit } from "./ui/pages/Access/Auth/userpass/UserPassUserEdit";
export const Main = () => (
<Router>
<Home path="/" state={pageState} />
<Me path="/me" state={pageState} />
<Login path="/login" state={pageState} />
<PasswordGenerator path="/pw_gen" />
<SetVaultURL path="/set_vault_url" state={pageState} />
<Unseal path="/unseal" state={pageState} />
<SetLanguage path="/set_language" state={pageState} />
<Router>
<Home path="/" state={pageState} />
<Me path="/me" state={pageState} />
<Login path="/login" state={pageState} />
<PasswordGenerator path="/pw_gen" />
<SetVaultURL path="/set_vault_url" state={pageState} />
<Unseal path="/unseal" state={pageState} />
<SetLanguage path="/set_language" state={pageState} />
<Secrets path="/secrets" state={pageState} />
<DeleteSecretsEngine path="/secrets/delete_engine/:mount" state={pageState} />
<Secrets path="/secrets" state={pageState} />
<DeleteSecretsEngine path="/secrets/delete_engine/:mount" state={pageState} />
<NewSecretsEngine path="/secrets/new_secrets_engine" />
<NewKVEngine path="/secrets/new_secrets_engine/kv" />
<NewTOTPEngine path="/secrets/new_secrets_engine/totp" />
<NewTransitEngine path="/secrets/new_secrets_engine/trasit" />
<NewSecretsEngine path="/secrets/new_secrets_engine" />
<NewKVEngine path="/secrets/new_secrets_engine/kv" />
<NewTOTPEngine path="/secrets/new_secrets_engine/totp" />
<NewTransitEngine path="/secrets/new_secrets_engine/trasit" />
<KeyValueNew path="/secrets/kv/new/:baseMount/:secretPath*?" state={pageState} />
<KeyValueList path="/secrets/kv/list/:baseMount/:secretPath*?" state={pageState} />
<KeyValueView path="/secrets/kv/view/:item/:baseMount/:secretPath*?" state={pageState} />
<KeyValueEdit path="/secrets/kv/edit/:item/:baseMount/:secretPath*?" state={pageState} />
<KeyValueDelete path="/secrets/kv/delete/:item/:baseMount/:secretPath*?" state={pageState} />
<KeyValueNew path="/secrets/kv/new/:baseMount/:secretPath*?" state={pageState} />
<KeyValueList path="/secrets/kv/list/:baseMount/:secretPath*?" state={pageState} />
<KeyValueView path="/secrets/kv/view/:item/:baseMount/:secretPath*?" state={pageState} />
<KeyValueEdit path="/secrets/kv/edit/:item/:baseMount/:secretPath*?" state={pageState} />
<KeyValueDelete path="/secrets/kv/delete/:item/:baseMount/:secretPath*?" state={pageState} />
<TOTPList path="/secrets/totp/list/:baseMount" state={pageState} />
<TOTPNew path="/secrets/totp/new/:baseMount" state={pageState} />
<TOTPDelete path="/secrets/totp/delete/:baseMount/:item" state={pageState} />
<TOTPList path="/secrets/totp/list/:baseMount" state={pageState} />
<TOTPNew path="/secrets/totp/new/:baseMount" state={pageState} />
<TOTPDelete path="/secrets/totp/delete/:baseMount/:item" state={pageState} />
<TransitNew path="/secrets/transit/new/:baseMount" state={pageState} />
<TransitList path="/secrets/transit/list/:baseMount" state={pageState} />
<TransitView path="/secrets/transit/view/:baseMount/:secretItem" state={pageState} />
<TransitEncrypt path="/secrets/transit/encrypt/:baseMount/:secretItem" state={pageState} />
<TransitDecrypt path="/secrets/transit/decrypt/:baseMount/:secretItem" state={pageState} />
<TransitRewrap path="/secrets/transit/rewrap/:baseMount/:secretItem" state={pageState} />
<TransitNew path="/secrets/transit/new/:baseMount" state={pageState} />
<TransitList path="/secrets/transit/list/:baseMount" state={pageState} />
<TransitView path="/secrets/transit/view/:baseMount/:secretItem" state={pageState} />
<TransitEncrypt path="/secrets/transit/encrypt/:baseMount/:secretItem" state={pageState} />
<TransitDecrypt path="/secrets/transit/decrypt/:baseMount/:secretItem" state={pageState} />
<TransitRewrap path="/secrets/transit/rewrap/:baseMount/:secretItem" state={pageState} />
<PoliciesHome path="/policies" state={pageState} />
<PolicyNew path="/policies/new" state={pageState} />
<PolicyView path="/policies/view/:policyName" state={pageState} />
<PolicyEdit path="/policies/edit/:policyName" state={pageState} />
<PoliciesHome path="/policies" state={pageState} />
<PolicyNew path="/policies/new" state={pageState} />
<PolicyView path="/policies/view/:policyName" state={pageState} />
<PolicyEdit path="/policies/edit/:policyName" state={pageState} />
<PolicyDelete path="/policies/delete/:policyName" state={pageState} />
<PolicyDelete path="/policies/delete/:policyName" state={pageState} />
<AccessHomePage path="/access" state={pageState} />
<AuthHome path="/access/auth" state={pageState} />
<AuthViewConfig path="/access/auth/view/:baseMount" state={pageState} />
<UserPassUsersList path="/access/auth/userpass/list/:baseMount" state={pageState} />
<UserPassUserNew path="/access/auth/userpass/new/:baseMount" state={pageState} />
<UserPassUserView path="/access/auth/userpass/view/:baseMount/:user" state={pageState} />
<UserPassUserEdit path="/access/auth/userpass/edit/:baseMount/:user" state={pageState} />
<UserPassUserDelete path="/access/auth/userpass/delete/:baseMount/:user" state={pageState} />
<div default>
<p>PAGE NOT YET IMPLEMENTED</p>
</div>
</Router>
);
<div default>
<p>PAGE NOT YET IMPLEMENTED</p>
</div>
</Router>
);

View file

@ -1,7 +1,3 @@
import { PageRouter } from "./pagerouter/PageRouter";
import { PageState } from "./state/PageState";
import i18next from "i18next";
// Playground is a way to debug and test things.
// Anything you put in here is gonna be run on page initial load
// before rendering.

View file

@ -1,16 +1,16 @@
@import "normalize.css/normalize.css";
.editor {
background-color: #3B4252;
padding: 1em;
margin: .5em 0;
overflow: auto;
background-color: #3b4252;
padding: 1em;
margin: 0.5em 0;
overflow: auto;
}
.code-block {
padding-top: 10px !important;
padding-right: 10px !important;
padding-bottom: 10px !important;
padding-left: 10px !important;
padding-top: 10px !important;
padding-right: 10px !important;
padding-bottom: 10px !important;
padding-left: 10px !important;
}
@import "./prism-nord.scss";
@import "./uikit.scss";
@import "./uikit.scss";

View file

@ -2,8 +2,7 @@ code[class*="language-"],
pre[class*="language-"] {
color: #f8f8f2;
background: none;
font-family: "Fira Code", Consolas, Monaco, "Andale Mono", "Ubuntu Mono",
monospace;
font-family: "Fira Code", Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
text-align: left;
white-space: pre;
word-spacing: normal;

View file

@ -10,7 +10,6 @@ $global-muted-background: #3b4252;
$global-primary-background: #5e81ac;
$global-secondary-background: #4c566a;
$global-success-background: #a3be8c;
$global-warning-background: #d08770;
$global-danger-background: #bf616a;
@ -83,4 +82,6 @@ $form-range-track-focus-background: $global-link-hover-color;
@import "uikit/src/scss/components/inverse.scss";
// TODO: replace this with a better solution to https://github.com/uikit/uikit/discussions/4458
.uk-input-copyable { padding-left: $form-icon-width !important; }
.uk-input-copyable {
padding-left: $form-icon-width !important;
}

View file

@ -2,60 +2,11 @@ import { StorageType } from "./storage/StorageType";
export class PageState {
constructor() {
const params = new URLSearchParams(window.location.search);
if (params.has("reset")) this.storage.clear();
if (params.has("state")) {
console.log("state owo");
this.loadState(JSON.parse(params.get("state")));
}
if (params.has("incognito")) {
this.storage = sessionStorage;
} else {
this.storage = localStorage;
}
this.storage = localStorage;
}
private storage: StorageType;
dumpState(): { [key: string]: unknown } {
return {
baseMount: this.baseMount,
secretPath: this.secretPath,
secretVersion: this.secretVersion,
secretItem: this.secretItem,
secretMountType: this.secretMountType,
policyItem: this.policyItem,
authPath: this.authPath,
userPassUser: this.userPassUser,
currentPage: this.currentPage,
};
}
loadState(newState: { [key: string]: unknown }) {
console.log(newState);
for (const prop in newState) {
console.log("WANTS", prop);
if (prop in this) {
console.log("HAS", prop.toString());
// @ts-ignore
this[prop] = newState[prop];
}
}
}
// NOTE: When a item in the page state isn't a string (e.g it is a array or object),
// you need to add helper methods to mutate it or else it wont save.
// example: secretPath is a array so when you try to .push() to it
// it will modify the object that was getted from this class
// then when you try to access it again, there will be a different object.
// I guess you could make another class that emulates a Array or Map
// by using a bunch of functions and modifying localStorage in order to remove some of
// the clunkyness of this approach, but for now, this works.
// these are all ones that persist across browser sessions
// usually in localStorage unless in incognito.
get apiURL(): string | null {
const apiurl = this.storage.getItem("apiURL") || "";
return apiurl.length > 0 ? apiurl : null;
@ -85,87 +36,4 @@ export class PageState {
set language(value: string) {
this.storage.setItem("language", value);
}
// all of these are sessionStorage and not persisted
// so can have multiple tabs open
// TODO: move to just local variables maybe
get baseMount(): string {
return sessionStorage.getItem("baseMount") || "";
}
set baseMount(value: string) {
sessionStorage.setItem("baseMount", value);
}
// Since this is a array we can't act directly on it so we need
// functions to do the same modifications.
// See the note at the start o
popSecretPath(): void {
const secPath = this.secretPath;
secPath.pop();
this.secretPath = secPath;
}
pushSecretPath(...args: string[]): void {
const secPath = this.secretPath;
secPath.push(...args);
this.secretPath = secPath;
}
get secretPath(): string[] {
return JSON.parse(sessionStorage.getItem("secretPath") || "[]") as string[];
}
set secretPath(value: string[]) {
sessionStorage.setItem("secretPath", JSON.stringify(value));
}
get secretVersion(): string | null {
const result = sessionStorage.getItem("secretVersion");
return result != "null" ? result || null : null;
}
set secretVersion(value: string) {
sessionStorage.setItem("secretVersion", String(value));
}
get secretItem(): string {
return sessionStorage.getItem("secretItem") || "";
}
set secretItem(value: string) {
sessionStorage.setItem("secretItem", value);
}
get secretMountType(): string {
return sessionStorage.getItem("secretMountType") || "";
}
set secretMountType(value: string) {
sessionStorage.setItem("secretMountType", value);
}
get policyItem(): string {
return sessionStorage.getItem("policyItem") || "";
}
set policyItem(value: string) {
sessionStorage.setItem("policyItem", value);
}
get authPath(): string {
return sessionStorage.getItem("authPath") || "";
}
set authPath(value: string) {
sessionStorage.setItem("authPath", value);
}
get userPassUser(): string {
return sessionStorage.getItem("userPassUser") || "";
}
set userPassUser(value: string) {
sessionStorage.setItem("userPassUser", value);
}
get currentPage(): string {
const curPage = sessionStorage.getItem("currentPage") || "HOME";
return curPage;
}
set currentPage(value: string) {
sessionStorage.setItem("currentPage", value);
}
}

View file

@ -1,8 +1,8 @@
import de from './de.js'
import en from './en.js'
import fr from './fr.js'
import nl from './nl.js'
import ru from './ru.js'
import de from "./de.js";
import en from "./en.js";
import fr from "./fr.js";
import nl from "./nl.js";
import ru from "./ru.js";
const translations = {
de: de,
@ -10,6 +10,6 @@ const translations = {
fr: fr,
nl: nl,
ru: ru,
}
};
export default translations;
export default translations;

View file

@ -1,37 +0,0 @@
import { render } from "preact";
import { PageRouter } from "../pagerouter/PageRouter";
import { PageState } from "../state/PageState";
import { CopyStateLinkButton } from "../ui/elements/CopyStateLinkButton";
export class Page {
constructor() {
// Do Nothing
}
public router: PageRouter;
public state: PageState;
async render(): Promise<void> {}
get name(): string {
return "Page";
}
async renderPageTitle(): Promise<void> {
render(
<>
<span>{this.name}</span>
<CopyStateLinkButton state={this.state} />
</>,
this.router.pageTitleElement,
);
}
async goBack(): Promise<void> {
await this.router.changePage("HOME");
}
async cleanup(): Promise<void> {
// Do Nothing
}
async setRouterAndState(router: PageRouter, state: PageState): Promise<void> {
this.router = router;
this.state = state;
}
}

View file

@ -1,33 +0,0 @@
import { Component, JSX, createRef } from "preact";
import { PageState } from "../../state/PageState";
import { addClipboardNotifications } from "../../pageUtils";
import ClipboardJS from "clipboard";
export type CopyStateLinkButtonProps = {
state: PageState;
};
export class CopyStateLinkButton extends Component<CopyStateLinkButtonProps, unknown> {
buttonRef = createRef();
componentDidMount(): void {
const clipboard = new ClipboardJS(this.buttonRef.current);
addClipboardNotifications(clipboard, 600);
}
render(): JSX.Element {
const newURL = new URL(window.location.toString());
newURL.searchParams.set("state", JSON.stringify(this.props.state.dumpState()));
return (
<a
ref={this.buttonRef}
class="uk-icon uk-margin-small-left"
uk-icon={"icon: copy"}
role="img"
aria-label="Copy Link"
data-clipboard-text={newURL.toString()}
></a>
);
}
}

View file

@ -1,5 +1,4 @@
import { JSX, render } from "preact";
import { PageRouter } from "../../pagerouter/PageRouter";
import { JSX } from "preact";
import { getCurrentUrl, route } from "preact-router";
import i18next from "i18next";

View file

@ -1,53 +1,48 @@
import { Grid, GridSizes } from "../../elements/Grid";
import { Page } from "../../../types/Page";
import { PageState } from "../../../state/PageState";
import { Tile } from "../../elements/Tile";
import { notImplemented, prePageChecks } from "../../../pageUtils";
import { render } from "preact";
import { Component } from "preact";
import i18next from "i18next";
import { DefaultPageProps } from "../../../types/DefaultPageProps";
import { route } from "preact-router";
import { PageTitle } from "../../elements/PageTitle";
export class AccessHomePage extends Page {
constructor() {
super();
export class AccessHomePage extends Component<DefaultPageProps> {
async componentDidMount() {
if (!(await prePageChecks(this.props.state))) return;
}
async goBack(): Promise<void> {
await this.router.changePage("HOME");
}
async render(): Promise<void> {
this.router.pageContentElement.innerHTML = "";
if (!(await prePageChecks(this.router.state as PageState))) return;
render(
<Grid size={GridSizes.MATCHING_TWO_ROWS}>
<Tile
title={i18next.t("access_auth_methods_title")}
description={i18next.t("access_auth_methods_description")}
icon="sign-in"
onclick={async () => await this.router.changePage("AUTH_HOME")}
/>
<Tile
title={i18next.t("access_entities_title")}
description={i18next.t("access_entities_description")}
icon="user"
onclick={async () => notImplemented()}
/>
<Tile
title={i18next.t("access_groups_title")}
description={i18next.t("access_groups_description")}
icon="users"
onclick={async () => notImplemented()}
/>
<Tile
title={i18next.t("access_leases_title")}
description={i18next.t("access_leases_description")}
icon="unlock"
onclick={async () => notImplemented()}
/>
</Grid>,
this.router.pageContentElement,
render() {
return (
<>
<PageTitle title={i18next.t("access_home_page_title")} />
<Grid size={GridSizes.MATCHING_TWO_ROWS}>
<Tile
title={i18next.t("access_auth_methods_title")}
description={i18next.t("access_auth_methods_description")}
icon="sign-in"
onclick={async () => route("/access/auth")}
/>
<Tile
title={i18next.t("access_entities_title")}
description={i18next.t("access_entities_description")}
icon="user"
onclick={async () => notImplemented()}
/>
<Tile
title={i18next.t("access_groups_title")}
description={i18next.t("access_groups_description")}
icon="users"
onclick={async () => notImplemented()}
/>
<Tile
title={i18next.t("access_leases_title")}
description={i18next.t("access_leases_description")}
icon="unlock"
onclick={async () => notImplemented()}
/>
</Grid>
</>
);
}
get name(): string {
return i18next.t("access_home_page_title");
}
}

View file

@ -1,13 +1,15 @@
import { AuthMethod } from "../../../../api/types/auth";
import { JSX, render } from "preact";
import { Page } from "../../../../types/Page";
import { Component, JSX } from "preact";
import { listAuth } from "../../../../api/auth/listAuth";
import { notImplemented } from "../../../../pageUtils";
import { objectToMap } from "../../../../utils";
import i18next from "i18next";
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
import { PageTitle } from "../../../elements/PageTitle";
import { route } from "preact-router";
import { authViewConfigURL, userPassUserListURL } from "../../pageLinks";
export type AuthListElementProps = {
page: Page;
path: string;
method: AuthMethod;
};
@ -16,9 +18,8 @@ export function AuthListElement(props: AuthListElementProps): JSX.Element {
const isClickable = props.method.type != "token";
const onHeaderLinkClick = async (props: AuthListElementProps) => {
props.page.state.authPath = props.path;
if (props.method.type == "userpass") {
await props.page.router.changePage("USERPASS_USERS_LIST");
route(userPassUserListURL(props.path));
}
};
@ -36,8 +37,7 @@ export function AuthListElement(props: AuthListElementProps): JSX.Element {
<button
class="uk-button uk-button-small uk-button-primary"
onClick={async () => {
props.page.state.baseMount = props.path;
await props.page.router.changePage("AUTH_VIEW_CONFIG");
route(authViewConfigURL(props.path));
}}
>
{i18next.t("auth_home_view_config")}
@ -50,27 +50,23 @@ export function AuthListElement(props: AuthListElementProps): JSX.Element {
);
}
export class AuthHomePage extends Page {
constructor() {
super();
}
async goBack(): Promise<void> {
await this.router.changePage("ACCESS_HOME");
}
async render(): Promise<void> {
this.state.secretPath = [];
export class AuthHome extends Component<DefaultPageProps, { authList: Map<String, AuthMethod> }> {
async componentDidMount() {
const authList = objectToMap(await listAuth()) as Map<string, AuthMethod>;
this.setState({ authList });
}
render() {
if (!this.state.authList) return;
render(
<div>
{Array.from(authList).map((values: [string, AuthMethod]) => (
<AuthListElement page={this} path={values[0]} method={values[1]} />
))}
</div>,
this.router.pageContentElement,
return (
<>
<PageTitle title={i18next.t("auth_home_title")} />
<div>
{Array.from(this.state.authList).map((values: [string, AuthMethod]) => (
<AuthListElement path={values[0]} method={values[1]} />
))}
</div>
</>
);
}
get name(): string {
return i18next.t("auth_home_title");
}
}

View file

@ -1,70 +1,69 @@
import { AuthMethod } from "../../../../api/types/auth";
import { HeaderAndContent } from "../../../elements/HeaderAndContent";
import { Page } from "../../../../types/Page";
import { listAuth } from "../../../../api/auth/listAuth";
import { objectToMap, toStr } from "../../../../utils";
import { render } from "preact";
import { Component } from "preact";
import i18next from "i18next";
import { DefaultPageProps } from "../../../../types/DefaultPageProps";
import { PageTitle } from "../../../elements/PageTitle";
export class AuthViewConfigPage extends Page {
constructor() {
super();
}
async goBack(): Promise<void> {
await this.router.changePage("AUTH_HOME");
}
async render(): Promise<void> {
export class AuthViewConfig extends Component<DefaultPageProps, { authMethod: AuthMethod }> {
async componentDidMount() {
const baseMount = this.props.matches["baseMount"];
const authList = objectToMap(await listAuth()) as Map<string, AuthMethod>;
const authMethod = authList.get(this.state.baseMount);
const authMethod = authList.get(baseMount + "/");
this.setState({ authMethod: authMethod });
}
render() {
if (!this.state.authMethod) return;
const baseMount = this.props.matches["baseMount"];
const authMethod = this.state.authMethod;
render(
<table class="uk-table">
<tbody>
<HeaderAndContent title={i18next.t("auth_view_config_type")} content={authMethod.type} />
<HeaderAndContent
title={i18next.t("auth_view_config_path")}
content={this.state.baseMount}
/>
<HeaderAndContent
title={i18next.t("auth_view_config_description")}
content={authMethod.description}
/>
<HeaderAndContent
title={i18next.t("auth_view_config_accessor")}
content={authMethod.accessor}
/>
<HeaderAndContent
title={i18next.t("auth_view_config_local")}
content={toStr(authMethod.local)}
/>
<HeaderAndContent
title={i18next.t("auth_view_config_seal_wrap")}
content={toStr(authMethod.seal_wrap)}
/>
<HeaderAndContent
title={i18next.t("auth_view_config_list_when_unauth")}
content={toStr(authMethod.config.listing_visibility)}
/>
<HeaderAndContent
title={i18next.t("auth_view_config_default_lease_ttl")}
content={toStr(authMethod.config.default_lease_ttl)}
/>
<HeaderAndContent
title={i18next.t("auth_view_config_max_lease_ttl")}
content={toStr(authMethod.config.max_lease_ttl)}
/>
<HeaderAndContent
title={i18next.t("auth_view_config_token_type")}
content={toStr(authMethod.config.token_type)}
/>
</tbody>
</table>,
this.router.pageContentElement,
return (
<>
<PageTitle title={i18next.t("auth_view_config_title")} />
<table class="uk-table">
<tbody>
<HeaderAndContent
title={i18next.t("auth_view_config_type")}
content={authMethod.type}
/>
<HeaderAndContent title={i18next.t("auth_view_config_path")} content={baseMount} />
<HeaderAndContent
title={i18next.t("auth_view_config_description")}
content={authMethod.description}
/>
<HeaderAndContent
title={i18next.t("auth_view_config_accessor")}
content={authMethod.accessor}
/>
<HeaderAndContent
title={i18next.t("auth_view_config_local")}
content={toStr(authMethod.local)}
/>
<HeaderAndContent
title={i18next.t("auth_view_config_seal_wrap")}
content={toStr(authMethod.seal_wrap)}
/>
<HeaderAndContent
title={i18next.t("auth_view_config_list_when_unauth")}
content={toStr(authMethod.config.listing_visibility)}
/>
<HeaderAndContent
title={i18next.t("auth_view_config_default_lease_ttl")}
content={toStr(authMethod.config.default_lease_ttl)}
/>
<HeaderAndContent
title={i18next.t("auth_view_config_max_lease_ttl")}
content={toStr(authMethod.config.max_lease_ttl)}
/>
<HeaderAndContent
title={i18next.t("auth_view_config_token_type")}
content={toStr(authMethod.config.token_type)}
/>
</tbody>
</table>
</>
);
}
get name(): string {
return i18next.t("auth_view_config_title");
}
}

View file

@ -1,34 +1,32 @@
import { Page } from "../../../../../types/Page";
import { deleteUserPassUser } from "../../../../../api/auth/userpass/deleteUserPassUser";
import { render } from "preact";
import { Component } from "preact";
import i18next from "i18next";
import { DefaultPageProps } from "../../../../../types/DefaultPageProps";
import { PageTitle } from "../../../../elements/PageTitle";
import { route } from "preact-router";
import { userPassUserListURL } from "../../../pageLinks";
export class UserPassUserDeletePage extends Page {
constructor() {
super();
}
async goBack(): Promise<void> {
await this.router.changePage("USERPASS_USERS_LIST");
}
async render(): Promise<void> {
render(
export class UserPassUserDelete extends Component<DefaultPageProps> {
render() {
const baseMount = this.props.matches["baseMount"];
const user = this.props.matches["user"];
return (
<>
<h5>{i18next.t("userpass_user_delete_text")}</h5>
<button
class="uk-button uk-button-danger"
onClick={async () => {
await deleteUserPassUser(this.state.authPath, this.state.userPassUser);
await this.goBack();
}}
>
{i18next.t("userpass_user_delete_btn")}
</button>
</>,
this.router.pageContentElement,
<PageTitle title={i18next.t("userpass_user_delete_title")} />
<div>
<h5>{i18next.t("userpass_user_delete_text")}</h5>
<button
class="uk-button uk-button-danger"
onClick={async () => {
await deleteUserPassUser(baseMount, user);
route(userPassUserListURL(baseMount));
}}
>
{i18next.t("userpass_user_delete_btn")}
</button>
</div>
</>
);
}
get name(): string {
return i18next.t("userpass_user_delete_title");
}
}

View file

@ -2,121 +2,131 @@ import { Form } from "../../../../elements/Form";
import { InputWithTitle } from "../../../../elements/InputWithTitle";
import { Margin } from "../../../../elements/Margin";
import { MarginInline } from "../../../../elements/MarginInline";
import { Page } from "../../../../../types/Page";
import { UserType } from "../../../../../api/types/userpass/user";
import { createOrUpdateUserPassUser } from "../../../../../api/auth/userpass/createOrUpdateUserPassUser";
import { getUserPassUser } from "../../../../../api/auth/userpass/getUserPassUser";
import { render } from "preact";
import { Component, render } from "preact";
import { setErrorText } from "../../../../../pageUtils";
import { toStr } from "../../../../../utils";
import i18next from "i18next";
import { DefaultPageProps } from "../../../../../types/DefaultPageProps";
import { PageTitle } from "../../../../elements/PageTitle";
import { route } from "preact-router";
import { userPassUserViewURL } from "../../../pageLinks";
const removeEmptyStrings = (arr: string[]) => arr.filter((e) => e.length > 0);
export class UserPassUserEditPage extends Page {
constructor() {
super();
}
async goBack(): Promise<void> {
await this.router.changePage("USERPASS_USER_VIEW");
export class UserPassUserEdit extends Component<DefaultPageProps, { user_data: UserType }> {
async componentDidMount() {
const baseMount = this.props.matches["baseMount"];
const user = this.props.matches["user"];
const user_data = await getUserPassUser(baseMount, user);
this.setState({ user_data });
}
async render(): Promise<void> {
const user = await getUserPassUser(this.state.authPath, this.state.userPassUser);
render() {
if (!this.state.user_data) return;
const user_data = this.state.user_data;
render(
<Form onSubmit={(data) => this.onSubmit(data)}>
<input
class="uk-input uk-form-width-large"
name="password"
type="password"
placeholder={i18next.t("auth_common_password")}
/>
return (
<>
<PageTitle title={i18next.t("userpass_user_edit_title")} />
<Form onSubmit={(data) => this.onSubmit(data)}>
<input
class="uk-input uk-form-width-large"
name="password"
type="password"
placeholder={i18next.t("auth_common_password")}
/>
<Margin>
<p>{i18next.t("auth_common_zero_default")}</p>
</Margin>
<Margin>
<p>{i18next.t("auth_common_zero_default")}</p>
</Margin>
<Margin>
<p>{i18next.t("auth_common_generated_tokens")}</p>
</Margin>
<Margin>
<p>{i18next.t("auth_common_generated_tokens")}</p>
</Margin>
<InputWithTitle title={i18next.t("auth_common_cidrs")}>
<input
class="uk-input uk-form-width-large"
name="cidrs"
type="text"
value={user.token_bound_cidrs.join()}
/>
</InputWithTitle>
<InputWithTitle title={i18next.t("auth_common_exp_max_ttl")}>
<input
class="uk-input uk-form-width-large"
name="exp_max_ttl"
type="number"
value={toStr(user.token_explicit_max_ttl)}
/>
</InputWithTitle>
<InputWithTitle title={i18next.t("auth_common_max_ttl")}>
<input
class="uk-input uk-form-width-large"
name="max_ttl"
type="number"
value={toStr(user.token_max_ttl)}
/>
</InputWithTitle>
<InputWithTitle title={i18next.t("auth_common_default_policy_attached")}>
<input
class="uk-checkbox"
name="def_pol_attached"
type="checkbox"
value={toStr(user.token_no_default_policy)}
/>
</InputWithTitle>
<InputWithTitle title={i18next.t("auth_common_max_token_uses")}>
<input
class="uk-input uk-form-width-large"
name="max_uses"
type="number"
value={toStr(user.token_num_uses)}
/>
</InputWithTitle>
<InputWithTitle title={i18next.t("auth_common_token_peroid")}>
<input
class="uk-input uk-form-width-large"
name="period"
type="number"
value={toStr(user.token_period)}
/>
</InputWithTitle>
<InputWithTitle title={i18next.t("auth_common_policies")}>
<input
class="uk-input uk-form-width-large"
name="policies"
type="text"
value={user.token_policies.join()}
/>
</InputWithTitle>
<InputWithTitle title={i18next.t("auth_common_initial_ttl")}>
<input
class="uk-input uk-form-width-large"
name="initial_ttl"
type="number"
value={toStr(user.token_ttl)}
/>
</InputWithTitle>
<p class="uk-text-danger" id="errorText" />
<MarginInline>
<button class="uk-button uk-button-primary" type="submit">
{i18next.t("userpass_user_edit_submit_btn")}
</button>
</MarginInline>
</Form>,
this.router.pageContentElement,
<InputWithTitle title={i18next.t("auth_common_cidrs")}>
<input
class="uk-input uk-form-width-large"
name="cidrs"
type="text"
value={user_data.token_bound_cidrs.join()}
/>
</InputWithTitle>
<InputWithTitle title={i18next.t("auth_common_exp_max_ttl")}>
<input
class="uk-input uk-form-width-large"
name="exp_max_ttl"
type="number"
value={toStr(user_data.token_explicit_max_ttl)}
/>
</InputWithTitle>
<InputWithTitle title={i18next.t("auth_common_max_ttl")}>
<input
class="uk-input uk-form-width-large"
name="max_ttl"
type="number"
value={toStr(user_data.token_max_ttl)}
/>
</InputWithTitle>
<InputWithTitle title={i18next.t("auth_common_default_policy_attached")}>
<input
class="uk-checkbox"
name="def_pol_attached"
type="checkbox"
value={toStr(user_data.token_no_default_policy)}
/>
</InputWithTitle>
<InputWithTitle title={i18next.t("auth_common_max_token_uses")}>
<input
class="uk-input uk-form-width-large"
name="max_uses"
type="number"
value={toStr(user_data.token_num_uses)}
/>
</InputWithTitle>
<InputWithTitle title={i18next.t("auth_common_token_peroid")}>
<input
class="uk-input uk-form-width-large"
name="period"
type="number"
value={toStr(user_data.token_period)}
/>
</InputWithTitle>
<InputWithTitle title={i18next.t("auth_common_policies")}>
<input
class="uk-input uk-form-width-large"
name="policies"
type="text"
value={user_data.token_policies.join()}
/>
</InputWithTitle>
<InputWithTitle title={i18next.t("auth_common_initial_ttl")}>
<input
class="uk-input uk-form-width-large"
name="initial_ttl"
type="number"
value={toStr(user_data.token_ttl)}
/>
</InputWithTitle>
<p class="uk-text-danger" id="errorText" />
<MarginInline>
<button class="uk-button uk-button-primary" type="submit">
{i18next.t("userpass_user_edit_submit_btn")}
</button>
</MarginInline>
</Form>
</>
);
}
async onSubmit(data: FormData): Promise<void> {
const baseMount = this.props.matches["baseMount"];
const user = this.props.matches["user"];
const apiData: Partial<UserType> = {
token_bound_cidrs: removeEmptyStrings(String(data.get("cidrs")).split(",")),
token_explicit_max_ttl: parseInt(data.get("exp_max_ttl") as string, 10),
@ -132,15 +142,11 @@ export class UserPassUserEditPage extends Page {
apiData.password = password;
}
try {
await createOrUpdateUserPassUser(this.state.authPath, this.state.userPassUser, apiData);
await this.router.changePage("USERPASS_USER_VIEW");
await createOrUpdateUserPassUser(baseMount, user, apiData);
route(userPassUserViewURL(baseMount, user));
} catch (e: unknown) {
const error = e as Error;
setErrorText(error.message);
}
}
get name(): string {
return i18next.t("userpass_user_edit_title");
}
}

View file

@ -1,69 +1,60 @@
import { Form } from "../../../../elements/Form";
import { Margin } from "../../../../elements/Margin";
import { MarginInline } from "../../../../elements/MarginInline";
import { Page } from "../../../../../types/Page";
import { UserType } from "../../../../../api/types/userpass/user";
import { createOrUpdateUserPassUser } from "../../../../../api/auth/userpass/createOrUpdateUserPassUser";
import { render } from "preact";
import { Component, render } from "preact";
import { setErrorText } from "../../../../../pageUtils";
import i18next from "i18next";
import { DefaultPageProps } from "../../../../../types/DefaultPageProps";
import { PageTitle } from "../../../../elements/PageTitle";
import { route } from "preact-router";
import { userPassUserViewURL } from "../../../pageLinks";
export class UserPassUserNewPage extends Page {
constructor() {
super();
}
async goBack(): Promise<void> {
await this.router.changePage("USERPASS_USERS_LIST");
}
async render(): Promise<void> {
render(
<Form onSubmit={(data) => this.onSubmit(data)}>
<Margin>
<input
class="uk-input uk-form-width-large"
name="username"
type="text"
placeholder={i18next.t("auth_common_username")}
/>
</Margin>
<Margin>
<input
class="uk-input uk-form-width-large"
name="password"
type="password"
placeholder={i18next.t("auth_common_password")}
/>
</Margin>
<p class="uk-text-danger" id="errorText" />
<MarginInline>
<button class="uk-button uk-button-primary" type="submit">
{i18next.t("userpass_user_new_create_btn")}
</button>
</MarginInline>
</Form>,
this.router.pageContentElement,
export class UserPassUserNew extends Component<DefaultPageProps> {
render() {
return (
<>
<PageTitle title={i18next.t("userpass_user_new_title")} />
<Form onSubmit={(data) => this.onSubmit(data)}>
<Margin>
<input
class="uk-input uk-form-width-large"
name="username"
type="text"
placeholder={i18next.t("auth_common_username")}
/>
</Margin>
<Margin>
<input
class="uk-input uk-form-width-large"
name="password"
type="password"
placeholder={i18next.t("auth_common_password")}
/>
</Margin>
<p class="uk-text-danger" id="errorText" />
<MarginInline>
<button class="uk-button uk-button-primary" type="submit">
{i18next.t("userpass_user_new_create_btn")}
</button>
</MarginInline>
</Form>
</>
);
}
async onSubmit(data: FormData): Promise<void> {
const baseMount = this.props.matches["baseMount"];
const apiData: Partial<UserType> = {
password: data.get("password") as string,
};
try {
await createOrUpdateUserPassUser(
this.state.authPath,
data.get("username") as string,
apiData,
);
await this.router.changePage("USERPASS_USERS_LIST");
await createOrUpdateUserPassUser(baseMount, data.get("username") as string, apiData);
route(userPassUserViewURL(baseMount, data.get("username") as string));
} catch (e: unknown) {
const error = e as Error;
setErrorText(error.message);
}
}
get name(): string {
return i18next.t("userpass_user_new_title");
}
}

View file

@ -1,98 +1,104 @@
import { HeaderAndContent } from "../../../../elements/HeaderAndContent";
import { Margin } from "../../../../elements/Margin";
import { Page } from "../../../../../types/Page";
import { getUserPassUser } from "../../../../../api/auth/userpass/getUserPassUser";
import { render } from "preact";
import { Component } from "preact";
import { toStr } from "../../../../../utils";
import i18next from "i18next";
import { DefaultPageProps } from "../../../../../types/DefaultPageProps";
import { UserType } from "../../../../../api/types/userpass/user";
import { PageTitle } from "../../../../elements/PageTitle";
import { route } from "preact-router";
import { userPassUserDeleteURL, userPassUserEditURL } from "../../../pageLinks";
export class UserPassUserViewPage extends Page {
constructor() {
super();
}
async goBack(): Promise<void> {
await this.router.changePage("USERPASS_USERS_LIST");
export class UserPassUserView extends Component<DefaultPageProps, { user_data: UserType }> {
async componentDidMount() {
const baseMount = this.props.matches["baseMount"];
const user = this.props.matches["user"];
const user_data = await getUserPassUser(baseMount, user);
this.setState({ user_data });
}
async render(): Promise<void> {
const user = await getUserPassUser(this.state.authPath, this.state.userPassUser);
render() {
if (!this.state.user_data) return;
const baseMount = this.props.matches["baseMount"];
const user = this.props.matches["user"];
const user_data = this.state.user_data;
render(
<div>
<p>
<button
class="uk-button uk-button-danger"
onClick={async () => {
await this.router.changePage("USERPASS_USER_DELETE");
}}
>
{i18next.t("userpass_user_view_delete_btn")}
</button>
<button
class="uk-button uk-button-primary"
onClick={async () => {
await this.router.changePage("USERPASS_USER_EDIT");
}}
>
{i18next.t("userpass_user_view_edit_btn")}
</button>
</p>
return (
<>
<PageTitle title={i18next.t("userpass_user_view_title")} />
<Margin>
<p>{i18next.t("auth_common_zero_default")}</p>
</Margin>
<div>
<p>
<button
class="uk-button uk-button-danger"
onClick={async () => {
route(userPassUserDeleteURL(baseMount, user));
}}
>
{i18next.t("userpass_user_view_delete_btn")}
</button>
<button
class="uk-button uk-button-primary"
onClick={async () => {
route(userPassUserEditURL(baseMount, user));
}}
>
{i18next.t("userpass_user_view_edit_btn")}
</button>
</p>
<Margin>
<p>{i18next.t("auth_common_generated_tokens")}</p>
</Margin>
<Margin>
<p>{i18next.t("auth_common_zero_default")}</p>
</Margin>
<table class="uk-table">
<tbody>
<HeaderAndContent
title={i18next.t("auth_common_cidrs")}
content={user.token_bound_cidrs.join()}
/>
<HeaderAndContent
title={i18next.t("auth_common_exp_max_ttl")}
content={toStr(user.token_explicit_max_ttl)}
/>
<HeaderAndContent
title={i18next.t("auth_common_max_ttl")}
content={toStr(user.token_max_ttl)}
/>
<HeaderAndContent
title={i18next.t("auth_common_default_policy_attached")}
content={toStr(user.token_no_default_policy)}
/>
<HeaderAndContent
title={i18next.t("auth_common_max_token_uses")}
content={toStr(user.token_num_uses)}
/>
<HeaderAndContent
title={i18next.t("auth_common_token_peroid")}
content={toStr(user.token_period)}
/>
<HeaderAndContent
title={i18next.t("auth_common_policies")}
content={user.token_policies.join()}
/>
<HeaderAndContent
title={i18next.t("auth_common_initial_ttl")}
content={toStr(user.token_ttl)}
/>
<HeaderAndContent
title={i18next.t("auth_common_type")}
content={toStr(user.token_type)}
/>
</tbody>
</table>
</div>,
this.router.pageContentElement,
<Margin>
<p>{i18next.t("auth_common_generated_tokens")}</p>
</Margin>
<table class="uk-table">
<tbody>
<HeaderAndContent
title={i18next.t("auth_common_cidrs")}
content={user_data.token_bound_cidrs.join()}
/>
<HeaderAndContent
title={i18next.t("auth_common_exp_max_ttl")}
content={toStr(user_data.token_explicit_max_ttl)}
/>
<HeaderAndContent
title={i18next.t("auth_common_max_ttl")}
content={toStr(user_data.token_max_ttl)}
/>
<HeaderAndContent
title={i18next.t("auth_common_default_policy_attached")}
content={toStr(user_data.token_no_default_policy)}
/>
<HeaderAndContent
title={i18next.t("auth_common_max_token_uses")}
content={toStr(user_data.token_num_uses)}
/>
<HeaderAndContent
title={i18next.t("auth_common_token_peroid")}
content={toStr(user_data.token_period)}
/>
<HeaderAndContent
title={i18next.t("auth_common_policies")}
content={user_data.token_policies.join()}
/>
<HeaderAndContent
title={i18next.t("auth_common_initial_ttl")}
content={toStr(user_data.token_ttl)}
/>
<HeaderAndContent
title={i18next.t("auth_common_type")}
content={toStr(user_data.token_type)}
/>
</tbody>
</table>
</div>
</>
);
}
get name(): string {
return i18next.t("userpass_user_view_title");
}
}
1;

View file

@ -1,51 +1,51 @@
import { Page } from "../../../../../types/Page";
import { listUserPassUsers } from "../../../../../api/auth/userpass/listUserPassUsers";
import { render } from "preact";
import { Component } from "preact";
import i18next from "i18next";
import { DefaultPageProps } from "../../../../../types/DefaultPageProps";
import { route } from "preact-router";
import { userPassUserNewURL, userPassUserViewURL } from "../../../pageLinks";
import { PageTitle } from "../../../../elements/PageTitle";
export class UserPassUsersListPage extends Page {
constructor() {
super();
}
async goBack(): Promise<void> {
await this.router.changePage("AUTH_HOME");
export class UserPassUsersList extends Component<DefaultPageProps, { users: string[] }> {
async componentDidMount() {
const baseMount = this.props.matches["baseMount"];
const users = await listUserPassUsers(baseMount);
this.setState({ users });
}
async render(): Promise<void> {
const users = await listUserPassUsers(this.state.authPath);
render() {
if (!this.state.users) return;
const baseMount = this.props.matches["baseMount"];
render(
<div>
<button
class="uk-button uk-margin uk-button-primary"
type="submit"
onClick={async () => {
await this.router.changePage("USERPASS_USER_NEW");
}}
>
{i18next.t("userpass_user_list_new_btn")}
</button>
return (
<>
<PageTitle title={i18next.t("userpass_users_list_title")} />
<div>
<button
class="uk-button uk-margin uk-button-primary"
type="submit"
onClick={async () => {
route(userPassUserNewURL(baseMount));
}}
>
{i18next.t("userpass_user_list_new_btn")}
</button>
<ul>
{...users.map((user) => (
<li>
<a
onClick={async () => {
this.state.userPassUser = user;
await this.router.changePage("USERPASS_USER_VIEW");
}}
>
{user}
</a>
</li>
))}
</ul>
</div>,
this.router.pageContentElement,
<ul>
{...this.state.users.map((user) => (
<li>
<a
onClick={async () => {
route(userPassUserViewURL(baseMount, user));
}}
>
{user}
</a>
</li>
))}
</ul>
</div>
</>
);
}
get name(): string {
return i18next.t("userpass_users_list_title");
}
}

View file

@ -18,8 +18,8 @@ export class PoliciesHome extends Component<DefaultPageProps, { policies: string
return policy_name !== "root";
});
this.setState({
policies: policies
})
policies: policies,
});
}
render() {
@ -33,7 +33,7 @@ export class PoliciesHome extends Component<DefaultPageProps, { policies: string
<button
class="uk-button uk-button-primary"
onClick={async () => {
route(policyNewURL())
route(policyNewURL());
}}
>
{i18next.t("policies_home_new_btn")}
@ -46,7 +46,7 @@ export class PoliciesHome extends Component<DefaultPageProps, { policies: string
<li>
<a
onClick={async () => {
route(policyViewURL(policyName))
route(policyViewURL(policyName));
}}
>
{policyName}

View file

@ -11,7 +11,7 @@ export class PolicyDelete extends Component<DefaultPageProps> {
const policyName = this.props.matches["policyName"];
return (
<>
<PageTitle title={i18next.t("policy_delete_title", {policy: policyName})} />
<PageTitle title={i18next.t("policy_delete_title", { policy: policyName })} />
<div>
<h5>{i18next.t("policy_delete_text")}</h5>
<button

View file

@ -2,7 +2,6 @@ import { CodeEditor } from "../../elements/CodeEditor";
import { Component, JSX, render } from "preact";
import { Margin } from "../../elements/Margin";
import { MarginInline } from "../../elements/MarginInline";
import { Page } from "../../../types/Page";
import { createOrUpdatePolicy } from "../../../api/sys/policies/createOrUpdatePolicy";
import { getPolicy } from "../../../api/sys/policies/getPolicy";
import { setErrorText } from "../../../pageUtils";
@ -18,13 +17,13 @@ type PolicyEditorProps = {
type PolicyEditorState =
| {
dataLoaded: false;
}
dataLoaded: false;
}
| {
dataLoaded: true;
policyData: string;
code: string;
};
dataLoaded: true;
policyData: string;
code: string;
};
export class PolicyEditor extends Component<PolicyEditorProps, PolicyEditorState> {
constructor() {
@ -39,7 +38,7 @@ export class PolicyEditor extends Component<PolicyEditorProps, PolicyEditorState
try {
await createOrUpdatePolicy(this.props.policyName, this.state.code);
route(policyViewURL(this.props.policyName))
route(policyViewURL(this.props.policyName));
} catch (e: unknown) {
const error = e as Error;
setErrorText(error.message);
@ -99,7 +98,7 @@ export class PolicyEdit extends Component<DefaultPageProps> {
const policyName = this.props.matches["policyName"];
return (
<>
<PageTitle title={i18next.t("policy_edit_title", {policy: policyName})} />
<PageTitle title={i18next.t("policy_edit_title", { policy: policyName })} />
<div>
<PolicyEditor policyName={policyName} />
</div>

View file

@ -9,48 +9,52 @@ import { PageTitle } from "../../elements/PageTitle";
import { route } from "preact-router";
import { policyDeleteURL, policyEditURL } from "../pageLinks";
export class PolicyView extends Component<DefaultPageProps, {policy: string, policyName: string}> {
export class PolicyView extends Component<
DefaultPageProps,
{ policy: string; policyName: string }
> {
async componentDidMount() {
if (!(await prePageChecks(this.props.state))) return;
console.log(this.props)
console.log(this.props);
const policyName = this.props.matches["policyName"];
const policy = await getPolicy(policyName);
this.setState({
policy, policyName
})
policy,
policyName,
});
}
render() {
if (!this.state.policy) return;
return (
<>
<PageTitle title={i18next.t("policy_view_title", {policy: this.state.policyName})} />
<div>
<p>
<button
class="uk-button uk-button-primary"
onClick={async () => {
route(policyEditURL(this.state.policyName));
}}
>
{i18next.t("policy_view_edit_btn")}
</button>
{this.state.policyName !== "default" && (
<PageTitle title={i18next.t("policy_view_title", { policy: this.state.policyName })} />
<div>
<p>
<button
class="uk-button uk-button-danger"
class="uk-button uk-button-primary"
onClick={async () => {
route(policyDeleteURL(this.state.policyName));
route(policyEditURL(this.state.policyName));
}}
>
{i18next.t("policy_view_delete_btn")}
{i18next.t("policy_view_edit_btn")}
</button>
)}
</p>
{this.state.policyName !== "default" && (
<button
class="uk-button uk-button-danger"
onClick={async () => {
route(policyDeleteURL(this.state.policyName));
}}
>
{i18next.t("policy_view_delete_btn")}
</button>
)}
</p>
<Margin>
<CodeBlock language="hcl" code={this.state.policy} />
</Margin>
</div>
<Margin>
<CodeBlock language="hcl" code={this.state.policy} />
</Margin>
</div>
</>
);
}

View file

@ -2,7 +2,6 @@ import { Component, JSX, createRef, render } from "preact";
import { CopyableInputBox } from "../elements/CopyableInputBox";
import { Form } from "../elements/Form";
import { Margin } from "../elements/Margin";
import { Page } from "../../types/Page";
import { PageTitle } from "../elements/PageTitle";
import i18next from "i18next";

View file

@ -19,8 +19,8 @@ export class TransitRewrap extends Component<DefaultPageProps, { transitKey: Tra
const baseMount = this.props.matches["baseMount"];
const secretItem = this.props.matches["secretItem"];
this.setState({
transitKey: await getTransitKey(baseMount, secretItem)
})
transitKey: await getTransitKey(baseMount, secretItem),
});
}
render() {

View file

@ -7,7 +7,11 @@ import { TransitKeyType } from "../../../../api/types/transit";
import { getTransitKey } from "../../../../api/transit/getTransitKey";
import i18next from "i18next";
import { route } from "preact-router";
import { transitDecryptSecretURL, transitEncryptSecretURL, transitRewrapSecretURL } from "../../pageLinks";
import {
transitDecryptSecretURL,
transitEncryptSecretURL,
transitRewrapSecretURL,
} from "../../pageLinks";
export class TransitView extends Component<DefaultPageProps, { transitKey: TransitKeyType }> {
async componentDidMount() {
@ -25,11 +29,7 @@ export class TransitView extends Component<DefaultPageProps, { transitKey: Trans
return (
<>
<SecretTitleElement
type="transit"
baseMount={baseMount}
item={secretItem}
/>
<SecretTitleElement type="transit" baseMount={baseMount} item={secretItem} />
<Grid size={GridSizes.MATCHING_TWO_ROWS}>
{transitKey.supports_encryption && (
<Tile

View file

@ -1,8 +1,7 @@
import { Component, render } from "preact";
import { Component } from "preact";
import { DefaultPageProps } from "../../types/DefaultPageProps";
import { Form } from "../elements/Form";
import { Margin } from "../elements/Margin";
import { Page } from "../../types/Page";
import { PageTitle } from "../elements/PageTitle";
import { route } from "preact-router";

View file

@ -1,10 +1,8 @@
import { Component, JSX, render } from "preact";
import { Form } from "../elements/Form";
import { MarginInline } from "../elements/MarginInline";
import { Page } from "../../types/Page";
import { QRScanner } from "../elements/QRScanner";
import { getSealStatus } from "../../api/sys/getSealStatus";
import { DefaultPageProps } from "../../types/DefaultPageProps";
import { PageTitle } from "../elements/PageTitle";
import { route } from "preact-router";

View file

@ -83,4 +83,32 @@ export function policyEditURL(policyName: string): string {
export function policyDeleteURL(policyName: string): string {
return `/policies/delete/${policyName}`;
}
}
// Access / Auth
export function authViewConfigURL(baseMount: string): string {
return `/access/auth/view/${baseMount}`;
}
// Access / Auth / UserPass
export function userPassUserListURL(baseMount: string): string {
return `/access/auth/userpass/list/${baseMount}`;
}
export function userPassUserNewURL(baseMount: string): string {
return `/access/auth/userpass/new/${baseMount}`;
}
export function userPassUserViewURL(baseMount: string, user: string): string {
return `/access/auth/userpass/view/${baseMount}/${user}`;
}
export function userPassUserEditURL(baseMount: string, user: string): string {
return `/access/auth/userpass/edit/${baseMount}/${user}`;
}
export function userPassUserDeleteURL(baseMount: string, user: string): string {
return `/access/auth/userpass/delete/${baseMount}/${user}`;
}