const { Controller } = require('libflitter') const Validator = require('email-validator') const path = require('path') class ProfileController extends Controller { static get services() { return [...super.services, 'models', 'utility'] } async fetch(req, res, next) { const User = this.models.get('auth:User') let user if ( req.params.user_id === 'me' ) user = req.user else { // if not me, verify that user can view profile if ( !req.user.can(`profile:view:${req.params.user_id}`) ) return res.status(401).api() user = await User.findById(req.params.user_id) } return res.api({ first_name: user.first_name, last_name: user.last_name, email: user.email, uid: user.uid, tagline: user.tagline || '', user_id: user.id, login_shell: user.login_shell || '', ...(user.notify_config ? { notify_config: await user.notify_config.to_api() } : {}) }) } async fetch_notify(req, res, next) { const User = this.models.get('auth:User') let user if ( req.params.user_id === 'me' ) user = req.user else { // If not me, verify that user can modify profile if ( !req.user.can(`profile:update:${req.params.user_id}`) ) return res.status(401).api() user = await User.findById(req.params.user_id) } if ( !user ) return res.status(404) .message(req.T('api.user_not_found')) .api() if ( user.notify_config ) { return res.api({ has_config: true, config: await user.notify_config.to_api(), }) } else { return res.api({ has_config: false, }) } } async test_notify(req, res, next) { const User = this.models.get('auth:User') let user if ( req.params.user_id === 'me' ) user = req.user else { // If not me, verify that user can modify profile if ( !req.user.can(`profile:update:${req.params.user_id}`) ) return res.status(401).api() user = await User.findById(req.params.user_id) } if ( !user ) return res.status(404) .message(req.T('api.user_not_found')) .api() if ( user.notify_config && user.notify_config.active ) { await user.notify_config.log({ message: req.T('profile.test_notification'), }) } return res.api() } async update_notify(req, res, next) { const User = this.models.get('auth:User') const NotifyConfig = this.models.get('system:NotifyConfig') let user if ( req.params.user_id === 'me' ) user = req.user else { // If not me, verify that user can modify profile if ( !req.user.can(`profile:update:${req.params.user_id}`) ) return res.status(401).api() user = await User.findById(req.params.user_id) } if ( !user ) return res.status(404) .message(req.T('api.user_not_found')) .api() if ( !user.notify_config ) { user.notify_config = new NotifyConfig({ user_id: user.id, gateway_url: String(req.body.gateway_url), application_key: String(req.body.app_key), created_on: new Date, active: String(req.body.app_key) && String(req.body.gateway_url), }, user) } else { user.notify_config.application_key = String(req.body.app_key) user.notify_config.gateway_url = String(req.body.gateway_url) user.notify_config.active = String(req.body.app_key) && String(req.body.gateway_url) } await user.save() return res.api() } async update(req, res, next) { const User = this.models.get('auth:User') const Message = this.models.get('Message') const Setting = this.models.get('Setting') let user if ( req.params.user_id === 'me' ) user = req.user else { // If not me, verify that user can modify profile if ( !req.user.can(`profile:update:${req.params.user_id}`) ) return res.status(401).api() user = await User.findById(req.params.user_id) } if ( !user ) return res.status(404) .message(req.T('api.user_not_found')) .api() // Make sure the required fields are provided const required_fields = ['first_name', 'last_name', 'email'] for ( const field of required_fields ) { if ( !req.body[field]?.trim() ) return res.status(400) .message(`${req.T('api.missing_field')} ${field}`) .api() } // Validate the e-mail if ( !Validator.validate(req.body.email) ) return res.status(400) .message(`${req.T('api.improper_field')} email ${req.T('api.email')}`) .api() // Update the user's profile if ( user.email !== req.body.email && (await Setting.get('auth.require_email_verify')) ) { await req.trap.begin('verify_email', { session_only: false }) await Message.create(req.user, 'Your e-mail address has changed, and a verification e-mail has been sent. You must complete this process to continue.') } user.first_name = req.body.first_name user.last_name = req.body.last_name user.email = req.body.email user.tagline = req.body.tagline user.login_shell = req.body.login_shell // Save the record await user.save() return res.api({ force_message_refresh: true, }) } async update_photo(req, res, next) { const User = this.models.get('auth:User') let user if ( req.params.user_id === 'me' ) user = req.user else user = await User.findById(req.params.user_id) if ( !user ) return res.status(404) .message(req.T('api.user_not_found')) .api() if ( !req?.uploads?.photo ) return res.status(400) .message(`${req.T('api.missing_field')} file`) .api() user.photo_file_id = req.uploads.photo.id await user.save() return res.api() } async get_photo(req, res, next) { const User = this.models.get('auth:User') let user if ( req.params.user_id === 'me' ) user = req.user else user = await User.findById(req.params.user_id) if ( !user ) return res.status(404) .message(req.T('api.user_not_found')) .api() const photo = await user.photo() if ( photo ) return photo.send(res) // The user does not have a profile. Send the default. return res.sendFile(this.utility.path('app/assets/people.png')) } } module.exports = exports = ProfileController