"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"); }); };