Merge branch 'dev' of gitlab.corp.qunar.com:mfe/yapi into dev

This commit is contained in:
wenbo.dong 2017-07-24 17:21:14 +08:00
commit d6090778aa
22 changed files with 243 additions and 147 deletions

View File

@ -1,19 +1,26 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { connect } from 'react-redux' import { connect } from 'react-redux'
import PropTypes from 'prop-types' import PropTypes from 'prop-types'
import { Route, HashRouter, Redirect, Switch } from 'react-router-dom' import { Route, HashRouter } from 'react-router-dom'
import { Home, ProjectGroups, Interface, News, AddInterface } from './containers/index' import { Home, ProjectGroups, Interface, News, AddInterface } from './containers/index'
import User from './containers/User/User.js' import User from './containers/User/User.js'
import Header from './components/Header/Header' import Header from './components/Header/Header'
import { checkLoginState } from './actions/login' import { checkLoginState } from './actions/login'
import { requireAuthentication } from './components/AuthenticatedComponent';
const LOADING_STATUS = 0; const LOADING_STATUS = 0;
const GUEST_STATUS = 1;
// const MEMBER_STATUS = 2;
class App extends Component {
@connect(
state => {
return{
loginState:state.login.loginState
}
},
{
checkLoginState
}
)
export default class App extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
@ -24,59 +31,32 @@ class App extends Component {
checkLoginState:PropTypes.func, checkLoginState:PropTypes.func,
loginState:PropTypes.number loginState:PropTypes.number
} }
componentDidMount() {
this.props.checkLoginState();
}
route = (status) => { route = (status) => {
let r; let r;
if (status === LOADING_STATUS) { if (status === LOADING_STATUS) {
return <span>loading...</span> return <span>loading...</span>
} else if (status === GUEST_STATUS) {
r = (
<HashRouter>
<div className="router-main">
<Header />
<Switch>
<Route
path="/"
component={Home}/>
<Redirect from="(/:str)" to="/" />
</Switch>
</div>
</HashRouter>
)
} else { } else {
r = ( r = (
<HashRouter> <HashRouter>
<div className="router-main"> <div className="router-main">
<Header /> <Header />
<Route path="/" component={Home} exact /> <Route path="/" component={Home} exact />
<Route path="/ProjectGroups" component={ProjectGroups} /> <Route path="/ProjectGroups" component={requireAuthentication(ProjectGroups)} />
<Route path="/Interface" component={Interface} /> <Route path="/Interface" component={requireAuthentication(Interface)} />
<Route path="/user" component={User} /> <Route path="/user" component={requireAuthentication(User)} />
<Route path="/News" component={News} /> <Route path="/News" component={requireAuthentication(News)} />
<Route path="/AddInterface" component={ AddInterface } /> <Route path="/AddInterface" component={ requireAuthentication(AddInterface) } />
</div> </div>
</HashRouter> </HashRouter>
) )
} }
return r return r
} }
componentDidMount() {
this.props.checkLoginState();
}
render() { render() {
return this.route(this.props.loginState) return this.route(this.props.loginState);
} }
} }
export default connect(
state => {
return{
loginState:state.login.loginState
}
},
{
checkLoginState
}
)(App)

View File

