'use strict'; const router = require('../router.js'); const api = require('../api.js'); const uri = require('../util/uri.js'); const misc = require('../util/misc.js'); const views = require('../util/views.js'); const User = require('../models/user.js'); const UserToken = require('../models/user_token.js'); const topNavigation = require('../models/top_navigation.js'); const UserView = require('../views/user_view.js'); const EmptyView = require('../views/empty_view.js'); class UserController { constructor(ctx, section) { const userName = ctx.parameters.name; if (!api.hasPrivilege('users:view') && !api.isLoggedIn({name: userName})) { this._view = new EmptyView(); this._view.showError('You don\'t have privileges to view users.'); return; } this._successMessages = []; this._errorMessages = []; let userTokenPromise = Promise.resolve([]); if (section === 'list-tokens') { userTokenPromise = UserToken.get(userName) .then(userTokens => { return userTokens.map(token => { token.isCurrentAuthToken = api.isCurrentAuthToken(token); return token; }); }, error => { return []; }); } topNavigation.setTitle('User ' + userName); Promise.all([ userTokenPromise, User.get(userName) ]).then(responses => { const [userTokens, user] = responses; const isLoggedIn = api.isLoggedIn(user); const infix = isLoggedIn ? 'self' : 'any'; this._name = userName; user.addEventListener('change', e => this._evtSaved(e, section)); const myRankIndex = api.user ? api.allRanks.indexOf(api.user.rank) : 0; let ranks = {}; for (let [rankIdx, rankIdentifier] of api.allRanks.entries()) { if (rankIdentifier === 'anonymous') { continue; } if (rankIdx > myRankIndex) { continue; } ranks[rankIdentifier] = api.rankNames.get(rankIdentifier); } if (isLoggedIn) { topNavigation.activate('account'); } else { topNavigation.activate('users'); } this._view = new UserView({ 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}`), canListTokens: api.hasPrivilege(`userTokens:list:${infix}`), canCreateToken: api.hasPrivilege(`userTokens:create:${infix}`), canEditToken: api.hasPrivilege(`userTokens:edit:${infix}`), canDeleteToken: api.hasPrivilege(`userTokens:delete:${infix}`), canDelete: api.hasPrivilege(`users:delete:${infix}`), ranks: ranks, tokens: userTokens, }); this._view.addEventListener('change', e => this._evtChange(e)); this._view.addEventListener('submit', e => this._evtUpdate(e)); this._view.addEventListener('delete', e => this._evtDelete(e)); this._view.addEventListener('create-token', e => this._evtCreateToken(e)); this._view.addEventListener('delete-token', e => this._evtDeleteToken(e)); this._view.addEventListener('update-token', e => this._evtUpdateToken(e)); for (let message of this._successMessages) { this.showSuccess(message); } for (let message of this._errorMessages) { this.showError(message); } }, error => { this._view = new EmptyView(); this._view.showError(error.message); }); } showSuccess(message) { if (typeof this._view === 'undefined') { this._successMessages.push(message) } else { this._view.showSuccess(message); } } showError(message) { if (typeof this._view === 'undefined') { this._errorMessages.push(message) } else { this._view.showError(message); } } _evtChange(e) { misc.enableExitConfirmation(); } _evtSaved(e, section) { misc.disableExitConfirmation(); if (this._name !== e.detail.user.name) { router.replace( uri.formatClientLink('user', e.detail.user.name, section), null, false); } } _evtUpdate(e) { this._view.clearMessages(); this._view.disableForm(); const isLoggedIn = api.isLoggedIn(e.detail.user); const infix = isLoggedIn ? 'self' : 'any'; if (e.detail.name !== undefined) { e.detail.user.name = e.detail.name; } if (e.detail.email !== undefined) { e.detail.user.email = e.detail.email; } if (e.detail.rank !== undefined) { e.detail.user.rank = e.detail.rank; } if (e.detail.password !== undefined) { e.detail.user.password = e.detail.password; } if (e.detail.avatarStyle !== undefined) { e.detail.user.avatarStyle = e.detail.avatarStyle; if (e.detail.avatarContent) { e.detail.user.avatarContent = e.detail.avatarContent; } } e.detail.user.save().then(() => { return isLoggedIn ? api.login( e.detail.name || api.userName, e.detail.password || api.userPassword, false) : Promise.resolve(); }).then(() => { this._view.showSuccess('Settings updated.'); this._view.enableForm(); }, error => { this._view.showError(error.message); this._view.enableForm(); }); } _evtDelete(e) { this._view.clearMessages(); this._view.disableForm(); const isLoggedIn = api.isLoggedIn(e.detail.user); e.detail.user.delete() .then(() => { if (isLoggedIn) { api.forget(); api.logout(); } if (api.hasPrivilege('users:list')) { const ctx = router.show(uri.formatClientLink('users')); ctx.controller.showSuccess('Account deleted.'); } else { const ctx = router.show(uri.formatClientLink()); ctx.controller.showSuccess('Account deleted.'); } }, error => { this._view.showError(error.message); this._view.enableForm(); }); } _evtCreateToken(e) { this._view.clearMessages(); this._view.disableForm(); UserToken.create(e.detail.user.name, e.detail.note, e.detail.expirationTime) .then(response => { const ctx = router.show(uri.formatClientLink('user', e.detail.user.name, 'list-tokens')); ctx.controller.showSuccess('Token ' + response.token + ' created.'); }, error => { this._view.showError(error.message); this._view.enableForm(); }); } _evtDeleteToken(e) { this._view.clearMessages(); this._view.disableForm(); if (api.isCurrentAuthToken(e.detail.userToken)) { router.show(uri.formatClientLink('logout')); } else { e.detail.userToken.delete(e.detail.user.name) .then(() => { const ctx = router.show(uri.formatClientLink('user', e.detail.user.name, 'list-tokens')); ctx.controller.showSuccess('Token ' + e.detail.userToken.token + ' deleted.'); }, error => { this._view.showError(error.message); this._view.enableForm(); }); } } _evtUpdateToken(e) { this._view.clearMessages(); this._view.disableForm(); if (e.detail.note !== undefined) { e.detail.userToken.note = e.detail.note; } e.detail.userToken.save(e.detail.user.name).then(response => { const ctx = router.show(uri.formatClientLink('user', e.detail.user.name, 'list-tokens')); ctx.controller.showSuccess('Token ' + response.token + ' updated.'); }, error => { this._view.showError(error.message); this._view.enableForm(); }); } } module.exports = router => { router.enter(['user', ':name'], (ctx, next) => { ctx.controller = new UserController(ctx, 'summary'); }); router.enter(['user', ':name', 'edit'], (ctx, next) => { ctx.controller = new UserController(ctx, 'edit'); }); router.enter(['user', ':name', 'list-tokens'], (ctx, next) => { ctx.controller = new UserController(ctx, 'list-tokens'); }); router.enter(['user', ':name', 'delete'], (ctx, next) => { ctx.controller = new UserController(ctx, 'delete'); }); };