Merge pull request #12048 from raisedadead/feature/reporting-profiles

feat(user): Report profiles
This commit is contained in:
Quincy Larson
2017-01-26 14:16:16 -06:00
committed by GitHub
6 changed files with 139 additions and 14 deletions

View File

@ -1184,7 +1184,7 @@ and (max-width : 400px) {
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
} }
// Reset/Delete Account Modal Styles // Account Modal Styles
.modal-dialog { .modal-dialog {
margin: 80px; margin: 80px;
@ -1223,6 +1223,14 @@ and (max-width : 400px) {
background-color: #208e36; background-color: #208e36;
border-color: darkgreen; border-color: darkgreen;
} }
.modal-textarea {
width: 100%;
max-width: 590px;
border: 2px solid #ccc;
border-radius: 5px;
padding: 5px;
}
} }
} }

View File

@ -12,7 +12,8 @@ import {
import certTypes from '../utils/certTypes.json'; import certTypes from '../utils/certTypes.json';
import { import {
ifNoUser401, ifNoUser401,
ifNoUserRedirectTo ifNoUserRedirectTo,
ifNotVerifiedRedirectToSettings
} from '../utils/middleware'; } from '../utils/middleware';
import { observeQuery } from '../utils/rx'; import { observeQuery } from '../utils/rx';
import { import {
@ -140,6 +141,7 @@ module.exports = function(app) {
const api = app.loopback.Router(); const api = app.loopback.Router();
const User = app.models.User; const User = app.models.User;
const Block = app.models.Block; const Block = app.models.Block;
const { Email } = app.models;
const map$ = cachedMap(Block); const map$ = cachedMap(Block);
function findUserByUsername$(username, fields) { function findUserByUsername$(username, fields) {
return observeQuery( return observeQuery(
@ -223,6 +225,18 @@ module.exports = function(app) {
); );
router.get('/:username', showUserProfile); router.get('/:username', showUserProfile);
router.get(
'/:username/report-user/',
sendNonUserToMap,
ifNotVerifiedRedirectToSettings,
getReportUserProfile
);
api.post(
'/:username/report-user/',
ifNoUser401,
postReportUserProfile
);
app.use('/:lang', router); app.use('/:lang', router);
app.use(api); app.use(api);
@ -631,4 +645,55 @@ module.exports = function(app) {
return res.render('account/forgot'); return res.render('account/forgot');
}); });
} }
function getReportUserProfile(req, res) {
const username = req.params.username.toLowerCase();
return res.render('account/report-profile', {
title: 'Report User',
username
});
}
function postReportUserProfile(req, res, next) {
const { user } = req;
const { username } = req.params;
const report = req.sanitize('reportDescription').trimTags();
if (!username || !report || report === '') {
req.flash('errors', {
msg: 'Oops, something is not right please re-check your submission.'
});
return next();
}
return Email.send$({
type: 'email',
to: 'Team@FreeCodeCamp.com',
cc: user.email,
from: 'Team@FreeCodeCamp.com',
subject: 'Abuse Report : Reporting ' + username + '\'s profile.',
text: dedent(`
Hello Team,\n
This is to report the profile of ${username}.\n
Report Details:\n
${report}\n\n
Reported by:
Username: ${user.username}
Name: ${user.name}
Email: ${user.email}\n
Thanks and regards,
${user.name}
`)
}, err => {
if (err) {
err.redirectTo = '/' + username;
return next(err);
}
req.flash('info', {
msg: 'A report was sent to the team with ' + user.email + ' in copy.'
});
return res.redirect('/');
});
}
}; };

View File

@ -26,6 +26,30 @@ export default function() {
// every file has contents // every file has contents
keys.map(key => value[key]).every(file => isPoly(file)); keys.map(key => value[key]).every(file => isPoly(file));
} }
},
customSanitizers: {
// Refer : http://stackoverflow.com/a/430240/1932901
trimTags(value) {
const tagBody = '(?:[^"\'>]|"[^"]*"|\'[^\']*\')*';
const tagOrComment = new RegExp(
'<(?:'
// Comment body.
+ '!--(?:(?:-*[^->])*--+|-?)'
// Special "raw text" elements whose content should be elided.
+ '|script\\b' + tagBody + '>[\\s\\S]*?</script\\s*'
+ '|style\\b' + tagBody + '>[\\s\\S]*?</style\\s*'
// Regular name
+ '|/?[a-z]'
+ tagBody
+ ')>',
'gi');
let rawValue;
do {
rawValue = value;
value = value.replace(tagOrComment, '');
} while (value !== rawValue);
return value.replace(/</g, '&lt;');
}
} }
}); });
} }

View File

@ -29,21 +29,17 @@ export function ifNoUser401(req, res, next) {
return res.status(401).end(); return res.status(401).end();
} }
export function flashIfNotVerified(req, res, next) { export function ifNotVerifiedRedirectToSettings(req, res, next) {
return next(); const { user } = req;
/*
// disabled until authorized required bug is fixed
const user = req.user;
if (!user) { if (!user) {
return next(); return next();
} }
const email = req.user.email; if (!user.emailVerified) {
const emailVerified = req.user.emailVerified; req.flash('error', {
if (!email || !emailVerified) { msg: 'We do not have your verified email address on record, '
req.flash('info', { + 'please add it in the settings to continue with your request.'
msg: 'Please verify your email address ' +
'<a href="/update-email">here</a>.'
}); });
return res.redirect('/settings');
} }
*/ return next();
} }

View File

@ -0,0 +1,29 @@
extends ../layout
block content
#modal-dialog.modal
.modal-dialog
.modal-content
.modal-header
a.close(href='/settings', data-dismiss='modal', aria-hidden='true') ×
h3 Do you want to report #{username}'s profile for abuse?
.modal-body
p We will notify the community moderators' team,
| and a send copy of this report to your email:
strong #{user.email}
| . We may get back to you for more information, if required.
.modal-footer
form(action='/' + username +'/report-user/', method='POST')
input(type='hidden', name='_csrf', value=_csrf)
div
textarea.modal-textarea(name='reportDescription', cols='40', rows='5')
.spacer
button.btn.btn-danger.btn-block(type='submit')
| Yes, submit my report about this user's profile.
.spacer
a.btn.btn-success.btn-block(href='/settings', data-dismiss='modal', aria-hidden='true')
| Nevermind, I don't want to report this user.
script.
document.addEventListener('DOMContentLoaded', function() {
const modal$ = document.getElementById('modal-dialog');
modal$.classList.add('show');
});

View File

@ -56,6 +56,9 @@ block content
if isBackEndCert if isBackEndCert
.button-spacer .button-spacer
a.btn.btn-primary.btn-block(href='/' + username + '/back-end-certification') View My Back End Development Certification a.btn.btn-primary.btn-block(href='/' + username + '/back-end-certification') View My Back End Development Certification
if (user && user.username != username)
.button-spacer
a.btn.btn-primary.btn-block(href='/' + username + '/report-user/') Report this user's profile for abuse
.row .row
.col-xs-12.text-center .col-xs-12.text-center
if (badges.coreTeam && badges.coreTeam.length) if (badges.coreTeam && badges.coreTeam.length)