Skip to content

Commit 97bc613

Browse files
committed
web: migrate to sdk for logs, permissions, and user settings
1 parent 468cc1e commit 97bc613

4 files changed

Lines changed: 65 additions & 86 deletions

File tree

web/app/admin/tools/logs/logs.module.tsx

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client"
22
import { Session } from "@/folderharborweb";
3-
import query from "@/utils/api";
3+
import { getClient, handleError } from "@/utils/api";
44
import { db } from "@/utils/db";
55
import { faArrowLeft, faArrowRight } from "@fortawesome/free-solid-svg-icons";
66
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@@ -9,7 +9,7 @@ import { useEffect, useState } from "react";
99
export default function Logs() {
1010
const [session, setSession] = useState<Session | undefined>();
1111
// eslint-disable-next-line @typescript-eslint/no-explicit-any
12-
const [logs, setLogs] = useState<{ userID: number, username: string | null, action: string, body: any | null, blurb: string, createdAt: string }[] | undefined>();
12+
const [logs, setLogs] = useState<{ userID: number, username: string | null, action: string, body: any | null, blurb: string, createdAt: Date }[] | undefined>();
1313
const [page, setPage] = useState<number>(1);
1414
const [pageCount, setPageCount] = useState<number>(1);
1515
useEffect(() => {
@@ -19,24 +19,22 @@ export default function Logs() {
1919
useEffect(() => {
2020
async function loadLogs() {
2121
if (!session) return;
22-
const res = await query(session, `admin/logs?page=${page}`);
23-
if ("error" in res) {
24-
alert(res.error);
25-
return;
22+
try {
23+
const logs = await getClient(session).admin.logs(page);
24+
setLogs(logs.logs);
25+
setPageCount(logs.pageCount);
26+
} catch (e) {
27+
const errBody = handleError(e as Error);
28+
if ("error" in errBody) alert(errBody.error);
29+
if ("redirect" in errBody) window.location.href = errBody.redirect;
2630
}
27-
if ("redirect" in res) {
28-
window.location.href = res.redirect;
29-
return;
30-
}
31-
setLogs(res.body.logs);
32-
setPageCount(res.body.pageCount);
3331
}
3432
loadLogs();
3533
}, [session, page]);
3634
return (
3735
<div className="flex flex-col mt-4">
3836
{(session && logs) && <div className="flex flex-col gap-2">
39-
{logs.map((entry) => <div key={entry.createdAt} className="bg-slate-700 p-2 rounded-lg">
37+
{logs.map((entry) => <div key={entry.createdAt.getTime()} className="bg-slate-700 p-2 rounded-lg">
4038
<div className="flex gap-1"><p className="font-semibold">{entry.username}</p> (ID #{entry.userID}) {entry.blurb} at {new Date(entry.createdAt).toLocaleString()} ({entry.action})</div>
4139
{entry.body && <pre className="word-wrap break-all">{JSON.stringify(entry.body, null, 2)}</pre>}
4240
</div>)}

web/app/admin/tools/permissions/permissions.module.tsx

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"use client"
22
import { Session } from "@/folderharborweb";
3-
import query from "@/utils/api";
3+
import { getClient, handleError } from "@/utils/api";
44
import { db } from "@/utils/db";
55
import { useEffect, useState } from "react";
66

@@ -14,16 +14,13 @@ export default function Permissions() {
1414
useEffect(() => {
1515
async function loadPermissions() {
1616
if (!session) return;
17-
const res = await query(session, `admin/permissions`);
18-
if ("error" in res) {
19-
alert(res.error);
20-
return;
17+
try {
18+
setPermissions(await getClient(session).admin.permissions());
19+
} catch (e) {
20+
const errBody = handleError(e as Error);
21+
if ("error" in errBody) alert(errBody.error);
22+
if ("redirect" in errBody) window.location.href = errBody.redirect;
2123
}
22-
if ("redirect" in res) {
23-
window.location.href = res.redirect;
24-
return;
25-
}
26-
setPermissions(res.body);
2724
}
2825
loadPermissions();
2926
}, [session]);

web/app/settings/settings.module.tsx

Lines changed: 47 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,41 @@
11
"use client"
2-
import { ClientConfig, Session } from "@/folderharborweb";
3-
import query from "@/utils/api";
2+
import { Session } from "@/folderharborweb";
3+
import { getClient, handleError } from "@/utils/api";
44
import { db } from "@/utils/db";
5+
import { FHClientConfig, FHSelfInfo } from "@folderharbor/sdk";
56
import { faLock, faTrash } from "@fortawesome/free-solid-svg-icons";
67
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
78
import { useRouter } from "next/navigation";
89
import { useEffect, useState } from "react";
910

10-
type SelfInfo = { id: number, username: string, sessions: { id: number, createdAt: string, expiry: string }[], activeSession: number, failedLoginLockout: boolean, permissions: string[] };
1111
export default function Settings() {
1212
const [session, setSession] = useState<Session | undefined>();
13-
const [selfInfo, setSelfInfo] = useState<SelfInfo | undefined>();
14-
const [clientConfig, setClientConfig] = useState<ClientConfig | undefined>();
13+
const [selfInfo, setSelfInfo] = useState<FHSelfInfo | undefined>();
14+
const [clientConfig, setClientConfig] = useState<FHClientConfig | undefined>();
1515
useEffect(() => {
1616
async function loadSession() { if (localStorage.getItem("activeSession")) setSession(await db.sessions.get(parseInt(localStorage.getItem("activeSession")!))); }
1717
loadSession();
1818
}, []);
1919
useEffect(() => {
2020
async function loadSelfInfo() {
2121
if (!session) return;
22-
const res = await query(session, "me");
23-
if ("error" in res) {
24-
alert(res.error);
25-
return;
26-
}
27-
if ("redirect" in res) {
28-
window.location.href = res.redirect;
29-
return;
22+
try {
23+
setSelfInfo(await getClient(session).me.info());
24+
} catch (e) {
25+
const errBody = handleError(e as Error);
26+
if ("error" in errBody) alert(errBody.error);
27+
if ("redirect" in errBody) window.location.href = errBody.redirect;
3028
}
31-
setSelfInfo(res.body);
3229
}
3330
async function loadClientConfig() {
3431
if (!session) return;
35-
const res = await query(session, "clientconfig");
36-
if ("error" in res) {
37-
alert(res.error);
38-
return;
39-
}
40-
if ("redirect" in res) {
41-
window.location.href = res.redirect;
42-
return;
32+
try {
33+
setClientConfig(await getClient(session).clientconfig());
34+
} catch (e) {
35+
const errBody = handleError(e as Error);
36+
if ("error" in errBody) alert(errBody.error);
37+
if ("redirect" in errBody) window.location.href = errBody.redirect;
4338
}
44-
setClientConfig({ selfUsernameChanges: res.body.selfUsernameChanges, registration: res.body.registration });
4539
}
4640
loadSelfInfo();
4741
loadClientConfig();
@@ -53,55 +47,49 @@ export default function Settings() {
5347
</div>
5448
);
5549
}
56-
function SettingsForm({ session, selfInfo, clientConfig }: { session: Session, selfInfo: SelfInfo, clientConfig: ClientConfig }) {
50+
function SettingsForm({ session, selfInfo, clientConfig }: { session: Session, selfInfo: FHSelfInfo, clientConfig: FHClientConfig }) {
5751
const router = useRouter();
5852
const [username, setUsername] = useState<string>(selfInfo.username);
5953
const [password, setPassword] = useState<string>("");
6054
async function clearFailedLogins() {
61-
const res = await query(session, "me", { method: "PATCH", body: JSON.stringify({ clearLoginAttempts: true }) });
62-
if ("error" in res) {
63-
alert(res.error);
64-
return;
55+
try {
56+
await getClient(session).me.edit({ clearLoginAttempts: true });
57+
alert("Successfully reset failed login attempts!");
58+
window.location.reload();
59+
} catch (e) {
60+
const errBody = handleError(e as Error);
61+
if ("error" in errBody) alert(errBody.error);
62+
if ("redirect" in errBody) window.location.href = errBody.redirect;
6563
}
66-
if ("redirect" in res) {
67-
window.location.href = res.redirect;
68-
return;
69-
}
70-
alert("Successfully reset failed login attempts!");
71-
window.location.reload();
7264
}
7365
async function revokeSession(id: number) {
74-
const res = await query(session, "me/session", { method: "DELETE", body: JSON.stringify({ sessionID: id }) });
75-
if ("error" in res) {
76-
alert(res.error);
77-
return;
78-
}
79-
if ("redirect" in res) {
66+
try {
67+
await getClient(session).me.revokeSession(id);
68+
window.location.reload();
69+
} catch (e) {
70+
const errBody = handleError(e as Error);
71+
if ("error" in errBody) alert(errBody.error);
8072
// eslint-disable-next-line react-hooks/immutability
81-
window.location.href = res.redirect;
82-
return;
73+
if ("redirect" in errBody) window.location.href = errBody.redirect;
8374
}
84-
window.location.reload();
8575
}
8676
async function updateInfo(e: React.SubmitEvent) {
8777
e.preventDefault();
88-
const res = await query(session, "me", { method: "PATCH", body: JSON.stringify({ username: (username !== selfInfo.username ? username : undefined), password: (password !== "" ? password : undefined) }) });
89-
if ("error" in res) {
90-
alert(res.error);
91-
return;
92-
}
93-
if ("redirect" in res) {
94-
window.location.href = res.redirect;
95-
return;
96-
}
97-
alert(`Updated your info successfully!${password !== "" ? `\nYou have been signed out of all sessions, and will need to log in again.\nAs a reminder, your server address is "${session.server}", and your username is "${username !== selfInfo.username ? username : selfInfo.username}".` : ""}`);
98-
if (password !== "") {
99-
db.sessions.delete(parseInt(localStorage.getItem("activeSession")!));
100-
localStorage.removeItem("activeSession");
101-
router.push("/");
102-
return;
78+
try {
79+
await getClient(session).me.edit({ username: (username !== selfInfo.username ? username : undefined), password: (password !== "" ? password : undefined) });
80+
alert(`Updated your info successfully!${password !== "" ? `\nYou have been signed out of all sessions, and will need to log in again.\nAs a reminder, your server address is "${session.server}", and your username is "${username !== selfInfo.username ? username : selfInfo.username}".` : ""}`);
81+
if (password !== "") {
82+
db.sessions.delete(parseInt(localStorage.getItem("activeSession")!));
83+
localStorage.removeItem("activeSession");
84+
router.push("/");
85+
return;
86+
}
87+
if (username !== selfInfo.username) db.sessions.update(parseInt(localStorage.getItem("activeSession")!), { username: username });
88+
} catch (e) {
89+
const errBody = handleError(e as Error);
90+
if ("error" in errBody) alert(errBody.error);
91+
if ("redirect" in errBody) window.location.href = errBody.redirect;
10392
}
104-
if (username !== selfInfo.username) db.sessions.update(parseInt(localStorage.getItem("activeSession")!), { username: username });
10593
}
10694
return (
10795
<div className={`grid grid-cols-1 ${selfInfo.permissions.length >= 1 ? "md:grid-cols-3" : "md:grid-cols-2"} gap-4 md:gap-2 my-4`}>

web/folderharborweb.d.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,4 @@ export type Session = {
44
token: string
55
username: string
66
permissions: string[]
7-
}
8-
export type ClientConfig = {
9-
selfUsernameChanges: boolean
10-
registration: boolean
117
}

0 commit comments

Comments
 (0)