|
| 1 | +import type { FastifyInstance } from "fastify"; |
| 2 | +import crypto from "node:crypto"; |
| 3 | +import { z } from "zod"; |
| 4 | + |
| 5 | +export async function anonymousRoutes(fastify: FastifyInstance) { |
| 6 | + |
| 7 | + const bodySchema = z.object({ |
| 8 | + userId: z.string().uuid(), |
| 9 | + threadId: z.string().uuid(), |
| 10 | + password: z.string().min(1), |
| 11 | + }); |
| 12 | + |
| 13 | + |
| 14 | + const animals = [ |
| 15 | + "Tiger", "Wolf", "Falcon", "Panther", "Phoenix", "Leopard", "Eagle", "Raven", |
| 16 | + "Cobra", "Viper", "Hawk", "Dragon", "Lynx", "Jaguar", "Shark", "Stallion", |
| 17 | + "Owl", "Rhino", "Bear", "Panda", "Griffin", "Kraken", "Hydra", "Fox", |
| 18 | + "Bison", "Cheetah", "Gorilla", "Turtle", "Scorpion", "Mantis", |
| 19 | + ]; |
| 20 | + |
| 21 | + const adjectives = [ |
| 22 | + "Shadow", "Silent", "Ghost", "Crimson", "Blue", "Iron", "Night", "Frost", |
| 23 | + "Storm", "Electric", "Golden", "Cyber", "Wild", "Atomic", "Nebula", "Lunar", |
| 24 | + "Solar", "Thunder", "Noble", "Brave", "Swift", "Hidden", "Obsidian", "Phantom", |
| 25 | + "Radiant", "Mystic", "Silver", "Scarlet", "Feral", "Arcane", |
| 26 | + ]; |
| 27 | + |
| 28 | + fastify.post("/anon-name", async (request, reply) => { |
| 29 | + const parsed = bodySchema.safeParse(request.body); |
| 30 | + |
| 31 | + if (!parsed.success) { |
| 32 | + return reply.status(400).send({ |
| 33 | + success: false, |
| 34 | + error: "Invalid userId, threadId, or password", |
| 35 | + }); |
| 36 | + } |
| 37 | + |
| 38 | + const { userId, threadId, password } = parsed.data; |
| 39 | + |
| 40 | + try { |
| 41 | + const seed = `${userId}-${threadId}`; |
| 42 | + |
| 43 | + const hash = crypto |
| 44 | + .createHmac("sha256", password) |
| 45 | + .update(seed) |
| 46 | + .digest("hex"); |
| 47 | + |
| 48 | + const adjIndex = parseInt(hash.substring(0, 8), 16) % adjectives.length; |
| 49 | + const animalIndex = parseInt(hash.substring(8, 16), 16) % animals.length; |
| 50 | + const num = parseInt(hash.substring(16, 20), 16) % 100; |
| 51 | + |
| 52 | + const anonName = `${adjectives[adjIndex]}${animals[animalIndex]}${num}`; |
| 53 | + |
| 54 | + return reply.status(200).send({ |
| 55 | + success: true, |
| 56 | + anonName, |
| 57 | + }); |
| 58 | + } catch (err) { |
| 59 | + fastify.log.error(err); |
| 60 | + return reply.status(500).send({ |
| 61 | + success: false, |
| 62 | + error: "Server error generating anonymous name", |
| 63 | + }); |
| 64 | + } |
| 65 | + }); |
| 66 | +} |
0 commit comments