3 changed files with 166 additions and 4 deletions
@ -0,0 +1,158 @@ |
|||||
|
// hive/user.js
|
||||
|
// Copyright (C) 2022 DTP Technologies, LLC
|
||||
|
// License: Apache-2.0
|
||||
|
|
||||
|
'use strict'; |
||||
|
|
||||
|
const fs = require('fs'); |
||||
|
|
||||
|
const express = require('express'); |
||||
|
const mongoose = require('mongoose'); |
||||
|
|
||||
|
const { SiteController, SiteError } = require('../../../lib/site-lib'); |
||||
|
|
||||
|
class HiveUserController extends SiteController { |
||||
|
|
||||
|
constructor (dtp) { |
||||
|
super(dtp, module.exports); |
||||
|
|
||||
|
this.methods = [ |
||||
|
{ |
||||
|
name: 'getResolveUsers', |
||||
|
url: '/resolve', |
||||
|
params: { |
||||
|
'q': 'string', |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
name: 'getUserProfile', |
||||
|
url: '/:userId', |
||||
|
method: 'GET', |
||||
|
}, |
||||
|
]; |
||||
|
} |
||||
|
|
||||
|
async start ( ) { |
||||
|
const router = express.Router(); |
||||
|
router.use(async (req, res, next) => { |
||||
|
res.locals.currentView = 'hive'; |
||||
|
return next(); |
||||
|
}); |
||||
|
|
||||
|
router.param('userId', this.populateUserId.bind(this)); |
||||
|
|
||||
|
router.get('/resolve', this.getResolveUser.bind(this)); |
||||
|
|
||||
|
router.get('/:userId/picture', this.getUserPicture.bind(this)); |
||||
|
router.get('/:userId', this.getUserProfile.bind(this)); |
||||
|
|
||||
|
router.get('/', this.getCoreUserRoot.bind(this)); |
||||
|
|
||||
|
return router; |
||||
|
} |
||||
|
|
||||
|
async populateUserId (req, res, next, userId) { |
||||
|
const { user: userService } = this.dtp.services; |
||||
|
try { |
||||
|
userId = mongoose.Types.ObjectId(userId); |
||||
|
res.locals.userProfile = await userService.getUserProfile(userId); |
||||
|
if (!res.locals.userProfile) { |
||||
|
throw new SiteError(404, 'User profile not found'); |
||||
|
} |
||||
|
res.locals.userProfile = userService.filterUserObject(res.locals.userProfile); |
||||
|
res.locals.userProfile.picture.large.imageUri = `/image/${res.locals.userProfile.picture.large._id}`; |
||||
|
res.locals.userProfile.picture.small.imageUri = `/image/${res.locals.userProfile.picture.small._id}`; |
||||
|
return next(); |
||||
|
} catch (error) { |
||||
|
this.log.error('failed to provide User profile', { userId, error }); |
||||
|
return res.status(error.statusCode || 500).json({ success: false, message: error.message }); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async getResolveUser (req, res) { |
||||
|
const { user: userService } = this.dtp.services; |
||||
|
res.locals.hiveView = 'resolve-user'; |
||||
|
|
||||
|
try { |
||||
|
if (!req.query.q || !req.query.q.length) { |
||||
|
throw new SiteError(406, 'Must include search term'); |
||||
|
} |
||||
|
|
||||
|
res.locals.q = await userService.filterUsername(req.query.q); |
||||
|
res.locals.pagination = this.getPaginationParameters(req, 20); |
||||
|
res.locals.userProfiles = await userService.getUserAccounts(res.locals.pagination, res.locals.q); |
||||
|
res.locals.userProfiles = res.locals.userProfiles.map((user) => { |
||||
|
const apiUser = userService.filterUserObject(user); |
||||
|
apiUser.picture.large = `/image/${user.picture.large}`; |
||||
|
apiUser.picture.small = `/image/${user.picture.small}`; |
||||
|
return apiUser; |
||||
|
}); |
||||
|
|
||||
|
res.status(200).json({ |
||||
|
success: true, |
||||
|
pagination: res.locals.pagination, |
||||
|
count: res.locals.userProfiles.length, |
||||
|
params: { |
||||
|
q: res.locals.q, |
||||
|
}, |
||||
|
users: res.locals.userProfiles, |
||||
|
}); |
||||
|
} catch (error) { |
||||
|
this.log.error("failed to resolve user accounts", { error }); |
||||
|
res.status(error.statusCode || 500).json({ success: false, message: error.message }); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async getUserPicture (req, res) { |
||||
|
const { hostCache: hostCacheService } = this.dtp.services; |
||||
|
const image = res.locals.userProfile.picture[req.query.s || 'small']; |
||||
|
|
||||
|
res.locals.hiveView = 'user-picture'; |
||||
|
|
||||
|
if (!image) { |
||||
|
return res.status(404).end('Image not found'); |
||||
|
} |
||||
|
|
||||
|
try { |
||||
|
const fileInfo = await hostCacheService.getFile(image.file.bucket, image.file.key); |
||||
|
const stream = fs.createReadStream(fileInfo.file.path); |
||||
|
res.header('Content-Type', image.type); |
||||
|
res.header('Content-Length', fileInfo.file.stats.size); |
||||
|
res.status(200); |
||||
|
stream.pipe(res); |
||||
|
} catch (error) { |
||||
|
this.log.error('failed to fetch image', { image, error }); |
||||
|
return res.status(error.statusCode || 500).json({ |
||||
|
success: false, |
||||
|
message: error.message, |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
async getUserProfile (req, res) { |
||||
|
res.locals.hiveView = 'user-profile'; |
||||
|
res.status(200).json({ |
||||
|
success: true, |
||||
|
user: res.locals.userProfile, |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
async getCoreUserRoot (req, res) { |
||||
|
res.locals.hiveView = 'info'; |
||||
|
res.status(200).json({ |
||||
|
component: this.component, |
||||
|
version: this.dtp.pkg.version, |
||||
|
services: this.services, |
||||
|
methods: this.methods, |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
module.exports = { |
||||
|
name: 'hiveUser', |
||||
|
slug: 'hive-user', |
||||
|
create: async (dtp) => { |
||||
|
let controller = new HiveUserController(dtp); |
||||
|
return controller; |
||||
|
}, |
||||
|
}; |
Loading…
Reference in new issue