Merge pull request #17187 from raisedadead/feat/authentication

feat(auth0): migrate auth to auth0
This commit is contained in:
Stuart Taylor
2018-05-20 12:19:45 +01:00
committed by GitHub
19 changed files with 906 additions and 1850 deletions

View File

@ -35,14 +35,46 @@ pre.wrappable {
word-wrap: break-word; /* IE 5+ */ word-wrap: break-word; /* IE 5+ */
} }
//input[type=checkbox] { .checkbox label:after {
// /* Double-sized Checkboxes */ content: '';
// -ms-transform: scale(2); /* IE */ display: table;
// -moz-transform: scale(2); /* FF */ clear: both;
// -webkit-transform: scale(2); /* Safari and Chrome */ }
// -o-transform: scale(2); /* Opera */
// padding: 10px; .checkbox .cr {
//} position: relative;
display: inline-block;
border: 1px solid #a9a9a9;
border-radius: .25em;
width: 1.3em;
height: 1.3em;
float: left;
margin-right: .5em;
}
.checkbox .cr .cr-icon {
position: absolute;
font-size: .8em;
line-height: 0;
top: 50%;
left: 15%;
}
.checkbox label input[type="checkbox"] {
display: none;
}
.checkbox label input[type="checkbox"]+.cr>.cr-icon {
opacity: 0;
}
.checkbox label input[type="checkbox"]:checked+.cr>.cr-icon {
opacity: 1;
}
.checkbox label input[type="checkbox"]:disabled+.cr {
opacity: .5;
}
.btn-group { .btn-group {
border-color: @brand-primary; border-color: @brand-primary;

View File

@ -4,8 +4,7 @@ import dedent from 'dedent';
import { import {
getSocialProvider, getSocialProvider,
getUsernameFromProvider, getUsernameFromProvider
createUserUpdatesFromProfile
} from '../../server/utils/auth'; } from '../../server/utils/auth';
import { observeMethod, observeQuery } from '../../server/utils/rx'; import { observeMethod, observeQuery } from '../../server/utils/rx';
import { wrapHandledError } from '../../server/utils/create-handled-error.js'; import { wrapHandledError } from '../../server/utils/create-handled-error.js';
@ -48,6 +47,24 @@ export default function(UserIdent) {
}, },
include: 'user' include: 'user'
}; };
if (provider === 'auth0') {
const email = profile.emails[0].value;
return User.findOne$({ where: { email } })
.flatMap(user => {
if (!user) {
return User.create$({ email });
}
return Observable.of(user);
})
.subscribe(
( user ) => cb(null, user, null, null),
cb
);
} else {
return UserIdent.findOne$(query) return UserIdent.findOne$(query)
.flatMap(identity => { .flatMap(identity => {
if (!identity) { if (!identity) {
@ -88,10 +105,7 @@ export default function(UserIdent) {
); );
}); });
} }
const updateUser = User.update$(
{ id: user.id },
createUserUpdatesFromProfile(provider, profile)
).map(() => user);
// identity already exists // identity already exists
// find user and log them in // find user and log them in
identity.credentials = credentials; identity.credentials = credentials;
@ -117,7 +131,7 @@ export default function(UserIdent) {
} }
); );
return Observable.combineLatest( return Observable.combineLatest(
updateUser, Observable.of(user),
updateIdentity, updateIdentity,
createToken, createToken,
(user, identity, token) => ({ user, identity, token }) (user, identity, token) => ({ user, identity, token })
@ -127,5 +141,6 @@ export default function(UserIdent) {
({ user, identity, token }) => cb(null, user, identity, token), ({ user, identity, token }) => cb(null, user, identity, token),
cb cb
); );
}
}; };
} }

View File

