diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e8ad9a5..73dee7f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -256,9 +256,6 @@ taehui-www: dependencies: - axios: - specifier: ^1.6.7 - version: 1.6.7 dayjs: specifier: ^1.11.10 version: 1.11.10 diff --git a/qwilight-fe/src/Utility.ts b/qwilight-fe/src/Utility.ts index ea02229..0900d86 100644 --- a/qwilight-fe/src/Utility.ts +++ b/qwilight-fe/src/Utility.ts @@ -1,6 +1,5 @@ import { TFunction } from "i18next"; -import { AbilitySiteYell } from "src/site/Site"; import i4 from "src/assets/i4.png"; import i5 from "src/assets/i5.png"; import i6 from "src/assets/i6.png"; @@ -63,6 +62,7 @@ import m81 from "src/assets/m81.png"; import m120 from "src/assets/m120.png"; import m121 from "src/assets/m121.png"; +import { AbilitySiteYell } from "src/site/Site"; export const is = [ "", diff --git a/qwilight-fe/src/Www.ts b/qwilight-fe/src/Www.ts index 1c628ae..93f16ec 100644 --- a/qwilight-fe/src/Www.ts +++ b/qwilight-fe/src/Www.ts @@ -9,21 +9,17 @@ wwwAXIOS.interceptors.response.use( (value) => value, - ({ response }: AxiosError) => { - switch (response?.status) { + (e: AxiosError) => { + switch (e.response?.status) { case 401: - if (!(response.data as { isSilent?: boolean }).isSilent) { - toast.error("Unauthorized"); - window.sessionStorage.removeItem("totem"); - window.location.reload(); - } - break; - case 413: - toast.error("Payload Too Large"); + toast.error("Unauthorized"); + window.sessionStorage.removeItem("totem"); break; case 502: toast.error("Bad Gateway"); break; } + + throw e; }, ); diff --git a/taehui-fe/src/Www.ts b/taehui-fe/src/Www.ts index c09d505..e4eaef6 100644 --- a/taehui-fe/src/Www.ts +++ b/taehui-fe/src/Www.ts @@ -1,21 +1,17 @@ -import axios, { AxiosError } from "axios"; +import axios, { AxiosError, isAxiosError } from "axios"; import { toast } from "react-toastify"; export const wwwAXIOS = axios.create({ baseURL: "/www", - validateStatus: (status) => status < 500, }); wwwAXIOS.interceptors.response.use( (value) => value, - ({ response }: AxiosError) => { - switch (response?.status) { + (e: AxiosError) => { + switch (e.response?.status) { case 401: - if (!(response.data as { isSilent?: boolean }).isSilent) { - toast.error("Unauthorized"); - window.sessionStorage.removeItem("totem"); - window.location.reload(); - } + toast.error("Unauthorized"); + window.sessionStorage.removeItem("totem"); break; case 413: toast.error("Payload Too Large"); @@ -24,5 +20,10 @@ toast.error("Bad Gateway"); break; } + + throw e; }, ); + +export const isClientFault = (e: Error) => + isAxiosError(e) && e.response?.status === 403; diff --git a/taehui-fe/src/avatar/usePostAvatar.ts b/taehui-fe/src/avatar/usePostAvatar.ts index 563ae83..bd74a9b 100644 --- a/taehui-fe/src/avatar/usePostAvatar.ts +++ b/taehui-fe/src/avatar/usePostAvatar.ts @@ -3,7 +3,7 @@ import { toast } from "react-toastify"; import { getMillis } from "taehui-ts/date"; -import { wwwAXIOS } from "src/Www"; +import { isClientFault, wwwAXIOS } from "src/Www"; import usePostGetTotem from "src/avatar/usePostGetTotem"; export default function usePostAvatar() { @@ -41,8 +41,10 @@ onSuccess: async (data, { avatarID, avatarCipher }) => { await postGetTotem({ avatarID, avatarCipher }); }, - onError: () => { - toast.error(t("alreadyAvatarID")); + onError: (e) => { + if (isClientFault(e)) { + toast.error(t("alreadyAvatarID")); + } }, }); } diff --git a/taehui-fe/src/avatar/usePostGetTotem.ts b/taehui-fe/src/avatar/usePostGetTotem.ts index 7c7c6c1..27e5081 100644 --- a/taehui-fe/src/avatar/usePostGetTotem.ts +++ b/taehui-fe/src/avatar/usePostGetTotem.ts @@ -3,9 +3,10 @@ import { toast } from "react-toastify"; import { getMillis } from "taehui-ts/date"; -import { wwwAXIOS } from "src/Www"; +import { isClientFault, wwwAXIOS } from "src/Www"; import { useAvatarStore } from "src/Stores"; import { sprintf } from "sprintf-js"; +import { isAxiosError } from "axios"; export default function usePostGetTotem() { const { setSession, saveTotem } = useAvatarStore(); @@ -39,8 +40,10 @@ saveTotem(); toast.success(sprintf(t("signedInText"), data.avatarName)); }, - onError: () => { - toast.warning(t("wrongAvatar")); + onError: (e) => { + if (isClientFault(e)) { + toast.warning(t("wrongAvatar")); + } }, }); } diff --git a/taehui-fe/src/avatar/usePutAvatar.ts b/taehui-fe/src/avatar/usePutAvatar.ts index 57f52f0..1f31051 100644 --- a/taehui-fe/src/avatar/usePutAvatar.ts +++ b/taehui-fe/src/avatar/usePutAvatar.ts @@ -5,8 +5,9 @@ import { getMillis } from "taehui-ts/date"; import { useTo } from "taehui-ts/fe-utility"; -import { wwwAXIOS } from "src/Www"; +import { isClientFault, wwwAXIOS } from "src/Www"; import { useAvatarStore } from "src/Stores"; +import { isAxiosError } from "axios"; export default function usePutAvatar() { const { t } = useTranslation(); @@ -69,8 +70,10 @@ to("/"); } }, - onError: () => { - toast.error(t("failedValidateCipher")); + onError: (e) => { + if (isClientFault(e)) { + toast.error(t("failedValidateCipher")); + } }, }); } diff --git a/taehui-fe/src/avatar/useWipeTotem.ts b/taehui-fe/src/avatar/useWipeTotem.ts index 9df326e..63a00d1 100644 --- a/taehui-fe/src/avatar/useWipeTotem.ts +++ b/taehui-fe/src/avatar/useWipeTotem.ts @@ -22,7 +22,7 @@ }); return data; }, - onSuccess: async (data) => { + onSuccess: async () => { toast.success(sprintf(t("notSignedInText"), taehuiAvatarName)); setSession({ totem: "", diff --git a/taehui-fe/src/commentary/usePutCommentary.ts b/taehui-fe/src/commentary/usePutCommentary.ts index 80af38c..40e9c7e 100644 --- a/taehui-fe/src/commentary/usePutCommentary.ts +++ b/taehui-fe/src/commentary/usePutCommentary.ts @@ -1,6 +1,6 @@ import { useMutation, useQueryClient } from "@tanstack/react-query"; -import { wwwAXIOS } from "src/Www"; +import { isClientFault, wwwAXIOS } from "src/Www"; import { toast } from "react-toastify"; import { useTranslation } from "react-i18next"; @@ -28,8 +28,10 @@ onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: ["commentary"] }); }, - onError: () => { - toast.error(t("failedValidateCipher")); + onError: (e) => { + if (isClientFault(e)) { + toast.error(t("failedValidateCipher")); + } }, }); } diff --git a/taehui-fe/src/commentary/useWipeCommentary.ts b/taehui-fe/src/commentary/useWipeCommentary.ts index a42ce9b..df17250 100644 --- a/taehui-fe/src/commentary/useWipeCommentary.ts +++ b/taehui-fe/src/commentary/useWipeCommentary.ts @@ -2,7 +2,7 @@ import { toast } from "react-toastify"; import { useTranslation } from "react-i18next"; -import { wwwAXIOS } from "src/Www"; +import { isClientFault, wwwAXIOS } from "src/Www"; import { GetCommentaryAPI } from "src/wwwAPI"; export default function useWipeCommentary() { @@ -28,8 +28,10 @@ onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: ["commentary"] }); }, - onError: () => { - toast.error(t("failedValidateCipher")); + onError: (e) => { + if (isClientFault(e)) { + toast.error(t("failedValidateCipher")); + } }, }); } diff --git a/taehui-fe/src/forum/useWipeComment.ts b/taehui-fe/src/forum/useWipeComment.ts index f33d21e..1a0266d 100644 --- a/taehui-fe/src/forum/useWipeComment.ts +++ b/taehui-fe/src/forum/useWipeComment.ts @@ -3,7 +3,7 @@ import { useTranslation } from "react-i18next"; import { getMillis } from "taehui-ts/date"; -import { wwwAXIOS } from "src/Www"; +import { isClientFault, wwwAXIOS } from "src/Www"; export default function useWipeComment() { const queryClient = useQueryClient(); @@ -28,8 +28,10 @@ onSuccess: async () => { await queryClient.invalidateQueries({ queryKey: ["comment"] }); }, - onError: () => { - toast.error(t("failedValidateCipher")); + onError: (e) => { + if (isClientFault(e)) { + toast.error(t("failedValidateCipher")); + } }, }); } diff --git a/taehui-www/package.json b/taehui-www/package.json index 2bf6369..5dd336c 100644 --- a/taehui-www/package.json +++ b/taehui-www/package.json @@ -3,7 +3,6 @@ "version": "1.0.0", "private": true, "dependencies": { - "axios": "^1.6.7", "dayjs": "^1.11.10", "htmlparser2": "^9.1.0", "koa": "^2.15.0", diff --git a/taehui-www/src/Www.ts b/taehui-www/src/Www.ts deleted file mode 100644 index 48e1b26..0000000 --- a/taehui-www/src/Www.ts +++ /dev/null @@ -1,4 +0,0 @@ -import axios from "axios"; - -export const wwwAXIOS = axios.create(); - diff --git a/taehui-www/src/mws/avatar.ts b/taehui-www/src/mws/avatar.ts index e008219..fcc0e3c 100644 --- a/taehui-www/src/mws/avatar.ts +++ b/taehui-www/src/mws/avatar.ts @@ -4,37 +4,35 @@ import DB from "src/system/DB"; -export const validateTotem: (isSilent: boolean) => Middleware = - (isSilent) => async (ctx, next) => { - const { - headers: { totem }, - } = ctx; +export const validateTotem: Middleware = async (ctx, next) => { + const { + headers: { totem }, + } = ctx; - const totemText = totem as string; + const totemText = totem as string; - const data = await DB.ta(async (db) => { - const data = await DB.getAvatarAsTotem(db, totemText); - - if (data) { - const datetime = getDatetime(); - if (dayjs(data.date).add(1, "hour").isAfter(datetime)) { - await DB.setTotemDateAsTotem(db, totemText, datetime); - return DB.getAvatarAsAvatarID(db, data.avatarID); - } else { - await DB.wipeTotem(db, totemText); - } - } - }); + const data = await DB.ta(async (db) => { + const data = await DB.getAvatarAsTotem(db, totemText); if (data) { - ctx.headers.avatarID = data.avatarID; - ctx.headers.avatarName = data.avatarName; - ctx.headers.level = String(data.level); - ctx.headers.fax = data.fax; - ctx.headers.avatarIntro = data.avatarIntro; - await next(); - } else { - ctx.body = { isSilent }; - ctx.status = 401; + const datetime = getDatetime(); + if (dayjs(data.date).add(1, "hour").isAfter(datetime)) { + await DB.setTotemDate(db, totemText, datetime); + return DB.getAvatarAsAvatarID(db, data.avatarID); + } else { + await DB.wipeTotem(db, totemText); + } } - }; + }); + + if (data) { + ctx.headers.avatarID = data.avatarID; + ctx.headers.avatarName = data.avatarName; + ctx.headers.level = String(data.level); + ctx.headers.fax = data.fax; + ctx.headers.avatarIntro = data.avatarIntro; + await next(); + } else { + ctx.status = 401; + } +}; diff --git a/taehui-www/src/mws/millis.ts b/taehui-www/src/mws/millis.ts index bb44e00..d78fda3 100644 --- a/taehui-www/src/mws/millis.ts +++ b/taehui-www/src/mws/millis.ts @@ -14,7 +14,6 @@ ) { await next(); } else { - ctx.body = { isSilent: true }; ctx.status = 401; } }; diff --git a/taehui-www/src/routers/autoEssay.ts b/taehui-www/src/routers/autoEssay.ts index f5725c7..3825f7b 100644 --- a/taehui-www/src/routers/autoEssay.ts +++ b/taehui-www/src/routers/autoEssay.ts @@ -10,7 +10,7 @@ const router = new Router(); -router.post("/:forumID", validateMillis, validateTotem(false), async (ctx) => { +router.post("/:forumID", validateMillis, validateTotem, async (ctx) => { const { params: { forumID }, headers: { avatarID }, @@ -27,7 +27,7 @@ ctx.status = 201; }); -router.get("/:forumID", validateTotem(false), async (ctx) => { +router.get("/:forumID", validateTotem, async (ctx) => { const { params: { forumID }, headers: { avatarID }, @@ -43,50 +43,40 @@ } }); -router.put( - "/:autoEssayID", - validateMillis, - validateTotem(false), - async (ctx) => { - const { - params: { autoEssayID }, - headers: { avatarID }, - request: { - body: { title, text }, - }, - } = ctx; +router.put("/:autoEssayID", validateMillis, validateTotem, async (ctx) => { + const { + params: { autoEssayID }, + headers: { avatarID }, + request: { + body: { title, text }, + }, + } = ctx; - if ( - await doModifyAutoEssay( - Number(autoEssayID), - avatarID as string, - title, - text, - ) - ) { - ctx.status = 204; - } else { - ctx.status = 403; - } - }, -); + if ( + await doModifyAutoEssay( + Number(autoEssayID), + avatarID as string, + title, + text, + ) + ) { + ctx.status = 204; + } else { + ctx.status = 403; + } +}); -router.delete( - "/:autoEssayID", - validateMillis, - validateTotem(false), - async (ctx) => { - const { - params: { autoEssayID }, - headers: { avatarID }, - } = ctx; +router.delete("/:autoEssayID", validateMillis, validateTotem, async (ctx) => { + const { + params: { autoEssayID }, + headers: { avatarID }, + } = ctx; - if (await wipeAutoEssay(Number(autoEssayID), avatarID as string)) { - ctx.status = 204; - } else { - ctx.status = 403; - } - }, -); + if (await wipeAutoEssay(Number(autoEssayID), avatarID as string)) { + ctx.status = 204; + } else { + ctx.status = 403; + } +}); export default router; diff --git a/taehui-www/src/routers/avatar.ts b/taehui-www/src/routers/avatar.ts index 466ee5a..c3c9f99 100644 --- a/taehui-www/src/routers/avatar.ts +++ b/taehui-www/src/routers/avatar.ts @@ -39,7 +39,7 @@ } }); -router.patch("/totem", validateMillis, validateTotem(true), async (ctx) => { +router.patch("/totem", validateMillis, validateTotem, async (ctx) => { const { request: { headers }, } = ctx; @@ -54,7 +54,7 @@ ctx.status = 201; }); -router.delete("/totem", validateMillis, validateTotem(false), async (ctx) => { +router.delete("/totem", validateMillis, validateTotem, async (ctx) => { const { headers: { avatarID }, } = ctx; @@ -66,7 +66,7 @@ } }); -router.put("/", validateMillis, validateTotem(false), async (ctx) => { +router.put("/", validateMillis, validateTotem, async (ctx) => { const { headers: { avatarID }, request: { @@ -97,23 +97,18 @@ } }); -router.put( - "/avatarIntro", - validateMillis, - validateTotem(false), - async (ctx) => { - const { - headers: { avatarID }, - request: { body }, - } = ctx; +router.put("/avatarIntro", validateMillis, validateTotem, async (ctx) => { + const { + headers: { avatarID }, + request: { body }, + } = ctx; - if (await doModifyAvatarIntro(avatarID as string, body)) { - ctx.status = 204; - } else { - ctx.status = 403; - } - }, -); + if (await doModifyAvatarIntro(avatarID as string, body)) { + ctx.status = 204; + } else { + ctx.status = 403; + } +}); router.post("/", validateMillis, async (ctx) => { const { @@ -151,7 +146,7 @@ router.post( "/drawing", validateMillis, - validateTotem(false), + validateTotem, async (ctx, next) => { const { headers: { avatarID }, diff --git a/taehui-www/src/routers/comment.ts b/taehui-www/src/routers/comment.ts index e524102..9f37944 100644 --- a/taehui-www/src/routers/comment.ts +++ b/taehui-www/src/routers/comment.ts @@ -25,7 +25,7 @@ ctx.status = 200; }); -router.post("/:essayID", validateMillis, validateTotem(false), async (ctx) => { +router.post("/:essayID", validateMillis, validateTotem, async (ctx) => { const { params: { essayID }, headers: { avatarID, level }, @@ -49,7 +49,7 @@ } }); -router.put("/:commentID", validateMillis, validateTotem(false), async (ctx) => { +router.put("/:commentID", validateMillis, validateTotem, async (ctx) => { const { params: { commentID }, headers: { avatarID, level }, @@ -72,24 +72,17 @@ } }); -router.delete( - "/:commentID", - validateMillis, - validateTotem(false), - async (ctx) => { - const { - params: { commentID }, - headers: { avatarID, level }, - } = ctx; +router.delete("/:commentID", validateMillis, validateTotem, async (ctx) => { + const { + params: { commentID }, + headers: { avatarID, level }, + } = ctx; - if ( - await wipeComment(Number(commentID), avatarID as string, Number(level)) - ) { - ctx.status = 204; - } else { - ctx.status = 403; - } - }, -); + if (await wipeComment(Number(commentID), avatarID as string, Number(level))) { + ctx.status = 204; + } else { + ctx.status = 403; + } +}); export default router; diff --git a/taehui-www/src/routers/essay.ts b/taehui-www/src/routers/essay.ts index 053dec5..e4b3c78 100644 --- a/taehui-www/src/routers/essay.ts +++ b/taehui-www/src/routers/essay.ts @@ -36,7 +36,7 @@ } }); -router.put("/:essayID", validateMillis, validateTotem(false), async (ctx) => { +router.put("/:essayID", validateMillis, validateTotem, async (ctx) => { const { params: { essayID }, headers: { avatarID, level }, @@ -60,25 +60,20 @@ } }); -router.delete( - "/:essayID", - validateMillis, - validateTotem(false), - async (ctx) => { - const { - params: { essayID }, - headers: { avatarID, level }, - } = ctx; +router.delete("/:essayID", validateMillis, validateTotem, async (ctx) => { + const { + params: { essayID }, + headers: { avatarID, level }, + } = ctx; - if (await wipeEssay(Number(essayID), avatarID as string, Number(level))) { - ctx.status = 204; - } else { - ctx.status = 403; - } - }, -); + if (await wipeEssay(Number(essayID), avatarID as string, Number(level))) { + ctx.status = 204; + } else { + ctx.status = 403; + } +}); -router.post("/:forumID", validateMillis, validateTotem(false), async (ctx) => { +router.post("/:forumID", validateMillis, validateTotem, async (ctx) => { const { params: { forumID }, headers: { avatarID, level }, diff --git a/taehui-www/src/routers/file.ts b/taehui-www/src/routers/file.ts index 38ba22e..a048179 100644 --- a/taehui-www/src/routers/file.ts +++ b/taehui-www/src/routers/file.ts @@ -12,7 +12,7 @@ router.post( "/", validateMillis, - validateTotem(false), + validateTotem, async (ctx, next) => { try { const { postLength } = Configure; diff --git a/taehui-www/src/system/DB.ts b/taehui-www/src/system/DB.ts index 7c32e37..4490d05 100644 --- a/taehui-www/src/system/DB.ts +++ b/taehui-www/src/system/DB.ts @@ -348,11 +348,7 @@ } } - async setTotemDateAsTotem( - db: PoolConnection, - totem: string, - datetime: string, - ) { + async setTotemDate(db: PoolConnection, totem: string, datetime: string) { await db.query( `UPDATE tn_totem SET Date = ? diff --git a/taehui-www/src/systems/avatar.ts b/taehui-www/src/systems/avatar.ts index c170557..d952e42 100644 --- a/taehui-www/src/systems/avatar.ts +++ b/taehui-www/src/systems/avatar.ts @@ -9,7 +9,6 @@ import DB from "src/system/DB"; import Configure from "src/system/Configure"; import { equalCipher } from "src/Utility"; -import { wwwAXIOS } from "src/Www"; import { AVATAR_ENTRY_PATH } from "src/TaehuiComponent"; const pw = promisify(pbkdf2); @@ -90,7 +89,10 @@ ) { if (avatarCipherModified) { await DB.wipeTotem(db, avatarID); - await wwwAXIOS.patch(`${Configure.www.qwilight}/totem`, avatarID); + await fetch(`${Configure.www.qwilight}/totem`, { + method: "PATCH", + body: JSON.stringify({ avatarID }), + }); } return true; } else { @@ -169,5 +171,8 @@ }; export const doInvalidateDrawing = async (avatarID: string) => { - return wwwAXIOS.patch(`${Configure.www.qwilight}/drawing`, avatarID); + await fetch(`${Configure.www.qwilight}/drawing`, { + method: "PATCH", + body: JSON.stringify({ avatarID }), + }); };