Public Source Viewer

비나래아카이브 개발자 포털

실제 서비스 구조를 살펴볼 수 있는 공개용 코드 뷰어입니다. 인증, 세션, 외부 연동, 토큰, 관리자 식별 등 보안상 민감한 구현은 파일 단위 또는 줄 단위로 검열됩니다.

Redacted View
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