Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 28 additions & 37 deletions web/app/admin/acls/[aclID]/acl.module.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client"
import { Session } from "@/folderharborweb";
import query from "@/utils/api";
import { getClient, handleError } from "@/utils/api";
import { db } from "@/utils/db";
import { faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
Expand All @@ -19,16 +19,13 @@ export default function ACLSettings({ aclID }: { aclID: number }) {
useEffect(() => {
async function loadACL() {
if (!session) return;
const res = await query(session, `admin/acls/${aclID}`);
if ("error" in res) {
alert(res.error);
return;
try {
setACL(await getClient(session).admin.acls.get(aclID));
} catch (e) {
const errBody = handleError(e as Error);
if ("error" in errBody) alert(errBody.error);
if ("redirect" in errBody) window.location.href = errBody.redirect;
}
if ("redirect" in res) {
window.location.href = res.redirect;
return;
}
setACL(res.body);
}
loadACL();
}, [session, aclID]);
Expand All @@ -45,30 +42,26 @@ function SettingsPanel({ session, acl, aclID }: { session: Session, acl: ACL, ac
const [name, setName] = useState<string>(acl.name);
async function updateInfo(e: React.SubmitEvent) {
e.preventDefault();
const res = await query(session, `admin/acls/${aclID}`, { method: "PATCH", body: JSON.stringify({ name: (name !== acl.name ? name : undefined) }) });
if ("error" in res) {
alert(res.error);
return;
}
if ("redirect" in res) {
window.location.href = res.redirect;
return;
try {
await getClient(session).admin.acls.edit(aclID, { name: (name !== acl.name ? name : undefined) });
alert(`Updated ${name !== acl.name ? name : acl.name}'s information!`);
} catch (e) {
const errBody = handleError(e as Error);
if ("error" in errBody) alert(errBody.error);
if ("redirect" in errBody) window.location.href = errBody.redirect;
}
alert(`Updated ${name !== acl.name ? name : acl.name}'s information!`);
}
async function deleteACL() {
const check = confirm(`Are you sure you want to permanently delete the ACL "${acl.name}" (ID ${aclID}) on "${session.server}"?`);
if (!check) return;
const res = await query(session, `admin/acls/${aclID}`, { method: "DELETE" });
if ("error" in res) {
alert(res.error);
return;
try {
await getClient(session).admin.acls.delete(aclID);
router.push("/admin/acls");
} catch (e) {
const errBody = handleError(e as Error);
if ("error" in errBody) alert(errBody.error);
if ("redirect" in errBody) window.location.href = errBody.redirect;
}
if ("redirect" in res) {
window.location.href = res.redirect;
return;
}
router.push("/admin/acls");
}
return (
<div className="grid gap-6 grid-cols-1 md:grid-cols-3">
Expand Down Expand Up @@ -108,16 +101,14 @@ function ACLPaths({ session, acl, aclID }: { session: Session, acl: ACL, aclID:
}
function removePath(item: string, state: string[], setState: Dispatch<SetStateAction<string[]>>) { setState(state.filter((current) => current !== item)); }
async function applyChanges() {
const res = await query(session, `admin/acls/${aclID}`, { method: "PATCH", body: JSON.stringify({ allow: (!isEqual(allow, acl.allow) ? allow : undefined), deny: (!isEqual(deny, acl.deny) ? deny : undefined) }) });
if ("error" in res) {
alert(res.error);
return;
}
if ("redirect" in res) {
window.location.href = res.redirect;
return;
try {
await getClient(session).admin.acls.edit(aclID, { allow: (!isEqual(allow, acl.allow) ? allow : undefined), deny: (!isEqual(deny, acl.deny) ? deny : undefined) });
alert("Saved new paths successfully!");
} catch (e) {
const errBody = handleError(e as Error);
if ("error" in errBody) alert(errBody.error);
if ("redirect" in errBody) window.location.href = errBody.redirect;
}
if (res.body.message !== "Nothing to update.") alert("Saved new paths successfully!");
}
return (
<div className="flex flex-col gap-4 items-center md:col-span-2">
Expand Down
17 changes: 7 additions & 10 deletions web/app/admin/acls/acls.module.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client"
import { Session } from "@/folderharborweb";
import query from "@/utils/api";
import { getClient, handleError } from "@/utils/api";
import { db } from "@/utils/db";
import { faPlus } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
Expand All @@ -17,16 +17,13 @@ export default function ACLs() {
useEffect(() => {
async function loadACLs() {
if (!session) return;
const res = await query(session, "admin/acls");
if ("error" in res) {
alert(res.error);
return;
try {
setACLs(await getClient(session).admin.acls.list());
} catch (e) {
const errBody = handleError(e as Error);
if ("error" in errBody) alert(errBody.error);
if ("redirect" in errBody) window.location.href = errBody.redirect;
}
if ("redirect" in res) {
window.location.href = res.redirect;
return;
}
setACLs(res.body);
}
loadACLs();
}, [session]);
Expand Down
18 changes: 8 additions & 10 deletions web/app/admin/acls/create/create.module.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client"
import { Session } from "@/folderharborweb";
import query from "@/utils/api";
import { getClient, handleError } from "@/utils/api";
import { db } from "@/utils/db";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
Expand All @@ -15,16 +15,14 @@ export default function CreateACL() {
}, []);
async function updateInfo(e: React.SubmitEvent) {
e.preventDefault();
const res = await query(session!, `admin/acls`, { method: "POST", body: JSON.stringify({ name }) });
if ("error" in res) {
alert(res.error);
return;
try {
const acl = await getClient(session!).admin.acls.create({ name });
router.push(`/admin/acls/${acl.id}`);
} catch (e) {
const errBody = handleError(e as Error);
if ("error" in errBody) alert(errBody.error);
if ("redirect" in errBody) window.location.href = errBody.redirect;
}
if ("redirect" in res) {
window.location.href = res.redirect;
return;
}
router.push(`/admin/acls/${res.body.id}`);
}
return (
<form onSubmit={updateInfo} className="flex flex-col gap-2">
Expand Down
17 changes: 7 additions & 10 deletions web/app/admin/config/config.module.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client"
import { Session } from "@/folderharborweb";
import query from "@/utils/api";
import { getClient, handleError } from "@/utils/api";
import { db } from "@/utils/db";
import { useEffect, useState } from "react";

Expand All @@ -14,16 +14,13 @@ export default function Config() {
useEffect(() => {
async function loadConfig() {
if (!session) return;
const res = await query(session, `admin/config`);
if ("error" in res) {
alert(res.error);
return;
try {
setConfig(await getClient(session).admin.config.read());
} catch (e) {
const errBody = handleError(e as Error);
if ("error" in errBody) alert(errBody.error);
if ("redirect" in errBody) window.location.href = errBody.redirect;
}
if ("redirect" in res) {
window.location.href = res.redirect;
return;
}
setConfig(res.body);
}
loadConfig();
}, [session]);
Expand Down
104 changes: 46 additions & 58 deletions web/app/admin/roles/[roleID]/role.module.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,32 @@
"use client"
import { Session } from "@/folderharborweb";
import query from "@/utils/api";
import { getClient, handleError } from "@/utils/api";
import { db } from "@/utils/db";
import { FHRole } from "@folderharbor/sdk";
import { faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { isEqual } from "lodash-es";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { Dispatch, SetStateAction, useEffect, useState } from "react";

type Role = { name: string, acls: number[], permissions: string[] }
export default function RoleSettings({ roleID }: { roleID: number }) {
const [session, setSession] = useState<Session | undefined>();
const [role, setRole] = useState<Role | undefined>();
const [role, setRole] = useState<FHRole | undefined>();
useEffect(() => {
async function loadSession() { if (localStorage.getItem("activeSession")) setSession(await db.sessions.get(parseInt(localStorage.getItem("activeSession")!))); }
loadSession();
}, []);
useEffect(() => {
async function loadRole() {
if (!session) return;
const res = await query(session, `admin/roles/${roleID}`);
if ("error" in res) {
alert(res.error);
return;
try {
setRole(await getClient(session).admin.roles.get(roleID));
} catch (e) {
const errBody = handleError(e as Error);
if ("error" in errBody) alert(errBody.error);
if ("redirect" in errBody) window.location.href = errBody.redirect;
}
if ("redirect" in res) {
window.location.href = res.redirect;
return;
}
setRole(res.body);
}
loadRole();
}, [session, roleID]);
Expand All @@ -41,34 +38,30 @@ export default function RoleSettings({ roleID }: { roleID: number }) {
</div>
);
}
function SettingsPanel({ session, role, roleID }: { session: Session, role: Role, roleID: number }) {
function SettingsPanel({ session, role, roleID }: { session: Session, role: FHRole, roleID: number }) {
const router = useRouter();
const [name, setName] = useState<string>(role.name);
async function updateInfo(e: React.SubmitEvent) {
e.preventDefault();
const res = await query(session, `admin/roles/${roleID}`, { method: "PATCH", body: JSON.stringify({ name: (name !== role.name ? name : undefined) }) });
if ("error" in res) {
alert(res.error);
return;
}
if ("redirect" in res) {
window.location.href = res.redirect;
return;
}
try {
await getClient(session).admin.roles.edit(roleID, { name: (name !== role.name ? name : undefined) });
} catch (e) {
const errBody = handleError(e as Error);
if ("error" in errBody) alert(errBody.error);
if ("redirect" in errBody) window.location.href = errBody.redirect;
}
alert(`Updated ${name !== role.name ? name : role.name}'s information!`);
}
async function deleteRole() {
const check = confirm(`Are you sure you want to permanently delete the role "${role.name}" (ID ${roleID}) on "${session.server}"?`);
if (!check) return;
const res = await query(session, `admin/roles/${roleID}`, { method: "DELETE" });
if ("error" in res) {
alert(res.error);
return;
}
if ("redirect" in res) {
window.location.href = res.redirect;
return;
}
try {
await getClient(session).admin.roles.delete(roleID);
} catch (e) {
const errBody = handleError(e as Error);
if ("error" in errBody) alert(errBody.error);
if ("redirect" in errBody) window.location.href = errBody.redirect;
}
router.push("/admin/roles");
}
return (
Expand Down Expand Up @@ -96,7 +89,7 @@ function SettingsPanel({ session, role, roleID }: { session: Session, role: Role
</div>
);
}
function RoleGrants({ session, role, roleID }: { session: Session, role: Role, roleID: number }) {
function RoleGrants({ session, role, roleID }: { session: Session, role: FHRole, roleID: number }) {
const [acls, setACLs] = useState<number[]>(role.acls);
const [permissions, setPermissions] = useState<string[]>(role.permissions);
const [newGrant, setNewGrant] = useState<{ acl: string, permission: string }>({ acl: "", permission: "" });
Expand All @@ -106,26 +99,23 @@ function RoleGrants({ session, role, roleID }: { session: Session, role: Role, r
if (!session) return;
let acls;
if (session.permissions.includes("acls:list")) {
acls = await query(session, `admin/acls`);
if ("error" in acls) {
alert(acls.error);
return;
}
if ("redirect" in acls) {
window.location.href = acls.redirect;
return;
try {
acls = await getClient(session).admin.acls.list();
} catch (e) {
const errBody = handleError(e as Error);
if ("error" in errBody) alert(errBody.error);
if ("redirect" in errBody) window.location.href = errBody.redirect;
}
}
const permissions = await query(session, `admin/permissions`);
if ("error" in permissions) {
alert(permissions.error);
return;
let permissions;
try {
permissions = await getClient(session).admin.permissions();
} catch (e) {
const errBody = handleError(e as Error);
if ("error" in errBody) alert(errBody.error);
if ("redirect" in errBody) window.location.href = errBody.redirect;
}
if ("redirect" in permissions) {
window.location.href = permissions.redirect;
return;
}
setLists({ acls: (acls ? acls.body : undefined), permissions: permissions.body });
setLists({ acls, permissions });
}
loadLists();
}, [session]);
Expand All @@ -140,16 +130,14 @@ function RoleGrants({ session, role, roleID }: { session: Session, role: Role, r
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function revokeItem(item: any, state: any[], setState: Dispatch<SetStateAction<any[]>>) { setState(state.filter((current) => current !== item)); }
async function applyChanges() {
const res = await query(session, `admin/roles/${roleID}`, { method: "PATCH", body: JSON.stringify({ acls: (!isEqual(acls, role.acls) ? acls : undefined), permissions: (!isEqual(permissions, role.permissions) ? permissions : undefined) }) });
if ("error" in res) {
alert(res.error);
return;
}
if ("redirect" in res) {
window.location.href = res.redirect;
return;
try {
await getClient(session).admin.roles.edit(roleID, { acls: (!isEqual(acls, role.acls) ? acls : undefined), permissions: (!isEqual(permissions, role.permissions) ? permissions : undefined) });
alert("Saved new grants successfully!");
} catch (e) {
const errBody = handleError(e as Error);
if ("error" in errBody) alert(errBody.error);
if ("redirect" in errBody) window.location.href = errBody.redirect;
}
if (res.body.message !== "Nothing to update.") alert("Saved new grants successfully!");
}
return (
<div className="flex flex-col gap-4 items-center md:col-span-2">
Expand Down
18 changes: 8 additions & 10 deletions web/app/admin/roles/create/create.module.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use client"
import { Session } from "@/folderharborweb";
import query from "@/utils/api";
import { getClient, handleError } from "@/utils/api";
import { db } from "@/utils/db";
import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
Expand All @@ -15,16 +15,14 @@ export default function CreateRole() {
}, []);
async function updateInfo(e: React.SubmitEvent) {
e.preventDefault();
const res = await query(session!, `admin/roles`, { method: "POST", body: JSON.stringify({ name }) });
if ("error" in res) {
alert(res.error);
return;
try {
const role = await getClient(session!).admin.roles.create({ name });
router.push(`/admin/roles/${role.id}`);
} catch (e) {
const errBody = handleError(e as Error);
if ("error" in errBody) alert(errBody.error);
if ("redirect" in errBody) window.location.href = errBody.redirect;
}
if ("redirect" in res) {
window.location.href = res.redirect;
return;
}
router.push(`/admin/roles/${res.body.id}`);
}
return (
<form onSubmit={updateInfo} className="flex flex-col gap-2">
Expand Down
Loading
Loading