Public Source Viewer

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

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

Redacted View
src/routes/train.routes.ts
공개 가능
1 import { Router, Request, Response } from 'express';
2 import fs from 'fs';
3 import path from 'path';
4 import { PUBLIC_DIR } from '../utils/paths';
5 import { getBookmarks, spendBookmarks } from '../services/bookmark.service';
6
7 const router = Router();
8
9 router.get('/hinana/train', function(req: Request, res: Response) {
10 const imageDir = path.join(PUBLIC_DIR, 'image');
11
12 let totalScenery = 0;
13
14 try {
15 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
16 [SECURITY REDACTED] 민감한 설정/인증/토큰 관련 코드입니다.
17 totalScenery = files.filter(file => /^scenery\d+\.png$/.test(file)).length;
18 } else {
19 console.error("이미지 폴더가 존재하지 않습니다:", imageDir);
20 totalScenery = 8;
21 }
22 } catch (err) {
23 console.error("이미지 폴더 읽기 실패:", err);
24 totalScenery = 8;
25 }
26
27 const username = req.session.username || null;
28 const trainType = (req.query.type as string) || 'hinana';
29
30 res.render('hinana/train', {
31 totalScenery: totalScenery,
32 username: username,
33 bookmarks: username ? getBookmarks(username) : 0,
34 trainType: trainType
35 });
36 });
37
38 router.post('/hinana/train/spend-bookmark', function(req: Request, res: Response) {
39 const username = req.session.username;
40 if (!username) {
41 return res.json({ success: false, needLogin: true });
42 }
43
44 const result = spendBookmarks(username, 1);
45 if (!result.success) {
46 return res.json({ success: false, insufficient: true, remaining: result.remaining });
47 }
48
49 return res.json({ success: true, remaining: result.remaining });
50 });
51
52 export default router;
53