@ -3,25 +3,28 @@ import {
FETCH_MORE_NEWS FETCH_MORE_NEWS
} from '../constants/action-types.js'; } from '../constants/action-types.js';
export function fetchNewsData (logId) { import axios from 'axios';
const data = { import variable from '../constants/variable';
newsList:[
{ key: 1,title: '日志标题', username: 'John Brown', content: '您好!亲爱的用户:您已成功申请接口:实时空气质量数据查询,请于两个月内进行应用验证,逾期接口将不能正常使用。如果您在使用的过程中遇到任何问题,欢迎前往交流社区反馈意见,谢谢!',time: '2014-12-01' }, export function fetchNewsData (uid,page,limit) {
{ key: 2,title: '日志标题', username: 'John Brown', content: 'My name is John Brown, I am 32 years old, living in New York No. 1 Lake Park.',time: '2014-12-01' }, // const data = {
{ key: 3,title: '日志标题', username: 'John Brown', content: 'My name is John Brown, I am 32 years old, living in New York No. 1 Lake Park.',time: '2014-12-01' } // newsList:[
], // { key: 1,title: '日志标题', username: 'John Brown', content: '您好!亲爱的用户:您已成功申请接口:实时空气质量数据查询,请于两个月内进行应用验证,逾期接口将不能正常使用。如果您在使用的过程中遇到任何问题,欢迎前往交流社区反馈意见,谢谢!',time: '2014-12-01' },
totalPage: 34 // { key: 2,title: '日志标题', username: 'John Brown', content: 'My name is John Brown, I am 32 years old, living in New York No. 1 Lake Park.',time: '2014-12-01' },
}; // { key: 3,title: '日志标题', username: 'John Brown', content: 'My name is John Brown, I am 32 years old, living in New York No. 1 Lake Park.',time: '2014-12-01' }
console.log(logId); // ],
// totalPage: 34
// };
const param = {
uid: uid,
page: page,
limit: variable.PAGE_LIMIT?variable.PAGE_LIMIT:limit
}
console.log(param);
return { return {
type: FETCH_NEWS_DATA, type: FETCH_NEWS_DATA,
payload: new Promise(function(reslove,reject){ payload: axios.get('/log/list',param)
if(data){
reslove(data);
}else{
reject("chucuole");
}
})
}; };
} }

View File

@ -0,0 +1,55 @@
import React from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types'
import { changeMenuItem } from '../actions/menu'
export function requireAuthentication(Component) {
class AuthenticatedComponent extends React.Component {
constructor(props){
super(props);
}
static propTypes ={
isAuthenticated : PropTypes.bool,
location: PropTypes.object,
dispatch: PropTypes.func,
history: PropTypes.object,
changeMenuItem:PropTypes.func
}
componentWillMount() {
this.checkAuth();
}
componentWillReceiveProps() {
this.checkAuth();
}
checkAuth() {
if( !this.props.isAuthenticated ){
this.props.history.push('/');
this.props.changeMenuItem('/');
}
}
render() {
return (
<div>
{this.props.isAuthenticated
? <Component {...this.props}/>
: null
}
</div>
)
}
}
return connect(
(state) => {
return{
isAuthenticated: state.login.isLogin
}
},
{
changeMenuItem
}
)(AuthenticatedComponent);
}

View File