@ -0,0 +1,462 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<title>Sign in to freeCodeCamp</title>
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
<style>
html,
body,
div,
span,
a,
li,
td,
th {
font-family: 'Lato', sans-serif;
}
bold {
font-family: 'Lato-Bold', sans-serif;
font-weight: Bold;
}
.checkbox label:after {
content: '';
display: table;
clear: both;
}
.checkbox .cr {
position: relative;
display: inline-block;
border: 1px solid #a9a9a9;
border-radius: .25em;
width: 1.3em;
height: 1.3em;
float: left;
margin-right: .5em;
}
.checkbox .cr .cr-icon {
position: absolute;
font-size: .8em;
line-height: 0;
top: 50%;
left: 15%;
}
.checkbox label input[type="checkbox"] {
display: none;
}
.checkbox label input[type="checkbox"]+.cr>.cr-icon {
opacity: 0;
}
.checkbox label input[type="checkbox"]:checked+.cr>.cr-icon {
opacity: 1;
}
.checkbox label input[type="checkbox"]:disabled+.cr {
opacity: .5;
}
.btn-social {
width: 100%;
max-width: 260px;
margin: auto;
}
.btn-link-social {
max-width: 400px;
margin: auto;
margin-bottom: 10px;
}
a {
font-weight: bold;
font-size: 15px;
}
p {
font-size: 15px;
}
h1,
h2 {
font-weight: 400;
}
h1,
h2,
h3,
h4,
h5,
h6,
p,
li {
padding-top: 5px;
padding-bottom: 5px;
}
.fa,
[class^='ion-'] {
margin-right: 5px;
}
.fa:hover {
text-decoration: none;
}
a {
color: darkgreen;
text-decoration: none;
}
a:hover {
color: darkgreen;
}
.img-center {
margin: 0 auto;
}
.button-spacer {
padding: 5px 0;
}
.spacer {
padding: 15px 0 15px 0;
}
.btn-primary {
color: darkgreen;
background-color: darkgreen;
border-color: #004a00;
}
.btn-lg,
.btn-group-lg>.btn {
padding: 10px 16px;
font-size: 19px;
line-height: 1.33;
border-radius: 6px;
}
.btn-block {
display: block;
width: 100%;
}
.btn {
font-weight: 400;
white-space: normal;
background: transparent;
-webkit-transition: background 0.2s ease-in-out, border 0.2s ease-in-out;
-moz-transition: background 0.2s ease-in-out, border 0.2s ease-in-out;
-ms-transition: background 0.2s ease-in-out, border 0.2s ease-in-out;
-o-transition: background 0.2s ease-in-out, border 0.2s ease-in-out;
transition: background 0.2s ease-in-out, border 0.2s ease-in-out;
}
.btn:hover,
.btn:focus,
.btn.focus {
color: #eeeeee;
text-decoration: none;
}
.btn-primary:hover,
.btn-primary:focus,
.btn-primary.focus,
.btn-primary:active,
.btn-primary:active:hover,
.btn-primary.active,
.open>.dropdown-toggle.btn-primary {
color: #eeeeee;
background-color: darkgreen;
border-color: #000d00;
}
.btn.disabled,
.btn[disabled],
fieldset[disabled] .btn {
cursor: not-allowed;
pointer-events: none;
opacity: 0.65;
filter: alpha(opacity=65);
-webkit-box-shadow: none;
box-shadow: none;
}
.btn-primary.disabled,
.btn-primary[disabled],
fieldset[disabled] .btn-primary,
.btn-primary.disabled:hover,
.btn-primary[disabled]:hover,
fieldset[disabled] .btn-primary:hover,
.btn-primary.disabled:focus,
.btn-primary[disabled]:focus,
fieldset[disabled] .btn-primary:focus,
.btn-primary.disabled.focus,
.btn-primary[disabled].focus,
fieldset[disabled] .btn-primary.focus,
.btn-primary.disabled:active,
.btn-primary[disabled]:active,
fieldset[disabled] .btn-primary:active,
.btn-primary.disabled.active,
.btn-primary[disabled].active,
fieldset[disabled] .btn-primary.active {
background-color: darkgreen;
border-color: #004a00;
}
h4 {
font-size: 22px;
}
.navbar-default .navbar-collapse,
.navbar-default .navbar-form {
border-color: #e7e7e7;
background: darkgreen;
}
.navbar {
white-space: nowrap;
border: none;
line-height: 1;
background: darkgreen;
}
@media (min-width: 767px) {
.navbar {
padding-left: 15px;
padding-right: 30px;
}
}
.navbar-default .navbar-nav>li>a {
color: #eeeeee;
}
</style>
</head>
<body>
<div class="navbar navbar-default navbar-static-top nav-height">
<div class="navbar-header">
<button class="hamburger navbar-toggle" data-target=".navbar-collapse" data-toggle="collapse" type="button">
<div class="col-xs-12">
<span class="hamburger-text">Menu</span>
</div></button> <a class="navbar-brand" href="http://freecodecamp.org"><img alt=
"learn to code javascript at freeCodeCamp logo" class=
"img-responsive nav-logo" src=
"https://s3.amazonaws.com/freecodecamp/freecodecamp_logo.svg"></a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav navbar-right hamburger-dropdown">
<li>
<a href="https://learn.freecodecamp.org" rel="noopener" target="_blank">Learn</a>
</li>
<li>
<a href="https://forum.freecodecamp.org" rel="noopener" target="_blank">Forum</a>
</li>
<li>
<a href="https://freecodecamp.org/">Home</a>
</li>
</ul>
</div>
</div>
<div class="container">
<div class="container">
<div class="col-xs-12">
<div class="row">
<div class="text-center">
<h2>Sign up (or sign in with your existing account)</h2>
<div class="button-spacer"></div>
</div>
<div class="col-sm-6 col-sm-offset-3">
<div class="form-group">
<div class="enter-email">
<input autofocus="" class="input-lg form-control" id="email" name="email" oninput="setCustomValidity('')" oninvalid="this.setCustomValidity('Enter your email address')" placeholder="Enter your email address" required="" type="email">
<div class="button-spacer">
</div>
<div class="checkbox">
<label><input name="quincy-emails" type="checkbox">
<span class="cr"><i class="cr-icon fa fa-check"></i></span> I
want weekly emails from Quincy, freeCodeCamp.org's
founder.</label>
</div>
<div class="checkbox">
<label><input id="terms-privacy" name="terms-privacy" type=
"checkbox"> <span class="cr"><i class=
"cr-icon fa fa-check"></i></span> I accept the <a href=
"/terms" target="_blank">Terms of Service</a> and <a href=
"/privacy" target="_blank">Privacy Policy</a>
(required)</label>
</div>
<div class="button-spacer">
</div>
<button id="send-email-btn" class="btn btn-primary btn-lg btn-block">Get a code on your email</button>
</div>
<div class="enter-code" style="display: none;">
<input name="code" id="code" value="" class="input-lg form-control" placeholder="Enter the code you recieved on your email">
<div class="button-spacer">
</div>
<button id="send-code-btn" class="btn btn-primary btn-lg btn-block">Submit Code</button>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-6 col-sm-offset-3">
<br>
<p class="text-center"><br>
<br>
<a href="https://freecodecamp.org/deprecated-signin">Continute with
old sign in methods</a>
</p>
</div>
</div>
</div>
</div>
</div>
<!--[if IE 8]>
<script src="//cdnjs.cloudflare.com/ajax/libs/ie8/0.2.5/ie8.js"></script>
<![endif]-->
<!--[if lte IE 9]>
<script src="https://cdn.auth0.com/js/polyfills/1.0/base64.min.js"></script>
<script src="https://cdn.auth0.com/js/polyfills/1.0/es5-shim.min.js"></script>
<![endif]-->
<!-- Latest compiled and minified JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="https://use.fontawesome.com/ae11c47b27.js">
</script>
<script src="https://cdn.auth0.com/js/auth0/9.2/auth0.min.js">
</script>
<script src="https://cdn.auth0.com/js/polyfills/1.0/object-assign.min.js">
</script>
<script>
$(document).ready(function() {
var config = JSON.parse(
decodeURIComponent(escape(window.atob('@@config@@')))
);
var params = Object.assign({
domain: config.auth0Domain,
clientID: config.clientID,
redirectUri: config.callbackURL,
scope: 'openid email',
audience: 'https://' + config.auth0Domain + '/userinfo',
responseType: 'code'
}, config.internalOptions);
var webAuth = new auth0.WebAuth(params);
function disableMagicButtonForAgreement(isLaunched) {
if (isLaunched) {
$('#send-email-btn').prop('disabled', true).html(
'<span style="color:#E0E0E0;">Get a code on your email<\/span>');
return;
} else {
$('#send-email-btn').prop('disabled', false).html(
'<span>Get a code on your email<\/span>');
}
}
function sendEmail() {
var email = $('input#email').val();
webAuth.passwordlessStart({
connection: 'email',
send: 'code',
email: email
}, function(err, res) {
if (err) {
// Handle error
console.log('err', err);
}
console.log('res', res);
// Hide the input and show the code entry screen
$('.enter-email').hide();
$('.enter-code').show();
});
}
function login() {
console.log('logging in...');
var email = $('input#email').val();
var code = $('input#code').val();
webAuth.passwordlessLogin({
connection: 'email',
email: email,
verificationCode: code
}, function(err, res) {
if (err) {
console.log('error logging-in', err);
alert('Couldn\'t login ' + err.message);
}
});
};
disableMagicButtonForAgreement(true);
$('#terms-privacy').click(function() {
if (this.checked) {
disableMagicButtonForAgreement(false);
} else {
disableMagicButtonForAgreement(true);
}
});
$('#send-email-btn').click(function(){
sendEmail();
});
$('#send-code-btn').click(function(){
login();
});
});
</script>
</body>
</html>

147
package-lock.json generated
View File

