# emmwaa **Repository Path**: quazero/emmwaa ## Basic Information - **Project Name**: emmwaa - **Description**: expressjs+mongodb+mailSTMP+jwtAuth+adminPanel+authAPI,极速开发Nodejs headless CMS无前端应用的脚手架,可节省50%以上的开发时间。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2021-12-14 - **Last Updated**: 2022-05-31 ## Categories & Tags **Categories**: Uncategorized **Tags**: Nodejs, Express, Mongoose, 管理面板, JWT ## README expressjs+mongodb+mailSTMP+jwtAuth+adminPanel+authAPI,极速开发Nodejs headless CMS无前端脚手架,直下直用,可节省50%以上的开发时间。 自用脚手架,一键搭建expressjs+mongodb+mailSTMP+jwtAuth+adminPanel+authAPI。 ## 更新日志 - 重写adminjs上传provider,支持跨平台上传处理。 - 重写adminjs中编辑器,替换成tiptap,支持html和markdown双语法,支持上传图片。 - 新增了blog博客的案例。 ## 运行方法: - git clone https://gitee.com/quazero/emmwaa - cd emmwaa - yarn - yarn dev - /v1/docs 可见内置API文档 - /admin 为内置管理面板 ## 特点(内置组件): - NoSQL数据库: MongoDB和Mongoose - 认证和授权: passport - 验证: Joi - 日志: winston和morgan - 测试: Jest - 错误处理: 集中式错误处理机制 - API文档: swagger-jsdoc和swagger-ui-express - 进程管理工具: PM2 - 依赖包处理: Yarn - 环境变量: dotenv 和 cross-env - 安全: helmet - 过滤: xss - CORS: cors - 压缩: compression - CI: Travis CI - Docker支持 - 代码覆盖: coveralls - 代码质量: Codacy - Git hooks: husky 和 lint-staged - Linting: ESLint 和 Prettier - 编辑器代码风格设置: EditorConfig 主要来源源码:https://github.com/hagopj13/node-express-boilerplate + https://github.com/SoftwareBrothers/adminjs ## 环境变量设置: 添加或修改.env文件 ``` # Port number PORT=3000 # URL of the Mongo DB MONGODB_URL=mongodb://127.0.0.1:27017/node-boilerplate # JWT # JWT secret key JWT_SECRET=thisisasamplesecret # Number of minutes after which an access token expires JWT_ACCESS_EXPIRATION_MINUTES=30 # Number of days after which a refresh token expires JWT_REFRESH_EXPIRATION_DAYS=30 # SMTP configuration options for the email service # For testing, you can use a fake SMTP service like Ethereal: https://ethereal.email/create SMTP_HOST=email-server SMTP_PORT=587 SMTP_USERNAME=email-server-username SMTP_PASSWORD=email-server-password EMAIL_FROM=support@yourapp.com ``` ## 文件结构: ``` src\ |--config\ # Environment variables and configuration related things |--controllers\ # Route controllers (controller layer) |--docs\ # Swagger files |--middlewares\ # Custom express middlewares |--models\ # Mongoose models (data layer) |--routes\ # Routes |--services\ # Business logic (service layer) |--utils\ # Utility classes and functions |--validations\ # Request data validation schemas |--app.js # Express app |--index.js # App entry point ``` ## API文档: 内置有认证和授权API ``` Auth routes: POST /v1/auth/register - register POST /v1/auth/login - login POST /v1/auth/refresh-tokens - refresh auth tokens POST /v1/auth/forgot-password - send reset password email POST /v1/auth/reset-password - reset password POST /v1/auth/send-verification-email - send verification email POST /v1/auth/verify-email - verify email User routes: POST /v1/users - create a user GET /v1/users - get all users GET /v1/users/:userId - get user PATCH /v1/users/:userId - update user DELETE /v1/users/:userId - delete user ``` ## 集中式错误处理: ``` const catchAsync = require('../utils/catchAsync'); const controller = catchAsync(async (req, res) => { // this error will be forwarded to the error handling middleware throw new Error('Something wrong happened'); }); ``` ### 内置ApiError类: ``` const httpStatus = require('http-status'); const ApiError = require('../utils/ApiError'); const User = require('../models/User'); const getUser = async (userId) => { const user = await User.findById(userId); if (!user) { throw new ApiError(httpStatus.NOT_FOUND, 'User not found'); } }; ``` ## 验证: 可参照joi的文档。验证schema在src/validations。 ``` const express = require('express'); const validate = require('../../middlewares/validate'); const userValidation = require('../../validations/user.validation'); const userController = require('../../controllers/user.controller'); const router = express.Router(); router.post('/users', validate(userValidation.createUser), userController.createUser); ``` ## 用户验证: ``` const express = require('express'); const auth = require('../../middlewares/auth'); const userController = require('../../controllers/user.controller'); const router = express.Router(); router.post('/users', auth(), userController.createUser); ``` ## 用户授权: ``` const express = require('express'); const auth = require('../../middlewares/auth'); const userController = require('../../controllers/user.controller'); const router = express.Router(); router.post('/users', auth('manageUsers'), userController.createUser); ``` ## 日志: ``` const logger = require('/config/logger'); logger.error('message'); // level 0 logger.warn('message'); // level 1 logger.info('message'); // level 2 logger.http('message'); // level 3 logger.verbose('message'); // level 4 logger.debug('message'); // level 5 ``` ## 内置Mongoose插件: ``` const mongoose = require('mongoose'); const { toJSON, paginate } = require('./plugins'); const userSchema = mongoose.Schema( { /* schema definition here */ }, { timestamps: true } ); userSchema.plugin(toJSON); userSchema.plugin(paginate); const User = mongoose.model('User', userSchema); ``` ### paginate: ``` const queryUsers = async (filter, options) => { const users = await User.paginate(filter, options); return users; }; //filter为mongodb检索条件 //options设置项如下 const options = { sortBy: 'name:desc', // sort order limit: 5, // maximum results per page page: 2, // page number }; //sortBy格式: name:desc,role:asc //返回 { "results": [], "page": 2, "limit": 5, "totalPages": 10, "totalResults": 48 } ``` ## Liting: 设置的文件:.eslintrc.json和.prettierrc.json. 过滤设置:.eslintignore和.prettierignore. 代码编写风格设置: .editorconfig ## 管理中心面板: 内置有admin管理面板,可自定义管理数据库表,在产品开发初期可直接免除开发管理后台的工序。 地址为ip:port/admin,利用邮箱和密码登录。 自定义管理面板文档:https://adminjs.co/ ### 截图: ![panbel](./panel.png)