@ -2,7 +2,7 @@
.footer{ .footer{
// max-width: 12rem; // max-width: 12rem;
margin: 20px auto; margin: 0px auto;
clear: both; clear: both;
font-size: 12px; font-size: 12px;
background: #000c15; background: #000c15;

View File

@ -85,16 +85,9 @@ class HeaderCom extends Component {
} }
linkTo = (e) =>{ linkTo = (e) =>{
this.props.changeMenuItem(e.key); this.props.changeMenuItem(e.key);
// this.props.curKey = e.key;
// this.setState({
// current : e.key
// })
} }
relieveLink = () => { relieveLink = () => {
this.props.changeMenuItem(""); this.props.changeMenuItem("");
// this.setState({
// current : ""
// })
} }
logout = (e) => { logout = (e) => {
e.preventDefault(); e.preventDefault();
@ -129,9 +122,10 @@ class HeaderCom extends Component {
} }
render () { render () {
const { login, user, msg, uid, curKey } = this.props; const { login, user, msg, uid, curKey } = this.props;
console.log(curKey);
return ( return (
<acticle className="header-box"> <acticle className="header-box">
<Layout className="'layout"> <Layout className="layout">
<Header> <Header>
<div className="content"> <div className="content">
<div className="logo"> <div className="logo">

View File

@ -10,6 +10,7 @@ import { fetchNewsData } from '../../actions/news.js'
@connect( @connect(
state => { state => {
return { return {
uid: state.user.curUid,
newsData: state.news.newsData?state.news.newsData:[] newsData: state.news.newsData?state.news.newsData:[]
} }
}, },
@ -27,7 +28,8 @@ class News extends Component {
} }
static propTypes = { static propTypes = {
newsData: PropTypes.object, newsData: PropTypes.object,
fetchNewsData: PropTypes.func fetchNewsData: PropTypes.func,
uid: PropTypes.string
} }
setLoading(bool){ setLoading(bool){
this.setState({ this.setState({
@ -35,7 +37,10 @@ class News extends Component {
}) })
} }
componentWillMount(){ componentWillMount(){
this.props.fetchNewsData() console.log(this.props.uid);
this.props.fetchNewsData(1,1,10).then(function(data){
console.log(data);
})
} }
render () { render () {
const data = this.props.newsData const data = this.props.newsData

View File

@ -18,7 +18,9 @@ const logList = [{
}]; }];
@connect( @connect(
state => { state => {
// console.log(state);
return { return {
uid: state.user.curUid,
newsData: state.news.newsData newsData: state.news.newsData
} }
}, },
@ -31,7 +33,8 @@ class NewsList extends Component {
static propTypes = { static propTypes = {
fetchNewsData: PropTypes.func, fetchNewsData: PropTypes.func,
setLoading: PropTypes.func setLoading: PropTypes.func,
uid: PropTypes.string
} }
constructor(props) { constructor(props) {
@ -48,7 +51,8 @@ class NewsList extends Component {
}) })
const that = this; const that = this;
this.props.setLoading(true); this.props.setLoading(true);
this.props.fetchNewsData(+e.key).then(function(){ this.props.fetchNewsData(+this.props.uid,0,5).then(function(data){
console.log(data.data);
that.props.setLoading(false); that.props.setLoading(false);
}) })
} }

View File

@ -57,7 +57,7 @@ class NewsTimeline extends Component {
<section className="news-timeline"> <section className="news-timeline">
<span className='removeAllNews'> <span className='removeAllNews'>
<Popconfirm title="你确定要清空所有消息吗?" onConfirm={removeConfirm} okText="删除" cancelText="取消"> <Popconfirm title="你确定要清空所有消息吗?" onConfirm={removeConfirm} okText="删除" cancelText="取消">
清空消息 项目日志
</Popconfirm> </Popconfirm>
</span> </span>
<Table <Table

View File

@ -3,7 +3,7 @@ import {
} from '../../constants/action-types.js' } from '../../constants/action-types.js'
const initialState = { const initialState = {
curKey: window.location.hash.split("#")[1] curKey: window.location.hash.split("#")[1] || '/'
} }
export default (state = initialState, action) => { export default (state = initialState, action) => {

View File

@ -10,6 +10,7 @@ const initialState = {
export default (state = initialState, action) => { export default (state = initialState, action) => {
switch (action.type) { switch (action.type) {
case FETCH_NEWS_DATA: { case FETCH_NEWS_DATA: {
// console.log(action.payload);
return { return {
...state, ...state,
newsData: action.payload newsData: action.payload

View File

@ -48,6 +48,10 @@ class interfaceController extends baseController{
return ctx.body = yapi.commons.resReturn(null, 400, '接口请求路径不能为空'); return ctx.body = yapi.commons.resReturn(null, 400, '接口请求路径不能为空');
} }
if(!yapi.commons.verifyPath(params.path)){
return ctx.body = yapi.commons.resReturn(null, 400, '接口path第一位必须是/,最后一位不能为/')
}
let checkRepeat = await this.Model.checkRepeat(params.path, params.method); let checkRepeat = await this.Model.checkRepeat(params.path, params.method);
if(checkRepeat > 0){ if(checkRepeat > 0){
return ctx.body = yapi.commons.resReturn(null, 401, '已存在的接口:' + params.path + '[' + params.method + ']'); return ctx.body = yapi.commons.resReturn(null, 401, '已存在的接口:' + params.path + '[' + params.method + ']');
@ -162,12 +166,17 @@ class interfaceController extends baseController{
return ctx.body = yapi.commons.resReturn(null, 400, '接口id不能为空'); return ctx.body = yapi.commons.resReturn(null, 400, '接口id不能为空');
} }
let interfaceData = await this.Model.get(id); let interfaceData = await this.Model.get(id);
if(params.path && !yapi.commons.verifyPath(params.path)){
return ctx.body = yapi.commons.resReturn(null, 400, '接口path第一位必须是/,最后一位不能为/')
}
if(params.path && params.path !== interfaceData.path && params.method !== interfaceData.method){ if(params.path && params.path !== interfaceData.path && params.method !== interfaceData.method){
let checkRepeat = await this.Model.checkRepeat(params.path, params.method); let checkRepeat = await this.Model.checkRepeat(params.path, params.method);
if(checkRepeat > 0){ if(checkRepeat > 0){
return ctx.body = yapi.commons.resReturn(null, 401, '已存在的接口:' + params.path + '[' + params.method + ']'); return ctx.body = yapi.commons.resReturn(null, 401, '已存在的接口:' + params.path + '[' + params.method + ']');
} }
} }
let data = { let data = {
up_time: yapi.commons.time() up_time: yapi.commons.time()

View File

@ -18,20 +18,12 @@ class projectController extends baseController {
if(!basepath) return false; if(!basepath) return false;
if(basepath[0] !== '/') basepath = '/' + basepath; if(basepath[0] !== '/') basepath = '/' + basepath;
if(basepath[basepath.length -1] === '/') basepath = basepath.substr(0, basepath.length -1) if(basepath[basepath.length -1] === '/') basepath = basepath.substr(0, basepath.length -1)
if(!this.verifyPath(basepath)){ if(yapi.commons.verifyPath(basepath)){
return false; return false;
} }
return basepath; return basepath;
} }
verifyPath(path){
if(/^[a-zA-Z0-9\-\/_:]+$/.test(path)){
return true;
}else{
return false;
}
}
verifyDomain(domain){ verifyDomain(domain){
if(!domain) return false; if(!domain) return false;
if(/^[a-zA-Z0-9\-_\.]+[a-zA-Z]{2,6}$/.test(domain)){ if(/^[a-zA-Z0-9\-_\.]+[a-zA-Z]{2,6}$/.test(domain)){
@ -256,12 +248,11 @@ class projectController extends baseController {
let count = await this.Model.listCount(group_id); let count = await this.Model.listCount(group_id);
let uids = []; let uids = [];
result.forEach( (item)=> { result.forEach( (item)=> {
if(uids.indexOf(item.uid) !== -1){ if(uids.indexOf(item.uid) === -1){
uids.push(item.uid) uids.push(item.uid)
} }
} ) } )
let _users = {}, users = await yapi.getInst(userModel).findByUids(uids); let _users = {}, users = await yapi.getInst(userModel).findByUids(uids);
users.forEach((item)=> { users.forEach((item)=> {
_users[item._id] = item; _users[item._id] = item;
@ -271,7 +262,7 @@ class projectController extends baseController {
list: result, list: result,
userinfo: _users userinfo: _users
}) })
}catch(err){ }catch(e){
ctx.body = yapi.commons.resReturn(null, 402, e.message) ctx.body = yapi.commons.resReturn(null, 402, e.message)
} }
} }

View File

@ -139,6 +139,10 @@ class userController extends baseController {
up_time: yapi.commons.time() up_time: yapi.commons.time()
} }
user = await userInst.save(data); user = await userInst.save(data);
yapi.commons.sendMail({
to: params.email,
contents: `<h3>亲爱的用户:</h3><p>您好感谢使用YApi,系统检测您是第一次用Qsso账号登录YApi服务,您的Email是 ${params.email} ,初始化密码为:${passsalt}</p>`
})
} }
this.setLoginCookie(user._id, user.passsalt) this.setLoginCookie(user._id, user.passsalt)
@ -276,7 +280,7 @@ class userController extends baseController {
}); });
yapi.commons.sendMail({ yapi.commons.sendMail({
to: params.email, to: params.email,
contents: `欢迎注册,您的账号 ${params.email} 已经注册成功` contents: `<h3>亲爱的用户:</h3><p>您好感谢使用YApi,您的账号 ${params.email} 已经注册成功</p>`
}) })
} catch (e) { } catch (e) {
ctx.body = yapi.commons.resReturn(null, 401, e.message); ctx.body = yapi.commons.resReturn(null, 401, e.message);

View File

@ -18,6 +18,12 @@ class logModel extends baseModel {
} }
} }
/**
* @param {String} title log标题
* @param {String} content log内容
* @param {Enum} type log类型 ['user', 'group', 'interface', 'project', 'other']
* @param {Number} uid 用户id
*/
async save(data) { async save(data) {
let userInst = yapi.getInst(userModel); let userInst = yapi.getInst(userModel);
let username = await userInst.findById(data.uid); let username = await userInst.findById(data.uid);

View File

@ -41,7 +41,7 @@ class userModel extends baseModel{
} }
findByUids(uids){ findByUids(uids){
return this.model.find({ return this.model.find({
_id: {$in: [107]} _id: {$in: uids}
}).select("_id username email role add_time up_time").exec() }).select("_id username email role add_time up_time").exec()
} }
listWithPaging(page, limit) { listWithPaging(page, limit) {

View File

@ -134,4 +134,16 @@ exports.filterRes = (list, rules) => {
}); });
return filteredRes; return filteredRes;
}) })
}
exports.verifyPath = (path) => {
if (/^\/[a-zA-Z0-9\-\/_:]+$/.test(path)) {
if (path[path.length - 1] === '/') {
return false;
} else {
return true
}
} else {
return false;
}
} }

View File

@ -114,21 +114,29 @@ var interfaceController = function (_baseController) {
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '接口请求路径不能为空')); return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '接口请求路径不能为空'));
case 8: case 8:
_context.next = 10; if (_yapi2.default.commons.verifyPath(params.path)) {
return this.Model.checkRepeat(params.path, params.method); _context.next = 10;
break;
}
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '接口path第一位必须是/,最后一位不能为/'));
case 10: case 10:
_context.next = 12;
return this.Model.checkRepeat(params.path, params.method);
case 12:
checkRepeat = _context.sent; checkRepeat = _context.sent;
if (!(checkRepeat > 0)) { if (!(checkRepeat > 0)) {
_context.next = 13; _context.next = 15;
break; break;
} }
return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, '已存在的接口:' + params.path + '[' + params.method + ']')); return _context.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, '已存在的接口:' + params.path + '[' + params.method + ']'));
case 13: case 15:
_context.prev = 13; _context.prev = 15;
data = { data = {
project_id: params.project_id, project_id: params.project_id,
title: params.title, title: params.title,
@ -148,28 +156,28 @@ var interfaceController = function (_baseController) {
if (params.req_params_form) data.req_params_form = params.req_params_form; if (params.req_params_form) data.req_params_form = params.req_params_form;
if (params.req_params_other) data.req_params_other = params.req_params_other; if (params.req_params_other) data.req_params_other = params.req_params_other;
_context.next = 19; _context.next = 21;
return this.Model.save(data); return this.Model.save(data);
case 19: case 21:
result = _context.sent; result = _context.sent;
ctx.body = _yapi2.default.commons.resReturn(result); ctx.body = _yapi2.default.commons.resReturn(result);
_context.next = 26; _context.next = 28;
break; break;
case 23: case 25:
_context.prev = 23; _context.prev = 25;
_context.t0 = _context['catch'](13); _context.t0 = _context['catch'](15);
ctx.body = _yapi2.default.commons.resReturn(null, 402, _context.t0.message); ctx.body = _yapi2.default.commons.resReturn(null, 402, _context.t0.message);
case 26: case 28:
case 'end': case 'end':
return _context.stop(); return _context.stop();
} }
} }
}, _callee, this, [[13, 23]]); }, _callee, this, [[15, 25]]);
})); }));
function add(_x) { function add(_x) {
@ -359,25 +367,33 @@ var interfaceController = function (_baseController) {
case 8: case 8:
interfaceData = _context4.sent; interfaceData = _context4.sent;
if (!(params.path && params.path !== interfaceData.path && params.method !== interfaceData.method)) { if (!(params.path && !_yapi2.default.commons.verifyPath(params.path))) {
_context4.next = 15; _context4.next = 11;
break; break;
} }
_context4.next = 12; return _context4.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 400, '接口path第一位必须是/,最后一位不能为/'));
case 11:
if (!(params.path && params.path !== interfaceData.path && params.method !== interfaceData.method)) {
_context4.next = 17;
break;
}
_context4.next = 14;
return this.Model.checkRepeat(params.path, params.method); return this.Model.checkRepeat(params.path, params.method);
case 12: case 14:
checkRepeat = _context4.sent; checkRepeat = _context4.sent;
if (!(checkRepeat > 0)) { if (!(checkRepeat > 0)) {
_context4.next = 15; _context4.next = 17;
break; break;
} }
return _context4.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, '已存在的接口:' + params.path + '[' + params.method + ']')); return _context4.abrupt('return', ctx.body = _yapi2.default.commons.resReturn(null, 401, '已存在的接口:' + params.path + '[' + params.method + ']'));
case 15: case 17:
data = { data = {
up_time: _yapi2.default.commons.time() up_time: _yapi2.default.commons.time()
}; };
@ -396,29 +412,29 @@ var interfaceController = function (_baseController) {
if (params.res_body_type) data.res_body_type = params.res_body_type; if (params.res_body_type) data.res_body_type = params.res_body_type;
if (params.res_body) data.res_body = params.res_body; if (params.res_body) data.res_body = params.res_body;
_context4.prev = 25; _context4.prev = 27;
_context4.next = 28; _context4.next = 30;
return this.Model.up(id, data); return this.Model.up(id, data);
case 28: case 30:
result = _context4.sent; result = _context4.sent;
ctx.body = _yapi2.default.commons.resReturn(result); ctx.body = _yapi2.default.commons.resReturn(result);
_context4.next = 35; _context4.next = 37;
break; break;
case 32: case 34:
_context4.prev = 32; _context4.prev = 34;
_context4.t0 = _context4['catch'](25); _context4.t0 = _context4['catch'](27);
ctx.body = _yapi2.default.commons.resReturn(null, 402, _context4.t0.message); ctx.body = _yapi2.default.commons.resReturn(null, 402, _context4.t0.message);
case 35: case 37:
case 'end': case 'end':
return _context4.stop(); return _context4.stop();
} }
} }
}, _callee4, this, [[25, 32]]); }, _callee4, this, [[27, 34]]);
})); }));
function up(_x4) { function up(_x4) {

View File

@ -77,20 +77,11 @@ var projectController = function (_baseController) {
if (!basepath) return false; if (!basepath) return false;
if (basepath[0] !== '/') basepath = '/' + basepath; if (basepath[0] !== '/') basepath = '/' + basepath;
if (basepath[basepath.length - 1] === '/') basepath = basepath.substr(0, basepath.length - 1); if (basepath[basepath.length - 1] === '/') basepath = basepath.substr(0, basepath.length - 1);
if (!this.verifyPath(basepath)) { if (_yapi2.default.commons.verifyPath(basepath)) {
return false; return false;
} }
return basepath; return basepath;
} }
}, {
key: 'verifyPath',
value: function verifyPath(path) {
if (/^[a-zA-Z0-9\-\/_:]+$/.test(path)) {
return true;
} else {
return false;
}
}
}, { }, {
key: 'verifyDomain', key: 'verifyDomain',
value: function verifyDomain(domain) { value: function verifyDomain(domain) {
@ -594,11 +585,10 @@ var projectController = function (_baseController) {
uids = []; uids = [];
result.forEach(function (item) { result.forEach(function (item) {
if (uids.indexOf(item.uid) !== -1) { if (uids.indexOf(item.uid) === -1) {
uids.push(item.uid); uids.push(item.uid);
} }
}); });
_users = {}; _users = {};
_context6.next = 15; _context6.next = 15;
return _yapi2.default.getInst(_user2.default).findByUids(uids); return _yapi2.default.getInst(_user2.default).findByUids(uids);
@ -621,7 +611,7 @@ var projectController = function (_baseController) {
_context6.prev = 20; _context6.prev = 20;
_context6.t0 = _context6['catch'](3); _context6.t0 = _context6['catch'](3);
ctx.body = _yapi2.default.commons.resReturn(null, 402, e.message); ctx.body = _yapi2.default.commons.resReturn(null, 402, _context6.t0.message);
case 23: case 23:
case 'end': case 'end':
@ -742,7 +732,7 @@ var projectController = function (_baseController) {
* @param {String} [desc] 项目描述 * @param {String} [desc] 项目描述
* @param {Array} [env] 项目环境配置 * @param {Array} [env] 项目环境配置
* @param {String} [env[].name] 环境名称 * @param {String} [env[].name] 环境名称
* @param {String} [env[].host] 环境域名 * @param {String} [env[].domain] 环境域名
* @returns {Object} * @returns {Object}
* @example ./api/project/up.json * @example ./api/project/up.json
*/ */

View File

@ -301,7 +301,7 @@ var userController = function (_baseController) {
user = _context4.sent; user = _context4.sent;
if (!(!user || !user._id)) { if (!(!user || !user._id)) {
_context4.next = 12; _context4.next = 13;
break; break;
} }
@ -321,24 +321,29 @@ var userController = function (_baseController) {
case 11: case 11:
user = _context4.sent; user = _context4.sent;
case 12: _yapi2.default.commons.sendMail({
to: params.email,
contents: '<h3>\u4EB2\u7231\u7684\u7528\u6237\uFF1A</h3><p>\u60A8\u597D\uFF0C\u611F\u8C22\u4F7F\u7528YApi,\u7CFB\u7EDF\u68C0\u6D4B\u60A8\u662F\u7B2C\u4E00\u6B21\u7528Qsso\u8D26\u53F7\u767B\u5F55YApi\u670D\u52A1,\u60A8\u7684Email\u662F\uFF1A ' + params.email + ' \uFF0C\u521D\u59CB\u5316\u5BC6\u7801\u4E3A\uFF1A' + passsalt + '</p>'
});
case 13:
this.setLoginCookie(user._id, user.passsalt); this.setLoginCookie(user._id, user.passsalt);
return _context4.abrupt('return', true); return _context4.abrupt('return', true);
case 16: case 17:
_context4.prev = 16; _context4.prev = 17;
_context4.t0 = _context4['catch'](2); _context4.t0 = _context4['catch'](2);
console.error(_context4.t0.message); console.error(_context4.t0.message);
return _context4.abrupt('return', false); return _context4.abrupt('return', false);
case 20: case 21:
case 'end': case 'end':
return _context4.stop(); return _context4.stop();
} }
} }
}, _callee4, this, [[2, 16]]); }, _callee4, this, [[2, 17]]);
})); }));
function handleThirdLogin(_x4, _x5) { function handleThirdLogin(_x4, _x5) {
@ -605,7 +610,7 @@ var userController = function (_baseController) {
}); });
_yapi2.default.commons.sendMail({ _yapi2.default.commons.sendMail({
to: params.email, to: params.email,
contents: '\u6B22\u8FCE\u6CE8\u518C\uFF0C\u60A8\u7684\u8D26\u53F7 ' + params.email + ' \u5DF2\u7ECF\u6CE8\u518C\u6210\u529F' contents: '<h3>\u4EB2\u7231\u7684\u7528\u6237\uFF1A</h3><p>\u60A8\u597D\uFF0C\u611F\u8C22\u4F7F\u7528YApi,\u60A8\u7684\u8D26\u53F7 ' + params.email + ' \u5DF2\u7ECF\u6CE8\u518C\u6210\u529F</p>'
}); });
_context8.next = 26; _context8.next = 26;
break; break;
@ -855,15 +860,16 @@ var userController = function (_baseController) {
key: 'update', key: 'update',
value: function () { value: function () {
var _ref12 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee12(ctx) { var _ref12 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee12(ctx) {
var params, userInst, id, data, checkRepeat, result; var _params, userInst, id, data, checkRepeat, result;
return _regenerator2.default.wrap(function _callee12$(_context12) { return _regenerator2.default.wrap(function _callee12$(_context12) {
while (1) { while (1) {
switch (_context12.prev = _context12.next) { switch (_context12.prev = _context12.next) {
case 0: case 0:
_context12.prev = 0; _context12.prev = 0;
params = ctx.request.body; _params = ctx.request.body;
if (!(this.getRole() !== 'admin' && params.uid != this.getUid())) { if (!(this.getRole() !== 'admin' && _params.uid != this.getUid())) {
_context12.next = 4; _context12.next = 4;
break; break;
} }
@ -872,7 +878,7 @@ var userController = function (_baseController) {
case 4: case 4:
userInst = _yapi2.default.getInst(_user2.default); userInst = _yapi2.default.getInst(_user2.default);
id = params.uid; id = _params.uid;
if (id) { if (id) {
_context12.next = 8; _context12.next = 8;
@ -888,10 +894,10 @@ var userController = function (_baseController) {
}; };
if (this.getRole() === 'admin') { if (this.getRole() === 'admin') {
params.role && (data.role = params.role); _params.role && (data.role = _params.role);
} }
params.username && (data.username = params.username); _params.username && (data.username = _params.username);
params.email && (data.email = params.email); _params.email && (data.email = _params.email);
if (!data.email) { if (!data.email) {
_context12.next = 18; _context12.next = 18;

View File

@ -67,6 +67,14 @@ var logModel = function (_baseModel) {
add_time: Number add_time: Number
}; };
} }
/**
* @param {String} title log标题
* @param {String} content log内容
* @param {Enum} type log类型 ['user', 'group', 'interface', 'project', 'other']
* @param {Number} uid 用户id
*/
}, { }, {
key: 'save', key: 'save',
value: function () { value: function () {

View File

@ -91,7 +91,7 @@ var userModel = function (_baseModel) {
key: 'findByUids', key: 'findByUids',
value: function findByUids(uids) { value: function findByUids(uids) {
return this.model.find({ return this.model.find({
_id: { $in: [107] } _id: { $in: uids }
}).select("_id username email role add_time up_time").exec(); }).select("_id username email role add_time up_time").exec();
} }
}, { }, {

View File

@ -155,4 +155,16 @@ exports.filterRes = function (list, rules) {
}); });
return filteredRes; return filteredRes;
}); });
};
exports.verifyPath = function (path) {
if (/^\/[a-zA-Z0-9\-\/_:]+$/.test(path)) {
if (path[path.length - 1] === '/') {
return false;
} else {
return true;
}
} else {
return false;
}
}; };