A decentralized music tracking and discovery platform built on AT Protocol 馃幍
at fix/spotify 99 lines 2.2 kB view raw
1import { ctx } from "context"; 2import { eq } from "drizzle-orm"; 3import { Hono } from "hono"; 4import jwt from "jsonwebtoken"; 5import { env } from "lib/env"; 6import users from "schema/users"; 7import webscrobblers from "schema/webscrobblers"; 8import { v4 as uuid } from "uuid"; 9 10const app = new Hono(); 11 12app.get("/", async (c) => { 13 const bearer = (c.req.header("authorization") || "").split(" ")[1]?.trim(); 14 15 if (!bearer || bearer === "null") { 16 c.status(401); 17 return c.text("Unauthorized"); 18 } 19 20 const { did } = jwt.verify(bearer, env.JWT_SECRET, { 21 ignoreExpiration: true, 22 }); 23 24 const user = await ctx.client.db.users 25 .filter({ 26 $any: [{ did }, { handle: did }], 27 }) 28 .getFirst(); 29 if (!user) { 30 c.status(401); 31 return c.text("Unauthorized"); 32 } 33 34 const records = await ctx.db 35 .select() 36 .from(webscrobblers) 37 .leftJoin(users, eq(webscrobblers.userId, users.id)) 38 .where(eq(users.did, did)) 39 .execute(); 40 41 if (records.length === 0) { 42 const record = await ctx.client.db.webscrobblers.create({ 43 uuid: uuid(), 44 user_id: user.xata_id, 45 name: "webscrobbler", 46 }); 47 return c.json(record); 48 } 49 50 return c.json(records[0].webscrobblers); 51}); 52 53app.put("/:id", async (c) => { 54 const bearer = (c.req.header("authorization") || "").split(" ")[1]?.trim(); 55 const id = c.req.param("id"); 56 57 if (!bearer || bearer === "null") { 58 c.status(401); 59 return c.text("Unauthorized"); 60 } 61 62 const { did } = jwt.verify(bearer, env.JWT_SECRET, { 63 ignoreExpiration: true, 64 }); 65 66 const user = await ctx.client.db.users 67 .filter({ 68 $any: [{ did }, { handle: did }], 69 }) 70 .getFirst(); 71 if (!user) { 72 c.status(401); 73 return c.text("Unauthorized"); 74 } 75 76 if ( 77 !id.match(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/) 78 ) { 79 c.status(400); 80 return c.text("Invalid id"); 81 } 82 83 const existing = await ctx.client.db.webscrobblers 84 .filter({ user_id: user.xata_id }) 85 .getFirst(); 86 87 const record = await ctx.client.db.webscrobblers.createOrReplace( 88 existing?.xata_id, 89 { 90 uuid: id, 91 user_id: user.xata_id, 92 name: "webscrobbler", 93 }, 94 ); 95 96 return c.json(record); 97}); 98 99export default app;