2020-11-20 10:02:30 +00:00
|
|
|
const mongoose = require('mongoose');
|
|
|
|
const uniqueValidator = require('mongoose-unique-validator');
|
|
|
|
const crypto = require('crypto');
|
|
|
|
const jwt = require('jsonwebtoken');
|
|
|
|
const secret = require('../config').secret;
|
|
|
|
|
|
|
|
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,
|
2020-11-25 14:49:11 +00:00
|
|
|
favorites: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Track' }],
|
2020-11-20 10:02:30 +00:00
|
|
|
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 },
|
|
|
|
);
|
2020-04-13 00:02:40 +00:00
|
|
|
|
2020-10-20 19:25:00 +00:00
|
|
|
UserSchema.plugin(uniqueValidator, { message: 'ist bereits vergeben. Sorry!' });
|
2020-04-13 00:02:40 +00:00
|
|
|
|
2020-10-20 19:25:00 +00:00
|
|
|
UserSchema.methods.validPassword = function (password) {
|
2020-11-20 10:02:30 +00:00
|
|
|
const hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
|
2020-04-13 00:02:40 +00:00
|
|
|
return this.hash === hash;
|
|
|
|
};
|
|
|
|
|
2020-10-20 19:25:00 +00:00
|
|
|
UserSchema.methods.setPassword = function (password) {
|
2020-04-13 00:02:40 +00:00
|
|
|
this.salt = crypto.randomBytes(16).toString('hex');
|
|
|
|
this.hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
|
|
|
|
};
|
|
|
|
|
2020-10-20 19:25:00 +00:00
|
|
|
UserSchema.methods.generateJWT = function () {
|
2020-11-20 10:02:30 +00:00
|
|
|
const today = new Date();
|
|
|
|
const exp = new Date(today);
|
2020-04-13 00:02:40 +00:00
|
|
|
exp.setDate(today.getDate() + 60);
|
|
|
|
|
2020-11-20 10:02:30 +00:00
|
|
|
return jwt.sign(
|
|
|
|
{
|
|
|
|
id: this._id,
|
|
|
|
username: this.username,
|
|
|
|
exp: parseInt(exp.getTime() / 1000),
|
|
|
|
},
|
|
|
|
secret,
|
|
|
|
);
|
2020-04-13 00:02:40 +00:00
|
|
|
};
|
|
|
|
|
2020-10-20 19:25:00 +00:00
|
|
|
UserSchema.methods.toAuthJSON = function () {
|
2020-04-13 00:02:40 +00:00
|
|
|
return {
|
|
|
|
username: this.username,
|
|
|
|
email: this.email,
|
|
|
|
token: this.generateJWT(),
|
|
|
|
bio: this.bio,
|
2020-08-15 08:59:00 +00:00
|
|
|
image: this.image,
|
2020-08-16 21:23:18 +00:00
|
|
|
areTracksVisibleForAll: this.areTracksVisibleForAll,
|
2020-11-20 10:02:30 +00:00
|
|
|
apiKey: this._id,
|
2020-04-13 00:02:40 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2020-10-20 19:25:00 +00:00
|
|
|
UserSchema.methods.toProfileJSONFor = function (user) {
|
2020-04-13 00:02:40 +00:00
|
|
|
return {
|
|
|
|
username: this.username,
|
|
|
|
bio: this.bio,
|
|
|
|
image: this.image || 'https://static.productionready.io/images/smiley-cyrus.jpg',
|
2020-11-20 10:02:30 +00:00
|
|
|
following: user ? user.isFollowing(this._id) : false,
|
2020-04-13 00:02:40 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2020-10-20 19:25:00 +00:00
|
|
|
UserSchema.methods.favorite = function (id) {
|
|
|
|
if (this.favorites.indexOf(id) === -1) {
|
2020-04-13 00:02:40 +00:00
|
|
|
this.favorites.push(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.save();
|
|
|
|
};
|
|
|
|
|
2020-10-20 19:25:00 +00:00
|
|
|
UserSchema.methods.unfavorite = function (id) {
|
2020-04-13 00:02:40 +00:00
|
|
|
this.favorites.remove(id);
|
|
|
|
return this.save();
|
|
|
|
};
|
|
|
|
|
2020-10-20 19:25:00 +00:00
|
|
|
UserSchema.methods.isFavorite = function (id) {
|
|
|
|
return this.favorites.some(function (favoriteId) {
|
2020-04-13 00:02:40 +00:00
|
|
|
return favoriteId.toString() === id.toString();
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2020-10-20 19:25:00 +00:00
|
|
|
UserSchema.methods.isTrackVisible = function (id) {
|
2020-08-16 21:23:18 +00:00
|
|
|
return this.areTracksVisibleForAll();
|
|
|
|
};
|
2020-04-13 00:02:40 +00:00
|
|
|
|
2020-10-20 19:25:00 +00:00
|
|
|
UserSchema.methods.follow = function (id) {
|
|
|
|
if (this.following.indexOf(id) === -1) {
|
2020-04-13 00:02:40 +00:00
|
|
|
this.following.push(id);
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.save();
|
|
|
|
};
|
|
|
|
|
2020-10-20 19:25:00 +00:00
|
|
|
UserSchema.methods.unfollow = function (id) {
|
2020-04-13 00:02:40 +00:00
|
|
|
this.following.remove(id);
|
|
|
|
return this.save();
|
|
|
|
};
|
|
|
|
|
2020-10-20 19:25:00 +00:00
|
|
|
UserSchema.methods.isFollowing = function (id) {
|
|
|
|
return this.following.some(function (followId) {
|
2020-04-13 00:02:40 +00:00
|
|
|
return followId.toString() === id.toString();
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
mongoose.model('User', UserSchema);
|
2020-11-23 23:29:16 +00:00
|
|
|
|
2020-11-25 14:49:11 +00:00
|
|
|
module.exports = mongoose.model('User');
|