// minio.js // Copyright (C) 2021 Digital Telepresence, LLC // License: Apache-2.0 'use strict'; const path = require('path'); const mongoose = require('mongoose'); const pug = require('pug'); const Link = mongoose.model('Link'); const LinkVisit = mongoose.model('LinkVisit'); const geoip = require('geoip-lite'); const striptags = require('striptags'); const { SiteService } = require('../../lib/site-lib'); const link = require('../models/link'); class LinkService extends SiteService { constructor (dtp) { super(dtp, module.exports); this.populateLink = [ { path: 'user', select: '_id username username_lc displayName picture', }, ]; } async start ( ) { this.templates = { }; let script = path.join(this.dtp.config.root, 'app', 'views', 'link', 'components', 'list-item-standalone.pug'); this.templates.link = pug.compileFile(script); } renderTemplate (templateId, viewModel) { return this.templates[templateId](viewModel); } async create (user, linkDefinition) { const NOW = new Date(); const link = new Link(); link.created = NOW; link.user = user._id; link.label = striptags(linkDefinition.label.trim()); link.href = striptags(linkDefinition.href.trim()); await link.save(); return link.toObject(); } async update (link, linkDefinition) { const updateOp = { $set: { } }; if (linkDefinition.label) { link.label = updateOp.$set.label = striptags(linkDefinition.label.trim()); } if (linkDefinition.href) { link.href = updateOp.$set.href = striptags(linkDefinition.href.trim()); } await Link.updateOne({ _id: link._id }, updateOp); } async getById (linkId) { const link = await Link .findById(linkId) .populate(this.populateLink) .lean(); return link; } async getForUser (user, pagination) { const links = await Link .find({ user: user._id }) .sort({ order: 1 }) .skip(pagination.skip) .limit(pagination.cpp) .lean(); return links; } async remove (link) { this.log.debug('removing link visit records', { link: link._id }); await LinkVisit.deleteMany({ link: link._id }); const { resource: resourceService } = this.dtp.services; await resourceService.remove('Link', link._id); } async recordVisit (link, req) { const NOW = new Date(); const visit = new LinkVisit(); visit.created = NOW; visit.link = link._id; if (req.user) { visit.user = req.user._id; } /* * We geo-analyze (but do not store) the IP address. */ const geo = geoip.lookup(req.ip); if (geo) { visit.geoip = { country: geo.country, region: geo.region, eu: geo.eu, timezone: geo.timezone, city: geo.city, location: geo.ll, }; } await visit.save(); } async setItemOrder (links) { for await (const link of links) { this.log.debug('set link order', { link }); await Link.updateOne({ _id: link._id }, { $set: { order: link.order } }); } } } module.exports = { slug: 'link', name: 'link', create: (dtp) => { return new LinkService(dtp); }, };