import { parseCookies } from '../auth.mjs'; function wikiCookie(wikiAuth, token, secure) { const parts = [ `${wikiAuth.COOKIE_NAME}=${encodeURIComponent(token)}`, 'Path=/', 'HttpOnly', 'SameSite=Lax', 'Max-Age=604800', ]; if (secure) parts.push('Secure'); return parts.join('; '); } function clearWikiCookie(wikiAuth, secure) { const parts = [ `${wikiAuth.COOKIE_NAME}=`, 'Path=/', 'HttpOnly', 'SameSite=Lax', 'Max-Age=0', ]; if (secure) parts.push('Secure'); return parts.join('; '); } export function attachPortalWikiRoutes({ router, jsonBody, wikiAuth, isSecureRequest, parseCookiesFn = parseCookies, } = {}) { if ( !router || typeof jsonBody !== 'function' || !wikiAuth || typeof isSecureRequest !== 'function' || typeof parseCookiesFn !== 'function' ) { throw new Error( 'attachPortalWikiRoutes requires route dependencies', ); } router.use(jsonBody); router.post('/auth/register', (req, res) => { const { username, password, displayName, } = req.body || {}; if (!username || !password) { return res.status(400).json({ message: '用户名和密码不能为空', }); } const result = wikiAuth.register( username, password, displayName, ); if (!result.ok) { return res.status(409).json({ message: result.message, }); } return res.json({ ok: true, user: result.user, }); }); router.post('/auth/login', (req, res) => { const { username, password } = req.body || {}; if (!username || !password) { return res.status(400).json({ message: '用户名和密码不能为空', }); } const result = wikiAuth.login( username, password, ); if (!result.ok) { return res.status(401).json({ message: result.message, }); } const secure = isSecureRequest(req); res.set( 'Set-Cookie', wikiCookie(wikiAuth, result.token, secure), ); return res.json({ ok: true, user: result.user, }); }); router.post('/auth/logout', (req, res) => { const cookies = parseCookiesFn( req.get('cookie'), ); wikiAuth.revoke( cookies[wikiAuth.COOKIE_NAME], ); res.set( 'Set-Cookie', clearWikiCookie( wikiAuth, isSecureRequest(req), ), ); return res.json({ ok: true }); }); router.get('/auth/me', (req, res) => { const cookies = parseCookiesFn( req.get('cookie'), ); const session = wikiAuth.verify( cookies[wikiAuth.COOKIE_NAME], ); if (!session) { return res.json({ authenticated: false, user: null, }); } const user = wikiAuth.getUser( session.username, ); return res.json({ authenticated: true, user, }); }); function requireWikiAuth(req, res, next) { const cookies = parseCookiesFn( req.get('cookie'), ); const session = wikiAuth.verify( cookies[wikiAuth.COOKIE_NAME], ); if (!session) { return res.status(401).json({ message: '未登录', }); } req.wikiUser = session; next(); } router.get( '/pages', requireWikiAuth, (req, res) => { const { q } = req.query; if (q) { return res.json( wikiAuth.searchPages( req.wikiUser.username, q, ), ); } res.json( wikiAuth.listPages( req.wikiUser.username, ), ); }, ); router.get( '/pages/:slug', requireWikiAuth, (req, res) => { const page = wikiAuth.getPage( req.wikiUser.username, req.params.slug, ); if (!page) { return res.status(404).json({ message: '页面不存在', }); } res.json(page); }, ); router.post( '/pages/:slug', requireWikiAuth, (req, res) => { const { title, content, tags } = req.body || {}; const page = wikiAuth.savePage( req.wikiUser.username, req.params.slug, title, content, tags, ); res.json(page); }, ); router.delete( '/pages/:slug', requireWikiAuth, (req, res) => { wikiAuth.deletePage( req.wikiUser.username, req.params.slug, ); res.json({ ok: true }); }, ); }