Public Source Viewer
비나래아카이브 개발자 포털
실제 서비스 구조를 살펴볼 수 있는 공개용 코드 뷰어입니다. 인증, 세션, 외부 연동, 토큰, 관리자 식별 등 보안상 민감한 구현은 파일 단위 또는 줄 단위로 검열됩니다.
src/routes/end.routes.ts
공개 가능
1
import { Router, Request, Response } from 'express';
2
import fs from 'fs';
3
import { v4 as uuidv4 } from 'uuid';
4
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
5
6
const router = Router();
7
8
function getEntries(): any[] {
9
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
10
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
11
}
12
13
function saveEntries(entries: any[]): void {
14
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
15
}
16
17
// end.hinana.moe 전용 미들웨어
18
router.use((req: Request, res: Response, next) => {
19
const host = req.hostname;
20
if (host === 'end.hinana.moe' || host === 'end.localhost') return next();
21
return next('router');
22
});
23
24
// 목록
25
router.get('/', (req: Request, res: Response) => {
26
const entries = getEntries()
27
.filter((e: any) => e.visible !== false)
28
.sort((a: any, b: any) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
29
res.render('end/index', {
30
entries,
31
username: req.session.username || null,
32
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
33
});
34
});
35
36
// 글 읽기
37
router.get('/entry/:id', (req: Request, res: Response) => {
38
const entry = getEntries().find((e: any) => e.id === req.params.id);
39
if (!entry || entry.visible === false) return res.status(404).render('end/404', {});
40
res.render('end/entry', {
41
entry,
42
username: req.session.username || null,
43
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
44
});
45
});
46
47
// underground 페이지
48
router.get('/underground', (req: Request, res: Response) => {
49
res.render('end/underground', {
50
username: req.session.username || null,
51
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
52
});
53
});
54
55
// reverse 페이지
56
router.get('/reverse', (req: Request, res: Response) => {
57
res.render('end/reverse', {
58
username: req.session.username || null,
59
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
60
});
61
});
62
63
// 글쓰기 폼 (관리자 전용)
64
router.get('/write', (req: Request, res: Response) => {
65
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
66
res.render('end/write', { username: req.session.username });
67
});
68
69
// 글쓰기 저장 (관리자 전용)
70
router.post('/write', (req: Request, res: Response) => {
71
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
72
const { title, content, mood } = req.body;
73
if (!title || !content) return res.redirect('/write');
74
const entries = getEntries();
75
const newEntry = {
76
id: uuidv4(),
77
title: String(title).trim(),
78
content: String(content).trim(),
79
excerpt: String(content).trim().replace(/\n+/g, ' ').substring(0, 80),
80
mood: mood || 'melancholic',
81
visible: true,
82
createdAt: new Date().toISOString()
83
};
84
entries.push(newEntry);
85
saveEntries(entries);
86
res.redirect(`/entry/${newEntry.id}`);
87
});
88
89
// 글 삭제 (관리자 전용)
90
router.post('/delete/:id', (req: Request, res: Response) => {
91
[SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
92
const entries = getEntries().filter((e: any) => e.id !== req.params.id);
93
saveEntries(entries);
94
res.redirect('/');
95
});
96
97
export default router;
98