2016-03-19 21:37:04 +01:00
|
|
|
'use strict';
|
|
|
|
|
2016-03-28 22:33:20 +02:00
|
|
|
const page = require('page');
|
2016-04-01 00:20:34 +02:00
|
|
|
const api = require('../api.js');
|
2016-04-07 22:54:45 +02:00
|
|
|
const config = require('../config.js');
|
2016-04-07 19:03:49 +02:00
|
|
|
const events = require('../events.js');
|
2016-04-07 22:54:45 +02:00
|
|
|
const misc = require('../util/misc.js');
|
2016-04-09 18:54:23 +02:00
|
|
|
const views = require('../util/views.js');
|
2016-04-01 00:20:34 +02:00
|
|
|
const topNavController = require('../controllers/top_nav_controller.js');
|
2016-04-10 22:13:01 +02:00
|
|
|
const pageController = require('../controllers/page_controller.js');
|
2016-04-01 00:20:34 +02:00
|
|
|
const RegistrationView = require('../views/registration_view.js');
|
2016-04-06 21:49:26 +02:00
|
|
|
const UserView = require('../views/user_view.js');
|
2016-04-14 12:11:31 +02:00
|
|
|
const UserListHeaderView = require('../views/user_list_header_view.js');
|
|
|
|
const UserListPageView = require('../views/user_list_page_view.js');
|
2016-04-09 22:35:09 +02:00
|
|
|
const EmptyView = require('../views/empty_view.js');
|
2016-03-28 22:33:20 +02:00
|
|
|
|
2016-03-19 21:37:04 +01:00
|
|
|
class UsersController {
|
2016-04-01 00:20:34 +02:00
|
|
|
constructor() {
|
|
|
|
this.registrationView = new RegistrationView();
|
2016-04-06 21:49:26 +02:00
|
|
|
this.userView = new UserView();
|
2016-04-14 12:11:31 +02:00
|
|
|
this.userListHeaderView = new UserListHeaderView();
|
|
|
|
this.userListPageView = new UserListPageView();
|
2016-04-09 22:35:09 +02:00
|
|
|
this.emptyView = new EmptyView();
|
2016-04-06 21:49:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
registerRoutes() {
|
|
|
|
page('/register', () => { this.createUserRoute(); });
|
2016-04-10 22:13:01 +02:00
|
|
|
page(
|
|
|
|
'/users/:query?',
|
|
|
|
(ctx, next) => { misc.parseSearchQueryRoute(ctx, next); },
|
|
|
|
(ctx, next) => { this.listUsersRoute(ctx, next); });
|
2016-04-06 21:49:26 +02:00
|
|
|
page(
|
|
|
|
'/user/:name',
|
2016-04-06 22:34:21 +02:00
|
|
|
(ctx, next) => { this.loadUserRoute(ctx, next); },
|
|
|
|
(ctx, next) => { this.showUserRoute(ctx, next); });
|
2016-04-06 21:49:26 +02:00
|
|
|
page(
|
|
|
|
'/user/:name/edit',
|
2016-04-06 22:34:21 +02:00
|
|
|
(ctx, next) => { this.loadUserRoute(ctx, next); },
|
|
|
|
(ctx, next) => { this.editUserRoute(ctx, next); });
|
2016-04-09 09:52:00 +02:00
|
|
|
page(
|
|
|
|
'/user/:name/delete',
|
|
|
|
(ctx, next) => { this.loadUserRoute(ctx, next); },
|
|
|
|
(ctx, next) => { this.deleteUserRoute(ctx, next); });
|
2016-04-12 23:49:46 +02:00
|
|
|
page.exit(/\/users\/.*/, (ctx, next) => {
|
|
|
|
pageController.stop();
|
|
|
|
next();
|
|
|
|
});
|
|
|
|
page.exit(/\/user\/.*/, (ctx, next) => {
|
|
|
|
this.user = null;
|
|
|
|
next();
|
|
|
|
});
|
2016-03-19 21:37:04 +01:00
|
|
|
}
|
|
|
|
|
2016-04-10 22:13:01 +02:00
|
|
|
listUsersRoute(ctx, next) {
|
2016-04-01 00:20:34 +02:00
|
|
|
topNavController.activate('users');
|
2016-04-10 22:13:01 +02:00
|
|
|
|
|
|
|
pageController.run({
|
2016-04-14 00:41:02 +02:00
|
|
|
state: ctx.state,
|
2016-04-10 22:13:01 +02:00
|
|
|
requestPage: page => {
|
|
|
|
return api.get(
|
|
|
|
'/users/?query={text}&page={page}&pageSize=30'.format({
|
|
|
|
text: ctx.searchQuery.text,
|
|
|
|
page: page}));
|
|
|
|
},
|
2016-04-13 22:14:00 +02:00
|
|
|
clientUrl: '/users/' + misc.formatSearchQuery({
|
|
|
|
text: ctx.searchQuery.text, page: '{page}'}),
|
2016-04-14 12:11:31 +02:00
|
|
|
searchQuery: ctx.searchQuery,
|
|
|
|
headerRenderer: this.userListHeaderView,
|
|
|
|
pageRenderer: this.userListPageView,
|
2016-04-10 22:13:01 +02:00
|
|
|
});
|
2016-03-19 21:37:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
createUserRoute() {
|
2016-04-01 00:20:34 +02:00
|
|
|
topNavController.activate('register');
|
2016-04-07 22:54:45 +02:00
|
|
|
this.registrationView.render({
|
|
|
|
register: (...args) => {
|
|
|
|
return this._register(...args);
|
|
|
|
}});
|
|
|
|
}
|
|
|
|
|
|
|
|
loadUserRoute(ctx, next) {
|
|
|
|
if (ctx.state.user) {
|
|
|
|
next();
|
|
|
|
} else if (this.user && this.user.name == ctx.params.name) {
|
|
|
|
ctx.state.user = this.user;
|
|
|
|
next();
|
|
|
|
} else {
|
|
|
|
api.get('/user/' + ctx.params.name).then(response => {
|
|
|
|
ctx.state.user = response.user;
|
|
|
|
ctx.save();
|
|
|
|
this.user = response.user;
|
|
|
|
next();
|
2016-04-09 23:41:56 +02:00
|
|
|
}, response => {
|
2016-04-09 22:35:09 +02:00
|
|
|
this.emptyView.render();
|
2016-04-07 22:54:45 +02:00
|
|
|
events.notify(events.Error, response.description);
|
|
|
|
});
|
|
|
|
}
|
2016-04-01 00:20:34 +02:00
|
|
|
}
|
|
|
|
|
2016-04-09 09:52:00 +02:00
|
|
|
showUserRoute(ctx, next) {
|
|
|
|
this._show(ctx.state.user, 'summary');
|
|
|
|
}
|
|
|
|
|
|
|
|
editUserRoute(ctx, next) {
|
|
|
|
this._show(ctx.state.user, 'edit');
|
|
|
|
}
|
|
|
|
|
|
|
|
deleteUserRoute(ctx, next) {
|
|
|
|
this._show(ctx.state.user, 'delete');
|
|
|
|
}
|
|
|
|
|
2016-04-01 00:20:34 +02:00
|
|
|
_register(name, password, email) {
|
|
|
|
const data = {
|
2016-04-08 10:01:32 +02:00
|
|
|
name: name,
|
|
|
|
password: password,
|
|
|
|
email: email
|
2016-04-01 00:20:34 +02:00
|
|
|
};
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
api.post('/users/', data).then(() => {
|
2016-04-09 19:53:53 +02:00
|
|
|
api.forget();
|
2016-04-09 23:41:56 +02:00
|
|
|
return api.login(name, password, false);
|
|
|
|
}, response => {
|
|
|
|
return Promise.reject(response.description);
|
|
|
|
}).then(() => {
|
|
|
|
resolve();
|
|
|
|
page('/');
|
|
|
|
events.notify(events.Success, 'Welcome aboard!');
|
|
|
|
}, errorMessage => {
|
2016-04-08 13:17:00 +02:00
|
|
|
reject();
|
2016-04-09 23:41:56 +02:00
|
|
|
events.notify(events.Error, errorMessage);
|
2016-04-01 00:20:34 +02:00
|
|
|
});
|
|
|
|
});
|
2016-03-19 21:37:04 +01:00
|
|
|
}
|
|
|
|
|
2016-04-10 15:55:56 +02:00
|
|
|
_edit(user, data) {
|
2016-04-29 13:19:11 +02:00
|
|
|
const isLoggedIn = api.isLoggedIn(user);
|
|
|
|
const infix = isLoggedIn ? 'self' : 'any';
|
2016-04-10 15:55:56 +02:00
|
|
|
let files = [];
|
|
|
|
|
|
|
|
if (!data.name) {
|
|
|
|
delete data.name;
|
|
|
|
}
|
|
|
|
if (!data.password) {
|
|
|
|
delete data.password;
|
|
|
|
}
|
2016-04-29 13:19:11 +02:00
|
|
|
if (!api.hasPrivilege('users:edit:' + infix + ':email')) {
|
2016-04-10 15:55:56 +02:00
|
|
|
delete data.email;
|
|
|
|
}
|
|
|
|
if (!data.rank) {
|
|
|
|
delete data.rank;
|
|
|
|
}
|
|
|
|
if (!data.avatarStyle ||
|
|
|
|
(data.avatarStyle == user.avatarStyle && !data.avatarContent)) {
|
|
|
|
delete data.avatarStyle;
|
|
|
|
}
|
|
|
|
if (data.avatarContent) {
|
|
|
|
files.avatar = data.avatarContent;
|
|
|
|
}
|
|
|
|
|
2016-04-07 22:54:45 +02:00
|
|
|
return new Promise((resolve, reject) => {
|
2016-04-10 15:55:56 +02:00
|
|
|
api.put('/user/' + user.name, data, files)
|
2016-04-07 22:54:45 +02:00
|
|
|
.then(response => {
|
2016-04-10 15:55:56 +02:00
|
|
|
this.user = response.user;
|
2016-04-09 23:41:56 +02:00
|
|
|
return isLoggedIn ?
|
2016-04-07 22:54:45 +02:00
|
|
|
api.login(
|
2016-04-10 15:55:56 +02:00
|
|
|
data.name || api.userName,
|
|
|
|
data.password || api.userPassword,
|
|
|
|
false) :
|
2016-04-09 23:41:56 +02:00
|
|
|
Promise.fulfill();
|
|
|
|
}, response => {
|
|
|
|
return Promise.reject(response.description);
|
|
|
|
}).then(() => {
|
|
|
|
resolve();
|
2016-04-10 15:55:56 +02:00
|
|
|
if (data.name && data.name !== user.name) {
|
|
|
|
page('/user/' + data.name + '/edit');
|
2016-04-07 22:54:45 +02:00
|
|
|
}
|
2016-04-09 23:41:56 +02:00
|
|
|
events.notify(events.Success, 'Settings updated.');
|
|
|
|
}, errorMessage => {
|
2016-04-07 22:54:45 +02:00
|
|
|
reject();
|
2016-04-09 23:41:56 +02:00
|
|
|
events.notify(events.Error, errorMessage);
|
2016-04-07 22:54:45 +02:00
|
|
|
});
|
|
|
|
});
|
2016-04-06 22:34:21 +02:00
|
|
|
}
|
|
|
|
|
2016-04-09 09:52:00 +02:00
|
|
|
_delete(user) {
|
2016-04-16 15:07:33 +02:00
|
|
|
const isLoggedIn = api.isLoggedIn(user);
|
2016-04-09 09:52:00 +02:00
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
api.delete('/user/' + user.name)
|
|
|
|
.then(response => {
|
|
|
|
if (isLoggedIn) {
|
2016-04-09 19:53:53 +02:00
|
|
|
api.forget();
|
2016-04-09 09:52:00 +02:00
|
|
|
api.logout();
|
|
|
|
}
|
|
|
|
resolve();
|
|
|
|
if (api.hasPrivilege('users:list')) {
|
|
|
|
page('/users');
|
|
|
|
} else {
|
|
|
|
page('/');
|
|
|
|
}
|
|
|
|
events.notify(events.Success, 'Account deleted');
|
2016-04-09 23:41:56 +02:00
|
|
|
}, response => {
|
2016-04-09 09:52:00 +02:00
|
|
|
reject();
|
|
|
|
events.notify(events.Error, response.description);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2016-04-06 22:34:21 +02:00
|
|
|
_show(user, section) {
|
2016-04-16 15:07:33 +02:00
|
|
|
const isLoggedIn = api.isLoggedIn(user);
|
2016-04-07 22:54:45 +02:00
|
|
|
const infix = isLoggedIn ? 'self' : 'any';
|
|
|
|
|
|
|
|
const myRankIdx = api.user ? config.ranks.indexOf(api.user.rank) : 0;
|
|
|
|
const rankNames = Object.values(config.rankNames);
|
|
|
|
let ranks = {};
|
|
|
|
for (let rankIdx of misc.range(config.ranks.length)) {
|
|
|
|
const rankIdentifier = config.ranks[rankIdx];
|
|
|
|
if (rankIdentifier === 'anonymous') {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (rankIdx > myRankIdx) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
ranks[rankIdentifier] = rankNames[rankIdx];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isLoggedIn) {
|
2016-04-01 00:20:34 +02:00
|
|
|
topNavController.activate('account');
|
2016-03-19 21:37:04 +01:00
|
|
|
} else {
|
2016-04-01 00:20:34 +02:00
|
|
|
topNavController.activate('users');
|
2016-03-19 21:37:04 +01:00
|
|
|
}
|
2016-04-06 22:34:21 +02:00
|
|
|
this.userView.render({
|
2016-04-07 22:54:45 +02:00
|
|
|
user: user,
|
|
|
|
section: section,
|
|
|
|
isLoggedIn: isLoggedIn,
|
|
|
|
canEditName: api.hasPrivilege('users:edit:' + infix + ':name'),
|
|
|
|
canEditPassword: api.hasPrivilege('users:edit:' + infix + ':pass'),
|
|
|
|
canEditEmail: api.hasPrivilege('users:edit:' + infix + ':email'),
|
|
|
|
canEditRank: api.hasPrivilege('users:edit:' + infix + ':rank'),
|
|
|
|
canEditAvatar: api.hasPrivilege('users:edit:' + infix + ':avatar'),
|
|
|
|
canEditAnything: api.hasPrivilege('users:edit:' + infix),
|
2016-04-09 09:52:00 +02:00
|
|
|
canDelete: api.hasPrivilege('users:delete:' + infix),
|
2016-04-07 22:54:45 +02:00
|
|
|
ranks: ranks,
|
|
|
|
edit: (...args) => { return this._edit(user, ...args); },
|
2016-04-09 09:52:00 +02:00
|
|
|
delete: (...args) => { return this._delete(user, ...args); },
|
2016-04-07 22:54:45 +02:00
|
|
|
});
|
2016-03-19 21:37:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-01 00:20:34 +02:00
|
|
|
module.exports = new UsersController();
|