All checks were successful
Gitea Actions Demo / Explore-Gitea-Actions (push) Successful in 1m22s
92 lines
2.5 KiB
TypeScript
92 lines
2.5 KiB
TypeScript
import express from 'express';
|
||
import { getDraftForUser, saveDraftForUser } from './db.ts';
|
||
import { loginUser, logoutSession, registerUser, requireAuth, resolveSession } from './auth.ts';
|
||
import type { DraftPayload } from './types.ts';
|
||
|
||
const app = express();
|
||
const port = Number(process.env.PORT || 8787);
|
||
|
||
app.use(express.json({ limit: '10mb' }));
|
||
|
||
app.get('/api/health', (_req, res) => {
|
||
res.json({ ok: true });
|
||
});
|
||
|
||
app.post('/api/auth/register', (req, res) => {
|
||
const username = String(req.body?.username || '').trim();
|
||
const password = String(req.body?.password || '');
|
||
|
||
if (username.length < 3 || password.length < 6) {
|
||
res.status(400).json({ error: '瑯뵀逞<EBB580> 3 貫,쵱쯤逞<ECAFA4> 6 貫' });
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const result = registerUser(username, password);
|
||
res.json(result);
|
||
} catch (error) {
|
||
res.status(400).json({ error: error instanceof Error ? error.message : '鬧꿍呵겨' });
|
||
}
|
||
});
|
||
|
||
app.post('/api/auth/login', (req, res) => {
|
||
const username = String(req.body?.username || '').trim();
|
||
const password = String(req.body?.password || '');
|
||
|
||
if (!username || !password) {
|
||
res.status(400).json({ error: '헝渴흙瑯뵀뵨쵱쯤' });
|
||
return;
|
||
}
|
||
|
||
try {
|
||
const result = loginUser(username, password);
|
||
res.json(result);
|
||
} catch (error) {
|
||
res.status(401).json({ error: error instanceof Error ? error.message : '되쩌呵겨' });
|
||
}
|
||
});
|
||
|
||
app.get('/api/auth/session', (req, res) => {
|
||
const header = req.headers.authorization || '';
|
||
const token = header.startsWith('Bearer ') ? header.slice(7) : '';
|
||
if (!token) {
|
||
res.status(401).json({ error: '灌되쩌' });
|
||
return;
|
||
}
|
||
|
||
const user = resolveSession(token);
|
||
if (!user) {
|
||
res.status(401).json({ error: '되쩌綠呵槻' });
|
||
return;
|
||
}
|
||
|
||
res.json({ user });
|
||
});
|
||
|
||
app.post('/api/auth/logout', requireAuth, (req, res) => {
|
||
if (req.authToken) {
|
||
logoutSession(req.authToken);
|
||
}
|
||
res.json({ ok: true });
|
||
});
|
||
|
||
app.get('/api/draft/current', requireAuth, (req, res) => {
|
||
const draft = getDraftForUser(req.authUser!.id);
|
||
res.json({ draft });
|
||
});
|
||
|
||
app.post('/api/draft/current', requireAuth, (req, res) => {
|
||
const payload = req.body?.draft as DraftPayload | undefined;
|
||
if (!payload || typeof payload !== 'object') {
|
||
res.status(400).json({ error: '꿇멨코휭轟槻' });
|
||
return;
|
||
}
|
||
|
||
const draft = saveDraftForUser(req.authUser!.id, payload);
|
||
res.json({ draft });
|
||
});
|
||
|
||
app.listen(port, '127.0.0.1', () => {
|
||
console.log(`ScriptFlow server listening on http://127.0.0.1:${port}`);
|
||
});
|