| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727 |
- const userModel = require('../models/user.js');
- const yapi = require('../yapi.js');
- const baseController = require('./base.js');
- const common = require('../utils/commons.js');
- const ldap = require('../utils/ldap.js');
- const interfaceModel = require('../models/interface.js');
- const groupModel = require('../models/group.js');
- const projectModel = require('../models/project.js');
- const avatarModel = require('../models/avatar.js');
- const jwt = require('jsonwebtoken');
- class userController extends baseController {
- constructor(ctx) {
- super(ctx);
- this.Model = yapi.getInst(userModel);
- }
- /**
- * 用户登录接口
- * @interface /user/login
- * @method POST
- * @category user
- * @foldnumber 10
- * @param {String} email email名称,不能为空
- * @param {String} password 密码,不能为空
- * @returns {Object}
- * @example ./api/user/login.json
- */
- async login(ctx) {
- //登录
- let userInst = yapi.getInst(userModel); //创建user实体
- let email = ctx.request.body.email;
- let password = ctx.request.body.password;
- if (!email) {
- return (ctx.body = yapi.commons.resReturn(null, 400, 'email不能为空'));
- }
- if (!password) {
- return (ctx.body = yapi.commons.resReturn(null, 400, '密码不能为空'));
- }
- let result = await userInst.findByEmail(email);
- if (!result) {
- return (ctx.body = yapi.commons.resReturn(null, 404, '该用户不存在'));
- } else if (yapi.commons.generatePassword(password, result.passsalt) === result.password) {
- this.setLoginCookie(result._id, result.passsalt);
- return (ctx.body = yapi.commons.resReturn(
- {
- username: result.username,
- role: result.role,
- uid: result._id,
- email: result.email,
- add_time: result.add_time,
- up_time: result.up_time,
- type: 'site',
- study: result.study
- },
- 0,
- 'logout success...'
- ));
- } else {
- return (ctx.body = yapi.commons.resReturn(null, 405, '密码错误'));
- }
- }
- /**
- * 退出登录接口
- * @interface /user/logout
- * @method GET
- * @category user
- * @foldnumber 10
- * @returns {Object}
- * @example ./api/user/logout.json
- */
- async logout(ctx) {
- ctx.cookies.set('_yapi_token', null);
- ctx.cookies.set('_yapi_uid', null);
- ctx.body = yapi.commons.resReturn('ok');
- }
- /**
- * 更新
- * @interface /user/up_study
- * @method GET
- * @category user
- * @foldnumber 10
- * @returns {Object}
- * @example
- */
- async upStudy(ctx) {
- let userInst = yapi.getInst(userModel); //创建user实体
- let data = {
- up_time: yapi.commons.time(),
- study: true
- };
- try {
- let result = await userInst.update(this.getUid(), data);
- ctx.body = yapi.commons.resReturn(result);
- } catch (e) {
- ctx.body = yapi.commons.resReturn(null, 401, e.message);
- }
- }
- async loginByToken(ctx) {
- try {
- let ret = await yapi.emitHook('third_login', ctx);
- let login = await this.handleThirdLogin(ret.email, ret.username);
- if (login === true) {
- yapi.commons.log('login success');
- ctx.redirect('/group');
- }
- } catch (e) {
- yapi.commons.log(e.message, 'error');
- ctx.redirect('/');
- }
- }
- /**
- * ldap登录
- * @interface /user/login_by_ldap
- * @method
- * @category user
- * @foldnumber 10
- * @param {String} email email名称,不能为空
- * @param {String} password 密码,不能为空
- * @returns {Object}
- *
- */
- async getLdapAuth(ctx) {
- try {
- const { email, password } = ctx.request.body;
- // const username = email.split(/\@/g)[0];
- const { info: ldapInfo } = await ldap.ldapQuery(email, password);
- const emailPrefix = email.split(/\@/g)[0];
- const emailPostfix = yapi.WEBCONFIG.ldapLogin.emailPostfix;
- const emailParams =
- ldapInfo[yapi.WEBCONFIG.ldapLogin.emailKey || 'mail'] ||
- (emailPostfix ? emailPrefix + emailPostfix : email);
- const username = ldapInfo[yapi.WEBCONFIG.ldapLogin.usernameKey] || emailPrefix;
- let login = await this.handleThirdLogin(emailParams, username);
- if (login === true) {
- let userInst = yapi.getInst(userModel); //创建user实体
- let result = await userInst.findByEmail(emailParams);
- return (ctx.body = yapi.commons.resReturn(
- {
- username: result.username,
- role: result.role,
- uid: result._id,
- email: result.email,
- add_time: result.add_time,
- up_time: result.up_time,
- type: result.type || 'third',
- study: result.study
- },
- 0,
- 'logout success...'
- ));
- }
- } catch (e) {
- yapi.commons.log(e.message, 'error');
- return (ctx.body = yapi.commons.resReturn(null, 401, e.message));
- }
- }
- // 处理第三方登录
- async handleThirdLogin(email, username) {
- let user, data, passsalt;
- let userInst = yapi.getInst(userModel);
- try {
- user = await userInst.findByEmail(email);
- // 新建用户信息
- if (!user || !user._id) {
- passsalt = yapi.commons.randStr();
- data = {
- username: username,
- password: yapi.commons.generatePassword(passsalt, passsalt),
- email: email,
- passsalt: passsalt,
- role: 'member',
- add_time: yapi.commons.time(),
- up_time: yapi.commons.time(),
- type: 'third'
- };
- user = await userInst.save(data);
- await this.handlePrivateGroup(user._id, username, email);
- yapi.commons.sendMail({
- to: email,
- contents: `<h3>亲爱的用户:</h3><p>您好,感谢使用YApi平台,你的邮箱账号是:${email}</p>`
- });
- }
- this.setLoginCookie(user._id, user.passsalt);
- return true;
- } catch (e) {
- console.error('third_login:', e.message); // eslint-disable-line
- throw new Error(`third_login: ${e.message}`);
- }
- }
- /**
- * 修改用户密码
- * @interface /user/change_password
- * @method POST
- * @category user
- * @param {Number} uid 用户ID
- * @param {Number} [old_password] 旧密码, 非admin用户必须传
- * @param {Number} password 新密码
- * @return {Object}
- * @example ./api/user/change_password.json
- */
- async changePassword(ctx) {
- let params = ctx.request.body;
- let userInst = yapi.getInst(userModel);
- if (!params.uid) {
- return (ctx.body = yapi.commons.resReturn(null, 400, 'uid不能为空'));
- }
- if (!params.password) {
- return (ctx.body = yapi.commons.resReturn(null, 400, '密码不能为空'));
- }
- let user = await userInst.findById(params.uid);
- if (this.getRole() !== 'admin' && params.uid != this.getUid()) {
- return (ctx.body = yapi.commons.resReturn(null, 402, '没有权限'));
- }
- if (this.getRole() !== 'admin' || user.role === 'admin') {
- if (!params.old_password) {
- return (ctx.body = yapi.commons.resReturn(null, 400, '旧密码不能为空'));
- }
- if (yapi.commons.generatePassword(params.old_password, user.passsalt) !== user.password) {
- return (ctx.body = yapi.commons.resReturn(null, 402, '旧密码错误'));
- }
- }
- let passsalt = yapi.commons.randStr();
- let data = {
- up_time: yapi.commons.time(),
- password: yapi.commons.generatePassword(params.password, passsalt),
- passsalt: passsalt
- };
- try {
- let result = await userInst.update(params.uid, data);
- ctx.body = yapi.commons.resReturn(result);
- } catch (e) {
- ctx.body = yapi.commons.resReturn(null, 401, e.message);
- }
- }
- async handlePrivateGroup(uid) {
- var groupInst = yapi.getInst(groupModel);
- await groupInst.save({
- uid: uid,
- group_name: 'User-' + uid,
- add_time: yapi.commons.time(),
- up_time: yapi.commons.time(),
- type: 'private'
- });
- }
- setLoginCookie(uid, passsalt) {
- let token = jwt.sign({ uid: uid }, passsalt, { expiresIn: '7 days' });
- this.ctx.cookies.set('_yapi_token', token, {
- expires: yapi.commons.expireDate(7),
- httpOnly: true
- });
- this.ctx.cookies.set('_yapi_uid', uid, {
- expires: yapi.commons.expireDate(7),
- httpOnly: true
- });
- }
- /**
- * 用户注册接口
- * @interface /user/reg
- * @method POST
- * @category user
- * @foldnumber 10
- * @param {String} email email名称,不能为空
- * @param {String} password 密码,不能为空
- * @param {String} [username] 用户名
- * @returns {Object}
- * @example ./api/user/login.json
- */
- async reg(ctx) {
- //注册
- if (yapi.WEBCONFIG.closeRegister) {
- return (ctx.body = yapi.commons.resReturn(null, 400, '禁止注册,请联系管理员'));
- }
- let userInst = yapi.getInst(userModel);
- let params = ctx.request.body; //获取请求的参数,检查是否存在用户名和密码
- params = yapi.commons.handleParams(params, {
- username: 'string',
- password: 'string',
- email: 'string'
- });
- if (!params.email) {
- return (ctx.body = yapi.commons.resReturn(null, 400, '邮箱不能为空'));
- }
- if (!params.password) {
- return (ctx.body = yapi.commons.resReturn(null, 400, '密码不能为空'));
- }
- let checkRepeat = await userInst.checkRepeat(params.email); //然后检查是否已经存在该用户
- if (checkRepeat > 0) {
- return (ctx.body = yapi.commons.resReturn(null, 401, '该email已经注册'));
- }
- let passsalt = yapi.commons.randStr();
- let data = {
- username: params.username,
- password: yapi.commons.generatePassword(params.password, passsalt), //加密
- email: params.email,
- passsalt: passsalt,
- role: 'member',
- add_time: yapi.commons.time(),
- up_time: yapi.commons.time(),
- type: 'site'
- };
- if (!data.username) {
- data.username = data.email.substr(0, data.email.indexOf('@'));
- }
- try {
- let user = await userInst.save(data);
- this.setLoginCookie(user._id, user.passsalt);
- await this.handlePrivateGroup(user._id, user.username, user.email);
- ctx.body = yapi.commons.resReturn({
- uid: user._id,
- email: user.email,
- username: user.username,
- add_time: user.add_time,
- up_time: user.up_time,
- role: 'member',
- type: user.type,
- study: false
- });
- yapi.commons.sendMail({
- to: user.email,
- contents: `<h3>亲爱的用户:</h3><p>您好,感谢使用YApi可视化接口平台,您的账号 ${
- params.email
- } 已经注册成功</p>`
- });
- } catch (e) {
- ctx.body = yapi.commons.resReturn(null, 401, e.message);
- }
- }
- /**
- * 获取用户列表
- * @interface /user/list
- * @method GET
- * @category user
- * @foldnumber 10
- * @param {Number} [page] 分页页码
- * @param {Number} [limit] 分页大小,默认为10条
- * @returns {Object}
- * @example
- */
- async list(ctx) {
- let page = ctx.request.query.page || 1,
- limit = ctx.request.query.limit || 10;
- const userInst = yapi.getInst(userModel);
- try {
- let user = await userInst.listWithPaging(page, limit);
- let count = await userInst.listCount();
- return (ctx.body = yapi.commons.resReturn({
- count: count,
- total: Math.ceil(count / limit),
- list: user
- }));
- } catch (e) {
- return (ctx.body = yapi.commons.resReturn(null, 402, e.message));
- }
- }
- /**
- * 获取用户个人信息
- * @interface /user/find
- * @method GET
- * @param id 用户uid
- * @category user
- * @foldnumber 10
- * @returns {Object}
- * @example
- */
- async findById(ctx) {
- //根据id获取用户信息
- try {
- let userInst = yapi.getInst(userModel);
- let id = ctx.request.query.id;
- if (!id) {
- return (ctx.body = yapi.commons.resReturn(null, 400, 'uid不能为空'));
- }
- let result = await userInst.findById(id);
- if (!result) {
- return (ctx.body = yapi.commons.resReturn(null, 402, '不存在的用户'));
- }
- return (ctx.body = yapi.commons.resReturn({
- uid: result._id,
- username: result.username,
- email: result.email,
- role: result.role,
- type: result.type,
- add_time: result.add_time,
- up_time: result.up_time
- }));
- } catch (e) {
- return (ctx.body = yapi.commons.resReturn(null, 402, e.message));
- }
- }
- /**
- * 删除用户,只有admin用户才有此权限
- * @interface /user/del
- * @method POST
- * @param id 用户uid
- * @category user
- * @foldnumber 10
- * @returns {Object}
- * @example
- */
- async del(ctx) {
- //根据id删除一个用户
- try {
- if (this.getRole() !== 'admin') {
- return (ctx.body = yapi.commons.resReturn(null, 402, 'Without permission.'));
- }
- let userInst = yapi.getInst(userModel);
- let id = ctx.request.body.id;
- if (id == this.getUid()) {
- return (ctx.body = yapi.commons.resReturn(null, 403, '禁止删除管理员'));
- }
- if (!id) {
- return (ctx.body = yapi.commons.resReturn(null, 400, 'uid不能为空'));
- }
- let result = await userInst.del(id);
- ctx.body = yapi.commons.resReturn(result);
- } catch (e) {
- ctx.body = yapi.commons.resReturn(null, 402, e.message);
- }
- }
- /**
- * 更新用户个人信息
- * @interface /user/update
- * @method POST
- * @param uid 用户uid
- * @param [role] 用户角色,只有管理员有权限修改
- * @param [username] String
- * @param [email] String
- * @category user
- * @foldnumber 10
- * @returns {Object}
- * @example
- */
- async update(ctx) {
- //更新用户信息
- try {
- let params = ctx.request.body;
- params = yapi.commons.handleParams(params, {
- username: 'string',
- email: 'string'
- });
- if (this.getRole() !== 'admin' && params.uid != this.getUid()) {
- return (ctx.body = yapi.commons.resReturn(null, 401, '没有权限'));
- }
- let userInst = yapi.getInst(userModel);
- let id = params.uid;
- if (!id) {
- return (ctx.body = yapi.commons.resReturn(null, 400, 'uid不能为空'));
- }
- let userData = await userInst.findById(id);
- if (!userData) {
- return (ctx.body = yapi.commons.resReturn(null, 400, 'uid不存在'));
- }
- let data = {
- up_time: yapi.commons.time()
- };
- params.username && (data.username = params.username);
- params.email && (data.email = params.email);
- if (data.email) {
- var checkRepeat = await userInst.checkRepeat(data.email); //然后检查是否已经存在该用户
- if (checkRepeat > 0) {
- return (ctx.body = yapi.commons.resReturn(null, 401, '该email已经注册'));
- }
- }
- let member = {
- uid: id,
- username: data.username || userData.username,
- email: data.email || userData.email
- };
- let groupInst = yapi.getInst(groupModel);
- await groupInst.updateMember(member);
- let projectInst = yapi.getInst(projectModel);
- await projectInst.updateMember(member);
- let result = await userInst.update(id, data);
- ctx.body = yapi.commons.resReturn(result);
- } catch (e) {
- ctx.body = yapi.commons.resReturn(null, 402, e.message);
- }
- }
- /**
- * 上传用户头像
- * @interface /user/upload_avatar
- * @method POST
- * @param {*} basecode base64编码,通过h5 api传给后端
- * @category user
- * @returns {Object}
- * @example
- */
- async uploadAvatar(ctx) {
- try {
- let basecode = ctx.request.body.basecode;
- if (!basecode) {
- return (ctx.body = yapi.commons.resReturn(null, 400, 'basecode不能为空'));
- }
- let pngPrefix = 'data:image/png;base64,';
- let jpegPrefix = 'data:image/jpeg;base64,';
- let type;
- if (basecode.substr(0, pngPrefix.length) === pngPrefix) {
- basecode = basecode.substr(pngPrefix.length);
- type = 'image/png';
- } else if (basecode.substr(0, jpegPrefix.length) === jpegPrefix) {
- basecode = basecode.substr(jpegPrefix.length);
- type = 'image/jpeg';
- } else {
- return (ctx.body = yapi.commons.resReturn(null, 400, '仅支持jpeg和png格式的图片'));
- }
- let strLength = basecode.length;
- if (parseInt(strLength - (strLength / 8) * 2) > 200000) {
- return (ctx.body = yapi.commons.resReturn(null, 400, '图片大小不能超过200kb'));
- }
- let avatarInst = yapi.getInst(avatarModel);
- let result = await avatarInst.up(this.getUid(), basecode, type);
- ctx.body = yapi.commons.resReturn(result);
- } catch (e) {
- ctx.body = yapi.commons.resReturn(null, 401, e.message);
- }
- }
- /**
- * 根据用户uid头像
- * @interface /user/avatar
- * @method GET
- * @param {*} uid
- * @category user
- * @returns {Object}
- * @example
- */
- async avatar(ctx) {
- try {
- let uid = ctx.query.uid ? ctx.query.uid : this.getUid();
- let avatarInst = yapi.getInst(avatarModel);
- let data = await avatarInst.get(uid);
- let dataBuffer, type;
- if (!data || !data.basecode) {
- dataBuffer = yapi.fs.readFileSync(yapi.path.join(yapi.WEBROOT, 'static/image/avatar.png'));
- type = 'image/png';
- } else {
- type = data.type;
- dataBuffer = new Buffer(data.basecode, 'base64');
- }
- ctx.set('Content-type', type);
- ctx.body = dataBuffer;
- } catch (err) {
- ctx.body = 'error:' + err.message;
- }
- }
- /**
- * 模糊搜索用户名或者email
- * @interface /user/search
- * @method GET
- * @category user
- * @foldnumber 10
- * @param {String} q
- * @return {Object}
- * @example ./api/user/search.json
- */
- async search(ctx) {
- const { q } = ctx.request.query;
- if (!q) {
- return (ctx.body = yapi.commons.resReturn(void 0, 400, 'No keyword.'));
- }
- if (!yapi.commons.validateSearchKeyword(q)) {
- return (ctx.body = yapi.commons.resReturn(void 0, 400, 'Bad query.'));
- }
- let queryList = await this.Model.search(q);
- let rules = [
- {
- key: '_id',
- alias: 'uid'
- },
- 'username',
- 'email',
- 'role',
- {
- key: 'add_time',
- alias: 'addTime'
- },
- {
- key: 'up_time',
- alias: 'upTime'
- }
- ];
- let filteredRes = common.filterRes(queryList, rules);
- return (ctx.body = yapi.commons.resReturn(filteredRes, 0, 'ok'));
- }
- /**
- * 根据路由id初始化项目数据
- * @interface /user/project
- * @method GET
- * @category user
- * @foldnumber 10
- * @param {String} type 可选group|interface|project
- * @param {Number} id
- * @return {Object}
- * @example
- */
- async project(ctx) {
- let { id, type } = ctx.request.query;
- let result = {};
- try {
- if (type === 'interface') {
- let interfaceInst = yapi.getInst(interfaceModel);
- let interfaceData = await interfaceInst.get(id);
- result.interface = interfaceData;
- type = 'project';
- id = interfaceData.project_id;
- }
- if (type === 'project') {
- let projectInst = yapi.getInst(projectModel);
- let projectData = await projectInst.get(id);
- result.project = projectData.toObject();
- let ownerAuth = await this.checkAuth(id, 'project', 'danger'),
- devAuth;
- if (ownerAuth) {
- result.project.role = 'owner';
- } else {
- devAuth = await this.checkAuth(id, 'project', 'site');
- if (devAuth) {
- result.project.role = 'dev';
- } else {
- result.project.role = 'member';
- }
- }
- type = 'group';
- id = projectData.group_id;
- }
- if (type === 'group') {
- let groupInst = yapi.getInst(groupModel);
- let groupData = await groupInst.get(id);
- result.group = groupData.toObject();
- let ownerAuth = await this.checkAuth(id, 'group', 'danger'),
- devAuth;
- if (ownerAuth) {
- result.group.role = 'owner';
- } else {
- devAuth = await this.checkAuth(id, 'group', 'site');
- if (devAuth) {
- result.group.role = 'dev';
- } else {
- result.group.role = 'member';
- }
- }
- }
- return (ctx.body = yapi.commons.resReturn(result));
- } catch (e) {
- return (ctx.body = yapi.commons.resReturn(result, 422, e.message));
- }
- }
- }
- module.exports = userController;
|