diff --git a/src/main.ts b/src/main.ts index 8c11810..710c130 100644 --- a/src/main.ts +++ b/src/main.ts @@ -23,6 +23,15 @@ async function setupDB() { created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); `); + await pool.query(` + CREATE TABLE IF NOT EXISTS saved ( + id SERIAL PRIMARY KEY, + user_id TEXT NOT NULL, + name TEXT NOT NULL, + data TEXT NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ); + `); } await setupDB(); @@ -32,7 +41,7 @@ app.use( cors({ origin: "*", allowHeaders: ["Content-Type", "Authorization"], - allowMethods: ["POST", "GET", "OPTIONS"], + allowMethods: ["POST", "PUT", "DELETE", "GET", "OPTIONS"], exposeHeaders: ["Content-Length"], maxAge: 600, credentials: true, @@ -138,6 +147,103 @@ if (process.env.REVIEWS_ENABLED) { }); } +app.get("/api/saved", async (c) => { + const authHeader = c.req.header("Authorization"); + if (!authHeader || !authHeader.startsWith("Bearer ")) { + return c.json({ error: "Unauthorized" }, 401); + } + const token = authHeader.split(" ")[1]; + if (!token) { + return c.json({ error: "Unauthorized" }, 401); + } + const isValid = await verifyToken(token); + if (!isValid) { + return c.json({ error: "Unauthorized" }, 401); + } + + const uid = await getTokenUID(token); + if (!uid) { + return c.json({ error: "Unauthorized" }, 401); + } + + const res = await pool.query( + "SELECT * FROM saved WHERE user_id = $1", + [uid], + ); + + return c.json(res.rows); +}) + +app.put("/api/saved", async (c) => { + const { name, data } = await c.req.json(); + if (!name || !data) { + return c.json( + { error: "name and data are required" }, + 400, + ); + } + + const authHeader = c.req.header("Authorization"); + if (!authHeader || !authHeader.startsWith("Bearer ")) { + return c.json({ error: "Unauthorized" }, 401); + } + const token = authHeader.split(" ")[1]; + if (!token) { + return c.json({ error: "Unauthorized" }, 401); + } + const isValid = await verifyToken(token); + if (!isValid) { + return c.json({ error: "Unauthorized" }, 401); + } + + const uid = await getTokenUID(token); + if (!uid) { + return c.json({ error: "Unauthorized" }, 401); + } + + const res = await pool.query( + "INSERT INTO saved (user_id, name, data) VALUES ($1, $2, $3) RETURNING *", + [uid, name, data], + ); + + return c.json(res.rows[0]); +}) + +app.delete("/api/saved", async (c) => { + const { name } = await c.req.json(); + if (!name) { + return c.json( + { error: "name is required" }, + 400, + ); + } + + const authHeader = c.req.header("Authorization"); + if (!authHeader || !authHeader.startsWith("Bearer ")) { + return c.json({ error: "Unauthorized" }, 401); + } + const token = authHeader.split(" ")[1]; + if (!token) { + return c.json({ error: "Unauthorized" }, 401); + } + const isValid = await verifyToken(token); + if (!isValid) { + return c.json({ error: "Unauthorized" }, 401); + } + + const uid = await getTokenUID(token); + if (!uid) { + return c.json({ error: "Unauthorized" }, 401); + } + + const res = await pool.query( + "DELETE FROM saved WHERE user_id = $1 AND name = $2", + [uid, name], + ); + + return c.json(res.rows[0]); +}) + if (process.env.TANKERKOENIG_API_KEY) { app.get("/api/fuel/list", async (c) => { // pass GET query parameters to the tankerkoenig API