apinode
Version:
An API server that can greatly reduce the work needed to implment API services. It can also cooperate with other API node to make it a mesh of services.
244 lines (205 loc) • 5.3 kB
JavaScript
/*!
* cnode
* authors: Ben Lue
* Copyright(c) 2015 Gocharm Inc.
*/
var async = require('async'),
soar = require('sql-soar'),
tokenUtil = require('../../../util/tokenUtil.js'),
userUtil = require('../util/userUtil.js');
// Below are some default data used by account creation.
var MEMBER_ROLE = 6;
var EMAIL_ACC_SCHEME = 1,
MOBILE_ACC_SCHEME = 2;
var psnCol = ['fname', 'lname', 'nid', 'dob', 'gender', 'addrID', 'email', 'mobile'];
var _tsWindow = 180 * 24 * 60 * 60 * 1000;
var psnExpr = soar.sql('Person')
.filter({name: 'Person_id', op: '='}),
usrExpr = soar.sql('GrpUser')
.filter({
op: 'and',
filters: [
{name: 'UGroup_id', op: '='},
{name: 'accName', op: '='}
]
}),
tknExpr = soar.sql('UserToken');
exports.run = function(rt, cb) {
var inData = rt.inData,
addr = inData.addr;
inData.isTemp = true;
delete inData.passwd;
delete inData.addrID;
createAccount(rt, function(err, result) {
if (err)
return cb(err);
if (addr) {
// run as the new user to update the address
var psnID = result.value.psnID,
uPro = {
psnID: psnID,
userID: result.value.id,
roleID: 6,
isGuest: false
},
oldUpro = rt.uPro;
rt.uPro = uPro;
delete result.value.psnID;
rt.forward(rt, 'geo/address/update', {addr: addr}, function(err, res) {
rt.uPro = oldUpro;
if (err) {
console.log('user/update error:\n%s', JSON.stringify(err, null, 4));
return cb(userUtil.internErr());
}
var addrID = res.value.addrID;
soar.update('Person', {addrID: addrID}, {Person_id: psnID}, function(err) {
cb( null, result );
});
});
}
else
cb( null, result );
});
};
function createAccount(rt, cb) {
var inData = rt.inData;
async.waterfall([
function(cb) {
soar.getConnection(cb);
},
function(conn, cb) {
conn.beginTransaction(function(err) {
cb(err, conn);
});
},
function doPerson(conn, cb) {
var psnData = {};
for (var i in psnCol) {
var key = psnCol[i];
if (inData.hasOwnProperty(key))
psnData[key] = inData[key];
}
createPerson(psnData, conn, function(err, psnPK) {
if (err)
return cb(userUtil.internErr(), conn);
cb( null, conn, psnPK );
});
},
function doUser(conn, psnPK, cb) {
var usrData = {
accName: inData.accName,
dspName: inData.dspName,
Person_id: psnPK.Person_id,
UGroup_id: rt.app.UGroup_id,
ExeRole_id: MEMBER_ROLE,
actScheme: 0,
isTemp : true,
isValid: true
};
if (inData.aux)
usrData._c_json = inData.aux;
createUser( usrData, conn, function(err, usrPK) {
if (err)
return cb(userUtil.internErr(), conn);
usrData.GrpUser_id = usrPK.GrpUser_id;
cb( null, conn, usrData );
});
},
function genToken(conn, usrData, cb) {
// because we have to enclose this in a transaction, we cannot call tokenUtil.recordToken()
var digest = rt.uPro.token.substring(0, 16),
randomNum = tokenUtil.random(),
token = digest + randomNum,
tknValid = Date.now() + _tsWindow;
var data = {
caID: rt.app.CApp_id,
GrpUser_id: usrData.GrpUser_id,
token: randomNum,
tknExpire: tknValid,
devID: rt.remoteAddr
},
cmd = {op: 'insert', expr: tknExpr, conn: conn};
soar.execute(cmd, data, null, function(err, pk) {
if (err)
cb({code: -100, message: 'Internal error'}, conn);
else {
var tknData = {
token: token,
validTo: tknValid
};
cb(null, conn, usrData, tknData);
}
});
}
],
function(err, conn, usrData, tknData) {
if (err) {
conn.rollback(function() {
conn.release();
cb( null, err );
});
}
else {
var value = {
id: usrData.GrpUser_id,
psnID: usrData.Person_id, // should be removed before returning to user
actScheme: 0
},
result = {code: 0, message: 'Ok', value: value, token: tknData};
conn.commit(function(err) {
if (err) {
conn.rollback(function() {
conn.release();
cb( null, userUtil.internErr() );
});
}
else {
conn.release();
cb( null, result );
}
});
}
});
};
function createPerson(data, conn, cb) {
var cmd = {
op: 'insert',
expr: psnExpr,
conn: conn
};
data.isNature = data.hasOwnProperty('isNature') ? data.isNature : 1;
//console.log('insert data is\n%s', JSON.stringify(psnData, null, 4));
soar.execute(cmd, data, null, cb);
};
function createUser(data, conn, cb) {
var dspName = data.dspName;
if (!dspName) {
dspName = data.email || data.accName;
if (dspName) {
var idx = dspName.indexOf('@');
dspName = dspName.substring(0, idx);
idx = dspName.indexOf('.');
if (idx > 0)
dspName = dspName.substring(0, idx);
}
}
data.dspName = dspName;
data.createTime = new Date();
var usrCmd = {
op: 'insert',
expr: usrExpr,
conn: conn
};
soar.execute(usrCmd, data, null, cb);
};
function isEmail(s) {
var idx = s.indexOf('@');
if (idx > 1) {
idx = s.indexOf('.', idx+1);
return idx > 1;
}
return false;
};
function isMobile(s) {
return s.length === 10 && s.indexOf('09') === 0;
};