注册锁

This commit is contained in:
chaosBreaking
2019-10-02 13:35:25 +08:00
parent 9cf8795fa4
commit 298d3da92d
2 changed files with 76 additions and 97 deletions

View File

@@ -5,7 +5,9 @@ const User = require('../user/user.model');
const { createNewUser } = require('../user/user.handler'); const { createNewUser } = require('../user/user.handler');
const Code = require('../msgCode/msgCode.controller'); const Code = require('../msgCode/msgCode.controller');
const Fund = require('../fund/fund.model'); const Fund = require('../fund/fund.model');
const Lock = require('../../utils/mutexlock');
const lock = new Lock();
const CODE_TYPE = Code.CODE_TYPE; const CODE_TYPE = Code.CODE_TYPE;
const msgCodeSignIn = async function (phone, code) { const msgCodeSignIn = async function (phone, code) {
const validCode = await Code.verifyCode({ id: phone, code, type: CODE_TYPE['msgSignIn'] }); const validCode = await Code.verifyCode({ id: phone, code, type: CODE_TYPE['msgSignIn'] });
@@ -13,6 +15,7 @@ const msgCodeSignIn = async function (phone, code) {
phone, phone,
}).exec() : null; }).exec() : null;
}; };
const phoneRegCN = /^\+86-[1]([3-9])[0-9]{9}$/;
module.exports = { module.exports = {
checkExist: async function (req, res) { checkExist: async function (req, res) {
@@ -46,7 +49,7 @@ module.exports = {
const token = createToken({ const token = createToken({
userId: user.id userId: user.id
}, JWT_SECRET, {}); }, JWT_SECRET, {});
res.json({ return res.json({
code: 0, code: 0,
msg: 'success', msg: 'success',
data: { data: {
@@ -58,7 +61,7 @@ module.exports = {
} }
}); });
} else { } else {
res.json({ return res.json({
code: 1, code: 1,
error: 'unknow user', error: 'unknow user',
msg: '账号或密码错误' msg: '账号或密码错误'
@@ -69,116 +72,71 @@ module.exports = {
signUpReqInviter: inject(function(SysConfig) { signUpReqInviter: inject(function(SysConfig) {
const { JWT_SECRET, PWD_HASH_SALT } = SysConfig; const { JWT_SECRET, PWD_HASH_SALT } = SysConfig;
return async (req, res) => { return async (req, res) => {
return res.json({ // return res.json({
code: 404, // code: 404,
msg: '暂停注册' // msg: '暂停注册'
}); // });
let { phone, code, inviter, password } = req.body; let { phone, code, inviter, password } = req.body;
if (!phone || !code || !password || !inviter) return res.json({ if (!phone || !code || !password || !inviter) return res.json({
code: 1, code: 1,
msg: 'Missing required parameters' msg: 'Missing required parameters'
}); });
const exist = await User.exists({ phone }); phone = String.prototype.trim.call(phone);
if (exist) return res.json({ const isValidPhone = phone.startsWith('+86-') ? phoneRegCN.test(phone) : true; //国际手机暂不检测
code: 1, if (!isValidPhone) return res.json({
msg: '' code: 5,
msg: 'Invalid phone',
}); });
let validInviter = ''; const isValidCode = await Code.verifyCode({ id: phone, code, type: CODE_TYPE['signUp'] });
if (inviter === 'AlUx9h!w0)y9') { if (!isValidCode) {
validInviter = { id: 'AlUx9h!w0)y9' }; return res.json({
} code: 2,
else { msg: 'Invalid code',
const invitePhone = '+86-' + parseInt(inviter, 36);
validInviter = await User.findOne({ phone: invitePhone }).catch(null);
if (!validInviter) return res.json({
code: 4,
msg: '邀请人不存在'
}); });
} }
const isCodeValid = await Code.verifyCode({ id: phone, code, type: CODE_TYPE['signUp'] }); let validInviter = '';
const invitePhone = '+86-' + parseInt(inviter, 36);
validInviter = await User.findOne({ phone: invitePhone }).catch(null);
if (!validInviter) return res.json({
code: 4,
msg: '邀请人不存在'
});
const exist = await User.exists({ phone });
if (exist || (!exist && !lock.acquire(phone))) return res.json({
code: 1,
msg: '重复注册'
});
password = Crypto.hash(password, { salt: PWD_HASH_SALT }); password = Crypto.hash(password, { salt: PWD_HASH_SALT });
const newInviteCode = typeof phone === 'string' && parseInt(phone.split('-')[1]).toString(36); const newInviteCode = typeof phone === 'string' && parseInt(phone.split('-')[1]).toString(36);
if (isCodeValid) { await createNewUser({
await createNewUser({ phone,
phone, inviter: validInviter.id,
inviter: validInviter.id, password,
password, inviteCode: newInviteCode
inviteCode: newInviteCode }).then(user => {
}).then(user => { lock.unlock(phone);
User.findByIdAndUpdate(validInviter.id, { $push: { group: user.id } }).catch(err => { User.findByIdAndUpdate(validInviter.id, { $push: { group: user.id } }).catch(err => {
mylog.error('将被邀请人加入到邀请人队列失败 uid', user.id, err && err.errmsg); mylog.error('将被邀请人加入到邀请人队列失败 uid', user.id, err && err.errmsg);
});
new Fund({userId: user.id }).save().catch(err => mylog.error('用户资金文档创建失败 uid', user.id, err && err.errmsg));
const token = createToken({
userId: user.id
}, JWT_SECRET, {});
res.json({
code: 0,
msg: 'success',
data: {
//刚注册需要返回的应该只有token其他的没意义
token
}
});
})
.catch(err => {
mylog.error(err);
res.json({
code: 3,
msg: JSON.stringify(err),
});
}); });
} else { new Fund({userId: user.id }).save().catch(err => mylog.error('用户资金文档创建失败 uid', user.id, err && err.errmsg));
res.json({ const token = createToken({
code: 2, userId: user.id
msg: 'Invalid code', }, JWT_SECRET, {});
return res.json({
code: 0,
msg: 'success',
data: { token }
});
}).catch(err => {
mylog.error('[SignUpWI]创建用户失败', err);
return res.json({
code: 3,
msg: JSON.stringify(err),
}); });
}
};
}),
signUp: inject(function(SysConfig) {
const { JWT_SECRET, PWD_HASH_SALT } = SysConfig;
return async (req, res) => {
let { phone, code, inviter, password } = req.body;
if (!phone || !code || !password) return res.json({
code: 1,
msg: 'Missing required parameters'
}); });
const isCodeValid = await Code.verifyCode({ id: phone, code, type: CODE_TYPE['signUp'] });
password = Crypto.hash(password, { salt: PWD_HASH_SALT });
if (isCodeValid) {
createNewUser({
phone,
inviter,
password
}).then(user => {
const token = createToken({
userId: user.id
}, JWT_SECRET, {});
res.json({
code: 0,
msg: 'success',
data: {
//刚注册需要返回的应该只有token其他的没意义
token
}
});
})
.catch(err => {
mylog.error(err);
res.json({
code: 3,
msg: JSON.stringify(err),
});
});
} else {
res.json({
code: 2,
msg: 'Invalid code',
});
}
}; };
}), }),
signUp: this.signUpReqInviter, // 暂时不用,先用要求邀请人的代替
forgetPasswd: inject(function(SysConfig) { forgetPasswd: inject(function(SysConfig) {
const { PWD_HASH_SALT } = SysConfig; const { PWD_HASH_SALT } = SysConfig;
return async (req, res) => { return async (req, res) => {

21
src/utils/mutexlock.js Normal file
View File

@@ -0,0 +1,21 @@
class MLock {
constructor (props) {
Object.defineProperty(this, 'map', {
value: new Map(),
writable: false
});
}
acquire (key) {
if (this.map.has(key)) {
return false;
}
this.map.set(key, true);
return true;
}
unlock (key) {
this.map.delete(key);
return true;
}
}
module.exports = MLock;