部分接口增加google recaptcha
This commit is contained in:
parent
49c02ca3d3
commit
50011f1eaf
@ -46,3 +46,6 @@ export const SCORE_GAME_STEP = 'game_step'
|
|||||||
export const SCORE_SOCIAL_TASK = 'Social Tasks'
|
export const SCORE_SOCIAL_TASK = 'Social Tasks'
|
||||||
// 积分类型-邀请用户额外收益
|
// 积分类型-邀请用户额外收益
|
||||||
export const SCORE_INVITE_REBATE = 'invite_rebate'
|
export const SCORE_INVITE_REBATE = 'invite_rebate'
|
||||||
|
|
||||||
|
// google reCaptcha最小分数
|
||||||
|
export const RECAPTCHA_MIN_SCORE = 0.5
|
||||||
|
@ -5,6 +5,7 @@ import { BaseController, ROLE_ANON, SyncLocker, ZError, ZRedisClient, role, rout
|
|||||||
import { ScoreRecord } from 'models/ScoreRecord'
|
import { ScoreRecord } from 'models/ScoreRecord'
|
||||||
import { formatAddress } from 'zutils/utils/chain.util'
|
import { formatAddress } from 'zutils/utils/chain.util'
|
||||||
import { isValidShareCode } from 'common/Utils'
|
import { isValidShareCode } from 'common/Utils'
|
||||||
|
import { checkReCaptcha } from 'services/google.svr'
|
||||||
|
|
||||||
const MAX_LIMIT = 100
|
const MAX_LIMIT = 100
|
||||||
export default class ActivityController extends BaseController {
|
export default class ActivityController extends BaseController {
|
||||||
@ -30,6 +31,7 @@ export default class ActivityController extends BaseController {
|
|||||||
@router('post /api/activity/upload_invite_code')
|
@router('post /api/activity/upload_invite_code')
|
||||||
async uploadInviteCode(req) {
|
async uploadInviteCode(req) {
|
||||||
new SyncLocker().checkLock(req)
|
new SyncLocker().checkLock(req)
|
||||||
|
await checkReCaptcha(req, 'invite_user')
|
||||||
let { code } = req.params
|
let { code } = req.params
|
||||||
if (!isValidShareCode(code)) {
|
if (!isValidShareCode(code)) {
|
||||||
throw new ZError(11, 'invalid invite code')
|
throw new ZError(11, 'invalid invite code')
|
||||||
|
@ -9,6 +9,7 @@ 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'
|
import { isObjectIdString, isValidShareCode } from 'common/Utils'
|
||||||
|
import { checkReCaptcha } from 'services/google.svr'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 宝箱相关接口
|
* 宝箱相关接口
|
||||||
@ -94,6 +95,7 @@ class BoxController extends BaseController {
|
|||||||
@router('post /api/chest/enhance')
|
@router('post /api/chest/enhance')
|
||||||
async enhance(req) {
|
async enhance(req) {
|
||||||
new SyncLocker().checkLock(req)
|
new SyncLocker().checkLock(req)
|
||||||
|
await checkReCaptcha(req, 'chest_share')
|
||||||
const { code } = req.params
|
const { code } = req.params
|
||||||
const user = req.user
|
const user = req.user
|
||||||
const uid = user.id
|
const uid = user.id
|
||||||
|
@ -37,6 +37,9 @@ export async function checkJoinGuld(guid: string, uid: string) {
|
|||||||
if (res.code === 10013) {
|
if (res.code === 10013) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if (res.code) {
|
||||||
|
throw new Error(res.message)
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false
|
return false
|
||||||
@ -54,6 +57,10 @@ export async function checkGotRole(guid: string, uid: string, roleId: string) {
|
|||||||
if (res.code === 10013) {
|
if (res.code === 10013) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if (res.code) {
|
||||||
|
// 如果有其他错误, 直接抛出异常, 让客户端重试
|
||||||
|
throw new Error(res.message)
|
||||||
|
}
|
||||||
if (res.roles.includes(roleId)) {
|
if (res.roles.includes(roleId)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
27
src/services/google.svr.ts
Normal file
27
src/services/google.svr.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { RECAPTCHA_MIN_SCORE } from 'common/Constants'
|
||||||
|
import { ZError } from 'zutils'
|
||||||
|
|
||||||
|
export const checkReCaptcha = async (req: any, action: string) => {
|
||||||
|
if (!(process.env.NEED_RECAPTCHA && process.env.NEED_RECAPTCHA === '1')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { rtoken } = req.params
|
||||||
|
if (!rtoken) {
|
||||||
|
throw new ZError(50, 'reCaptcha token is required')
|
||||||
|
}
|
||||||
|
const url = `https://www.google.com/recaptcha/api/siteverify?secret=${process.env.RECAPTCHA_SECRET}&response=${rtoken}`
|
||||||
|
const response = await fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
})
|
||||||
|
const data = await response.json()
|
||||||
|
if (!data.success) {
|
||||||
|
throw new ZError(51, `reCaptcha invalid`)
|
||||||
|
}
|
||||||
|
if (data.action !== action) {
|
||||||
|
throw new ZError(52, `reCaptcha action invalid`)
|
||||||
|
}
|
||||||
|
if (data.score < RECAPTCHA_MIN_SCORE) {
|
||||||
|
throw new ZError(53, `reCaptcha score invalid`)
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user