Move chat to private authenticated API
This commit is contained in:
44
apps/api/src/chat/routes.ts
Normal file
44
apps/api/src/chat/routes.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { Router } from "express";
|
||||
import { z } from "zod";
|
||||
import { requireAuth } from "../auth/middleware.js";
|
||||
import { addMessage, addReaction, listChat } from "./store.js";
|
||||
|
||||
export const chatRouter = Router();
|
||||
|
||||
const MessageBody = z.object({
|
||||
content: z.string().trim().min(1).max(2000),
|
||||
replyToId: z.string().max(128).optional(),
|
||||
replyToPubkey: z.string().max(128).optional(),
|
||||
});
|
||||
|
||||
const ReactionBody = z.object({
|
||||
messageId: z.string().min(1).max(128),
|
||||
content: z.string().trim().min(1).max(32),
|
||||
});
|
||||
|
||||
chatRouter.use(requireAuth);
|
||||
|
||||
chatRouter.get("/", (_req, res) => {
|
||||
res.json(listChat());
|
||||
});
|
||||
|
||||
chatRouter.post("/messages", (req, res) => {
|
||||
const body = MessageBody.parse(req.body);
|
||||
const message = addMessage({
|
||||
pubkey: req.session!.pubkey,
|
||||
content: body.content,
|
||||
...(body.replyToId ? { replyToId: body.replyToId } : {}),
|
||||
...(body.replyToPubkey ? { replyToPubkey: body.replyToPubkey } : {}),
|
||||
});
|
||||
res.status(201).json(message);
|
||||
});
|
||||
|
||||
chatRouter.post("/reactions", (req, res) => {
|
||||
const body = ReactionBody.parse(req.body);
|
||||
const reaction = addReaction({
|
||||
pubkey: req.session!.pubkey,
|
||||
messageId: body.messageId,
|
||||
content: body.content,
|
||||
});
|
||||
res.status(201).json(reaction);
|
||||
});
|
||||
62
apps/api/src/chat/store.ts
Normal file
62
apps/api/src/chat/store.ts
Normal file
@@ -0,0 +1,62 @@
|
||||
export type StoredChatMessage = {
|
||||
id: string;
|
||||
pubkey: string;
|
||||
content: string;
|
||||
createdAt: number;
|
||||
replyToId: string;
|
||||
replyToPubkey: string;
|
||||
};
|
||||
|
||||
export type StoredChatReaction = {
|
||||
id: string;
|
||||
pubkey: string;
|
||||
messageId: string;
|
||||
content: string;
|
||||
createdAt: number;
|
||||
};
|
||||
|
||||
const MAX_MESSAGES = 500;
|
||||
const MAX_REACTIONS = 2000;
|
||||
|
||||
const messages: StoredChatMessage[] = [];
|
||||
const reactions: StoredChatReaction[] = [];
|
||||
|
||||
export function listChat(): { messages: StoredChatMessage[]; reactions: StoredChatReaction[] } {
|
||||
return { messages: [...messages], reactions: [...reactions] };
|
||||
}
|
||||
|
||||
export function addMessage(input: {
|
||||
pubkey: string;
|
||||
content: string;
|
||||
replyToId?: string;
|
||||
replyToPubkey?: string;
|
||||
}): StoredChatMessage {
|
||||
const message: StoredChatMessage = {
|
||||
id: crypto.randomUUID(),
|
||||
pubkey: input.pubkey,
|
||||
content: input.content,
|
||||
createdAt: Math.floor(Date.now() / 1000),
|
||||
replyToId: input.replyToId ?? "",
|
||||
replyToPubkey: input.replyToPubkey ?? "",
|
||||
};
|
||||
messages.push(message);
|
||||
if (messages.length > MAX_MESSAGES) messages.splice(0, messages.length - MAX_MESSAGES);
|
||||
return message;
|
||||
}
|
||||
|
||||
export function addReaction(input: {
|
||||
pubkey: string;
|
||||
messageId: string;
|
||||
content: string;
|
||||
}): StoredChatReaction {
|
||||
const reaction: StoredChatReaction = {
|
||||
id: crypto.randomUUID(),
|
||||
pubkey: input.pubkey,
|
||||
messageId: input.messageId,
|
||||
content: input.content,
|
||||
createdAt: Math.floor(Date.now() / 1000),
|
||||
};
|
||||
reactions.push(reaction);
|
||||
if (reactions.length > MAX_REACTIONS) reactions.splice(0, reactions.length - MAX_REACTIONS);
|
||||
return reaction;
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import fs from "node:fs";
|
||||
import { config } from "./config.js";
|
||||
import { logger } from "./logger.js";
|
||||
import { authRouter } from "./auth/routes.js";
|
||||
import { chatRouter } from "./chat/routes.js";
|
||||
import { datumRouter } from "./datum/routes.js";
|
||||
import { errorHandler } from "./errors.js";
|
||||
|
||||
@@ -61,6 +62,7 @@ export function buildApp() {
|
||||
res.json({ ok: true });
|
||||
});
|
||||
app.use("/api/auth", authRouter);
|
||||
app.use("/api/chat", chatRouter);
|
||||
app.use("/api/datum", datumRouter);
|
||||
|
||||
const staticDir = config.staticDir
|
||||
|
||||
Reference in New Issue
Block a user