diff --git a/pkg/notes/mod.ts b/pkg/notes/mod.ts index 9628ac92..55e53e62 100644 --- a/pkg/notes/mod.ts +++ b/pkg/notes/mod.ts @@ -1,7 +1,9 @@ import { OpenAPIHono } from '@hono/zod-openapi'; -import { Result } from '@mikuroxina/mini-fn'; +import { Cat, Ether, Promise, Result } from '@mikuroxina/mini-fn'; import type { AccountID } from '../accounts/model/account.js'; +import { authenticateToken } from '../accounts/service/authenticationTokenService.js'; +import { authenticateMiddleware } from '../adaptors/authenticateMiddleware.js'; import { prismaClient } from '../adaptors/prisma.js'; import { SnowflakeIDGenerator } from '../id/mod.js'; import type { ID } from '../id/type.js'; @@ -31,7 +33,22 @@ import { FetchBookmarkService } from './service/fetchBookmark.js'; import { RenoteService } from './service/renote.js'; const isProduction = process.env.NODE_ENV === 'production'; -export const noteHandlers = new OpenAPIHono(); +export const noteHandlers = new OpenAPIHono<{ + Variables: { + /* + * @description authorization token (JWT, ES256) + */ + token: string; + /* + * @description whether the token is checked (if allowUnAuthorized set true, this will be false) + */ + isValidToken: boolean; + /* + * @description account name (if allowUnAuthorized set true, this will be undefined) + */ + accountName?: string; + }; +}>(); const noteRepository = isProduction ? new PrismaNoteRepository(prismaClient) : new InMemoryNoteRepository(); @@ -42,6 +59,19 @@ const idGenerator = new SnowflakeIDGenerator(0, { now: () => BigInt(Date.now()), }); +const composer = Ether.composeT(Promise.monad); +const liftOverPromise = , T>( + ether: Ether.Ether, +): Ether.EtherT => ({ + ...ether, + handler: (resolved) => Promise.pure(ether.handler(resolved)), +}); +const AuthMiddleware = await Ether.runEtherT( + Cat.cat(liftOverPromise(authenticateMiddleware)).feed( + composer(authenticateToken), + ).value, +); + // Account const accountModule = new AccountModule(); @@ -77,6 +107,10 @@ noteHandlers.doc('/notes/doc.json', { }, }); +noteHandlers[CreateNoteRoute.method]( + CreateNoteRoute.path, + AuthMiddleware.handle({ allowUnAuthorized: false }), +); noteHandlers.openapi(CreateNoteRoute, async (c) => { const { content, visibility, contents_warning_comment, send_to } = c.req.valid('json'); @@ -94,6 +128,10 @@ noteHandlers.openapi(CreateNoteRoute, async (c) => { return c.json(res[1]); }); +noteHandlers[GetNoteRoute.method]( + GetNoteRoute.path, + AuthMiddleware.handle({ allowUnAuthorized: true }), +); noteHandlers.openapi(GetNoteRoute, async (c) => { const { id } = c.req.param(); const res = await controller.getNoteByID(id); @@ -104,6 +142,10 @@ noteHandlers.openapi(GetNoteRoute, async (c) => { return c.json(res[1]); }); +noteHandlers[RenoteRoute.method]( + RenoteRoute.path, + AuthMiddleware.handle({ allowUnAuthorized: false }), +); noteHandlers.openapi(RenoteRoute, async (c) => { const { id } = c.req.param(); const req = c.req.valid('json'); @@ -122,6 +164,10 @@ noteHandlers.openapi(RenoteRoute, async (c) => { return c.json(res[1]); }); +noteHandlers[CreateBookmarkRoute.method]( + CreateBookmarkRoute.path, + AuthMiddleware.handle({ allowUnAuthorized: false }), +); noteHandlers.openapi(CreateBookmarkRoute, async (c) => { const { id: noteID } = c.req.valid('param'); // ToDo: read AccountID from token @@ -137,6 +183,10 @@ noteHandlers.openapi(CreateBookmarkRoute, async (c) => { return c.json(res[1]); }); +noteHandlers[DeleteBookmarkRoute.method]( + DeleteBookmarkRoute.path, + AuthMiddleware.handle({ allowUnAuthorized: false }), +); noteHandlers.openapi(DeleteBookmarkRoute, async (c) => { const { id: noteID } = c.req.valid('param'); // ToDo: read AccountID from token