import koaBody from "koa-body"; import Router from "koa-router"; import { join } from "path"; import { readFileSync } from "fs"; import { doInvalidateDrawing, doModifyAvatar, doModifyAvatarIntro, getAvatarDrawing, getLatestAvatars, getTotem, postAvatar, quitTotem, } from "src/systems/avatar"; import { validateTotem } from "src/mws/avatar"; import { validateMillis } from "src/mws/millis"; import { ASSETS_ENTRY_PATH, AVATAR_ENTRY_PATH } from "src/TaehuiComponent"; const router = new Router(); router.get("/latest", async (ctx) => { ctx.body = await getLatestAvatars(); ctx.status = 200; }); router.post("/getTotem", validateMillis, async (ctx) => { const { request: { body: { avatarID, avatarCipher }, }, } = ctx; const data = await getTotem(avatarID, avatarCipher); if (data) { ctx.body = data; ctx.status = 200; } else { ctx.status = 403; } }); router.patch("/totem", validateMillis, validateTotem(true), async (ctx) => { const { request: { headers }, } = ctx; ctx.body = { avatarID: headers.avatarID, avatarName: headers.avatarName, level: Number(headers.level), fax: headers.fax, avatarIntro: headers.avatarIntro, }; ctx.status = 201; }); router.delete("/totem", validateMillis, validateTotem(false), async (ctx) => { const { headers: { avatarID }, } = ctx; if (await quitTotem(avatarID as string)) { ctx.status = 204; } else { ctx.status = 403; } }); router.put("/", validateMillis, validateTotem(false), async (ctx) => { const { headers: { avatarID }, request: { body: { avatarCipher, avatarCipherModified, avatarName, fax, avatarIntro, }, }, } = ctx; if ( await doModifyAvatar( avatarID as string, avatarCipher, avatarCipherModified, avatarName, fax, avatarIntro, ) ) { ctx.body = avatarCipherModified; ctx.status = 204; } else { ctx.status = 403; } }); router.put( "/avatarIntro", validateMillis, validateTotem(false), async (ctx) => { const { headers: { avatarID }, request: { body }, } = ctx; if (await doModifyAvatarIntro(avatarID as string, body)) { ctx.status = 204; } else { ctx.status = 403; } }, ); router.post("/", validateMillis, async (ctx) => { const { request: { ip, body: { avatarID, avatarCipher, avatarName, fax }, }, } = ctx; if (await postAvatar(avatarID, avatarCipher, avatarName, ip, fax)) { ctx.status = 201; } else { ctx.status = 403; } }); const defaultDrawing = readFileSync(join(ASSETS_ENTRY_PATH, "Avatar.png")); router.get("/drawing", async (ctx) => { ctx.set("content-type", "image/png"); ctx.body = defaultDrawing; ctx.status = 200; }); router.get("/drawing/:avatarID", async (ctx) => { const { params: { avatarID }, } = ctx; ctx.set("content-type", "image/png"); ctx.body = (await getAvatarDrawing(avatarID)) ?? defaultDrawing; ctx.status = 200; }); router.post( "/drawing", validateMillis, validateTotem(false), async (ctx, next) => { const { headers: { avatarID }, } = ctx; await koaBody({ multipart: true, formidable: { keepExtensions: true, uploadDir: AVATAR_ENTRY_PATH, onFileBegin: (_, file) => { file.filepath = join(AVATAR_ENTRY_PATH, avatarID + ".png"); }, }, })(ctx, next); }, async (ctx) => { const { headers: { avatarID }, } = ctx; await doInvalidateDrawing(avatarID as string); ctx.status = 201; }, ); export default router;