Added login screen
parent
7153f7bb9b
commit
861fb48bb6
|
@ -0,0 +1,31 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
|
||||
// Local variables
|
||||
mode: 'development', // or production
|
||||
|
||||
// Random strings to prevent hijacking
|
||||
session: 'SomeSecret',
|
||||
cookie: 'SomeOtherSecret',
|
||||
|
||||
// Location of your mongoDB
|
||||
mongoSetup: 'mongodb://localhost:27017/tracman',
|
||||
|
||||
// URL and port where this will run
|
||||
url: 'https://localhost:8080',
|
||||
port: 8080,
|
||||
|
||||
// OAuth API keys
|
||||
facebookAppId: 'XXXXXXXXXXXXXXXX',
|
||||
facebookAppSecret: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
twitterConsumerKey: 'XXXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
twitterConsumerSecret: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
|
||||
googleClientId: '############-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.apps.googleusercontent.com',
|
||||
googleClientSecret: 'XXXXXXXXX_XXXXXXXXXXXXXX',
|
||||
|
||||
// Google maps API key
|
||||
googleMapsAPI: 'XXXXXXXXXXXXXXX_XXXXXXXXXXXXXXXXXXXXXXX',
|
||||
|
||||
|
||||
};
|
|
@ -0,0 +1,16 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = require('nodemailer').createTransport({
|
||||
host: 'keithirwin.us',
|
||||
port: 587,
|
||||
secure: false,
|
||||
requireTLS: true,
|
||||
auth: {
|
||||
user: 'NoReply@tracman.org',
|
||||
pass: 'Ei0UwfrZuE'
|
||||
},
|
||||
// logger: true,
|
||||
// debug: true
|
||||
});
|
||||
|
||||
// require('./mail.js').(mailData, context).then(...).catch(...);
|
|
@ -0,0 +1,37 @@
|
|||
'use strict';
|
||||
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
const userSchema = new mongoose.Schema({
|
||||
name: {type:String, required:true},
|
||||
email: String,
|
||||
slug: {type:String, required:true, unique:true},
|
||||
requestId: String,
|
||||
isAdmin: {type:Boolean, required:true, default:false},
|
||||
isPro: {type:Boolean, required:true, default:false},
|
||||
created: Date,
|
||||
lastLogin: Date,
|
||||
googleID: {type:Number, unique:true},
|
||||
settings: {
|
||||
units: {type:String, default:'standard'},
|
||||
defaultMap: {type:String, default:'road'},
|
||||
defaultZoom: {type:Number, default:11},
|
||||
showSpeed: {type:Boolean, default:false},
|
||||
showTemp: {type:Boolean, default:false},
|
||||
showAlt: {type:Boolean, default:false},
|
||||
showStreetview: {type:Boolean, default:false}
|
||||
},
|
||||
last: {
|
||||
time: Date,
|
||||
lat: {type:Number, default:0},
|
||||
lon: {type:Number, default:0},
|
||||
dir: {type:Number, default:0},
|
||||
alt: {type:Number, default:0},
|
||||
spd: {type:Number, default:0}
|
||||
},
|
||||
sk32: {type:String, required:true, unique:true}
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
'user': mongoose.model('User', userSchema)
|
||||
};
|
|
@ -0,0 +1,141 @@
|
|||
'use strict';
|
||||
|
||||
var vars = require('./env.js'),
|
||||
User = require('./models.js').user,
|
||||
LocalStrategy = require('passport-local').Strategy,
|
||||
GoogleStrategy = require('passport-google-oauth20').Strategy,
|
||||
FacebookStrategy = require('passport-facebook').Strategy,
|
||||
TwitterStrategy = require('passport-twitter').Strategy;
|
||||
|
||||
module.exports = function(passport) {
|
||||
|
||||
// Serialize/deserialize users
|
||||
passport.serializeUser(function(user,done) {
|
||||
done(null, user.id);
|
||||
});
|
||||
passport.deserializeUser(function(id,done) {
|
||||
User.findById(id, function(err, user) {
|
||||
if(!err){ done(null, user); }
|
||||
else { done(err, null); }
|
||||
});
|
||||
});
|
||||
|
||||
// Signup
|
||||
// passport.use('signup', new LocalStrategy({
|
||||
// usernameField: 'email',
|
||||
// passwordField: 'password',
|
||||
// passReqToCallback : true
|
||||
// }, function(req, email, password, done) {
|
||||
// process.nextTick(function() {
|
||||
// User.findOne({'email':email }, function(err, user) {
|
||||
// if (err){ return done(err); }
|
||||
|
||||
// // Check for existing user
|
||||
// if (user) {
|
||||
// return done( null, false, req.flash('warning','That email is already in use. Try logging in below.') );
|
||||
|
||||
// // Create user
|
||||
// } else {
|
||||
// var newUser = new User();
|
||||
// newUser.email = email;
|
||||
// newUser.created = Date.now();
|
||||
// newUser.lastLogin = Date.now();
|
||||
// newUser.generateHash(password, function(err, hash){
|
||||
// if (err){ return done(err); }
|
||||
// newUser.auth.password = hash;
|
||||
// newUser.save(function(err) {
|
||||
// if (err){ return done(err); }
|
||||
// return done( null, newUser );
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
|
||||
// });
|
||||
// });
|
||||
// })
|
||||
// );
|
||||
|
||||
// Local
|
||||
passport.use('local', new LocalStrategy({
|
||||
usernameField: 'email',
|
||||
passwordField: 'password',
|
||||
passReqToCallback : true
|
||||
}, function(req, email, password, done) {
|
||||
User.findOne({ 'email':email }, function (err, user) {
|
||||
if (err){ return done(err); }
|
||||
|
||||
// Wrong username
|
||||
if (!user) {
|
||||
return done( null, false, req.flash('danger','No account exists for that email.') );
|
||||
// Username correct, password incorrect
|
||||
} else {
|
||||
// Check password
|
||||
user.validPassword(password, function(err,res){
|
||||
if (err){ console.log('Passport error:\n',err); }
|
||||
if (!res) { // Password incorrect
|
||||
return done( null, false, req.flash('danger','Incorrect password.') );
|
||||
} else { // Successful login
|
||||
user.lastLogin = Date.now();
|
||||
user.save();
|
||||
return done( null, user );
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
));
|
||||
|
||||
// Social login
|
||||
function socialLogin(req, service, profileId, done) {
|
||||
if (!req.user) { // Log in
|
||||
var query = {};
|
||||
query['auth.'+service] = profileId;
|
||||
User.findOne(query, function (err, user) {
|
||||
if (err){ return done(err); }
|
||||
else if (!user){ return done(); }
|
||||
else { return done(null, user); }
|
||||
});
|
||||
} else {
|
||||
req.user.auth[service] = profileId;
|
||||
req.user.save(function(err){
|
||||
if (err){ return done(err); }
|
||||
else { return done(null, req.user); }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Google
|
||||
passport.use('google', new GoogleStrategy({
|
||||
clientID: vars.googleClientId,
|
||||
clientSecret: vars.googleClientSecret,
|
||||
callbackURL: vars.url+'/login/google/cb',
|
||||
passReqToCallback: true
|
||||
}, function(req, accessToken, refreshToken, profile, done) {
|
||||
socialLogin(req, 'google', profile.id, done);
|
||||
}
|
||||
));
|
||||
|
||||
// Facebook
|
||||
passport.use('facebook', new FacebookStrategy({
|
||||
clientID: vars.facebookAppId,
|
||||
clientSecret: vars.facebookAppSecret,
|
||||
callbackURL: vars.url+'/login/facebook/cb',
|
||||
passReqToCallback: true
|
||||
}, function(req, accessToken, refreshToken, profile, done) {
|
||||
socialLogin(req, 'facebook', profile.id, done);
|
||||
}
|
||||
));
|
||||
|
||||
// Twitter
|
||||
passport.use(new TwitterStrategy({
|
||||
consumerKey: vars.twitterConsumerKey,
|
||||
consumerSecret: vars.twitterConsumerSecret,
|
||||
callbackURL: vars.url+'/login/twitter/cb',
|
||||
passReqToCallback: true
|
||||
}, function(req, token, tokenSecret, profile, done) {
|
||||
socialLogin(req, 'twitter', profile.id, done);
|
||||
}
|
||||
));
|
||||
|
||||
return passport;
|
||||
};
|
|
@ -0,0 +1,59 @@
|
|||
|
||||
|
||||
form label {
|
||||
font-size: 1.2em;
|
||||
margin-right: 3%;
|
||||
}
|
||||
|
||||
form input, form textarea, form select {
|
||||
-moz-box-shadow: inset .11vw .18vw .25vw rgba(0,0,0,.5);
|
||||
-webkit-box-shadow: inset .11vw .18vw .25vw rgba(0,0,0,.5);
|
||||
box-shadow: inset .11vw .18vw .25vw rgba(0,0,0,.5);
|
||||
color: #eee;
|
||||
background-color: rgba(255,255,255,0.1);
|
||||
padding: 1% 1.5%;
|
||||
border: 1px solid #666;
|
||||
border-radius: .3vw;
|
||||
}
|
||||
form input:active, form textarea:active, form select:active,
|
||||
form input:focus, form textarea:focus, form select:focus {
|
||||
outline: none;
|
||||
border: 1px solid #fbc93d;
|
||||
}
|
||||
|
||||
::-webkit-input-placeholder {
|
||||
color: #666;
|
||||
}:-moz-placeholder {
|
||||
color: #666;
|
||||
opacity: 1;
|
||||
}::-moz-placeholder {
|
||||
color: #666;
|
||||
opacity: 1;
|
||||
}:-ms-input-placeholder {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
form select {
|
||||
-moz-box-shadow: inset 0 1px 6px rgba(255,255,255,.2),
|
||||
inset -.11vw -.18vw .52vw rgba(0,0,0,.4);
|
||||
-webkit-box-shadow: inset -.11vw -.18vw .52vw rgba(255,255,255,.2),
|
||||
inset -.11vw -.18vw .52vw rgba(0,0,0,.4);
|
||||
box-shadow: inset 0 .11vw .52vw rgba(255,255,255,.2),
|
||||
inset 0 .11vw .52vw rgba(0,0,0,.4);
|
||||
}
|
||||
form select > option {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
form input[type="checkbox"], form input[type="radio"] {
|
||||
width: auto;
|
||||
margin: 8px 8px 8px 0;
|
||||
}
|
||||
form input[type="checkbox"]:active, form input[type="radio"]:active,
|
||||
form input[type="checkbox"]:focus, form input[type="radio"]:focus {
|
||||
outline: 1px solid #fbc93d;
|
||||
}
|
||||
|
||||
form .btn {
|
||||
font-size: 1.5em;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
section > .flex > div {
|
||||
width: 50%;
|
||||
padding: 0 2%;
|
||||
}
|
||||
|
||||
form input {
|
||||
width: 96%;
|
||||
}
|
||||
|
||||
form input.btn,
|
||||
form #social-login {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#social-login .btn {
|
||||
padding: 0;
|
||||
font-size: 1.3em;
|
||||
height: 60px;
|
||||
text-align: center;
|
||||
width: 60px;
|
||||
margin: 0 3%;
|
||||
color: #FFF;
|
||||
} #social-login .btn .fa {
|
||||
margin: 0;
|
||||
position: relative;
|
||||
padding-top: 20px;
|
||||
} #social-login .btn.gp {
|
||||
background: rgb(206,77,57);
|
||||
} #social-login .btn.gp:hover {
|
||||
background: rgb(251,122,102);
|
||||
} #social-login .btn.fb {
|
||||
background: rgb(48,88,145);
|
||||
} #social-login .btn.fb:hover {
|
||||
background: rgb(93,133,190);
|
||||
} #social-login .btn.tw {
|
||||
background: rgb(44,168,210);
|
||||
} #social-login .btn.tw:hover {
|
||||
background: rgb(89,213,255);
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
section > .flex {
|
||||
flex-direction: column;
|
||||
}
|
||||
section > .flex > div {
|
||||
width: 100%;
|
||||
}
|
||||
hr.hide { display:block; }
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
{% extends 'templates/base.html' %}
|
||||
{% block title %}{{super()}} | Privacy Policy{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<section class='container'>
|
||||
|
||||
<h2>Privacy Policy</h2>
|
||||
|
||||
<p>In lieu of legalease, which I don't speak, here is a quick rundown of what Tracman does with your data (such as location). </p>
|
||||
|
||||
<h3>Location history</h3>
|
||||
|
||||
<p>Your location is saved on the database as long as you have it "set" or "tracking". If you "clear" the data, it will be deleted from the database too. This doesn't mean all copies are destroyed. Our servers keep occasional backups, and caches could exist on other servers (google index, wayback archive, etc). </p>
|
||||
|
||||
<p>This means that all public access to your location is essentially deleted when you clear it. But anyone could record your location while it's publicly available and rebroadcast it. Tracman doesn't store location histories (except as mentioned above), but histories may exist elsewhere! If you have (or plan to have) trouble with the law, don't use Tracman. Authorities have easy access to those histories. </p>
|
||||
|
||||
<h3>Email addresses</h3>
|
||||
|
||||
<p>Tracman stores email addresses so we can contact users for important stuff (urgent security updates, deletion requests, lost passwords). We will never subscribe you to anything else by default. </p>
|
||||
|
||||
</section>
|
||||
{% endblock %}
|
Loading…
Reference in New Issue