aysec0/aysec

GitHub: aysec0/aysec

一套可自托管的全栈网络安全培训平台,集成课程管理、CTF 挑战赛、博客系统和付费订阅,开箱即用。

Stars: 0 | Forks: 0

# 个人站点 + 网络安全培训平台 包含网络安全培训平台的个人网站:免费 + 付费课程,CTF 带有评分/排行榜的挑战赛、博客/解题报告(writeup)、用户账户、进度 追踪以及 Stripe 结账。 **技术栈:** 原生 HTML/CSS/JS 前端 · Node.js + Express 后端 · SQLite (通过 `better-sqlite3`) · Stripe 支付 · HttpOnly cookie 中的 JWT 认证。 ## 快速开始 ``` cp .env.example .env # edit secrets npm install npm run db:init # creates ./data/app.db + seeds sample data npm run dev # → http://localhost:3000 ``` 默认管理员 (填充数据后):`admin` / `changeme` — 请立即修改。 ## 布局 ``` . ├── server.js # Express entry, mounts routes + static ├── db/ │ ├── schema.sql # Tables (users, courses, lessons, challenges, …) │ ├── index.js # better-sqlite3 connection + migrate() │ └── init.js # Run once: migrate + seed sample data ├── routes/ │ ├── auth.js # /api/auth/{register,login,logout,me} │ ├── courses.js # /api/courses, /api/courses/:slug │ ├── challenges.js # /api/challenges/*, leaderboard, flag submit │ ├── posts.js # /api/posts, /api/posts/:slug │ └── payments.js # Stripe checkout + webhook ├── middleware/ │ └── auth.js # JWT cookie helpers, requireAuth/requireAdmin └── public/ # Static frontend (vanilla) ├── index.html # Landing ├── courses.html # Course list (filters: free/paid/difficulty + search) ├── course-detail.html # Detail + lesson viewer (served at /courses/:slug) ├── challenges.html # CTF grid (filters: category + difficulty) + leaderboard ├── challenge-detail.html # Challenge + flag submit form (served at /challenges/:slug) ├── blog.html # Posts + writeups (filters: kind + search) ├── post-detail.html # Single post (served at /blog/:slug) ├── about.html ├── dashboard.html # User stats, enrolled courses w/ progress, recent solves ├── login.html, signup.html ├── 404.html # Terminal-style not-found ├── css/styles.css # Full design system in CSS variables ├── js/ │ ├── theme.js # Sets data-theme early to avoid FOUC │ ├── api.js # fetch wrapper + escapeHtml/fmtPrice/fmtDate helpers │ ├── layout.js # Injects navbar/footer + theme toggle + auth state │ ├── terminal.js # Hero typewriter (landing only) │ ├── main.js # Landing section loaders │ ├── auth.js # Login + signup form handling │ ├── courses-list.js # Course list page │ ├── course-detail.js # Course detail + lesson viewer │ ├── challenges-list.js # CTF list + leaderboard │ ├── challenge-detail.js # Challenge detail + flag submission │ ├── blog-list.js # Blog list │ ├── post-detail.js # Post detail (markdown HTML from API) │ └── dashboard.js # User dashboard └── img/favicon.svg ``` ## API 接口 (当前) | 方法 | 路径 | 认证 | 备注 | |--------|------------------------------------|--------|----------------------------------------| | POST | `/api/auth/register` | — | `{username, email, password}` | | POST | `/api/auth/login` | — | `{identifier, password}` (email 或 username) | | POST | `/api/auth/logout` | — | | | GET | `/api/auth/me` | 用户 | 返回当前用户 | | GET | `/api/courses` | — | 已发布的课程 | | GET | `/api/courses/:slug` | — | 课程 + 课时 + 访问标识 | | GET | `/api/challenges` | — | 已发布的挑战 (包含解决次数,你的解决标识) | | GET | `/api/challenges/:slug` | — | 挑战详情 | | POST | `/api/challenges/:slug/submit` | 用户 | `{flag}` — sha256 校验,限速 | | GET | `/api/challenges/leaderboard/top` | — | 前 50 名得分者 | | GET | `/api/posts` | — | `?kind=writeup` 进行筛选 | | GET | `/api/posts/:slug` | — | | | POST | `/api/payments/checkout` | 用户 | `{courseSlug}` → Stripe 结账 URL | | POST | `/api/payments/webhook` | Stripe | 在 `checkout.session.completed` 时授予访问权限 | ## 部署说明 - **本地 + VPS:** 开箱即用。SQLite 文件位于 `./data/app.db`。 - **Vercel / Netlify:** 本地 SQLite 文件在冷启动之间不会持久化。 替换为 **[Turso](https://turso.tech)** (兼容 SQLite 的无服务器数据库): - 将 `better-sqlite3` 替换为 `@libsql/client`。 - 在 `.env` 中设置 `TURSO_URL` + `TURSO_AUTH_TOKEN`。 - SQL 保持不变。 - **Stripe webhook URL:** `https://your-site/api/payments/webhook。` 将 `STRIPE_WEBHOOK_SECRET` 设置为你的 Stripe 仪表板中的签名密钥。 ## 路线图 **已完成** - [x] 基于 token 的主题 (深色 + 浅色),通过 `layout.js` 共享导航栏/页脚 - [x] 落地页 (hero / 关于 / 课程 / CTF / 排行榜 / 解题报告 / CTA) - [x] DB schema + 初始数据 (3 门课程,9 个课时,4 个挑战,3 篇文章) - [x] 认证:注册 / 登录 / 登出 / me / 仪表板 (HttpOnly cookie 中的 JWT) - [x] `/courses` + `/courses/:slug`,带有课时查看器 + 进度追踪 - [x] 免费课程自主注册,付费课程 Stripe 结账 - [x] 课时 + 文章的 Markdown 渲染 (通过 `marked`) - [x] `/challenges` + 筛选器 (分类,难度) + `/challenges/:slug` 包含 flag 提交,sha256 验证,5次/分钟限速,排行榜 - [x] `/blog` + 筛选器 + `/blog/:slug` (阅读时间,标签,复制链接) - [x] `/login`,`/signup` (验证,通过 `?next=` 实现登录后重定向) - [x] `/about`,`/dashboard` (统计数据,进行中的课程,最近的解决记录) - [x] 自定义 404 页面 **下一步** - [ ] 管理面板 (对课程、课时、挑战、文章进行 CRUD 操作) - [ ] 邮箱验证 + 密码重置 - [ ] 文章评论 (或外部 Discord 频道链接) - [ ] 博客的 RSS 订阅源 - [ ] 将数据库层切换至 Turso/libsql 以用于无服务器部署 - [ ] 文本代码块的语法高亮 (Prism / Shiki) - [ ] 一旦非管理员用户可以发帖,即对渲染的 markdown 进行 HTML 净化 (DOMPurify) ## 测试 ``` npm start # in one terminal node _scripts/smoke.mjs # 18 routes return 200 node _scripts/e2e.mjs # signup → flag → dashboard → leaderboard ``` ## 自定义 - **品牌 / 代号:** 在 `public/index.html`, `public/404.html`,`public/img/favicon.svg` 和 `db/init.js` 中找到 `aysec` 并替换。 - **颜色:** 全部定义在 `public/css/styles.css` 顶部的 `:root` 和 `[data-theme="light"]` 中。可在该处替换主题色 / 终端 / 分类颜色。 - **Hero 终端:** `public/js/terminal.js` — 编辑 `lines` 数组。 ## 许可证 个人项目。请在发布前选择相应的许可证。
标签:better-sqlite3, CEH认证, CRTO备考, CTF挑战, Express, GNU通用公共许可证, HttpOnly Cookie, JWT认证, MITM代理, Node.js, OSCP备考, OSEP备考, OSWE备考, PNPT备考, RESTful API, Security+认证, SQLite, Stripe支付集成, Syscall, Web安全, Web开发, 个人作品集, 个人网站, 免费与付费课程, 博客, 在线教育, 多模态安全, 学习路径, 安全认证, 实战靶场, 实验室工具箱, 技能档案, 排行榜, 提示词优化, 数据可视化, 活动日历, 游戏化学习, 漏洞复现报告, 用户账户, 等级系统, 纯HTML/CSS/JS, 经验值, 网络安全培训平台, 网络安全课程, 自定义脚本, 蓝队分析, 进度跟踪, 速查表