fix: audit fixes for registration flow

- loadProfile() now returns Promise (was missing return)
- Avatar upload via COS instead of storing WeChat temp path
- Add POST /user/avatar endpoint with multer + COS SDK
- Incomplete registration detection: redirect to register if phone is empty
这个提交包含在:
Guoguo
2026-05-06 06:18:21 -07:00
父节点 2f6ab74eab
当前提交 52456d850e
修改 6 个文件,包含 185 行新增5 行删除
+23
查看文件
@@ -1,11 +1,15 @@
const router = require('express').Router()
const multer = require('multer')
const COS = require('cos-nodejs-sdk-v5')
const { ok, fail } = require('../lib/response')
const { requireUser } = require('../middleware/auth')
const { getPhoneNumber } = require('../lib/wechat')
const config = require('../config')
const userDao = require('../dao/user.dao')
const deviceDao = require('../dao/device.dao')
const logDao = require('../dao/log.dao')
const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 2 * 1024 * 1024 } })
const wrap = fn => (req, res, next) => fn(req, res, next).catch(next)
router.get('/user/profile', requireUser, wrap(async (req, res) => {
@@ -32,6 +36,25 @@ router.put('/user/profile', requireUser, wrap(async (req, res) => {
res.json(ok({ message: 'success' }))
}))
router.post('/user/avatar', requireUser, upload.single('file'), wrap(async (req, res) => {
if (!req.file) return res.json(fail(2001, 'file required'))
const ext = (req.file.originalname || '').split('.').pop() || 'jpg'
const key = 'avatars/' + req.user.user_id + '_' + Date.now() + '.' + ext
const cos = new COS({ SecretId: config.cos.secretId, SecretKey: config.cos.secretKey })
const result = await new Promise((resolve, reject) => {
cos.putObject({
Bucket: config.cos.bucket,
Region: config.cos.region,
Key: key,
Body: req.file.buffer,
ContentType: req.file.mimetype
}, (err, data) => err ? reject(err) : resolve(data))
})
const avatarUrl = 'https://' + config.cos.bucket + '.cos.' + config.cos.region + '.myqcloud.com/' + key
await userDao.updateProfile(req.user.user_id, { nickname: null, avatar: avatarUrl, gender: null })
res.json(ok({ avatar: avatarUrl }))
}))
router.post('/user/phone', requireUser, wrap(async (req, res) => {
const code = String(req.body.code || '').trim()
if (!code) return res.json(fail(2001, 'phone code required'))