chore: format all files
This commit is contained in:
parent
e75a71a9bc
commit
481999b278
|
@ -9,7 +9,10 @@ async function sendEmail({ to, subject, html, from = config.emailFrom }) {
|
|||
await transporter.sendMail({ from, to, subject, html });
|
||||
} else {
|
||||
console.log({
|
||||
to, subject, html, from
|
||||
to,
|
||||
subject,
|
||||
html,
|
||||
from,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
module.exports = errorHandler;
|
||||
|
||||
function errorHandler(err, req, res, next) {
|
||||
switch (true) {
|
||||
case typeof err === 'string':
|
||||
// custom application error
|
||||
const is404 = err.toLowerCase().endsWith('not found');
|
||||
const statusCode = is404 ? 404 : 400;
|
||||
return res.status(statusCode).json({ message: err });
|
||||
case err.name === 'ValidationError':
|
||||
// mongoose validation error
|
||||
return res.status(400).json({ message: err.message });
|
||||
case err.name === 'UnauthorizedError':
|
||||
// jwt authentication error
|
||||
return res.status(401).json({ message: 'Unauthorized' });
|
||||
default:
|
||||
return res.status(500).json({ message: err.message });
|
||||
}
|
||||
}
|
||||
switch (true) {
|
||||
case typeof err === 'string':
|
||||
// custom application error
|
||||
const is404 = err.toLowerCase().endsWith('not found');
|
||||
const statusCode = is404 ? 404 : 400;
|
||||
return res.status(statusCode).json({ message: err });
|
||||
case err.name === 'ValidationError':
|
||||
// mongoose validation error
|
||||
return res.status(400).json({ message: err.message });
|
||||
case err.name === 'UnauthorizedError':
|
||||
// jwt authentication error
|
||||
return res.status(401).json({ message: 'Unauthorized' });
|
||||
default:
|
||||
return res.status(500).json({ message: err.message });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,14 +6,14 @@ function validateRequest(req, next, schema) {
|
|||
const options = {
|
||||
abortEarly: false, // include all errors
|
||||
allowUnknown: true, // ignore unknown props
|
||||
stripUnknown: true // remove unknown props
|
||||
stripUnknown: true, // remove unknown props
|
||||
};
|
||||
const { error, value } = schema.validate(req.body, options);
|
||||
if (error) {
|
||||
console.log('error: ', error)
|
||||
next(`Validation error: ${error.details.map(x => x.message).join(', ')}`);
|
||||
console.log('error: ', error);
|
||||
next(`Validation error: ${error.details.map((x) => x.message).join(', ')}`);
|
||||
} else {
|
||||
req.body = value;
|
||||
next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const crypto = require("crypto");
|
||||
const crypto = require('crypto');
|
||||
const mongoose = require('mongoose');
|
||||
const sendEmail = require('../_helpers/send-email');
|
||||
var User = mongoose.model('User');
|
||||
const User = mongoose.model('User');
|
||||
|
||||
module.exports = {
|
||||
register,
|
||||
|
@ -54,13 +54,12 @@ async function forgotPassword({ email }, origin) {
|
|||
// create reset token that expires after 24 hours
|
||||
account.resetToken = {
|
||||
token: randomTokenString(),
|
||||
expires: new Date(Date.now() + 24 * 60 * 60 * 1000)
|
||||
expires: new Date(Date.now() + 24 * 60 * 60 * 1000),
|
||||
};
|
||||
await account.save();
|
||||
|
||||
console.log('forgotPassword account saved', account);
|
||||
|
||||
|
||||
// send email
|
||||
await sendPasswordResetEmail(account, origin);
|
||||
}
|
||||
|
@ -68,7 +67,7 @@ async function forgotPassword({ email }, origin) {
|
|||
async function validateResetToken({ token }) {
|
||||
const account = await User.findOne({
|
||||
'resetToken.token': token,
|
||||
'resetToken.expires': { $gt: Date.now() }
|
||||
'resetToken.expires': { $gt: Date.now() },
|
||||
});
|
||||
|
||||
if (!account) throw 'Invalid token';
|
||||
|
@ -77,13 +76,13 @@ async function validateResetToken({ token }) {
|
|||
async function resetPassword({ token, password }) {
|
||||
const account = await User.findOne({
|
||||
'resetToken.token': token,
|
||||
'resetToken.expires': { $gt: Date.now() }
|
||||
'resetToken.expires': { $gt: Date.now() },
|
||||
});
|
||||
|
||||
if (!account) throw 'Invalid token';
|
||||
|
||||
// update password and remove reset token
|
||||
account.setPassword(password)
|
||||
account.setPassword(password);
|
||||
account.resetToken = undefined;
|
||||
await account.save();
|
||||
}
|
||||
|
@ -108,7 +107,7 @@ async function sendVerificationEmail(account, origin) {
|
|||
subject: 'Sign-up Verification API - Verify Email',
|
||||
html: `<h4>Verify Email</h4>
|
||||
<p>Thanks for registering!</p>
|
||||
${message}`
|
||||
${message}`,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -125,7 +124,7 @@ async function sendAlreadyRegisteredEmail(email, origin) {
|
|||
subject: 'Sign-up Verification API - Email Already Registered',
|
||||
html: `<h4>Email Already Registered</h4>
|
||||
<p>Your email <strong>${email}</strong> is already registered.</p>
|
||||
${message}`
|
||||
${message}`,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -144,6 +143,6 @@ async function sendPasswordResetEmail(account, origin) {
|
|||
to: account.email,
|
||||
subject: 'Sign-up Verification API - Reset Password',
|
||||
html: `<h4>Reset Password Email</h4>
|
||||
${message}`
|
||||
${message}`,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,56 +18,60 @@ function registerSchema(req, res, next) {
|
|||
username: Joi.string().required(),
|
||||
email: Joi.string().email().required(),
|
||||
password: Joi.string().min(6).required(),
|
||||
confirmPassword: Joi.string().valid(Joi.ref('password')).required()
|
||||
confirmPassword: Joi.string().valid(Joi.ref('password')).required(),
|
||||
});
|
||||
|
||||
validateRequest(req, next, schema);
|
||||
}
|
||||
|
||||
function register(req, res, next) {
|
||||
accountService.register(req.body, req.get('origin'))
|
||||
accountService
|
||||
.register(req.body, req.get('origin'))
|
||||
.then(() => res.json({ message: 'Registration successful, please check your email for verification instructions' }))
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
next(err)
|
||||
next(err);
|
||||
});
|
||||
}
|
||||
|
||||
function verifyEmailSchema(req, res, next) {
|
||||
const schema = Joi.object({
|
||||
token: Joi.string().required()
|
||||
token: Joi.string().required(),
|
||||
});
|
||||
validateRequest(req, next, schema);
|
||||
}
|
||||
|
||||
function verifyEmail(req, res, next) {
|
||||
accountService.verifyEmail(req.body)
|
||||
accountService
|
||||
.verifyEmail(req.body)
|
||||
.then(() => res.json({ message: 'Verification successful, you can now login' }))
|
||||
.catch(next);
|
||||
}
|
||||
|
||||
function forgotPasswordSchema(req, res, next) {
|
||||
const schema = Joi.object({
|
||||
email: Joi.string().email().required()
|
||||
email: Joi.string().email().required(),
|
||||
});
|
||||
validateRequest(req, next, schema);
|
||||
}
|
||||
|
||||
function forgotPassword(req, res, next) {
|
||||
accountService.forgotPassword(req.body, req.get('origin'))
|
||||
accountService
|
||||
.forgotPassword(req.body, req.get('origin'))
|
||||
.then(() => res.json({ message: 'Please check your email for password reset instructions' }))
|
||||
.catch(next);
|
||||
}
|
||||
|
||||
function validateResetTokenSchema(req, res, next) {
|
||||
const schema = Joi.object({
|
||||
token: Joi.string().required()
|
||||
token: Joi.string().required(),
|
||||
});
|
||||
validateRequest(req, next, schema);
|
||||
}
|
||||
|
||||
function validateResetToken(req, res, next) {
|
||||
accountService.validateResetToken(req.body)
|
||||
accountService
|
||||
.validateResetToken(req.body)
|
||||
.then(() => res.json({ message: 'Token is valid' }))
|
||||
.catch(next);
|
||||
}
|
||||
|
@ -76,13 +80,14 @@ function resetPasswordSchema(req, res, next) {
|
|||
const schema = Joi.object({
|
||||
token: Joi.string().required(),
|
||||
password: Joi.string().min(6).required(),
|
||||
confirmPassword: Joi.string().valid(Joi.ref('password')).required()
|
||||
confirmPassword: Joi.string().valid(Joi.ref('password')).required(),
|
||||
});
|
||||
validateRequest(req, next, schema);
|
||||
}
|
||||
|
||||
function resetPassword(req, res, next) {
|
||||
accountService.resetPassword(req.body)
|
||||
accountService
|
||||
.resetPassword(req.body)
|
||||
.then(() => res.json({ message: 'Password reset successful, you can now login' }))
|
||||
.catch(next);
|
||||
}
|
||||
|
|
41
app.js
41
app.js
|
@ -1,18 +1,18 @@
|
|||
var http = require('http'),
|
||||
path = require('path'),
|
||||
methods = require('methods'),
|
||||
express = require('express'),
|
||||
bodyParser = require('body-parser'),
|
||||
session = require('express-session'),
|
||||
cors = require('cors'),
|
||||
passport = require('passport'),
|
||||
errorhandler = require('errorhandler'),
|
||||
mongoose = require('mongoose');
|
||||
const http = require('http');
|
||||
const path = require('path');
|
||||
const methods = require('methods');
|
||||
const express = require('express');
|
||||
const bodyParser = require('body-parser');
|
||||
const session = require('express-session');
|
||||
const cors = require('cors');
|
||||
const passport = require('passport');
|
||||
const errorhandler = require('errorhandler');
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
var isProduction = process.env.NODE_ENV === 'production';
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
|
||||
// Create global app object
|
||||
var app = express();
|
||||
const app = express();
|
||||
|
||||
app.use(cors());
|
||||
|
||||
|
@ -30,7 +30,8 @@ if (!isProduction) {
|
|||
app.use(errorhandler());
|
||||
}
|
||||
|
||||
const mongodbUrl = process.env.MONGODB_URL || (isProduction ? 'mongodb://localhost/obs' : 'mongodb://localhost/obsTest')
|
||||
const mongodbUrl =
|
||||
process.env.MONGODB_URL || (isProduction ? 'mongodb://localhost/obs' : 'mongodb://localhost/obsTest');
|
||||
mongoose.connect(mongodbUrl);
|
||||
mongoose.set('debug', !isProduction);
|
||||
|
||||
|
@ -44,7 +45,7 @@ app.use(require('./routes'));
|
|||
|
||||
/// catch 404 and forward to error handler
|
||||
app.use(function (req, res, next) {
|
||||
var err = new Error('Not Found');
|
||||
const err = new Error('Not Found');
|
||||
err.status = 404;
|
||||
next(err);
|
||||
});
|
||||
|
@ -60,10 +61,10 @@ if (!isProduction) {
|
|||
res.status(err.status || 500);
|
||||
|
||||
res.json({
|
||||
'errors': {
|
||||
errors: {
|
||||
message: err.message,
|
||||
error: err
|
||||
}
|
||||
error: err,
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -73,10 +74,10 @@ if (!isProduction) {
|
|||
app.use(function (err, req, res, next) {
|
||||
res.status(err.status || 500);
|
||||
res.json({
|
||||
'errors': {
|
||||
errors: {
|
||||
message: err.message,
|
||||
error: {}
|
||||
}
|
||||
error: {},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
const forcedMail = process.argv.findIndex(s => s === '--devSendMails') !== -1;
|
||||
const forcedMail = process.argv.findIndex((s) => s === '--devSendMails') !== -1;
|
||||
|
||||
module.exports = {
|
||||
"sendMails": isProduction || forcedMail,
|
||||
"emailFrom": process.env.MAILSENDER,
|
||||
"smtpOptions": {
|
||||
"host": process.env.MAILSERVER,
|
||||
"port": 587,
|
||||
"auth": {
|
||||
"user": process.env.MAILUSER,
|
||||
"pass": process.env.MAILPW
|
||||
}
|
||||
}
|
||||
sendMails: isProduction || forcedMail,
|
||||
emailFrom: process.env.MAILSENDER,
|
||||
smtpOptions: {
|
||||
host: process.env.MAILSERVER,
|
||||
port: 587,
|
||||
auth: {
|
||||
user: process.env.MAILUSER,
|
||||
pass: process.env.MAILPW,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
module.exports = {
|
||||
secret: process.env.NODE_ENV === 'production' ? process.env.SECRET : 'secret'
|
||||
secret: process.env.NODE_ENV === 'production' ? process.env.SECRET : 'secret',
|
||||
};
|
||||
|
|
|
@ -1,22 +1,28 @@
|
|||
var passport = require('passport');
|
||||
var LocalStrategy = require('passport-local').Strategy;
|
||||
var mongoose = require('mongoose');
|
||||
var User = mongoose.model('User');
|
||||
const passport = require('passport');
|
||||
const LocalStrategy = require('passport-local').Strategy;
|
||||
const mongoose = require('mongoose');
|
||||
const User = mongoose.model('User');
|
||||
|
||||
passport.use(new LocalStrategy({
|
||||
usernameField: 'user[email]',
|
||||
passwordField: 'user[password]'
|
||||
}, function (email, password, done) {
|
||||
User.findOne({ email: email }).then(function (user) {
|
||||
if (!user || !user.validPassword(password)) {
|
||||
return done(null, false, { errors: { 'email or password': 'is invalid' } });
|
||||
}
|
||||
passport.use(
|
||||
new LocalStrategy(
|
||||
{
|
||||
usernameField: 'user[email]',
|
||||
passwordField: 'user[password]',
|
||||
},
|
||||
function (email, password, done) {
|
||||
User.findOne({ email: email })
|
||||
.then(function (user) {
|
||||
if (!user || !user.validPassword(password)) {
|
||||
return done(null, false, { errors: { 'email or password': 'is invalid' } });
|
||||
}
|
||||
|
||||
if (user && user.needsEmailValidation) {
|
||||
return done(null, false, { errors: { 'E-Mail-Bestätigung': 'noch nicht erfolgt' } });
|
||||
}
|
||||
|
||||
return done(null, user);
|
||||
}).catch(done);
|
||||
}));
|
||||
if (user && user.needsEmailValidation) {
|
||||
return done(null, false, { errors: { 'E-Mail-Bestätigung': 'noch nicht erfolgt' } });
|
||||
}
|
||||
|
||||
return done(null, user);
|
||||
})
|
||||
.catch(done);
|
||||
},
|
||||
),
|
||||
);
|
||||
|
|
|
@ -2,17 +2,17 @@ const csvParse = require('csv-parse/lib/sync');
|
|||
|
||||
function _parseFloat(token) {
|
||||
if (typeof token !== 'string') {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
token = token.trim()
|
||||
token = token.trim();
|
||||
|
||||
if (token === '') {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
if (/^nan$/i.test(token)) {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
let f = parseFloat(token);
|
||||
|
@ -29,27 +29,27 @@ function _parseFloat(token) {
|
|||
}
|
||||
|
||||
function _parseInt(token) {
|
||||
const asFloat = parseFloat(token)
|
||||
const asFloat = parseFloat(token);
|
||||
if (asFloat !== null) {
|
||||
return Math.floor(asFloat)
|
||||
} else{
|
||||
return asFloat
|
||||
return Math.floor(asFloat);
|
||||
} else {
|
||||
return asFloat;
|
||||
}
|
||||
}
|
||||
|
||||
function _parseString(token) {
|
||||
if (typeof token !== 'string') {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
// This time we do not trim -- because we assume that the quoting mechanism
|
||||
// from CSV might have kicked in and we actually want the spacing around the
|
||||
// token.
|
||||
|
||||
if (token === '') {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
return token
|
||||
return token;
|
||||
}
|
||||
|
||||
function replaceDollarNewlinesHack(body) {
|
||||
|
@ -87,7 +87,7 @@ function addPointsToTrack(trackInfo, body, format = null) {
|
|||
}
|
||||
|
||||
function detectFormat(body) {
|
||||
body = replaceDollarNewlinesHack(body)
|
||||
body = replaceDollarNewlinesHack(body);
|
||||
|
||||
if (!body.length) {
|
||||
return 'invalid';
|
||||
|
@ -98,7 +98,7 @@ function detectFormat(body) {
|
|||
if (firstLinebreakIndex === -1) {
|
||||
// We need at least one linebreak in the whole file, to separate header and
|
||||
// data. If the file contains no header, it is in valid.
|
||||
return 'invalid'
|
||||
return 'invalid';
|
||||
}
|
||||
|
||||
const firstLine = body.substring(0, firstLinebreakIndex);
|
||||
|
@ -161,17 +161,17 @@ function* parseObsver1(body) {
|
|||
|
||||
if (!record.latitude && !record.longitude) {
|
||||
// invalid record, make sure lat/lng say `null` instead of `0`
|
||||
record.latitude = null
|
||||
record.longitude = null
|
||||
record.latitude = null;
|
||||
record.longitude = null;
|
||||
}
|
||||
|
||||
// in old format, 255 or 999 means "no measurement"
|
||||
if (record.d1 === 255 || record.d1 === 999) {
|
||||
record.d1 = null
|
||||
record.d1 = null;
|
||||
}
|
||||
|
||||
if (record.d2 === 255 || record.d2 === 999) {
|
||||
record.d2 = null
|
||||
record.d2 = null;
|
||||
}
|
||||
|
||||
yield record;
|
||||
|
|
|
@ -1,44 +1,47 @@
|
|||
var mongoose = require('mongoose');
|
||||
var uniqueValidator = require('mongoose-unique-validator');
|
||||
var slug = require('slug');
|
||||
var User = mongoose.model('User');
|
||||
const mongoose = require('mongoose');
|
||||
const uniqueValidator = require('mongoose-unique-validator');
|
||||
const slug = require('slug');
|
||||
const User = mongoose.model('User');
|
||||
|
||||
var ArticleSchema = new mongoose.Schema({
|
||||
slug: {type: String, lowercase: true, unique: true},
|
||||
title: String,
|
||||
description: String,
|
||||
body: String,
|
||||
favoritesCount: {type: Number, default: 0},
|
||||
comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }],
|
||||
tagList: [{ type: String }],
|
||||
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
|
||||
}, {timestamps: true});
|
||||
const ArticleSchema = new mongoose.Schema(
|
||||
{
|
||||
slug: { type: String, lowercase: true, unique: true },
|
||||
title: String,
|
||||
description: String,
|
||||
body: String,
|
||||
favoritesCount: { type: Number, default: 0 },
|
||||
comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }],
|
||||
tagList: [{ type: String }],
|
||||
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
|
||||
},
|
||||
{ timestamps: true },
|
||||
);
|
||||
|
||||
ArticleSchema.plugin(uniqueValidator, {message: 'is already taken'});
|
||||
ArticleSchema.plugin(uniqueValidator, { message: 'is already taken' });
|
||||
|
||||
ArticleSchema.pre('validate', function(next){
|
||||
if(!this.slug) {
|
||||
ArticleSchema.pre('validate', function (next) {
|
||||
if (!this.slug) {
|
||||
this.slugify();
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
ArticleSchema.methods.slugify = function() {
|
||||
this.slug = slug(this.title) + '-' + (Math.random() * Math.pow(36, 6) | 0).toString(36);
|
||||
ArticleSchema.methods.slugify = function () {
|
||||
this.slug = slug(this.title) + '-' + ((Math.random() * Math.pow(36, 6)) | 0).toString(36);
|
||||
};
|
||||
|
||||
ArticleSchema.methods.updateFavoriteCount = function() {
|
||||
var article = this;
|
||||
ArticleSchema.methods.updateFavoriteCount = function () {
|
||||
const article = this;
|
||||
|
||||
return User.count({favorites: {$in: [article._id]}}).then(function(count){
|
||||
return User.count({ favorites: { $in: [article._id] } }).then(function (count) {
|
||||
article.favoritesCount = count;
|
||||
|
||||
return article.save();
|
||||
});
|
||||
};
|
||||
|
||||
ArticleSchema.methods.toJSONFor = function(user){
|
||||
ArticleSchema.methods.toJSONFor = function (user) {
|
||||
return {
|
||||
slug: this.slug,
|
||||
title: this.title,
|
||||
|
@ -49,7 +52,7 @@ ArticleSchema.methods.toJSONFor = function(user){
|
|||
tagList: this.tagList,
|
||||
favorited: user ? user.isFavorite(this._id) : false,
|
||||
favoritesCount: this.favoritesCount,
|
||||
author: this.author.toProfileJSONFor(user)
|
||||
author: this.author.toProfileJSONFor(user),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -1,18 +1,21 @@
|
|||
var mongoose = require('mongoose');
|
||||
const mongoose = require('mongoose');
|
||||
|
||||
var CommentSchema = new mongoose.Schema({
|
||||
body: String,
|
||||
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
|
||||
article: { type: mongoose.Schema.Types.ObjectId, ref: 'Article' }
|
||||
}, {timestamps: true});
|
||||
const CommentSchema = new mongoose.Schema(
|
||||
{
|
||||
body: String,
|
||||
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
|
||||
article: { type: mongoose.Schema.Types.ObjectId, ref: 'Article' },
|
||||
},
|
||||
{ timestamps: true },
|
||||
);
|
||||
|
||||
// Requires population of author
|
||||
CommentSchema.methods.toJSONFor = function(user){
|
||||
CommentSchema.methods.toJSONFor = function (user) {
|
||||
return {
|
||||
id: this._id,
|
||||
body: this.body,
|
||||
createdAt: this.createdAt,
|
||||
author: this.author.toProfileJSONFor(user)
|
||||
author: this.author.toProfileJSONFor(user),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -1,33 +1,36 @@
|
|||
var mongoose = require('mongoose');
|
||||
var uniqueValidator = require('mongoose-unique-validator');
|
||||
var slug = require('slug');
|
||||
var User = mongoose.model('User');
|
||||
var TrackData = mongoose.model('TrackData');
|
||||
const mongoose = require('mongoose');
|
||||
const uniqueValidator = require('mongoose-unique-validator');
|
||||
const slug = require('slug');
|
||||
const User = mongoose.model('User');
|
||||
const TrackData = mongoose.model('TrackData');
|
||||
|
||||
var TrackSchema = new mongoose.Schema({
|
||||
slug: {type: String, lowercase: true, unique: true},
|
||||
title: String,
|
||||
description: String,
|
||||
body: String,
|
||||
visible: Boolean,
|
||||
numEvents: {type: Number, default: 0},
|
||||
comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }],
|
||||
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
|
||||
trackData: { type: mongoose.Schema.Types.ObjectId, ref: 'TrackData' },
|
||||
}, {timestamps: true});
|
||||
const TrackSchema = new mongoose.Schema(
|
||||
{
|
||||
slug: { type: String, lowercase: true, unique: true },
|
||||
title: String,
|
||||
description: String,
|
||||
body: String,
|
||||
visible: Boolean,
|
||||
numEvents: { type: Number, default: 0 },
|
||||
comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }],
|
||||
author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
|
||||
trackData: { type: mongoose.Schema.Types.ObjectId, ref: 'TrackData' },
|
||||
},
|
||||
{ timestamps: true },
|
||||
);
|
||||
|
||||
TrackSchema.plugin(uniqueValidator, {message: 'is already taken'});
|
||||
TrackSchema.plugin(uniqueValidator, { message: 'is already taken' });
|
||||
|
||||
TrackSchema.pre('validate', function(next){
|
||||
if(!this.slug) {
|
||||
TrackSchema.pre('validate', function (next) {
|
||||
if (!this.slug) {
|
||||
this.slugify();
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
TrackSchema.methods.slugify = function() {
|
||||
this.slug = slug(this.title) + '-' + (Math.random() * Math.pow(36, 6) | 0).toString(36);
|
||||
TrackSchema.methods.slugify = function () {
|
||||
this.slug = slug(this.title) + '-' + ((Math.random() * Math.pow(36, 6)) | 0).toString(36);
|
||||
};
|
||||
|
||||
TrackSchema.methods.toJSONFor = function (user, include) {
|
||||
|
|
|
@ -1,34 +1,39 @@
|
|||
var mongoose = require('mongoose');
|
||||
var uniqueValidator = require('mongoose-unique-validator');
|
||||
var slug = require('slug');
|
||||
const mongoose = require('mongoose');
|
||||
const uniqueValidator = require('mongoose-unique-validator');
|
||||
const slug = require('slug');
|
||||
|
||||
var TrackDataSchema = new mongoose.Schema({
|
||||
slug: {type: String, lowercase: true, unique: true},
|
||||
points: [ {
|
||||
date: String,
|
||||
time : String,
|
||||
latitude: Number,
|
||||
longitude: Number,
|
||||
course: Number,
|
||||
speed: Number,
|
||||
d1: Number,
|
||||
d2: Number,
|
||||
flag: Number,
|
||||
private: Number
|
||||
}]
|
||||
}, {timestamps: true});
|
||||
const TrackDataSchema = new mongoose.Schema(
|
||||
{
|
||||
slug: { type: String, lowercase: true, unique: true },
|
||||
points: [
|
||||
{
|
||||
date: String,
|
||||
time: String,
|
||||
latitude: Number,
|
||||
longitude: Number,
|
||||
course: Number,
|
||||
speed: Number,
|
||||
d1: Number,
|
||||
d2: Number,
|
||||
flag: Number,
|
||||
private: Number,
|
||||
},
|
||||
],
|
||||
},
|
||||
{ timestamps: true },
|
||||
);
|
||||
|
||||
TrackDataSchema.plugin(uniqueValidator, {message: 'is already taken'});
|
||||
TrackDataSchema.plugin(uniqueValidator, { message: 'is already taken' });
|
||||
|
||||
TrackDataSchema.pre('validate', function(next){
|
||||
if(!this.slug) {
|
||||
TrackDataSchema.pre('validate', function (next) {
|
||||
if (!this.slug) {
|
||||
this.slugify();
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
TrackDataSchema.methods.slugify = function() {
|
||||
this.slug = slug("td") + '-' + (Math.random() * Math.pow(36, 6) | 0).toString(36);
|
||||
TrackDataSchema.methods.slugify = function () {
|
||||
this.slug = slug('td') + '-' + ((Math.random() * Math.pow(36, 6)) | 0).toString(36);
|
||||
};
|
||||
|
||||
mongoose.model('TrackData', TrackDataSchema);
|
||||
|
|
|
@ -1,31 +1,48 @@
|
|||
var mongoose = require('mongoose');
|
||||
var uniqueValidator = require('mongoose-unique-validator');
|
||||
var crypto = require('crypto');
|
||||
var jwt = require('jsonwebtoken');
|
||||
var secret = require('../config').secret;
|
||||
const mongoose = require('mongoose');
|
||||
const uniqueValidator = require('mongoose-unique-validator');
|
||||
const crypto = require('crypto');
|
||||
const jwt = require('jsonwebtoken');
|
||||
const secret = require('../config').secret;
|
||||
|
||||
var UserSchema = new mongoose.Schema({
|
||||
username: { type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/^[a-zA-Z0-9]+$/, 'is invalid'], index: true },
|
||||
email: { type: String, lowercase: true, unique: true, required: [true, "can't be blank"], match: [/\S+@\S+\.\S+/, 'is invalid'], index: true },
|
||||
bio: String,
|
||||
image: String,
|
||||
favorites: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Article' }],
|
||||
following: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }],
|
||||
areTracksVisibleForAll: Boolean,
|
||||
hash: String,
|
||||
salt: String,
|
||||
needsEmailValidation: Boolean,
|
||||
verificationToken: String,
|
||||
resetToken: {
|
||||
token: String,
|
||||
expires: Date
|
||||
}
|
||||
}, { timestamps: true });
|
||||
const UserSchema = new mongoose.Schema(
|
||||
{
|
||||
username: {
|
||||
type: String,
|
||||
lowercase: true,
|
||||
unique: true,
|
||||
required: [true, "can't be blank"],
|
||||
match: [/^[a-zA-Z0-9]+$/, 'is invalid'],
|
||||
index: true,
|
||||
},
|
||||
email: {
|
||||
type: String,
|
||||
lowercase: true,
|
||||
unique: true,
|
||||
required: [true, "can't be blank"],
|
||||
match: [/\S+@\S+\.\S+/, 'is invalid'],
|
||||
index: true,
|
||||
},
|
||||
bio: String,
|
||||
image: String,
|
||||
favorites: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Article' }],
|
||||
following: [{ type: mongoose.Schema.Types.ObjectId, ref: 'User' }],
|
||||
areTracksVisibleForAll: Boolean,
|
||||
hash: String,
|
||||
salt: String,
|
||||
needsEmailValidation: Boolean,
|
||||
verificationToken: String,
|
||||
resetToken: {
|
||||
token: String,
|
||||
expires: Date,
|
||||
},
|
||||
},
|
||||
{ timestamps: true },
|
||||
);
|
||||
|
||||
UserSchema.plugin(uniqueValidator, { message: 'ist bereits vergeben. Sorry!' });
|
||||
|
||||
UserSchema.methods.validPassword = function (password) {
|
||||
var hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
|
||||
const hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
|
||||
return this.hash === hash;
|
||||
};
|
||||
|
||||
|
@ -35,15 +52,18 @@ UserSchema.methods.setPassword = function (password) {
|
|||
};
|
||||
|
||||
UserSchema.methods.generateJWT = function () {
|
||||
var today = new Date();
|
||||
var exp = new Date(today);
|
||||
const today = new Date();
|
||||
const exp = new Date(today);
|
||||
exp.setDate(today.getDate() + 60);
|
||||
|
||||
return jwt.sign({
|
||||
id: this._id,
|
||||
username: this.username,
|
||||
exp: parseInt(exp.getTime() / 1000),
|
||||
}, secret);
|
||||
return jwt.sign(
|
||||
{
|
||||
id: this._id,
|
||||
username: this.username,
|
||||
exp: parseInt(exp.getTime() / 1000),
|
||||
},
|
||||
secret,
|
||||
);
|
||||
};
|
||||
|
||||
UserSchema.methods.toAuthJSON = function () {
|
||||
|
@ -54,7 +74,7 @@ UserSchema.methods.toAuthJSON = function () {
|
|||
bio: this.bio,
|
||||
image: this.image,
|
||||
areTracksVisibleForAll: this.areTracksVisibleForAll,
|
||||
apiKey: this._id
|
||||
apiKey: this._id,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -63,7 +83,7 @@ UserSchema.methods.toProfileJSONFor = function (user) {
|
|||
username: this.username,
|
||||
bio: this.bio,
|
||||
image: this.image || 'https://static.productionready.io/images/smiley-cyrus.jpg',
|
||||
following: user ? user.isFollowing(this._id) : false
|
||||
following: user ? user.isFollowing(this._id) : false,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -90,7 +110,6 @@ UserSchema.methods.isTrackVisible = function (id) {
|
|||
return this.areTracksVisibleForAll();
|
||||
};
|
||||
|
||||
|
||||
UserSchema.methods.follow = function (id) {
|
||||
if (this.following.indexOf(id) === -1) {
|
||||
this.following.push(id);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var router = require('express').Router();
|
||||
const router = require('express').Router();
|
||||
|
||||
router.use('/', require('./users'));
|
||||
router.use('/profiles', require('./profiles'));
|
||||
|
@ -13,7 +13,7 @@ router.use(function (err, req, res, next) {
|
|||
errors[key] = err.errors[key].message;
|
||||
|
||||
return errors;
|
||||
}, {})
|
||||
}, {}),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,53 +1,67 @@
|
|||
var router = require('express').Router();
|
||||
var mongoose = require('mongoose');
|
||||
var User = mongoose.model('User');
|
||||
var auth = require('../auth');
|
||||
const router = require('express').Router();
|
||||
const mongoose = require('mongoose');
|
||||
const User = mongoose.model('User');
|
||||
const auth = require('../auth');
|
||||
|
||||
// Preload user profile on routes with ':username'
|
||||
router.param('username', function(req, res, next, username){
|
||||
User.findOne({username: username}).then(function(user){
|
||||
if (!user) { return res.sendStatus(404); }
|
||||
router.param('username', function (req, res, next, username) {
|
||||
User.findOne({ username: username })
|
||||
.then(function (user) {
|
||||
if (!user) {
|
||||
return res.sendStatus(404);
|
||||
}
|
||||
|
||||
req.profile = user;
|
||||
req.profile = user;
|
||||
|
||||
return next();
|
||||
}).catch(next);
|
||||
return next();
|
||||
})
|
||||
.catch(next);
|
||||
});
|
||||
|
||||
router.get('/:username', auth.optional, function(req, res, next){
|
||||
if(req.payload){
|
||||
User.findById(req.payload.id).then(function(user){
|
||||
if(!user){ return res.json({profile: req.profile.toProfileJSONFor(false)}); }
|
||||
router.get('/:username', auth.optional, function (req, res, next) {
|
||||
if (req.payload) {
|
||||
User.findById(req.payload.id).then(function (user) {
|
||||
if (!user) {
|
||||
return res.json({ profile: req.profile.toProfileJSONFor(false) });
|
||||
}
|
||||
|
||||
return res.json({profile: req.profile.toProfileJSONFor(user)});
|
||||
return res.json({ profile: req.profile.toProfileJSONFor(user) });
|
||||
});
|
||||
} else {
|
||||
return res.json({profile: req.profile.toProfileJSONFor(false)});
|
||||
return res.json({ profile: req.profile.toProfileJSONFor(false) });
|
||||
}
|
||||
});
|
||||
|
||||
router.post('/:username/follow', auth.required, function(req, res, next){
|
||||
var profileId = req.profile._id;
|
||||
router.post('/:username/follow', auth.required, function (req, res, next) {
|
||||
const profileId = req.profile._id;
|
||||
|
||||
User.findById(req.payload.id).then(function(user){
|
||||
if (!user) { return res.sendStatus(401); }
|
||||
User.findById(req.payload.id)
|
||||
.then(function (user) {
|
||||
if (!user) {
|
||||
return res.sendStatus(401);
|
||||
}
|
||||
|
||||
return user.follow(profileId).then(function(){
|
||||
return res.json({profile: req.profile.toProfileJSONFor(user)});
|
||||
});
|
||||
}).catch(next);
|
||||
return user.follow(profileId).then(function () {
|
||||
return res.json({ profile: req.profile.toProfileJSONFor(user) });
|
||||
});
|
||||
})
|
||||
.catch(next);
|
||||
});
|
||||
|
||||
router.delete('/:username/follow', auth.required, function(req, res, next){
|
||||
var profileId = req.profile._id;
|
||||
router.delete('/:username/follow', auth.required, function (req, res, next) {
|
||||
const profileId = req.profile._id;
|
||||
|
||||
User.findById(req.payload.id).then(function(user){
|
||||
if (!user) { return res.sendStatus(401); }
|
||||
User.findById(req.payload.id)
|
||||
.then(function (user) {
|
||||
if (!user) {
|
||||
return res.sendStatus(401);
|
||||
}
|
||||
|
||||
return user.unfollow(profileId).then(function(){
|
||||
return res.json({profile: req.profile.toProfileJSONFor(user)});
|
||||
});
|
||||
}).catch(next);
|
||||
return user.unfollow(profileId).then(function () {
|
||||
return res.json({ profile: req.profile.toProfileJSONFor(user) });
|
||||
});
|
||||
})
|
||||
.catch(next);
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
var router = require('express').Router();
|
||||
var mongoose = require('mongoose');
|
||||
var Track = mongoose.model('Track');
|
||||
const router = require('express').Router();
|
||||
const mongoose = require('mongoose');
|
||||
const Track = mongoose.model('Track');
|
||||
|
||||
// return a list of tags
|
||||
router.get('/', function(req, res, next) {
|
||||
Track.find().distinct('tagList').then(function(tags){
|
||||
return res.json({tags: tags});
|
||||
}).catch(next);
|
||||
router.get('/', function (req, res, next) {
|
||||
Track.find()
|
||||
.distinct('tagList')
|
||||
.then(function (tags) {
|
||||
return res.json({ tags: tags });
|
||||
})
|
||||
.catch(next);
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
|
|
@ -1,45 +1,53 @@
|
|||
var mongoose = require('mongoose');
|
||||
var router = require('express').Router();
|
||||
var passport = require('passport');
|
||||
var User = mongoose.model('User');
|
||||
var auth = require('../auth');
|
||||
const mongoose = require('mongoose');
|
||||
const router = require('express').Router();
|
||||
const passport = require('passport');
|
||||
const User = mongoose.model('User');
|
||||
const auth = require('../auth');
|
||||
|
||||
router.get('/user', auth.required, function (req, res, next) {
|
||||
User.findById(req.payload.id).then(function (user) {
|
||||
if (!user) { return res.sendStatus(401); }
|
||||
User.findById(req.payload.id)
|
||||
.then(function (user) {
|
||||
if (!user) {
|
||||
return res.sendStatus(401);
|
||||
}
|
||||
|
||||
return res.json({ user: user.toAuthJSON() });
|
||||
}).catch(next);
|
||||
return res.json({ user: user.toAuthJSON() });
|
||||
})
|
||||
.catch(next);
|
||||
});
|
||||
|
||||
router.put('/user', auth.required, function (req, res, next) {
|
||||
User.findById(req.payload.id).then(function (user) {
|
||||
if (!user) { return res.sendStatus(401); }
|
||||
User.findById(req.payload.id)
|
||||
.then(function (user) {
|
||||
if (!user) {
|
||||
return res.sendStatus(401);
|
||||
}
|
||||
|
||||
// only update fields that were actually passed...
|
||||
if (typeof req.body.user.username !== 'undefined') {
|
||||
user.username = req.body.user.username;
|
||||
}
|
||||
if (typeof req.body.user.email !== 'undefined') {
|
||||
user.email = req.body.user.email;
|
||||
}
|
||||
if (typeof req.body.user.bio !== 'undefined') {
|
||||
user.bio = req.body.user.bio;
|
||||
}
|
||||
if (typeof req.body.user.image !== 'undefined') {
|
||||
user.image = req.body.user.image;
|
||||
}
|
||||
if (typeof req.body.user.areTracksVisibleForAll !== 'undefined') {
|
||||
user.areTracksVisibleForAll = req.body.user.areTracksVisibleForAll;
|
||||
}
|
||||
if (typeof req.body.user.password !== 'undefined' && req.body.user.password != '') {
|
||||
user.setPassword(req.body.user.password);
|
||||
}
|
||||
// only update fields that were actually passed...
|
||||
if (typeof req.body.user.username !== 'undefined') {
|
||||
user.username = req.body.user.username;
|
||||
}
|
||||
if (typeof req.body.user.email !== 'undefined') {
|
||||
user.email = req.body.user.email;
|
||||
}
|
||||
if (typeof req.body.user.bio !== 'undefined') {
|
||||
user.bio = req.body.user.bio;
|
||||
}
|
||||
if (typeof req.body.user.image !== 'undefined') {
|
||||
user.image = req.body.user.image;
|
||||
}
|
||||
if (typeof req.body.user.areTracksVisibleForAll !== 'undefined') {
|
||||
user.areTracksVisibleForAll = req.body.user.areTracksVisibleForAll;
|
||||
}
|
||||
if (typeof req.body.user.password !== 'undefined' && req.body.user.password != '') {
|
||||
user.setPassword(req.body.user.password);
|
||||
}
|
||||
|
||||
return user.save().then(function () {
|
||||
return res.json({ user: user.toAuthJSON() });
|
||||
});
|
||||
}).catch(next);
|
||||
return user.save().then(function () {
|
||||
return res.json({ user: user.toAuthJSON() });
|
||||
});
|
||||
})
|
||||
.catch(next);
|
||||
});
|
||||
|
||||
router.post('/users/login', function (req, res, next) {
|
||||
|
@ -52,7 +60,9 @@ router.post('/users/login', function (req, res, next) {
|
|||
}
|
||||
|
||||
passport.authenticate('local', { session: false }, function (err, user, info) {
|
||||
if (err) { return next(err); }
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
if (user) {
|
||||
user.token = user.generateJWT();
|
||||
|
|
|
@ -1,29 +1,31 @@
|
|||
var jwt = require('express-jwt');
|
||||
var secret = require('../config').secret;
|
||||
const jwt = require('express-jwt');
|
||||
const secret = require('../config').secret;
|
||||
|
||||
function getTokenFromHeader(req) {
|
||||
if (req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Token' ||
|
||||
req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer') {
|
||||
if (
|
||||
(req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Token') ||
|
||||
(req.headers.authorization && req.headers.authorization.split(' ')[0] === 'Bearer')
|
||||
) {
|
||||
return req.headers.authorization.split(' ')[1];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
var auth = {
|
||||
const auth = {
|
||||
required: jwt({
|
||||
secret: secret,
|
||||
userProperty: 'payload',
|
||||
getToken: getTokenFromHeader,
|
||||
algorithms: ['HS256']
|
||||
algorithms: ['HS256'],
|
||||
}),
|
||||
optional: jwt({
|
||||
secret: secret,
|
||||
userProperty: 'payload',
|
||||
credentialsRequired: false,
|
||||
getToken: getTokenFromHeader,
|
||||
algorithms: ['HS256']
|
||||
})
|
||||
algorithms: ['HS256'],
|
||||
}),
|
||||
};
|
||||
|
||||
module.exports = auth;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var router = require('express').Router();
|
||||
const router = require('express').Router();
|
||||
|
||||
router.use('/api', require('./api'));
|
||||
|
||||
|
|
Loading…
Reference in a new issue