-
Notifications
You must be signed in to change notification settings - Fork 243
/
pilot.js
138 lines (126 loc) · 3.72 KB
/
pilot.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
'use strict';
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const bcrypt = require('bcryptjs');
const Ride = require('./ride');
// Define the Pilot schema.
const PilotSchema = new Schema({
email: {
type: String,
required: true,
unique: true,
validate: {
// Custom validator to check if the email was already used.
validator: PilotEmailValiidator,
message: 'This email already exists. Please try to log in instead.',
}
},
password: {
type: String,
required: true
},
type: {
type: String,
default: 'individual',
enum: ['individual', 'company']
},
firstName: String,
lastName: String,
address: String,
postalCode: String,
city: String,
state: { type: String},
country: { type: String, default: 'US' },
created: { type: Date, default: Date.now },
rocket: {
model: String,
license: String,
color: String
},
businessName: String,
// Stripe account ID to send payments obtained with Stripe Connect.
stripeAccountId: String,
onboardingComplete: Boolean
});
// Check the email addess to make sure it's unique (no existing pilot with that address).
function PilotEmailValiidator(email) {
const Pilot = mongoose.model('Pilot');
// Asynchronously resolve a promise to validate whether an email already exists
return new Promise((resolve, reject) => {
// Only check model updates for new pilots (or if the email address is updated).
if (this.isNew || this.isModified('email')) {
// Try to find a matching pilot
Pilot.findOne({email}).exec((err, pilot) => {
// Handle errors
if (err) {
console.log(err);
resolve(false);
return;
}
// Validate depending on whether a matching pilot exists.
if (pilot) {
resolve(false);
} else {
resolve(true);
}
});
} else {
resolve(true);
}
});
}
// Return a pilot name for display.
PilotSchema.methods.displayName = function() {
if (this.type === 'company') {
return this.businessName;
} else {
return `${this.firstName} ${this.lastName}`;
}
};
// List rides of the past week for the pilot.
PilotSchema.methods.listRecentRides = function() {
const weekAgo = Date.now() - (7*24*60*60*1000);
return Ride.find({ pilot: this, created: { $gte: weekAgo } })
.populate('passenger')
.sort({ created: -1 })
.exec();
};
// Generate a password hash (with an auto-generated salt for simplicity here).
PilotSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, 8);
};
// Check if the password is valid by comparing with the stored hash.
PilotSchema.methods.validatePassword = function(password) {
return bcrypt.compareSync(password, this.password);
};
// Get the first fully onboarded pilot.
PilotSchema.statics.getFirstOnboarded = function() {
return Pilot.findOne({ stripeAccountId: { $ne: null } })
.sort({ created: 1 })
.exec();
};
// Get the latest fully onboarded pilot.
PilotSchema.statics.getLatestOnboarded = function() {
return Pilot.findOne({ stripeAccountId: { $ne: null } })
.sort({ created: -1 })
.exec();
};
// Pre-save hook to define some default properties for pilots.
PilotSchema.pre('save', function(next) {
// Make sure certain fields are blank depending on the pilot type.
if (this.isModified('type')) {
if (this.type === 'individual') {
this.businessName = null;
} else {
this.firstName = null;
this.lastName = null;
}
}
// Make sure the password is hashed before being stored.
if (this.isModified('password')) {
this.password = this.generateHash(this.password);
}
next();
});
const Pilot = mongoose.model('Pilot', PilotSchema);
module.exports = Pilot;