ionian/packages/client/src/state/user.ts
2024-04-06 09:23:50 +09:00

109 lines
No EOL
2.7 KiB
TypeScript

import { atom, useAtomValue, setAtomValue } from "../lib/atom.ts";
type LoginLocalStorage = {
username: string;
permission: string[];
accessExpired: number;
};
let localObj: LoginLocalStorage | null = null;
function getUserSessions() {
if (localObj === null) {
const storagestr = localStorage.getItem("UserLoginContext") as string | null;
const storage = storagestr !== null ? (JSON.parse(storagestr) as LoginLocalStorage | null) : null;
localObj = storage;
}
if (localObj !== null && localObj.accessExpired > Math.floor(Date.now() / 1000)) {
return {
username: localObj.username,
permission: localObj.permission,
};
}
return null;
}
async function refresh() {
const res = await fetch("/user/refresh", {
method: "POST",
});
if (res.status !== 200) throw new Error("Maybe Network Error");
const r = (await res.json()) as LoginLocalStorage & { refresh: boolean };
if (r.refresh) {
localObj = {
...r
};
} else {
localObj = {
accessExpired: 0,
username: "",
permission: r.permission,
};
}
localStorage.setItem("UserLoginContext", JSON.stringify(localObj));
return {
username: r.username,
permission: r.permission,
};
}
export const doLogout = async () => {
const req = await fetch("/api/user/logout", {
method: "POST",
});
const setVal = setAtomValue(userLoginStateAtom);
try {
const res = await req.json();
localObj = {
accessExpired: 0,
username: "",
permission: res.permission,
};
window.localStorage.setItem("UserLoginContext", JSON.stringify(localObj));
setVal(localObj);
return {
username: localObj.username,
permission: localObj.permission,
};
} catch (error) {
console.error(`Server Error ${error}`);
return {
username: "",
permission: [],
};
}
};
export const doLogin = async (userLoginInfo: {
username: string;
password: string;
}): Promise<string | LoginLocalStorage> => {
const res = await fetch("/api/user/login", {
method: "POST",
body: JSON.stringify(userLoginInfo),
headers: { "content-type": "application/json" },
});
const b = await res.json();
if (res.status !== 200) {
return b.detail as string;
}
const setVal = setAtomValue(userLoginStateAtom);
localObj = b;
setVal(b);
window.localStorage.setItem("UserLoginContext", JSON.stringify(localObj));
return b;
};
export async function getInitialValue() {
const user = getUserSessions();
if (user) {
return user;
}
return refresh();
}
export const userLoginStateAtom = atom("userLoginState", getUserSessions());
export function useLogin() {
const val = useAtomValue(userLoginStateAtom);
return val;
}