diff --git a/src/controllers/sign.controller.ts b/src/controllers/sign.controller.ts index 4d7e914..91df4c1 100644 --- a/src/controllers/sign.controller.ts +++ b/src/controllers/sign.controller.ts @@ -3,9 +3,11 @@ import { DEFAULT_EXPIRED, NonceRecord } from 'modules/NonceRecord' import { SiweMessage } from 'siwe' import { checkParamsNeeded } from 'zutils/utils/net.util' import { BaseController, role, ROLE_ANON, router, ZError } from 'zutils' +import { checkNonce } from 'plats/PlatExternalWallet' const LOGIN_TIP = 'This signature is just to verify your identity' + class SignController extends BaseController { @role(ROLE_ANON) @router('get /wallet/third/nonce') @@ -20,21 +22,21 @@ class SignController extends BaseController { async walletVerify(req, res) { const { signature, message } = req.params checkParamsNeeded(signature, message) - if (!message.nonce) { - throw new ZError(11, 'Invalid nonce') + checkNonce(message.nonce) + if (message.nonce.length === 24) { + let record = await NonceRecord.findById(message.nonce) + if (!record || record.status !== 0) { + throw new ZError(12, 'nonce invalid') + } + if (record.expired < Date.now()) { + throw new ZError(13, 'nonce expired') + } + record.status = 1 + await record.save() } - let record = await NonceRecord.findById(message.nonce) - if (!record || record.status !== 0) { - throw new ZError(12, 'nonce invalid') - } - if (record.expired < Date.now()) { - throw new ZError(13, 'nonce expired') - } - record.status = 1 - await record.save() const msgSign = new SiweMessage(message) try { - await msgSign.verify({ signature, nonce: record.id }) + await msgSign.verify({ signature, nonce: message.nonce }) } catch (e) { throw new ZError(14, 'signature invalid') } diff --git a/src/plats/PlatExternalWallet.ts b/src/plats/PlatExternalWallet.ts index 729c0e7..ac47212 100644 --- a/src/plats/PlatExternalWallet.ts +++ b/src/plats/PlatExternalWallet.ts @@ -7,27 +7,43 @@ import { DocumentType } from '@typegoose/typegoose' import { AccountClass } from 'modules/Account' import { Wallet } from 'modules/Wallet' +// check if none is hex string with 24 length, or is timestamp within 5 minutes +export const checkNonce = (nonce: string) => { + if (!nonce) { + throw new ZError(11, 'Invalid nonce') + } + // use regex to check if nonce is 24 length hex string + if (nonce.length === 13) { + const timestamp = parseInt(nonce) + if (Date.now() - timestamp > 5 * 60 * 1000) { + throw new ZError(13, 'nonce expired') + } + } else { + if (!/^[0-9a-f]{24}$/.test(nonce)) { + throw new ZError(11, 'Invalid nonce.') + } + } +} export class PlatExternalWallet implements IPlat { async verifyToken(req: any): Promise { // here code is signature let { code, message } = req.params checkParamsNeeded(code, message) - if (!message.nonce) { - throw new ZError(11, 'Invalid nonce') + checkNonce(message.nonce) + if (message.nonce.length === 24) { + let record = await NonceRecord.findById(message.nonce) + if (!record || record.status !== 0) { + throw new ZError(12, 'nonce invalid') + } + if (record.expired < Date.now()) { + throw new ZError(13, 'nonce expired') + } + record.status = 1 + await record.save() } - - let record = await NonceRecord.findById(message.nonce) - if (!record || record.status !== 0) { - throw new ZError(12, 'nonce invalid') - } - if (record.expired < Date.now()) { - throw new ZError(13, 'nonce expired') - } - record.status = 1 - await record.save() const msgSign = new SiweMessage(message) try { - await msgSign.verify({ signature: code, nonce: record.id }) + await msgSign.verify({ signature: code, nonce: message.nonce }) } catch (e) { throw new ZError(14, 'signature invalid') }