增强提交参数的检查

This commit is contained in:
CounterFire2023 2024-03-27 17:02:27 +08:00
parent 8ea3064744
commit 24efac0604
5 changed files with 37 additions and 8 deletions

View File

9
src/common/Utils.ts Normal file
View File

@ -0,0 +1,9 @@
export const isObjectIdString = (str: string) => {
return /^[0-9a-fA-F]{24}$/.test(str)
}
// check if a string is a valid share code
// alphabet:'3fBCM8j17XNA9xYun4wmLWep2oHFlhPcgyEJskqOz6GK0UtV5ZRaDSvrTbidQI'
export const isValidShareCode = (str: string) => {
return /^[3fBCM8j17XNA9xYun4wmLWep2oHFlhPcgyEJskqOz6GK0UtV5ZRaDSvrTbidQI]{10}$/.test(str)
}

View File

@ -6,6 +6,7 @@ import { ScoreRecord } from 'models/ScoreRecord'
import { formatAddress } from 'zutils/utils/chain.util' import { formatAddress } from 'zutils/utils/chain.util'
import { formatDate } from 'zutils/utils/date.util' import { formatDate } from 'zutils/utils/date.util'
import { SCORE_INVITE_INVITEE, SCORE_INVITE_USER } from 'common/Constants' import { SCORE_INVITE_INVITEE, SCORE_INVITE_USER } from 'common/Constants'
import { isValidShareCode } from 'common/Utils'
const shareCfg = require('../../configs/share_cfg.json') const shareCfg = require('../../configs/share_cfg.json')
const MAX_LIMIT = 100 const MAX_LIMIT = 100
@ -33,6 +34,9 @@ export default class ActivityController extends BaseController {
async uploadInviteCode(req) { async uploadInviteCode(req) {
new SyncLocker().checkLock(req) new SyncLocker().checkLock(req)
let { code } = req.params let { code } = req.params
if (!isValidShareCode(code)) {
throw new ZError(11, 'invalid invite code')
}
let user = req.user let user = req.user
if (user.inviteUser) { if (user.inviteUser) {
throw new ZError(11, 'invite user already set') throw new ZError(11, 'invite user already set')

View File

@ -8,6 +8,7 @@ import { ChestRecord } from 'models/chain/ChestRecord'
import { generateNewChest } from 'services/game.svr' import { generateNewChest } from 'services/game.svr'
import { SCORE_OPEN_CHEST } from 'common/Constants' import { SCORE_OPEN_CHEST } from 'common/Constants'
import { formatAddress } from 'zutils/utils/chain.util' import { formatAddress } from 'zutils/utils/chain.util'
import { isObjectIdString, isValidShareCode } from 'common/Utils'
/** /**
* *
@ -45,8 +46,8 @@ class BoxController extends BaseController {
const user = req.user const user = req.user
let { chestId, chestid } = req.params let { chestId, chestid } = req.params
chestid = chestId || chestid chestid = chestId || chestid
if (!chestid) { if (!isObjectIdString(chestid)) {
throw new ZError(11, 'chestId is required') throw new ZError(11, 'must provide valid chestid')
} }
const chest = await ActivityChest.findById(chestid) const chest = await ActivityChest.findById(chestid)
if (!chest) { if (!chest) {
@ -84,20 +85,26 @@ class BoxController extends BaseController {
const { code } = req.params const { code } = req.params
const user = req.user const user = req.user
const uid = user.id const uid = user.id
if (!isValidShareCode(code)) {
throw new ZError(11, 'invalid share code')
}
// TODO:: 待规则确定后, 检查用户是否符合助力条件 // TODO:: 待规则确定后, 检查用户是否符合助力条件
const chest = await ActivityChest.findOne({ shareCode: code, activity: user.activity }) const chest = await ActivityChest.findOne({ shareCode: code, activity: user.activity })
if (!chest) {
throw new ZError(12, 'chest not found')
}
if (chest.bonusUsers.includes(uid)) { if (chest.bonusUsers.includes(uid)) {
throw new ZError(10, 'user already enhanced') throw new ZError(10, 'user already enhanced')
} }
if (chest.bonusUsers.length >= chest.maxBounsCount) { if (chest.bonusUsers.length >= chest.maxBounsCount) {
throw new ZError(12, 'enhanced times exceed') throw new ZError(13, 'enhanced times exceed')
} }
if (chest.status === ChestStatusEnum.OPENED) { if (chest.status === ChestStatusEnum.OPENED) {
throw new ZError(13, 'chest already opened') throw new ZError(14, 'chest already opened')
} }
if (chest.status === ChestStatusEnum.LOCKED) { if (chest.status === ChestStatusEnum.LOCKED) {
throw new ZError(14, 'chest is locked') throw new ZError(15, 'chest is locked')
} }
// 生产环境不能助力自己 // 生产环境不能助力自己
if (process.env.NODE_ENV === 'production' && chest.user === uid) { if (process.env.NODE_ENV === 'production' && chest.user === uid) {
@ -141,8 +148,8 @@ class BoxController extends BaseController {
new SyncLocker().checkLock(req) new SyncLocker().checkLock(req)
const user = req.user const user = req.user
const { chestId } = req.params const { chestId } = req.params
if (!chestId) { if (!isObjectIdString(chestId)) {
throw new ZError(11, 'chestId is required') throw new ZError(11, 'must provide valid chestId')
} }
const openRecord = await ChestRecord.findOne({ from: user.address.toLowerCase(), chestId }) const openRecord = await ChestRecord.findOne({ from: user.address.toLowerCase(), chestId })
if (!openRecord) { if (!openRecord) {

View File

@ -73,10 +73,13 @@ class GameController extends BaseController {
new SyncLocker().checkLock(req) new SyncLocker().checkLock(req)
const user = req.user const user = req.user
let { days } = req.params let { days } = req.params
if (!days) { if (!days || isNaN(days)) {
throw new ZError(11, 'invalid days') throw new ZError(11, 'invalid days')
} }
days = parseInt(days) days = parseInt(days)
if (days < 1) {
throw new ZError(12, 'invalid days')
}
const dateTag = formatDate(new Date()) const dateTag = formatDate(new Date())
const checkRecord = await checkInToday(user.address.toLowerCase(), dateTag) const checkRecord = await checkInToday(user.address.toLowerCase(), dateTag)
if (!checkRecord) { if (!checkRecord) {
@ -198,7 +201,11 @@ class GameController extends BaseController {
if (isNaN(step)) { if (isNaN(step)) {
throw new ZError(11, 'invalid step') throw new ZError(11, 'invalid step')
} }
// check if step is safe int
step = parseInt(step) step = parseInt(step)
if (step < 1) {
step = 1
}
// const session = await mongoose.startSession() // const session = await mongoose.startSession()
// session.startTransaction() // session.startTransaction()
// try { // try {
@ -227,6 +234,8 @@ class GameController extends BaseController {
updateData.maxNoChestCount = 0 updateData.maxNoChestCount = 0
const level = generateChestLevel() const level = generateChestLevel()
chests.push(generateNewChest(user.id, user.activity, level, ChestStatusEnum.NORMAL)) chests.push(generateNewChest(user.id, user.activity, level, ChestStatusEnum.NORMAL))
} else {
updateData['$inc']['maxNoChestCount'] = step
} }
} }
await ActivityGame.updateOne({ user: user.id, activity: user.activity }, updateData) await ActivityGame.updateOne({ user: user.id, activity: user.activity }, updateData)