feat: add gdpr privacy and terms

This commit is contained in:
Mrugesh Mohapatra
2018-05-27 17:29:04 +05:30
parent d68c568490
commit 3ad70a7926
6 changed files with 195 additions and 2 deletions

View File

@ -99,6 +99,10 @@
"twitter": {
"type": "string"
},
"acceptedPrivacyTerms": {
"type": "boolean",
"default": false
},
"sendQuincyEmail": {
"type": "boolean",
"default": true

View File

@ -51,6 +51,20 @@ module.exports = function enableAuthentication(app) {
})
);
router.get(
'/accept-privacy-terms',
ifNoUserRedirectHome,
(req, res) => {
const { user } = req;
if (user && !user.acceptedPrivacyTerms) {
return res.render('account/accept-privacy-terms', {
title: 'Privacy Policy and Terms of Service'
});
}
return res.redirect('/settings');
}
);
const defaultErrorMsg = dedent`
Oops, something is not right,
please request a fresh link to sign in / sign up.

View File

@ -1,5 +1,4 @@
import { check } from 'express-validator/check';
import {
ifNoUser401,
createValidatorErrorHandler
@ -147,6 +146,36 @@ export default function settingsController(app) {
);
}
const updatePrivacyTerms = (req, res, next) => {
const {
user,
body: { quincyemails }
} = req;
const update = {
acceptedPrivacyTerms: true,
sendQuincyEmail: !!quincyemails
};
return user.update$(update)
.do(() => {
req.user = Object.assign(req.user, update);
})
.subscribe(
() => {
res.status(200).json({
message: 'We have updated your preferences. ' +
'You can now continue using freeCodeCamp.'
});
},
next
);
};
api.post(
'/update-privacy-terms',
ifNoUser401,
updatePrivacyTerms
);
api.post(
'/refetch-user-completed-challenges',
ifNoUser401,

View File

@ -57,7 +57,8 @@
"./middlewares/csp": {},
"./middlewares/jade-helpers": {},
"./middlewares/flash-cheaters": {},
"./middlewares/passport-login": {}
"./middlewares/passport-login": {},
"./middlewares/privacy-terms-notice": {}
},
"files": {},
"final:after": {

View File

@ -0,0 +1,22 @@
const ALLOWED_METHODS = ['GET'];
const EXCLUDED_PATHS = [
'/api/flyers/findOne',
'/signout',
'/accept-privacy-terms'
];
export default function privacyTermsNotAcceptedNotice() {
return function(req, res, next) {
if (
ALLOWED_METHODS.indexOf(req.method) !== -1 &&
EXCLUDED_PATHS.indexOf(req.path) === -1
) {
const { user } = req;
if (user && user.acceptedPrivacyTerms !== true) {
res.redirect('/accept-privacy-terms');
return next;
}
}
return next();
};
}

View File

@ -0,0 +1,123 @@
extends ../layout
block content
.container
.row.flashMessage.negative-30
.col-sm-6.col-sm-offset-3
#flash-board.alert.fade.in(style='display: none;')
button.close(type='button', data-dismiss='alert')
span.ion-close-circled#flash-close
#flash-content
.col-xs-12
#accept-privacy-terms
.row
.text-center
h3 Please review our privacy policy and the terms of service.
br
.row
.col-sm-6.col-sm-offset-3
form(method='POST', action='/update-privacy-terms')
input(type='hidden', name='_csrf', value=_csrf)
.checkbox
label
input(id='terms', name='privacy', type='checkbox')
span.cr
i.cr-icon.fa.fa-check
| I accept the
a(href='https://www.freecodecamp.org/terms' target='_blank') terms of service
| (required).
.checkbox
label
input(id='privacy', name='privacy', type='checkbox')
span.cr
i.cr-icon.fa.fa-check
| I accept the
a(href='https://www.freecodecamp.org/privacy' target='_blank') privacy policy
| (required).
.checkbox
label
input(id='quincyemails', name='quincyemails', type='checkbox')
span.cr
i.cr-icon.fa.fa-check
| I want weekly emails from Quincy (freeCodeCamp.org's founder)
.button-spacer
button.btn.btn-primary.btn-lg.btn-block(id='submit-button', type='submit')
.row
.col-sm-6.col-sm-offset-3
a.btn.btn-primary.btn-lg.btn-block(id='continue-button', href='/', style='display: none;')
| Continue to freeCodeCamp
script.
$(document).ready(function() {
var checkedBoxCount = 0;
function disableContinueButtonForAgreement(isLaunched) {
if (isLaunched) {
$('#submit-button').prop('disabled', true).html(
'<span style="color:#E0E0E0;">Submit<\/span>');
return;
}
if (!isLaunched && checkedBoxCount === 2){
$('#submit-button').prop('disabled', false).html(
'<span>Submit<\/span>');
}
}
disableContinueButtonForAgreement(true);
$('#terms').click(function() {
if (this.checked) {
checkedBoxCount++;
disableContinueButtonForAgreement(false);
} else {
checkedBoxCount--;
disableContinueButtonForAgreement(true);
}
});
$('#privacy').click(function() {
if (this.checked) {
checkedBoxCount++;
disableContinueButtonForAgreement(false);
} else {
checkedBoxCount--;
disableContinueButtonForAgreement(true);
}
});
$('form').submit(function(event){
event.preventDefault();
$('#flash-board').hide();
var $form = $(event.target);
$.ajax({
type : 'POST',
url : $form.attr('action'),
data : $form.serialize(),
dataType : 'json',
encode : true,
xhrFields : { withCredentials: true }
})
.fail(error => {
if (error.responseText){
var data = JSON.parse(error.responseText);
if(data.message)
$('#flash-content').html(data.message);
$('#flash-board')
.removeClass('alert-success')
.addClass('alert-info')
.fadeIn();
}
})
.done(data =>{
if(data && data.message){
$('#flash-content').html(data.message);
$('#flash-board')
.removeClass('alert-info')
.addClass('alert-success')
.fadeIn();
$('#accept-privacy-terms').hide();
$('#continue-button').show();
}
});
});
});