Browse Source

switch links to a[href, onclick]

pull/1/head
Rob Colbert 2 years ago
parent
commit
1737a1a5bb
  1. 11
      app/controllers/admin.js
  2. 84
      app/controllers/home.js
  3. 12
      app/controllers/link.js
  4. 33
      app/services/user.js
  5. 7
      app/views/profile/home.pug
  6. 10
      client/js/site-app.js
  7. 2
      config/limiter.js

11
app/controllers/admin.js

@ -51,11 +51,22 @@ class AdminController extends SiteController {
router.use('/settings',await this.loadChild(path.join(__dirname, 'admin', 'settings')));
router.use('/user', await this.loadChild(path.join(__dirname, 'admin', 'user')));
router.get('/diagnostics', this.getDiagnostics.bind(this));
router.get('/', this.getHomeView.bind(this));
return router;
}
async getDiagnostics (req, res) {
res.status(200).json({
success: true,
url: req.url,
ip: req.ip,
headers: req.headers,
});
}
async getHomeView (req, res) {
const { link: linkService, dashboard: dashboardService } = this.dtp.services;
res.locals.stats = {

84
app/controllers/home.js

@ -8,6 +8,8 @@ const DTP_COMPONENT_NAME = 'home';
const express = require('express');
const moment = require('moment');
const { SiteController, SiteError } = require('../../lib/site-lib');
class HomeController extends SiteController {
@ -30,6 +32,8 @@ class HomeController extends SiteController {
return next();
});
router.get('/:username/embed', this.getPublicProfileEmbed.bind(this));
router.get('/:username/json', this.getPublicProfileJSON.bind(this));
router.get('/:username',
limiterService.create(limiterService.config.home.getPublicProfile),
this.getPublicProfile.bind(this),
@ -53,6 +57,86 @@ class HomeController extends SiteController {
}
}
async getPublicProfileEmbed (req, res, next) {
const { link: linkService, user: userService } = this.dtp.services;
try {
this.log.debug('profile request', { url: req.url });
if (!res.locals.userProfile) {
return next(new SiteError(404, 'Member profile not found'));
}
res.locals.currentView = 'profile-embed';
res.locals.pageTitle = `${res.locals.userProfile.displayName || res.locals.userProfile.username} | ${this.dtp.config.site.name}`;
res.locals.pageDescription = res.locals.userProfile.bio || this.dtp.config.site.description;
res.locals.pagination = this.getPaginationParameters(req, 20);
res.locals.links = await linkService.getForUser(res.locals.userProfile, res.locals.pagination);
await userService.recordProfileView(res.locals.userProfile, req);
res.render('profile/embed');
} catch (error) {
this.log.error('failed to display landing page', { error });
return next(error);
}
}
async getPublicProfileJSON (req, res) {
const { link: linkService, user: userService } = this.dtp.services;
try {
this.log.debug('profile request', { url: req.url });
if (!res.locals.userProfile) {
throw new SiteError(404, 'Member profile not found');
}
res.locals.currentView = 'profile-embed';
res.locals.pageTitle = `${res.locals.userProfile.displayName || res.locals.userProfile.username} | ${this.dtp.config.site.name}`;
res.locals.pageDescription = res.locals.userProfile.bio || this.dtp.config.site.description;
res.locals.pagination = this.getPaginationParameters(req, 20);
res.locals.links = await linkService.getForUser(res.locals.userProfile, res.locals.pagination);
await userService.recordProfileView(res.locals.userProfile, req);
if (res.locals.userProfile.picture) {
if (res.locals.userProfile.picture.large) {
res.locals.userProfile.picture.large = this.makeSiteLink(`/image/${res.locals.userProfile.picture.large._id}`);
}
if (res.locals.userProfile.picture.small) {
res.locals.userProfile.picture.small = this.makeSiteLink(`/image/${res.locals.userProfile.picture.small._id}`);
}
}
if (res.locals.userProfile.header) {
res.locals.userProfile.header = this.makeSiteLink(`/image/${res.locals.userProfile.header._id}`);
}
delete res.locals.userProfile._id;
res.locals.userProfile.createdText = moment(res.locals.userProfile.created).fromNow();
res.locals.links.forEach((link) => {
link.href = this.makeSiteLink(`/link/${link._id}/visit`);
});
res.status(200).json({
success: true,
user: res.locals.userProfile,
links: res.locals.links,
});
} catch (error) {
this.log.error('failed to display landing page', { error });
return res.status(error.statusCode || 500).json({
success: false,
message: error.message,
});
}
}
makeSiteLink (url) {
return `https://${this.dtp.config.site.domain}${url}`;
}
async getPublicProfile (req, res, next) {
const { link: linkService, user: userService } = this.dtp.services;
try {

12
app/controllers/link.js

@ -34,11 +34,6 @@ class LinkController extends SiteController {
return next();
});
router.post('/visit/:linkId',
limiterService.create(limiterService.config.link.postCreateLinkVisit),
this.postCreateLinkVisit.bind(this),
);
router.post('/sort',
limiterService.create(limiterService.config.link.postSortLinksList),
authRequired,
@ -59,6 +54,11 @@ class LinkController extends SiteController {
this.postCreateLink.bind(this),
);
router.get('/:linkId/visit',
limiterService.create(limiterService.config.link.getCreateLinkVisit),
this.getCreateLinkVisit.bind(this),
);
router.delete('/:linkId', authRequired, this.deleteLink.bind(this));
}
@ -73,7 +73,7 @@ class LinkController extends SiteController {
}
}
async postCreateLinkVisit (req, res, next) {
async getCreateLinkVisit (req, res, next) {
const { resource: resourceService } = this.dtp.services;
try {
this.log.info('recording link visit', { link: res.locals.link._id, ip: req.ip });

33
app/services/user.js

@ -20,6 +20,18 @@ class UserService {
constructor (dtp) {
this.dtp = dtp;
this.log = new SiteLog(dtp, `svc:${module.exports.slug}`);
this.populateUser = [
{
path: 'picture.large',
},
{
path: 'picture.small',
},
{
path: 'header',
},
];
}
async start ( ) {
@ -263,17 +275,7 @@ class UserService {
const user = await User
.findById(userId)
.select('+email +flags +permissions')
.populate([
{
path: 'picture.large',
},
{
path: 'picture.small',
},
{
path: 'header',
},
])
.populate(this.populateUser)
.lean();
if (!user) {
throw new SiteError(404, 'Member account not found');
@ -305,7 +307,10 @@ class UserService {
} catch (error) {
user = User.findOne({ username: userId });
}
user = await user.select('+email +flags +settings').lean();
user = await user
.select('+email +flags +settings')
.populate(this.populateUser)
.lean();
return user;
}
@ -316,7 +321,9 @@ class UserService {
username = username.trim().toLowerCase();
const user = await User
.findOne({ username_lc: username })
.select('_id created username username_lc displayName bio picture header');
.select('_id created username username_lc displayName bio picture header')
.populate(this.populateUser)
.lean();
return user;
}

7
app/views/profile/home.pug

@ -5,8 +5,11 @@ block content
ul.uk-list
each link in links
li
form(method="POST", action=`/link/visit/${link._id}`).uk-form.uk-display-block.uk-width-1-1
button(type="submit").dtp-link-button.uk-display-block.uk-border-rounded.uk-width-1-1= link.label
a(
href= link.href,
data-visit-url= `/link/${link._id}/visit`,
onclick="return dtp.app.visitLink(event);",
).dtp-link-button.uk-display-block.uk-border-rounded.uk-width-1-1= link.label
block dtp-navbar
block dtp-off-canvas

10
client/js/site-app.js

@ -616,6 +616,16 @@ export default class DtpSiteApp extends DtpApp {
}
}
async visitLink (event) {
event.preventDefault();
event.stopPropagation();
const url = (event.currentTarget || event.target).getAttribute('data-visit-url');
window.location = url;
return true;
}
async renderStatsGraph (selector, title, data) {
try {
const canvas = document.querySelector(selector);

2
config/limiter.js

@ -98,7 +98,7 @@ module.exports = {
},
link: {
postCreateLinkVisit: {
getCreateLinkVisit: {
total: 30,
expire: ONE_MINUTE,
message: 'You are visiting links too quickly',

Loading…
Cancel
Save