You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 lines
2.1 KiB
JavaScript

import crypto from 'crypto'
import bodyParser from 'body-parser'
import cookieParser from 'cookie-parser'
import express from 'express'
import { authMiddleware, PingRouter, StatusRouter } from './middlewares.js'
import { createDatabase, getUser, updateUser } from './db/database.js'
import { initialDatabaseValue } from './db/example-data.js'
export async function createApiRouter() {
const sessions = {
store: {},
createSession(username) {
const sid = crypto.randomBytes(10).toString('hex')
this.store[sid] = username
return sid
},
getUserForSession(sid) {
return this.store[sid] ?? null
},
}
const db = createDatabase('./db.local.json', initialDatabaseValue)
const r = express.Router()
r.use(bodyParser.json())
r.use(cookieParser())
r.use(authMiddleware(sid => sessions.getUserForSession(sid)))
r.use('/api/status', new StatusRouter())
r.use('/api/ping', new PingRouter())
r.get('/api/current-user', async (req, res) => {
const userId = sessions.getUserForSession(req.cookies.sid)
if (!userId) {
res.cookie('sid', '', { expires: new Date() })
res.status(400)
res.end('Invalid session token')
return
}
const user = await getUser(db, userId)
res.json({
username: userId,
...user,
})
})
r.post('/api/login', (req, res) => {
const { username } = req.body
res.cookie('sid', sessions.createSession(username), { maxAge: 1000 * 60 * 60 * 24 * 7 })
res.json({ status: 'ok' })
})
r.post('/api/logout', (req, res) => {
res.cookie('sid', '', { expires: new Date() })
res.json({ status: 'ok' })
})
r.get('/api/user/:id', async (req, res) => {
const user = await getUser(db, req.params.id)
if (user) {
res.json(user)
} else {
res.sendStatus(404)
}
})
r.post('/api/user/:id', async (req, res) => {
await updateUser(db, req.params.id, req.body)
res.sendStatus(200)
})
return r
}