@ -721,6 +721,32 @@
"integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=", "integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=",
"dev": true "dev": true
}, },
"auth0-js": {
"version": "9.5.1",
"resolved": "https://registry.npmjs.org/auth0-js/-/auth0-js-9.5.1.tgz",
"integrity": "sha1-NN6msPEbXl7hOWBWEfSbHA8V27E=",
"requires": {
"base64-js": "1.3.0",
"idtoken-verifier": "1.2.0",
"js-cookie": "2.2.0",
"qs": "6.5.1",
"superagent": "3.8.3",
"url-join": "1.1.0",
"winchan": "0.2.0"
},
"dependencies": {
"base64-js": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
"integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw=="
},
"url-join": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/url-join/-/url-join-1.1.0.tgz",
"integrity": "sha1-dBxsL0WWxIMNZxhGCSDQySIC3Hg="
}
}
},
"aws-sdk": { "aws-sdk": {
"version": "2.141.0", "version": "2.141.0",
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.141.0.tgz", "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.141.0.tgz",
@ -3889,6 +3915,11 @@
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
}, },
"cookiejar": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.1.tgz",
"integrity": "sha1-Qa1XsbVVlR7BcUEqgZQrHoIA00o="
},
"copy-concurrently": { "copy-concurrently": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
@ -4225,6 +4256,11 @@
"resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-1.0.9.tgz", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-1.0.9.tgz",
"integrity": "sha1-zFRJaF37hesRyYKKzHy4erW7/MA=" "integrity": "sha1-zFRJaF37hesRyYKKzHy4erW7/MA="
}, },
"crypto-js": {
"version": "3.1.9-1",
"resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz",
"integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg="
},
"crypto-random-string": { "crypto-random-string": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
@ -8806,6 +8842,30 @@
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
}, },
"idtoken-verifier": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/idtoken-verifier/-/idtoken-verifier-1.2.0.tgz",
"integrity": "sha512-8jmmFHwdPz8L73zGNAXHHOV9yXNC+Z0TUBN5rafpoaFaLFltlIFr1JkQa3FYAETP23eSsulVw0sBiwrE8jqbUg==",
"requires": {
"base64-js": "1.3.0",
"crypto-js": "3.1.9-1",
"jsbn": "0.1.1",
"superagent": "3.8.3",
"url-join": "1.1.0"
},
"dependencies": {
"base64-js": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
"integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw=="
},
"url-join": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/url-join/-/url-join-1.1.0.tgz",
"integrity": "sha1-dBxsL0WWxIMNZxhGCSDQySIC3Hg="
}
}
},
"ieee754": { "ieee754": {
"version": "1.1.8", "version": "1.1.8",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
@ -9628,6 +9688,11 @@
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.1.1.tgz", "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.1.1.tgz",
"integrity": "sha1-NHwcIcfgBBFeCk2jLOzgQfrTyKM=" "integrity": "sha1-NHwcIcfgBBFeCk2jLOzgQfrTyKM="
}, },
"js-cookie": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.0.tgz",
"integrity": "sha1-Gywnmm7s44ChIWi5JIUmWzWx7/s="
},
"js-tokens": { "js-tokens": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
@ -9656,8 +9721,7 @@
"jsbn": { "jsbn": {
"version": "0.1.1", "version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
"optional": true
}, },
"jschardet": { "jschardet": {
"version": "1.6.0", "version": "1.6.0",
@ -13935,6 +13999,16 @@
"pause": "0.0.1" "pause": "0.0.1"
} }
}, },
"passport-auth0": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/passport-auth0/-/passport-auth0-0.6.1.tgz",
"integrity": "sha512-JJzb7BhR7eH19h9awD1+rZQbo0FCPMH1Wf6cGcSnw+boGYaIWc+A3ID0KDd6A8eFwqDEZgy+NEuYhIGOpngFuA==",
"requires": {
"passport-oauth": "1.0.0",
"request": "2.83.0",
"xtend": "4.0.1"
}
},
"passport-facebook": { "passport-facebook": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/passport-facebook/-/passport-facebook-2.1.1.tgz", "resolved": "https://registry.npmjs.org/passport-facebook/-/passport-facebook-2.1.1.tgz",
@ -18143,6 +18217,70 @@
"chalk": "1.1.3" "chalk": "1.1.3"
} }
}, },
"superagent": {
"version": "3.8.3",
"resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz",
"integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==",
"requires": {
"component-emitter": "1.2.1",
"cookiejar": "2.1.1",
"debug": "3.1.0",
"extend": "3.0.1",
"form-data": "2.3.1",
"formidable": "1.2.1",
"methods": "1.1.2",
"mime": "1.4.1",
"qs": "6.5.1",
"readable-stream": "2.3.6"
},
"dependencies": {
"component-emitter": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
"integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
},
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
"ms": "2.0.0"
}
},
"formidable": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz",
"integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg=="
},
"process-nextick-args": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
"core-util-is": "1.0.2",
"inherits": "2.0.3",
"isarray": "1.0.0",
"process-nextick-args": "2.0.0",
"safe-buffer": "5.1.1",
"string_decoder": "1.1.1",
"util-deprecate": "1.0.2"
}
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "5.1.1"
}
}
}
},
"supports-color": { "supports-color": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
@ -20339,6 +20477,11 @@
"semver": "5.4.1" "semver": "5.4.1"
} }
}, },
"winchan": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/winchan/-/winchan-0.2.0.tgz",
"integrity": "sha1-OGMCjn+XSw2hQS8oQXukJJcqvZQ="
},
"window-size": { "window-size": {
"version": "0.1.0", "version": "0.1.0",
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",

View File

@ -40,6 +40,7 @@
"dependencies": { "dependencies": {
"@freecodecamp/loopback-component-passport": "^1.0.0", "@freecodecamp/loopback-component-passport": "^1.0.0",
"accepts": "^1.3.0", "accepts": "^1.3.0",
"auth0-js": "^9.5.1",
"babel-core": "^6.18.1", "babel-core": "^6.18.1",
"babel-preset-es2015": "^6.3.13", "babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.3.13", "babel-preset-react": "^6.3.13",
@ -101,6 +102,7 @@
"normalizr": "2.2.1", "normalizr": "2.2.1",
"opbeat": "^4.14.0", "opbeat": "^4.14.0",
"passport": "^0.4.0", "passport": "^0.4.0",
"passport-auth0": "^0.6.1",
"passport-facebook": "^2.0.0", "passport-facebook": "^2.0.0",
"passport-github": "^1.0.0", "passport-github": "^1.0.0",
"passport-google-oauth2": "~0.1.6", "passport-google-oauth2": "~0.1.6",

View File

@ -1,97 +0,0 @@
.vimeo-image,
.vimeo-image:after,
.vimeo-embed {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.vimeo {
position: relative;
padding-bottom: 56.25%;
background: #e2e2e2;
}
.vimeo iframe {
border: 0;
}
.vimeo-image {
background-position: center center;
background-size: 100% auto;
}
.vimeo-image:after {
z-index: 1;
display: block;
content: '';
background: rgba(0,0,0,0.3);
}
.vimeo-play-button,
.vimeo-loading {
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}
.vimeo-play-button {
z-index: 2;
position: absolute;
padding: 0;
width: 70px;
border: 0;
background: none;
}
.vimeo-play-button:focus {
outline: none;
}
.vimeo-play-button svg {
fill: #fff;
-webkit-filter: drop-shadow(0 1px 1px rgba(0,0,0,0.8));
filter: drop-shadow(0 1px 1px rgba(0,0,0,0.8));
}
.vimeo-loading {
z-index: 4;
position: absolute;
width: 32px;
height: 32px;
}
.vimeo-loading svg {
fill: #000;
transform-origin: 50% 50%;
-webkit-animation: spinner 0.8s infinite linear;
animation: spinner 0.8s infinite linear;
}
.vimeo-embed iframe {
width: 100%;
height: 100%;
}
@-moz-keyframes spinner {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@-webkit-keyframes spinner {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@-o-keyframes spinner {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@keyframes spinner {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,151 +0,0 @@
@import url("http://fonts.googleapis.com/css?family=Montserrat:400,700");
@import url("http://fonts.googleapis.com/css?family=Raleway:400,300");
// Colors
// -------------------------
@gray-lighter: #f5f5f5;
@gray-light: #e0e0e0;
@gray: #737373;
@gray-dark: #404040;
@gray-darker: #121212;
@brand-primary: #2ac5ee;
@brand-success: #0f9d58;
@brand-warning: #f4b400;
@brand-danger: #d80017;
@brand-info: #5bc0dd;
// Footer
// -------------------------
footer {
color: #fff;
background-color: @gray-darker;
a:hover {
color: #fff;
}
}
// Typography
// -------------------------
@font-size-base: 13px;
@font-family-base: 'Montserrat', sans-serif;
@headings-font-family: 'Montserrat', sans-serif;
@headings-font-weight: 700;
@text-color: @gray-darker;
@link-color: @brand-primary;
@link-hover-color: @gray-darker;
a {
transition: all .4s cubic-bezier(.24,.45,.46,.92);
&:hover {
text-decoration: none;
}
}
ul,
p {
font-family: 'Raleway', sans-serif;
font-size: 14px;
font-weight: 300;
}
.text-danger {
color: @brand-danger;
}
// Dropdowns
// -------------------------
@dropdown-link-color: @gray-darker;
.dropdown-menu > li > a {
font-weight: 300;
}
// Buttons
// -------------------------
@btn-default-bg: @gray-lighter;
@btn-default-color: @gray-darker;
.btn {
padding: 10px 16px;
border: 0;
border-radius: 3px;
transition: all .4s cubic-bezier(.24,.45,.46,.92);
&:hover {
color: #fff;
background-color: @gray-darker;
}
}
.btn-social {
padding: 10px 50px;
:first-child {
width: 38px;
line-height: 38px;
}
}
.btn-link {
&:hover {
color: @gray-darker;
text-decoration: none;
background-color: transparent;
}
}
// Forms
// -------------------------
@input-border-radius: 2px;
@input-border-focus: #999;
@input-border: #f0f0f0;
@input-color: #444;
@input-color-placeholder: #999;
@input-height-base: 44px;
// Form states and alerts
// -------------------------
@state-success-bg: @brand-success;
@state-info-bg: @brand-primary;
@state-warning-bg: @brand-warning;
@state-danger-bg: @brand-danger;
.alert {
font-family: 'Raleway', sans-serif;
color: #fff;
}
// Navbar
// -------------------------
@navbar-height: 50px;
@navbar-default-bg: rgba(255,255,255,0.95);
@navbar-default-link-color: @gray-darker;
@navbar-default-link-active-color: @brand-primary;
@navbar-default-link-active-bg: transparent;
@navbar-default-link-hover-color: @brand-primary;
@navbar-default-link-hover-bg: transparent;
@navbar-default-brand-color: @gray-darker;
@navbar-default-brand-hover-color: @brand-primary;
.navbar-default {
border: 0;
box-shadow: 0 1px 5px rgba(0,0,0,.15);
.navbar-nav {
> li > a {
transition: color .4s cubic-bezier(.24,.45,.46,.92);
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,17 +0,0 @@
<link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/apple-touch-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/apple-touch-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/apple-touch-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon-180x180.png">
<link rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="/android-chrome-192x192.png" sizes="192x192">
<link rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16">
<link rel="manifest" href="/android-chrome-manifest.json">
<meta name="msapplication-TileColor" content="#492c14">
<meta name="msapplication-TileImage" content="/mstile-144x144.png">
<meta name="theme-color" content="#ffffff">

View File

@ -0,0 +1,37 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="600.000000pt" height="600.000000pt" viewBox="0 0 600.000000 600.000000"
preserveAspectRatio="xMidYMid meet">
<metadata>
Created by potrace 1.15, written by Peter Selinger 2001-2017
</metadata>
<g transform="translate(0.000000,600.000000) scale(0.100000,-0.100000)"
fill="#006400" stroke="none">
<path d="M0 3000 l0 -3000 3000 0 3000 0 0 3000 0 3000 -3000 0 -3000 0 0
-3000z m1565 1504 c13 -8 28 -29 34 -46 16 -46 -6 -83 -142 -226 -143 -152
-228 -268 -301 -411 -122 -241 -176 -471 -176 -761 0 -319 54 -567 180 -825
75 -154 157 -269 299 -418 118 -125 157 -186 145 -232 -8 -34 -59 -75 -93 -75
-83 0 -215 113 -367 316 -199 264 -305 511 -366 851 -20 112 -23 161 -22 383
0 239 1 263 26 381 66 306 188 557 396 816 176 217 305 301 387 247z m2840 -3
c64 -29 145 -102 236 -211 287 -347 421 -684 460 -1158 41 -503 -98 -959 -414
-1352 -137 -171 -269 -280 -337 -280 -29 0 -77 27 -90 49 -29 54 -7 92 137
243 168 176 267 319 344 497 194 452 178 1048 -40 1496 -85 174 -168 288 -343
472 -49 51 -93 104 -98 118 -22 57 -5 106 45 133 28 16 54 14 100 -7z m-1729
-165 c162 -43 314 -169 383 -317 38 -82 48 -118 91 -344 25 -128 48 -187 84
-210 45 -30 114 3 129 62 7 33 -10 100 -44 167 -16 33 -29 67 -29 78 0 56 115
-21 230 -153 161 -187 217 -361 208 -644 -6 -162 -29 -250 -100 -369 -73 -123
-291 -316 -357 -316 -18 0 -51 24 -51 37 0 3 28 35 61 71 122 133 168 222 176
340 8 121 -31 247 -100 320 -17 17 -39 32 -49 32 -16 0 -16 -3 -4 -38 7 -20
17 -56 21 -80 6 -39 4 -45 -28 -77 -32 -32 -40 -35 -92 -35 -112 0 -130 32
-121 210 6 118 5 128 -17 175 -39 81 -133 165 -184 165 -26 0 -32 -33 -10 -47
32 -20 47 -58 47 -123 0 -101 -32 -155 -152 -260 -153 -134 -188 -194 -188
-324 0 -174 84 -328 208 -383 39 -17 52 -28 50 -41 -6 -30 -70 -19 -171 30
-161 78 -280 190 -356 338 -53 101 -74 185 -75 300 -1 159 38 253 240 576 178
286 221 392 212 531 -7 109 -81 238 -159 279 -30 15 -39 48 -16 57 24 10 113
6 163 -7z m1435 -2395 c32 -32 39 -46 39 -77 0 -51 -18 -83 -59 -111 l-34 -23
-1049 0 c-1143 0 -1080 -3 -1127 56 -14 18 -21 41 -21 72 0 38 5 50 39 83 l39
39 1067 0 1067 0 39 -39z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,199 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 18.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="Layer_1"
x="0px"
y="0px"
viewBox="0 0 498.8 72"
enable-background="new 0 0 498.8 72"
xml:space="preserve"
inkscape:version="0.48.5 r10040"
width="100%"
height="100%"
sodipodi:docname="freeCodeCamp.svg"><metadata
id="metadata47"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs45">
</defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1366"
inkscape:window-height="705"
id="namedview43"
showgrid="false"
inkscape:zoom="1"
inkscape:cx="215.72458"
inkscape:cy="-163.56938"
inkscape:window-x="-4"
inkscape:window-y="-4"
inkscape:window-maximized="1"
inkscape:current-layer="Layer_1" />
<rect
style="fill:#502d16;fill-opacity:1;stroke:none"
id="rect3038"
width="493"
height="72.63604"
x="3.0000002"
y="-0.75736016"
ry="9.0263624"
inkscape:export-filename="C:\Users\anon\Desktop\logo4.0.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path5"
d="m 27.2,28.5 h -4 c -1.4,0 -2.1,-0.6 -2.1,-1.8 0,-1.2 0.7,-1.8 2.1,-1.8 h 4 v -3.5 c 0,-6.1 3.1,-9.1 9.3,-9.1 2.5,0 4.6,0.5 6.3,1.4 2.1,1.3 3.2,3.2 3.2,5.6 0,1.6 -0.6,2.3 -1.8,2.3 -0.8,0 -1.5,-0.5 -1.9,-1.4 -0.5,-1.6 -1,-2.5 -1.3,-2.9 -0.7,-0.9 -2.2,-1.4 -4.4,-1.4 -3.8,0 -5.6,1.9 -5.6,5.6 v 3.4 h 7.3 c 1.6,0 2.4,0.6 2.4,1.8 0,1.2 -0.8,1.8 -2.4,1.8 H 31 v 22.9 c 0,1.4 -0.6,2.1 -1.8,2.1 -1.2,0 -1.8,-0.7 -1.8,-2.1 V 28.5 z"
inkscape:export-filename="C:\Users\anon\Desktop\logo4.0.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path7"
d="M 59.7,49.4 V 28.5 h -5.4 c -1.5,0 -2.2,-0.6 -2.2,-1.8 0,-1.2 0.7,-1.8 2.2,-1.8 h 7.2 c 1.2,0 1.9,1.1 1.9,3.1 2.2,-2.4 4.6,-3.7 7.1,-3.7 2.1,0 3.7,0.6 4.9,1.9 1.2,1.3 1.8,3 1.8,5 0,1.4 -0.6,2.1 -1.8,2.1 -0.7,0 -1.2,-0.5 -1.5,-1.4 -0.5,-1.7 -0.8,-2.6 -0.9,-2.7 -0.5,-0.9 -1.5,-1.4 -2.8,-1.4 -1.4,0 -2.7,0.5 -3.9,1.5 -0.7,0.5 -1.7,1.6 -3,3.2 v 16.7 h 6.8 c 1.5,0 2.2,0.6 2.2,1.7 0,1.2 -0.7,1.9 -2.2,1.9 H 54.2 C 52.7,52.8 52,52.2 52,51 c 0,-1.2 0.7,-1.8 2.2,-1.8 h 5.5 z"
inkscape:export-filename="C:\Users\anon\Desktop\logo4.0.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path9"
d="m 87,39.6 v 4 c 0,4.3 3,6.4 9.1,6.4 2.2,0 4,-0.2 5.4,-0.7 0.7,-0.2 2,-0.9 3.7,-2.1 1.1,-1 1.9,-1.5 2.2,-1.5 1,0 1.5,0.5 1.5,1.6 0,1.1 -0.7,2.2 -2.2,3.4 -2.4,1.9 -6,2.9 -10.8,2.9 -8.4,0 -12.6,-3.3 -12.6,-9.9 v -10 c 0,-2.3 0.9,-4.3 2.6,-5.9 2.3,-2.2 5.7,-3.2 10.3,-3.2 8.2,0 12.3,4.1 12.3,12.2 0,2 -0.8,3 -2.3,3 H 87 z M 87,36 h 17.9 c 0,-5.4 -3,-8.1 -9.1,-8.1 -2.2,0 -4.2,0.5 -6,1.5 C 88,30.7 87,32.2 87,33.9 V 36 z"
inkscape:export-filename="C:\Users\anon\Desktop\logo4.0.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path11"
d="m 118.4,39.6 v 4 c 0,4.3 3,6.4 9.1,6.4 2.2,0 4,-0.2 5.4,-0.7 0.7,-0.2 2,-0.9 3.7,-2.1 1.1,-1 1.9,-1.5 2.2,-1.5 1,0 1.5,0.5 1.5,1.6 0,1.1 -0.7,2.2 -2.2,3.4 -2.4,1.9 -6,2.9 -10.8,2.9 -8.4,0 -12.6,-3.3 -12.6,-9.9 v -10 c 0,-2.3 0.9,-4.3 2.6,-5.9 2.3,-2.2 5.7,-3.2 10.3,-3.2 8.2,0 12.3,4.1 12.3,12.2 0,2 -0.8,3 -2.3,3 h -19.2 z m 0,-3.6 h 17.9 c 0,-5.4 -3,-8.1 -9.1,-8.1 -2.2,0 -4.2,0.5 -6,1.5 -1.9,1.3 -2.8,2.8 -2.8,4.5 V 36 z"
inkscape:export-filename="C:\Users\anon\Desktop\logo4.0.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path13"
d="M 146.5,41.9 V 26.3 c 0,-8.2 4.3,-12.2 13,-12.2 3.5,0 6.3,0.8 8.5,2.3 2.5,1.9 3.7,4.5 3.7,7.7 0,1.5 -0.6,2.3 -1.9,2.3 -0.9,0 -1.5,-0.7 -1.9,-2.2 -0.2,-1.2 -0.7,-2.4 -1.4,-3.5 -1.1,-2 -3.5,-2.9 -7.3,-2.9 -3.2,0 -5.5,0.8 -6.9,2.4 -1.3,1.5 -2,3.8 -2,7.1 v 13 c 0,3.4 0.7,5.8 2.1,7.3 1.5,1.6 3.8,2.5 7,2.5 4.9,0 7.7,-1.7 8.4,-5.1 0.3,-1.3 0.4,-1.9 0.4,-2 0.3,-0.7 0.8,-1.1 1.5,-1.1 1.2,0 1.9,0.8 1.9,2.3 0,3.1 -1.3,5.5 -3.9,7.4 -2.1,1.4 -4.8,2.1 -8.2,2.1 -4,0 -7.1,-0.9 -9.4,-2.8 -2.4,-2.1 -3.6,-5.1 -3.6,-9 z"
inkscape:export-filename="C:\Users\anon\Desktop\logo4.0.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path15"
d="M 177.5,44.1 V 33.8 c 0,-6.3 4.2,-9.4 12.6,-9.4 8.4,0 12.6,3.1 12.6,9.4 v 10.3 c 0,6.3 -4.1,9.4 -12.4,9.4 -8.6,0 -12.8,-3.1 -12.8,-9.4 z m 21.5,0 V 33.8 c 0,-3.9 -3,-5.9 -9.1,-5.9 -5.8,0 -8.8,2 -8.8,5.9 v 10.3 c 0,3.9 3,5.9 9,5.8 6,0 8.9,-1.9 8.9,-5.8 z"
inkscape:export-filename="C:\Users\anon\Desktop\logo4.0.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path17"
d="m 230.2,50.1 c -1.7,1.3 -3.2,2.1 -4.5,2.6 -1.4,0.5 -3.1,0.8 -5.1,0.8 -3.4,0 -6.1,-0.7 -8.2,-2.1 -2.4,-1.6 -3.6,-4 -3.6,-7.3 V 33.6 c 0,-3.1 1.2,-5.5 3.5,-7.1 2,-1.4 4.7,-2.1 7.9,-2.1 2.1,0 3.9,0.2 5.3,0.7 1.4,0.5 2.9,1.4 4.5,2.7 V 14.9 c 0,-1.7 0.6,-2.6 1.7,-2.6 1.2,0 1.9,0.9 1.9,2.6 v 36.7 c 0,1.3 -0.6,1.9 -1.7,1.9 -0.7,0 -1.2,-0.4 -1.4,-1.2 -0.2,-0.6 -0.3,-1.3 -0.3,-2.2 z M 230,45.9 V 31.5 c -1.8,-1.3 -3.2,-2.2 -4.3,-2.6 -1.5,-0.6 -3.1,-0.9 -4.9,-0.9 -2.3,0 -4.2,0.4 -5.6,1.3 -1.8,1.1 -2.7,2.7 -2.7,4.7 v 9.9 c 0,2.1 0.9,3.7 2.8,4.8 1.5,0.8 3.4,1.3 5.7,1.3 1.9,0 3.6,-0.3 5,-0.9 1.2,-0.8 2.5,-1.8 4,-3.2 z"
inkscape:export-filename="C:\Users\anon\Desktop\logo4.0.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path19"
d="m 243.8,39.6 v 4 c 0,4.3 3,6.4 9.1,6.4 2.2,0 4,-0.2 5.4,-0.7 0.7,-0.2 2,-0.9 3.7,-2.1 1.1,-1 1.9,-1.5 2.2,-1.5 1,0 1.5,0.5 1.5,1.6 0,1.1 -0.7,2.2 -2.2,3.4 -2.4,1.9 -6,2.9 -10.8,2.9 -8.4,0 -12.6,-3.3 -12.6,-9.9 v -10 c 0,-2.3 0.9,-4.3 2.6,-5.9 2.3,-2.2 5.7,-3.2 10.3,-3.2 8.2,0 12.3,4.1 12.3,12.2 0,2 -0.8,3 -2.3,3 h -19.2 z m 0,-3.6 h 17.9 c 0,-5.4 -3,-8.1 -9.1,-8.1 -2.2,0 -4.2,0.5 -6,1.5 -1.9,1.3 -2.8,2.8 -2.8,4.5 V 36 z"
inkscape:export-filename="C:\Users\anon\Desktop\logo4.0.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path21"
d="M 271.9,41.9 V 26.3 c 0,-8.2 4.3,-12.2 13,-12.2 3.5,0 6.3,0.8 8.5,2.3 2.5,1.9 3.7,4.5 3.7,7.7 0,1.5 -0.6,2.3 -1.9,2.3 -0.9,0 -1.5,-0.7 -1.9,-2.2 -0.2,-1.2 -0.7,-2.4 -1.4,-3.5 -1.1,-2 -3.5,-2.9 -7.3,-2.9 -3.2,0 -5.5,0.8 -6.9,2.4 -1.3,1.5 -2,3.8 -2,7.1 v 13 c 0,3.4 0.7,5.8 2.1,7.3 1.5,1.6 3.8,2.5 7,2.5 4.9,0 7.7,-1.7 8.4,-5.1 0.3,-1.3 0.4,-1.9 0.4,-2 0.3,-0.7 0.8,-1.1 1.5,-1.1 1.2,0 1.9,0.8 1.9,2.3 0,3.1 -1.3,5.5 -3.9,7.4 -2.1,1.4 -4.8,2.1 -8.2,2.1 -4,0 -7.1,-0.9 -9.4,-2.8 -2.3,-2.1 -3.6,-5.1 -3.6,-9 z"
inkscape:export-filename="C:\Users\anon\Desktop\logo4.0.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path23"
d="m 323.1,50.1 c -1.8,1.3 -3.2,2.2 -4.2,2.6 -1.3,0.5 -2.9,0.8 -4.9,0.8 -3,0 -5.5,-0.6 -7.4,-1.9 -2.2,-1.5 -3.4,-3.7 -3.4,-6.6 0,-2.9 1.2,-5.2 3.5,-6.8 2,-1.5 4.6,-2.2 7.6,-2.2 2.5,0 5.3,0.6 8.5,1.7 v -4.4 c 0,-2.1 -1,-3.6 -3,-4.5 -1.4,-0.6 -3.1,-0.9 -5.1,-0.9 -4.7,0 -7.2,1.3 -7.7,3.9 -0.2,1.2 -0.4,1.8 -0.4,1.9 -0.3,0.6 -0.8,0.9 -1.5,0.9 -1.3,0 -2,-0.7 -2,-2.1 0,-1.9 0.7,-3.6 2.2,-5.2 1.8,-2 5.1,-3 9.7,-3 3.7,0 6.4,0.6 8.2,1.8 2.1,1.5 3.2,4 3.2,7.5 v 12.8 c 0,1.5 0.3,2.5 0.9,3 0.1,0.1 0.7,0.4 1.7,0.8 0.6,0.3 0.9,0.8 0.9,1.7 0,1 -0.5,1.5 -1.6,1.5 -0.3,0 -0.8,-0.1 -1.6,-0.4 -1.4,-0.5 -2.3,-0.8 -2.5,-0.9 -0.5,-0.3 -0.9,-1 -1.1,-2 z m -0.2,-3.8 V 41 c -2.8,-0.9 -5.5,-1.4 -7.9,-1.4 -5.4,0 -8.1,1.7 -8.1,5.2 0,1.8 0.8,3.2 2.4,4 1.3,0.7 2.9,1.1 4.9,1.1 1.7,0 3.3,-0.3 4.7,-1 1.1,-0.4 2.4,-1.3 4,-2.6 z"
inkscape:export-filename="C:\Users\anon\Desktop\logo4.0.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path25"
d="m 337.1,27.4 c 0.9,-1.1 1.7,-1.9 2.3,-2.2 0.8,-0.5 1.8,-0.8 3.1,-0.8 2,0 3.7,1 5.2,3.1 1,-1.2 1.9,-2 2.7,-2.4 0.9,-0.5 2.1,-0.7 3.5,-0.7 4.3,0 6.5,2.1 6.5,6.3 V 51 c 0,1.7 -0.6,2.5 -1.9,2.5 -1.2,0 -1.8,-0.8 -1.8,-2.5 V 31.9 c 0,-2.6 -1.1,-4 -3.2,-4 -1.6,0 -3.2,1 -4.6,2.9 V 51 c 0,1.7 -0.6,2.5 -1.8,2.5 -1.2,0 -1.8,-0.8 -1.8,-2.5 V 32.3 c 0,-2.9 -1.2,-4.3 -3.5,-4.3 -1.5,0 -2.9,1 -4.4,2.9 V 51 c 0,1.7 -0.6,2.5 -1.9,2.5 -1.2,0 -1.8,-0.8 -1.8,-2.5 V 26.2 c 0,-1.2 0.5,-1.8 1.5,-1.8 0.5,0 1,0.4 1.3,1.1 0.4,0.5 0.6,1.2 0.6,1.9 z"
inkscape:export-filename="C:\Users\anon\Desktop\logo4.0.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path27"
d="m 369.6,27.4 c 2.8,-2 6.1,-3 9.7,-3 7.6,0 11.4,3.2 11.4,9.5 v 10.4 c 0,3 -1.1,5.3 -3.2,7 -1.9,1.5 -4.5,2.3 -7.8,2.3 -3.9,0 -7.2,-1 -10.1,-3.1 v 11.8 c 0,1.8 -0.6,2.7 -1.8,2.7 -1.2,0 -1.8,-0.9 -1.8,-2.7 V 27.1 c 0,-1.8 0.5,-2.7 1.5,-2.7 0.5,0 1,0.4 1.4,1.1 0.2,0.6 0.5,1.3 0.7,1.9 z m 0,19 c 2.6,2.3 5.8,3.5 9.5,3.5 2.3,0 4.1,-0.4 5.5,-1.3 1.7,-1 2.5,-2.5 2.5,-4.4 V 33.8 c 0,-2.2 -0.9,-3.7 -2.7,-4.7 -1.4,-0.7 -3.3,-1.1 -5.6,-1.1 -2.1,0 -3.8,0.3 -5.1,0.9 -1.2,0.5 -2.5,1.6 -4.1,3.2 v 14.3 z"
inkscape:export-filename="C:\Users\anon\Desktop\logo4.0.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path29"
d="m 403.1,36.5 c 0,-7.9 2.7,-14.9 8.2,-21.1 2,-2.3 3.6,-3.4 4.7,-3.4 0.4,0 0.8,0.1 1.1,0.4 0.3,0.3 0.5,0.6 0.5,1 0,0.6 -0.7,1.5 -2.1,2.9 -5.7,5.5 -8.6,12.3 -8.6,20.4 0,9 3,16.3 8.9,21.9 1.2,1.1 1.8,2 1.8,2.7 0,0.4 -0.2,0.8 -0.5,1.1 -0.3,0.3 -0.7,0.5 -1.1,0.5 -1.4,0 -3.3,-1.6 -5.8,-4.8 -4.8,-5.9 -7.1,-13.1 -7.1,-21.6 z"
inkscape:export-filename="C:\Users\anon\Desktop\logo4.0.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" /><path
style="fill:#ffffff"
inkscape:connector-curvature="0"
id="path31"
d="m 478.8,38.5 c 0,7.9 -2.7,14.9 -8.2,21.1 -2,2.3 -3.6,3.4 -4.7,3.4 -0.4,0 -0.8,-0.1 -1.1,-0.4 -0.3,-0.3 -0.5,-0.7 -0.5,-1.1 0,-0.6 0.7,-1.5 2.1,-2.8 5.7,-5.5 8.6,-12.3 8.6,-20.4 0,-9 -3,-16.3 -8.9,-21.9 -1.2,-1.1 -1.8,-2 -1.8,-2.7 0,-0.4 0.2,-0.8 0.5,-1.1 0.3,-0.3 0.7,-0.5 1.1,-0.5 1.3,0 3.3,1.6 5.8,4.8 4.7,6 7.1,13.2 7.1,21.6 z"
inkscape:export-filename="C:\Users\anon\Desktop\logo4.0.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<g
id="g33"
style="fill:#f9f9f9"
inkscape:export-filename="C:\Users\anon\Desktop\logo4.0.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
transform="translate(-4.8945596e-8,2)">
<line
x1="424.39999"
y1="54.099998"
x2="459.10001"
y2="54.099998"
id="line35"
style="fill:#f9f9f9" />
<path
d="m 459,56.2 h -34.7 c -1.1,0 -2.1,-0.9 -2.1,-2.1 0,-1.2 0.9,-2.1 2.1,-2.1 H 459 c 1.1,0 2.1,0.9 2.1,2.1 0,1.2 -0.9,2.1 -2.1,2.1 z"
id="path37"
style="fill:#f9f9f9"
inkscape:connector-curvature="0" />
</g>
<path
id="path3081"
d="m 452.3464,28.078901 c -0.56036,-1.883074 -1.43977,-3.650779 -2.80221,-5.059704 -0.3609,-0.373149 -0.74714,-0.721366 -1.13213,-1.069159 -0.30173,-0.272573 -1.04972,-0.714182 -1.20565,-1.080993 0.79404,1.868705 1.58979,3.807139 0.99013,5.855869 -0.27089,0.926746 -1.29609,3.146204 -2.63148,2.580351 -1.26313,-0.535425 -1.11607,-3.182546 -1.22468,-4.252128 -0.26708,-2.624301 -0.84687,-5.243532 -2.2465,-7.514969 -0.76236,-1.237353 -1.76095,-2.337784 -3.01816,-3.084083 -1.65107,-0.979993 -3.36342,-1.638815 -5.24226,-0.928437 0.41371,-0.156359 1.50316,1.095783 1.70642,1.337084 0.65841,0.780529 1.20693,1.703895 1.50063,2.685578 0.59671,1.994639 0.0761,4.266075 -0.62079,6.16732 -1.4423,3.934762 -3.84855,7.473554 -5.00349,11.51988 -0.40274,1.410192 -0.67911,2.859686 -0.75476,4.326083 -0.23749,4.619363 2.16072,8.850785 5.95941,11.434517 0.86209,0.586136 2.39483,1.32018 3.48639,0.942382 -3.18846,-1.705162 -4.24875,-3.106057 -4.74107,-5.11295 -1.14142,-4.652748 3.21255,-7.607094 5.09563,-11.287455 0.50119,-0.97957 0.86504,-2.055914 0.73826,-3.166911 -0.0473,-0.414141 -0.51894,-2.451038 -1.14438,-2.350883 1.89576,-0.303845 3.13014,0.958018 3.77883,2.60444 0.68333,1.73432 1.08944,3.515971 0.78771,5.36059 -0.101,0.616985 -0.56501,2.544431 0.32836,2.669518 1.22974,0.172841 2.28538,-1.458791 2.03309,-3.032949 -0.12974,-0.723901 -0.25905,-1.852646 -0.25905,-1.85307 1.30666,1.609657 1.89913,3.22058 2.09099,4.987441 0.34315,3.162263 -1.00408,7.318463 -3.53837,9.899238 1.06536,-1.085219 2.42146,-1.835322 3.45005,-2.994071 1.05056,-1.182837 1.85222,-2.551193 2.47893,-3.999419 1.403,-3.241286 2.22241,-6.905166 1.99421,-10.444382 -0.10818,-1.68868 -0.35413,-3.459344 -0.85406,-5.138728 z"
inkscape:connector-curvature="0"
style="fill:#ffffff"
inkscape:export-filename="C:\Users\anon\Desktop\logo4.0.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" /></svg>

Before

Width:  |  Height:  |  Size: 14 KiB

View File

@ -29,25 +29,26 @@ module.exports = function enableAuthentication(app) {
const api = app.loopback.Router(); const api = app.loopback.Router();
const { AuthToken, User } = app.models; const { AuthToken, User } = app.models;
router.get('/login', (req, res) => res.redirect(301, '/signin')); router.get('/email-signin', (req, res) => res.redirect(301, '/login'));
router.get('/logout', (req, res) => res.redirect(301, '/signout')); router.get('/signin', (req, res) => res.redirect(301, '/signup'));
router.get('/signup', (req, res) => res.redirect(301, '/signin')); router.get('/signout', (req, res) => res.redirect(301, '/logout'));
router.get('/email-signin', (req, res) => res.redirect(301, '/signin'));
function getEmailSignin(req, res) { function getLegacySignUp(req, res) {
if (isSignUpDisabled) { if (isSignUpDisabled) {
return res.render('account/beta', { return res.render('account/beta', {
title: 'New sign ups are disabled' title: 'New sign ups are disabled'
}); });
} }
return res.render('account/email-signin', { return res.render('account/deprecated-signup', {
title: 'Sign in to freeCodeCamp using your Email Address' title: 'Sign in to freeCodeCamp using your Email Address'
}); });
} }
router.get('/signup', ifUserRedirect, getLegacySignUp);
router.get('/login',
ifUserRedirect,
(req, res) => res.redirect(301, '/auth/auth0'));
router.get('/signin', ifUserRedirect, getEmailSignin); router.get('/logout', (req, res) => {
router.get('/signout', (req, res) => {
req.logout(); req.logout();
res.redirect('/'); res.redirect('/');
}); });

View File

@ -2,6 +2,7 @@ import passport from 'passport';
import { PassportConfigurator } from import { PassportConfigurator } from
'@freecodecamp/loopback-component-passport'; '@freecodecamp/loopback-component-passport';
import passportProviders from './passport-providers'; import passportProviders from './passport-providers';
import url from 'url';
const passportOptions = { const passportOptions = {
emailOptional: true, emailOptional: true,
@ -90,8 +91,58 @@ export default function setupPassport(app) {
configurator.init(); configurator.init();
Object.keys(passportProviders).map(function(strategy) { Object.keys(passportProviders).map(function(strategy) {
var config = passportProviders[strategy]; let config = passportProviders[strategy];
config.session = config.session !== false; config.session = config.session !== false;
// https://stackoverflow.com/q/37430452
let successRedirect = (req) => {
if (!!req && req.session && req.session.returnTo) {
let returnTo = req.session.returnTo;
delete req.session.returnTo;
return returnTo;
}
return config.successRedirect || '';
};
config.customCallback = !config.useCustomCallback
? null
: (req, res, next) => {
passport.authenticate(
strategy,
{ session: false },
(err, user) => {
if (err) {
return next(err);
}
if (!user) {
return res.redirect(config.failureRedirect);
}
let redirect = url.parse(successRedirect(req), true);
delete redirect.search;
req.flash(
'success',
'Success! You have signed in to your account. Happy Coding!'
);
// redirect.query = {
// /* eslint-disable camelcase */
// access_token: info.accessToken.id,
// /* eslint-enable camelcase */
// userId: user.id.toString()
// };
user.loginByRequest(req, res);
redirect = url.format(redirect);
return res.redirect(redirect);
}
)(req, res, next);
};
configurator.configureProvider( configurator.configureProvider(
strategy, strategy,
{ {

View File

@ -10,7 +10,7 @@ const log = debug('fcc:middlewares:error-reporter');
const isOpbeatDisabled = !opbeat.appId; const isOpbeatDisabled = !opbeat.appId;
export default function errrorReporter() { export default function errrorReporter() {
if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV !== 'production' && process.env.ERROR_REPORTER) {
return (err, req, res, next) => { return (err, req, res, next) => {
if (isHandledError(err)) { if (isHandledError(err)) {
// log out user messages in development // log out user messages in development

View File

@ -1,5 +1,5 @@
const successRedirect = '/'; const successRedirect = '/';
const failureRedirect = '/signin'; const failureRedirect = '/';
const linkSuccessRedirect = '/settings'; const linkSuccessRedirect = '/settings';
const linkFailureRedirect = '/settings'; const linkFailureRedirect = '/settings';
@ -165,5 +165,21 @@ export default {
'We\'ve updated your profile based ', 'We\'ve updated your profile based ',
'on your your GitHub account.' 'on your your GitHub account.'
].join('') ].join('')
},
'auth0-login': {
provider: 'auth0',
module: 'passport-auth0',
clientID: process.env.AUTH0_CLIENT_ID,
clientSecret: process.env.AUTH0_CLIENT_SECRET,
domain: process.env.AUTH0_DOMAIN,
cookieDomain: 'freeCodeCamp.org',
callbackURL: '/auth/auth0/callback',
authPath: '/auth/auth0',
callbackPath: '/auth/auth0/callback',
useCustomCallback: true,
successRedirect: successRedirect,
failureRedirect: failureRedirect,
scope: ['openid email'],
failureFlash: true
} }
}; };

View File

@ -1,7 +1,10 @@
extends ../layout extends ../layout
block content block content
.container
.col-xs-12
.row
.text-center .text-center
h2 If you originally signed up using one of these methods, you can sign in and add your email address to your account: h3 Sign in with one of these options if you used them as your original sign up methods :
br br
a.btn.btn-lg.btn-block.btn-social.btn-github(href='/auth/github') a.btn.btn-lg.btn-block.btn-social.btn-github(href='/auth/github')
i.fa.fa-github i.fa.fa-github
@ -19,6 +22,11 @@ block content
i.fa.fa-twitter i.fa.fa-twitter
| Sign in with Twitter | Sign in with Twitter
br br
h3
| We are unable to create new accounts using these methods
h4 If you haven't updated your email with us, you should do that as soon as possible,
| after you login here, to avoid losing access to your account.
br
p p
a(href="/signin") Or click here to go back. a(href="/signin") Or click here to go back.

View File

@ -0,0 +1,20 @@
extends ../layout
block content
.container
.col-xs-12
.row
.text-center
h2 Sign up (or sign in with your existing account)
br
br
br
a.btn.btn-lg.btn-primary(href='/auth/auth0')
| Continue with your email
.row
.text-center
br
br
br
br
a(href="/deprecated-signin")
| Continute with an old sign in method, that you used previously.

View File

@ -1,100 +0,0 @@
extends ../layout
block content
.container
.col-xs-12
.row
.col-sm-6.col-sm-offset-3.flashMessage.negative-30
#flash-board.alert.fade.in(style='display: none;')
button.close(type='button', data-dismiss='alert')
span.ion-close-circled#flash-close
#flash-content
.row
.text-center
h2 Sign up (or sign in with your existing account)
.button-spacer
.col-sm-6.col-sm-offset-3
form(method='POST', action='/passwordless-auth')
input(type='hidden', name='_csrf', value=_csrf)
.form-group
input.input-lg.form-control(type='email', name='email', id='email', placeholder='Enter your email address', autofocus=true, required, oninvalid="this.setCustomValidity('Enter your email address')", oninput="setCustomValidity('')")
.button-spacer
button#magic-btn.btn.btn-primary.btn-lg.btn-block(type='submit')
| Get a sign in link
.row
.col-sm-6.col-sm-offset-3
br
p.text-center
br
br
a(href="/deprecated-signin") Try old sign in methods
script.
$(document).ready(function() {
function disableMagicButton (isDisabled) {
if (isDisabled) {
$('#magic-btn')
.prop('disabled', true)
.html('<span style="color:#E0E0E0;"><i class="fa fa-circle-o-notch fa-spin fa-fw"></i>OK - we\'re sending you an email. Open it and click sign in link.</span>');
} else {
$('#magic-btn')
.prop('disabled', true)
.html('<span style="color:#E0E0E0;">If you didn\'t get the email, check your spam folder, or reload the page to try again.</span>');
}
}
$('form').submit(function(event){
event.preventDefault();
$('#flash-board').hide();
disableMagicButton(true);
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.error && data.error.message) {
$('#flash-content').html(data.error.message);
$('#flash-board')
.removeClass('alert-success')
.addClass('alert-info')
.slideDown(400)
.delay(800)
.fadeIn();
disableMagicButton(false);
}
}
})
.done(data => {
if(data && data.message) {
var alertType = 'alert-';
switch (data.type) {
case 'errors': {
alertType += 'danger';
break
}
case 'success': {
alertType += 'success';
break
}
default: {
alertType += 'info';
}
}
$('#flash-content').html(data.message);
$('#flash-board')
.removeClass('alert-info alert-success alert-danger')
.addClass(alertType)
.slideDown(400)
.delay(800)
.fadeIn();
disableMagicButton(false);
}
});
});
});