'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 config = require('../config.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 = []; topNavigation.setTitle('User ' + userName); User.get(userName).then(async user => { 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'); } let userTokens = []; if (section === 'list-tokens') { userTokens = await UserToken.get(userName) .then(response => { return response; }, error => { return []; }); } 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)); for (let i = 0; i < this._successMessages.length; i++) { this.showSuccess(this._successMessages[i]); } for (let i = 0; i < this._errorMessages.length; i++) { this.showError(this._errorMessages[i]); } }, 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) .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(); 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(); }); } } 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'); }); };