@positivegrid/pg-mongoose-schema 27.8.5 → 28.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +5 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/models/banks.d.ts +3 -0
- package/dist/models/banks.js +33 -0
- package/dist/models/banks.js.map +1 -0
- package/dist/models/device.d.ts +3 -0
- package/dist/models/device.js +48 -0
- package/dist/models/device.js.map +1 -0
- package/dist/models/featuredList.d.ts +3 -0
- package/dist/models/featuredList.js +70 -0
- package/dist/models/featuredList.js.map +1 -0
- package/dist/models/hardware.d.ts +3 -0
- package/dist/models/hardware.js +213 -0
- package/dist/models/hardware.js.map +1 -0
- package/dist/models/homeConfig.d.ts +3 -0
- package/dist/models/homeConfig.js +38 -0
- package/dist/models/homeConfig.js.map +1 -0
- package/dist/models/oauth.d.ts +3 -0
- package/dist/models/oauth.js +48 -0
- package/dist/models/oauth.js.map +1 -0
- package/dist/models/partner.d.ts +3 -0
- package/dist/models/partner.js +165 -0
- package/dist/models/partner.js.map +1 -0
- package/dist/models/payment.d.ts +3 -0
- package/dist/models/payment.js +859 -0
- package/dist/models/payment.js.map +1 -0
- package/dist/models/pgConfig.d.ts +3 -0
- package/dist/models/pgConfig.js +64 -0
- package/dist/models/pgConfig.js.map +1 -0
- package/dist/models/preset.d.ts +3 -0
- package/dist/models/preset.js +802 -0
- package/dist/models/preset.js.map +1 -0
- package/dist/models/promotion.d.ts +3 -0
- package/dist/models/promotion.js +585 -0
- package/dist/models/promotion.js.map +1 -0
- package/dist/models/redeem.d.ts +3 -0
- package/dist/models/redeem.js +26 -0
- package/dist/models/redeem.js.map +1 -0
- package/dist/models/toneTheme.d.ts +3 -0
- package/dist/models/toneTheme.js +29 -0
- package/dist/models/toneTheme.js.map +1 -0
- package/dist/models/toneThemeFeaturedList.d.ts +3 -0
- package/dist/models/toneThemeFeaturedList.js +18 -0
- package/dist/models/toneThemeFeaturedList.js.map +1 -0
- package/dist/models/user.d.ts +3 -0
- package/dist/models/user.js +565 -0
- package/dist/models/user.js.map +1 -0
- package/dist/models/userTrack.d.ts +3 -0
- package/dist/models/userTrack.js +82 -0
- package/dist/models/userTrack.js.map +1 -0
- package/dist/types/banks.types.d.ts +25 -0
- package/dist/types/banks.types.js +3 -0
- package/dist/types/banks.types.js.map +1 -0
- package/dist/types/device.types.d.ts +41 -0
- package/dist/types/device.types.js +3 -0
- package/dist/types/device.types.js.map +1 -0
- package/dist/types/featuredList.types.d.ts +32 -0
- package/dist/types/featuredList.types.js +3 -0
- package/dist/types/featuredList.types.js.map +1 -0
- package/dist/types/hardware.types.d.ts +123 -0
- package/dist/types/hardware.types.js +3 -0
- package/dist/types/hardware.types.js.map +1 -0
- package/dist/types/homeConfig.types.d.ts +24 -0
- package/dist/types/homeConfig.types.js +3 -0
- package/dist/types/homeConfig.types.js.map +1 -0
- package/dist/types/index.d.ts +17 -0
- package/dist/types/index.js +34 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/oauth.types.d.ts +38 -0
- package/dist/types/oauth.types.js +3 -0
- package/dist/types/oauth.types.js.map +1 -0
- package/dist/types/partner.types.d.ts +91 -0
- package/dist/types/partner.types.js +3 -0
- package/dist/types/partner.types.js.map +1 -0
- package/dist/types/payment.types.d.ts +304 -0
- package/dist/types/payment.types.js +3 -0
- package/dist/types/payment.types.js.map +1 -0
- package/dist/types/pgConfig.types.d.ts +35 -0
- package/dist/types/pgConfig.types.js +3 -0
- package/dist/types/pgConfig.types.js.map +1 -0
- package/dist/types/preset.types.d.ts +110 -0
- package/dist/types/preset.types.js +3 -0
- package/dist/types/preset.types.js.map +1 -0
- package/dist/types/promotion.types.d.ts +282 -0
- package/dist/types/promotion.types.js +3 -0
- package/dist/types/promotion.types.js.map +1 -0
- package/dist/types/redeem.types.d.ts +16 -0
- package/dist/types/redeem.types.js +3 -0
- package/dist/types/redeem.types.js.map +1 -0
- package/dist/types/toneTheme.types.d.ts +16 -0
- package/dist/types/toneTheme.types.js +3 -0
- package/dist/types/toneTheme.types.js.map +1 -0
- package/dist/types/toneThemeFeaturedList.types.d.ts +9 -0
- package/dist/types/toneThemeFeaturedList.types.js +3 -0
- package/dist/types/toneThemeFeaturedList.types.js.map +1 -0
- package/dist/types/user.types.d.ts +166 -0
- package/dist/types/user.types.js +6 -0
- package/dist/types/user.types.js.map +1 -0
- package/dist/types/userTrack.types.d.ts +39 -0
- package/dist/types/userTrack.types.js +12 -0
- package/dist/types/userTrack.types.js.map +1 -0
- package/package.json +38 -12
- package/index.js +0 -28
- package/models/banks.js +0 -42
- package/models/device.js +0 -51
- package/models/featuredList.js +0 -91
- package/models/hardware.js +0 -256
- package/models/homeConfig.js +0 -97
- package/models/oauth.js +0 -52
- package/models/partner.js +0 -265
- package/models/payment.js +0 -899
- package/models/pgConfig.js +0 -88
- package/models/preset.js +0 -845
- package/models/promotion.js +0 -590
- package/models/redeem.js +0 -26
- package/models/toneTheme.js +0 -78
- package/models/toneThemeFeaturedList.js +0 -49
- package/models/user.js +0 -639
- package/models/userTrack.js +0 -107
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
module.exports = function (mongoose) {
|
|
4
|
-
const Schema = mongoose.Schema
|
|
5
|
-
const ObjectId = Schema.Types.ObjectId
|
|
6
|
-
|
|
7
|
-
const ToneThemeFeaturedListSchema = new Schema({
|
|
8
|
-
tone_theme_id: {
|
|
9
|
-
type: ObjectId,
|
|
10
|
-
ref: 'ToneTheme',
|
|
11
|
-
required: true
|
|
12
|
-
},
|
|
13
|
-
featured_list_id: {
|
|
14
|
-
type: ObjectId,
|
|
15
|
-
ref: 'FeaturedList',
|
|
16
|
-
required: true
|
|
17
|
-
},
|
|
18
|
-
order: {
|
|
19
|
-
type: Number,
|
|
20
|
-
default: 0
|
|
21
|
-
},
|
|
22
|
-
created_on: {
|
|
23
|
-
type: Date,
|
|
24
|
-
default: Date.now
|
|
25
|
-
}
|
|
26
|
-
}, {
|
|
27
|
-
collection: 'tone_theme_featured_list'
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
// 索引
|
|
31
|
-
ToneThemeFeaturedListSchema.index({
|
|
32
|
-
tone_theme_id: 1,
|
|
33
|
-
order: 1
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
ToneThemeFeaturedListSchema.index({
|
|
37
|
-
featured_list_id: 1
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
// 確保同一個 featured_list 不會被加入同一個 theme 兩次
|
|
41
|
-
ToneThemeFeaturedListSchema.index({
|
|
42
|
-
tone_theme_id: 1,
|
|
43
|
-
featured_list_id: 1
|
|
44
|
-
}, {
|
|
45
|
-
unique: true
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
mongoose.model('ToneThemeFeaturedList', ToneThemeFeaturedListSchema)
|
|
49
|
-
}
|
package/models/user.js
DELETED
|
@@ -1,639 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const crypto = require('crypto')
|
|
4
|
-
const randomString = require('random-string')
|
|
5
|
-
const _ = require('lodash')
|
|
6
|
-
const ApiErrorCode = require('@positivegrid/pg-error').ApiErrorCode
|
|
7
|
-
const isEmail = require('is-email')
|
|
8
|
-
const debug = require('debug')('model:user')
|
|
9
|
-
|
|
10
|
-
module.exports = function (mongoose) {
|
|
11
|
-
const Schema = mongoose.Schema
|
|
12
|
-
const ObjectId = Schema.Types.ObjectId
|
|
13
|
-
|
|
14
|
-
function encryptPassword (pwd) {
|
|
15
|
-
if (!pwd) return ''
|
|
16
|
-
|
|
17
|
-
const encryptType = 'sha1'
|
|
18
|
-
const salt = randomString({ length: 5, numeric: true, letters: true }).toLowerCase()
|
|
19
|
-
const password = crypto.createHash(encryptType).update(String(salt) + String(pwd)).digest('hex')
|
|
20
|
-
|
|
21
|
-
return `${encryptType}$${salt}$${password}`
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function verifyPassword (pwd, pwdArr) {
|
|
25
|
-
if (!pwd) return false
|
|
26
|
-
|
|
27
|
-
return (crypto.createHash(pwdArr[0]).update(String(pwdArr[1]) + String(pwd)).digest('hex') === pwdArr[2])
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const FLAG_EMAIL_EVENTS = [
|
|
31
|
-
'bounce',
|
|
32
|
-
'complaint',
|
|
33
|
-
'reject'
|
|
34
|
-
]
|
|
35
|
-
const UserEmailStatusSchema = new Schema({
|
|
36
|
-
user_id: { type: ObjectId, ref: 'User', required: true },
|
|
37
|
-
email_status: { type: String, enum: FLAG_EMAIL_EVENTS, required: true },
|
|
38
|
-
creted_on: { type: Date, default: Date.now, required: true }
|
|
39
|
-
}, { collection: 'user_email_status' })
|
|
40
|
-
|
|
41
|
-
let UserProfileSchema = new Schema({
|
|
42
|
-
user_id: { type: ObjectId, ref: 'User', required: true },
|
|
43
|
-
full_name: { type: String, default: null },
|
|
44
|
-
first_name: { type: String, default: null },
|
|
45
|
-
last_name: { type: String, default: null },
|
|
46
|
-
title: { type: String, default: null },
|
|
47
|
-
gender: { type: String, default: null },
|
|
48
|
-
country: { type: String, default: null },
|
|
49
|
-
postal: { type: String, default: null },
|
|
50
|
-
city: { type: String, default: null },
|
|
51
|
-
state: { type: String, default: null },
|
|
52
|
-
address: { type: String, default: null },
|
|
53
|
-
phone: { type: String, default: null },
|
|
54
|
-
description: { type: String },
|
|
55
|
-
bc_token: { type: String, default: null },
|
|
56
|
-
facebook_access_token: { type: String, default: null },
|
|
57
|
-
reset_password_token: { type: String, default: null },
|
|
58
|
-
profile_image_url: { type: String, default: null },
|
|
59
|
-
profile_thumb_url: { type: String, default: null },
|
|
60
|
-
facebook_image_url: { type: String, default: null },
|
|
61
|
-
facebook_thumb_url: { type: String, default: null },
|
|
62
|
-
reset_password_expire: { type: Date, default: null },
|
|
63
|
-
is_email_verified: { type: Boolean, default: false },
|
|
64
|
-
is_registered: { type: Boolean, default: true },
|
|
65
|
-
stripe_customer_id: { type: String, default: null },
|
|
66
|
-
selected_country: { type: String, default: null },
|
|
67
|
-
date_joined: { type: Date, default: Date.now },
|
|
68
|
-
search_mark: { type: Number, default: 0 } // control the order of search
|
|
69
|
-
}, { collection: 'jamup_userprofile', toJSON: { virtuals: true }, toObject: { virtuals: true } })
|
|
70
|
-
UserProfileSchema
|
|
71
|
-
.index({ user_id: 1 }, { unique: true })
|
|
72
|
-
.index({ reset_password_token: 1 })
|
|
73
|
-
UserProfileSchema.index({full_name: 'text', first_name: 'text', last_name: 'text'})
|
|
74
|
-
|
|
75
|
-
const UserAddressSchema = new Schema({
|
|
76
|
-
user_id: { type: ObjectId, ref: 'User', required: true },
|
|
77
|
-
country: { type: String, default: null },
|
|
78
|
-
zip: { type: String, default: null },
|
|
79
|
-
city: { type: String, default: null },
|
|
80
|
-
state: { type: String, default: null },
|
|
81
|
-
address: { type: String, default: null },
|
|
82
|
-
phone: { type: String, default: null },
|
|
83
|
-
default: { type: Boolean, default: false }
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
const emailFormat = [/^\S+@\S+\.\S+$/, 'Invalid Email Address']
|
|
87
|
-
let UserSchema = new Schema({
|
|
88
|
-
username: { type: String, trim: true, required: true },
|
|
89
|
-
email: { type: String, trim: true, unique: true, match: emailFormat, required: true },
|
|
90
|
-
password: { type: String, default: null, set: encryptPassword, required: true },
|
|
91
|
-
user_status: { type: Number, default: 1 }, // 1: active 2: delete 3: migration
|
|
92
|
-
user_role: { type: Number, default: 1 }, // 1: users, 2: member, 3: admin, 4: partner/dealer
|
|
93
|
-
is_active: { type: Boolean, default: false },
|
|
94
|
-
activate_token: { type: String, default: null },
|
|
95
|
-
activate_expire: { type: Date, default: null },
|
|
96
|
-
fb_access_token: { type: String, default: null },
|
|
97
|
-
facebook_id: { type: String, default: null },
|
|
98
|
-
shopify_id: { type: Schema.Types.Mixed, default: null },
|
|
99
|
-
bk_username: [{ type: String }],
|
|
100
|
-
auth: {
|
|
101
|
-
firebase_id: { type: String },
|
|
102
|
-
google_id: { type: String },
|
|
103
|
-
apple_id: { type: String },
|
|
104
|
-
wechat_id: { type: String }
|
|
105
|
-
},
|
|
106
|
-
metadata: {
|
|
107
|
-
gdpr: { type: Boolean, default: false },
|
|
108
|
-
country: { type: String, default: null },
|
|
109
|
-
},
|
|
110
|
-
date_joined: { type: Date, default: Date.now },
|
|
111
|
-
last_login: { type: Date, default: Date.now }
|
|
112
|
-
}, { collection: 'auth_user', toJSON: { virtuals: true }, toObject: { virtuals: true } })
|
|
113
|
-
UserSchema
|
|
114
|
-
.index({ shopify_id: 1 })
|
|
115
|
-
.index({ username: 1 })
|
|
116
|
-
.index({ email: 1 }, { unique: true })
|
|
117
|
-
.index({ 'auth.firebase_id': 1 })
|
|
118
|
-
.index({ 'auth.apple_id': 1 })
|
|
119
|
-
.index({ 'auth.facebook_id': 1 })
|
|
120
|
-
|
|
121
|
-
// Remove in the future?
|
|
122
|
-
const UserProductSchema = new Schema({
|
|
123
|
-
user_id: { type: ObjectId, ref: 'User', required: true },
|
|
124
|
-
product: { type: String, required: true },
|
|
125
|
-
platform: { type: 'String', required: true },
|
|
126
|
-
metadata: { type: Schema.Types.Mixed, default: null },
|
|
127
|
-
last_login: { type: Date, default: Date.now }
|
|
128
|
-
}, { collection: 'user_product_meta' })
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Save user product status which will co-work with Listrak segmentation
|
|
132
|
-
* Hope to replace UserProductSchema after it works stable.
|
|
133
|
-
*/
|
|
134
|
-
const UserProductTrackerSchema = new Schema({
|
|
135
|
-
user_id: { type: ObjectId, ref: 'User', required: true },
|
|
136
|
-
product: { type: String, required: true },
|
|
137
|
-
status: { type: Number, default: 1 },
|
|
138
|
-
created_on: { type: Date, default: Date.now }
|
|
139
|
-
}, { collection: 'user_product_tracker' })
|
|
140
|
-
UserProductTrackerSchema.index({ user_id: 1, product: 1 }, { unique: true })
|
|
141
|
-
|
|
142
|
-
let ApikeySchema = new Schema({
|
|
143
|
-
apikey: { type: String, required: true, unique: true },
|
|
144
|
-
permission: { type: Array, required: true }, // follow model - user, payment
|
|
145
|
-
description: { type: String, required: true },
|
|
146
|
-
status: { type: Boolean, required: true },
|
|
147
|
-
created_on: { type: Date, default: Date.now },
|
|
148
|
-
call_number: { type: Number },
|
|
149
|
-
partner_name: { type: String }, // Would be used when permission has 'partner'
|
|
150
|
-
updated_on: { type: Date, default: Date.now }
|
|
151
|
-
}, { collection: 'auth_apikey' })
|
|
152
|
-
|
|
153
|
-
let UserReferralSchema = new Schema({
|
|
154
|
-
user_id: { type: ObjectId, ref: 'User', required: true },
|
|
155
|
-
referred_user_email: { type: 'String' },
|
|
156
|
-
created_on: { type: Date, default: Date.now },
|
|
157
|
-
updated_on: { type: Date, default: Date.now }
|
|
158
|
-
}, { collection: 'user_referral' })
|
|
159
|
-
|
|
160
|
-
const UserTokenSchema = new Schema({
|
|
161
|
-
tid: { type: String, trim: true, required: true },
|
|
162
|
-
expired_at: { type: Date, required: true },
|
|
163
|
-
created_on: { type: Date, default: Date.now }
|
|
164
|
-
}, {
|
|
165
|
-
collection: 'auth_token',
|
|
166
|
-
toJSON: { virtuals: true },
|
|
167
|
-
toObject: { virtuals: true }
|
|
168
|
-
})
|
|
169
|
-
UserTokenSchema.index({
|
|
170
|
-
tid: 1
|
|
171
|
-
}, {
|
|
172
|
-
unique: true
|
|
173
|
-
})
|
|
174
|
-
UserTokenSchema.index({
|
|
175
|
-
expired_at: 1
|
|
176
|
-
}, {
|
|
177
|
-
expireAfterSeconds: 0
|
|
178
|
-
})
|
|
179
|
-
|
|
180
|
-
const UserFollowSchema = new Schema(
|
|
181
|
-
{
|
|
182
|
-
user_id: { type: Schema.Types.ObjectId, ref: 'User', required: true, index: true },
|
|
183
|
-
follow_user_id: { type: Schema.Types.ObjectId, ref: 'User', required: true, index: true },
|
|
184
|
-
follow_platform: { type: String } // spark or bias ...
|
|
185
|
-
},
|
|
186
|
-
{
|
|
187
|
-
timestamps: { createdAt: true, updatedAt: false },
|
|
188
|
-
versionKey: false,
|
|
189
|
-
collection: 'jamup_userFollow',
|
|
190
|
-
toJSON: { virtuals: true },
|
|
191
|
-
toObject: { virtuals: true }
|
|
192
|
-
}
|
|
193
|
-
)
|
|
194
|
-
UserFollowSchema.index(
|
|
195
|
-
{
|
|
196
|
-
user_id: 1,
|
|
197
|
-
follow_platform: 1,
|
|
198
|
-
follow_user_id: 1
|
|
199
|
-
},
|
|
200
|
-
{ unique: true }
|
|
201
|
-
)
|
|
202
|
-
UserFollowSchema.index({
|
|
203
|
-
follow_platform: 1
|
|
204
|
-
}, {
|
|
205
|
-
user_id: 1
|
|
206
|
-
}, {
|
|
207
|
-
createdAt: 1
|
|
208
|
-
})
|
|
209
|
-
UserFollowSchema.index({
|
|
210
|
-
follow_platform: 1
|
|
211
|
-
}, {
|
|
212
|
-
follow_user_id: 1
|
|
213
|
-
}, {
|
|
214
|
-
createdAt: 1
|
|
215
|
-
})
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Methods
|
|
219
|
-
*/
|
|
220
|
-
UserSchema.method({
|
|
221
|
-
authenticate: function (plainText) {
|
|
222
|
-
var passwordArr = this.password.split('$')
|
|
223
|
-
if (passwordArr.length !== 3) {
|
|
224
|
-
return false
|
|
225
|
-
} else {
|
|
226
|
-
return verifyPassword(plainText, passwordArr)
|
|
227
|
-
}
|
|
228
|
-
},
|
|
229
|
-
makeSalt: function () {
|
|
230
|
-
return Math.round((new Date().valueOf() * Math.random())) + ''
|
|
231
|
-
}
|
|
232
|
-
})
|
|
233
|
-
|
|
234
|
-
// Statics
|
|
235
|
-
UserTokenSchema.static({
|
|
236
|
-
createTokenMeta: async function () {
|
|
237
|
-
try {
|
|
238
|
-
const tid = crypto.randomUUID()
|
|
239
|
-
const nowDate = new Date()
|
|
240
|
-
const expiredAt = new Date().setDate(nowDate.getDate() + 14)
|
|
241
|
-
return await this.create({
|
|
242
|
-
tid,
|
|
243
|
-
expired_at: expiredAt,
|
|
244
|
-
created_on: nowDate
|
|
245
|
-
})
|
|
246
|
-
} catch (err) {
|
|
247
|
-
debug('ERR:createTokenMeta:%j', err)
|
|
248
|
-
throw err
|
|
249
|
-
}
|
|
250
|
-
},
|
|
251
|
-
isValid: async function (tid) {
|
|
252
|
-
const userTokenMeta = await this.findOne({ tid }).exec()
|
|
253
|
-
return (userTokenMeta) ? true : false
|
|
254
|
-
},
|
|
255
|
-
revokeToken: async function (tid) {
|
|
256
|
-
return await this.findOneAndRemove({
|
|
257
|
-
tid
|
|
258
|
-
})
|
|
259
|
-
}
|
|
260
|
-
})
|
|
261
|
-
UserSchema.static({
|
|
262
|
-
_async_auth: async function (username, password) {
|
|
263
|
-
username = String(username).toLowerCase().replace('@', '_')
|
|
264
|
-
let user
|
|
265
|
-
let bgUser
|
|
266
|
-
try {
|
|
267
|
-
user = await this.findOne({username}).exec()
|
|
268
|
-
} catch (err) {
|
|
269
|
-
throw new ApiErrorCode('internal_sysmtem_error', err.message)
|
|
270
|
-
}
|
|
271
|
-
if (!user) {
|
|
272
|
-
// Fallback
|
|
273
|
-
try {
|
|
274
|
-
bgUser = await this.findOne({ bk_username: { $in: [username] } }).exec()
|
|
275
|
-
} catch (err) {
|
|
276
|
-
throw new ApiErrorCode('INTERNAL_SYSMTEM_ERROR', err.message)
|
|
277
|
-
}
|
|
278
|
-
if (!bgUser) {
|
|
279
|
-
throw new ApiErrorCode('USER_NOT_EXIST', `Cannot find user ${username}`)
|
|
280
|
-
} else if (!bgUser.authenticate(password)) {
|
|
281
|
-
throw new ApiErrorCode('USER_UNAUTHORIZED', 'unauthorized')
|
|
282
|
-
}
|
|
283
|
-
return bgUser
|
|
284
|
-
}
|
|
285
|
-
if (user.user_status === 2) {
|
|
286
|
-
// Account deleted
|
|
287
|
-
throw new ApiErrorCode('ACCOUNT_WERE_DELETED', `Account ${user.email} already deleted`)
|
|
288
|
-
}
|
|
289
|
-
if (!user.authenticate(password)) {
|
|
290
|
-
if (user.facebook_id !== null) {
|
|
291
|
-
throw new ApiErrorCode('USER_OAUTH_LOGIN', 'Please use FB to login your account')
|
|
292
|
-
} else {
|
|
293
|
-
throw new ApiErrorCode('USER_UNAUTHORIZED', 'unauthorized')
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
return user
|
|
297
|
-
},
|
|
298
|
-
auth: function (uname, password, cb) {
|
|
299
|
-
if (!cb) {
|
|
300
|
-
return this._async_auth(uname, password)
|
|
301
|
-
}
|
|
302
|
-
let username = String(uname).toLowerCase().replace('@', '_')
|
|
303
|
-
let that = this
|
|
304
|
-
|
|
305
|
-
that.findOne({ username: username }, function (err, user) {
|
|
306
|
-
if (err) {
|
|
307
|
-
return cb(new ApiErrorCode('internal_sysmtem_error', err.message))
|
|
308
|
-
} else if (!user) {
|
|
309
|
-
that.findOne({ bk_username: { $in: [uname] } }, function (err, bgUser) {
|
|
310
|
-
if (err) {
|
|
311
|
-
return cb(new ApiErrorCode('INTERNAL_SYSMTEM_ERROR', err.message))
|
|
312
|
-
} else if (!bgUser) {
|
|
313
|
-
return cb(new ApiErrorCode('USER_NOT_EXIST', `Cannot find user ${uname}`))
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
return (!user.authenticate(password))
|
|
317
|
-
? cb(new ApiErrorCode('USER_UNAUTHORIZED', 'unauthorized'))
|
|
318
|
-
: cb(null, bgUser)
|
|
319
|
-
})
|
|
320
|
-
} else {
|
|
321
|
-
if (user.user_status === 2) {
|
|
322
|
-
return cb(new ApiErrorCode('ACCOUNT_WERE_DELETED', `Account ${user.email} already deleted`))
|
|
323
|
-
} else if (!user.authenticate(password)) {
|
|
324
|
-
if (user.facebook_id !== null) {
|
|
325
|
-
return cb(new ApiErrorCode('USER_OAUTH_LOGIN', 'Please use FB to login your account'))
|
|
326
|
-
} else {
|
|
327
|
-
return cb(new ApiErrorCode('USER_UNAUTHORIZED', 'unauthorized'))
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
return cb(null, user)
|
|
331
|
-
}
|
|
332
|
-
})
|
|
333
|
-
},
|
|
334
|
-
login: function (query, cb) {
|
|
335
|
-
if (!_.isObject(query)) {
|
|
336
|
-
return cb(Error('Invalid login parameter'))
|
|
337
|
-
} else {
|
|
338
|
-
this.findOne(query, cb)
|
|
339
|
-
}
|
|
340
|
-
},
|
|
341
|
-
loginForPassport: function (query, cb) {
|
|
342
|
-
let self = this
|
|
343
|
-
|
|
344
|
-
if (!_.isObject(query)) {
|
|
345
|
-
return cb(Error('Invalid login parameter'))
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
if (_.has(query, 'username')) {
|
|
349
|
-
query['username'] = String(_.trim(query['username'])).toLowerCase()
|
|
350
|
-
}
|
|
351
|
-
if (_.has(query, 'email')) {
|
|
352
|
-
query['email'] = String(_.trim(query['email'])).toLowerCase()
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
debug('loginForPassport:%o', query)
|
|
356
|
-
self.findOne(query, function (err, user) {
|
|
357
|
-
if (err) {
|
|
358
|
-
return cb({ status: 500, errorMessage: err })
|
|
359
|
-
} else if (!user) {
|
|
360
|
-
return cb({ status: 404, errorMessage: `Cannot found target user` })
|
|
361
|
-
} else if (user['user_status'] === 2) {
|
|
362
|
-
return cb({ status: 410, errorMessage: `This account already deleted` })
|
|
363
|
-
} else {
|
|
364
|
-
return cb(null, user)
|
|
365
|
-
}
|
|
366
|
-
})
|
|
367
|
-
},
|
|
368
|
-
list: function (options, cb) {
|
|
369
|
-
var criteria = options.criteria || {}
|
|
370
|
-
var sort = options.sort || { createdAt: -1 }
|
|
371
|
-
var limit = options.limit === 0 ? 0 : (options.limit || 10)
|
|
372
|
-
var page = options.page || 0
|
|
373
|
-
|
|
374
|
-
this.find(criteria)
|
|
375
|
-
.select('name username email')
|
|
376
|
-
.sort(sort)
|
|
377
|
-
.skip(limit * page)
|
|
378
|
-
.limit(limit)
|
|
379
|
-
.exec(cb)
|
|
380
|
-
},
|
|
381
|
-
getUser: function (username, cb) {
|
|
382
|
-
this.findOne({ username: String(username).toLowerCase() })
|
|
383
|
-
.sort({ date_joined: -1 })
|
|
384
|
-
.select('email user_role user_status auth')
|
|
385
|
-
.exec(cb)
|
|
386
|
-
},
|
|
387
|
-
getUserPromise: async function (username) {
|
|
388
|
-
const userData = await this.findOne({ username: String(username).toLowerCase() })
|
|
389
|
-
.select('email user_role user_status auth')
|
|
390
|
-
.exec()
|
|
391
|
-
return userData
|
|
392
|
-
},
|
|
393
|
-
getUserById: function (id, cb) {
|
|
394
|
-
this.findById(id).exec(cb)
|
|
395
|
-
},
|
|
396
|
-
getUserFullData: function (username) {
|
|
397
|
-
const cursor = this.aggregate([
|
|
398
|
-
{ '$match': { username: String(username).toLowerCase(), user_status: 1 } },
|
|
399
|
-
{ '$lookup': { 'from': 'jamup_userprofile', 'localField': '_id', 'foreignField': 'user_id', 'as': 'userprofile' } },
|
|
400
|
-
{ '$unwind': '$userprofile' }
|
|
401
|
-
]).cursor({ batchSize: 100, useMongooseAggCursor: true }).exec()
|
|
402
|
-
return cursor.eachAsync()
|
|
403
|
-
},
|
|
404
|
-
// Promise rewrite getUserFullData
|
|
405
|
-
getUserDetail: async function (query, projectFields = {}) {
|
|
406
|
-
try {
|
|
407
|
-
if (!_.isObject(query)) {
|
|
408
|
-
throw new Error('Query need to be object!')
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
const queryCondition = _.assign({}, {
|
|
412
|
-
'user_status': 1
|
|
413
|
-
}, query)
|
|
414
|
-
|
|
415
|
-
const defaultProjectFields = _.assign({}, {
|
|
416
|
-
'_id': 1,
|
|
417
|
-
'email': 1,
|
|
418
|
-
'username': 1,
|
|
419
|
-
'date_joined': 1,
|
|
420
|
-
'last_login': 1,
|
|
421
|
-
'userprofile.first_name': 1,
|
|
422
|
-
'userprofile.last_name': 1,
|
|
423
|
-
'userprofile.full_name': 1
|
|
424
|
-
}, projectFields)
|
|
425
|
-
const ret = await this.aggregate([
|
|
426
|
-
{ '$match': queryCondition },
|
|
427
|
-
{
|
|
428
|
-
'$lookup': {
|
|
429
|
-
'from': 'jamup_userprofile',
|
|
430
|
-
'localField': '_id',
|
|
431
|
-
'foreignField': 'user_id',
|
|
432
|
-
'as': 'userprofile'
|
|
433
|
-
}
|
|
434
|
-
},
|
|
435
|
-
{ '$unwind': '$userprofile' },
|
|
436
|
-
{ '$project': defaultProjectFields }
|
|
437
|
-
]).exec()
|
|
438
|
-
|
|
439
|
-
debug('INFO:getUserDetail %o:%o', queryCondition, ret)
|
|
440
|
-
return ret
|
|
441
|
-
} catch (err) {
|
|
442
|
-
debug('ERR:getUserDetail %o', err)
|
|
443
|
-
throw err
|
|
444
|
-
}
|
|
445
|
-
},
|
|
446
|
-
getDealerDetail: async function (query) {
|
|
447
|
-
try {
|
|
448
|
-
if (!_.isObject(query)) {
|
|
449
|
-
throw new Error('Query need to be object!')
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
const queryCondition = _.assign({}, {
|
|
453
|
-
'user_status': 1
|
|
454
|
-
}, query)
|
|
455
|
-
|
|
456
|
-
const ret = await this.aggregate([
|
|
457
|
-
{ '$match': queryCondition },
|
|
458
|
-
{
|
|
459
|
-
'$lookup': {
|
|
460
|
-
'from': 'jamup_userprofile',
|
|
461
|
-
'localField': '_id',
|
|
462
|
-
'foreignField': 'user_id',
|
|
463
|
-
'as': 'userprofile'
|
|
464
|
-
}
|
|
465
|
-
},
|
|
466
|
-
{ '$unwind': '$userprofile' },
|
|
467
|
-
{
|
|
468
|
-
'$lookup': {
|
|
469
|
-
'from': 'b2b_dealer_profile',
|
|
470
|
-
'localField': '_id',
|
|
471
|
-
'foreignField': 'dealer_id',
|
|
472
|
-
'as': 'dealer'
|
|
473
|
-
}
|
|
474
|
-
},
|
|
475
|
-
{ '$unwind': '$dealer' }
|
|
476
|
-
]).exec()
|
|
477
|
-
|
|
478
|
-
debug('INFO:getDealerDetail %o:%o', queryCondition, ret)
|
|
479
|
-
return ret
|
|
480
|
-
} catch (err) {
|
|
481
|
-
debug('ERR:getDealerDetail %o', err)
|
|
482
|
-
throw err
|
|
483
|
-
}
|
|
484
|
-
},
|
|
485
|
-
createUser: function (userObj, cb) {
|
|
486
|
-
debug(userObj)
|
|
487
|
-
this.create(userObj, function (err, userObj) {
|
|
488
|
-
if (err) return cb(err)
|
|
489
|
-
|
|
490
|
-
return cb(null, userObj)
|
|
491
|
-
})
|
|
492
|
-
},
|
|
493
|
-
deleteUser: function (userId, cb) {
|
|
494
|
-
this.remove({ _id: userId }).exec(cb)
|
|
495
|
-
},
|
|
496
|
-
findUserByEmail: function (email, cb) {
|
|
497
|
-
this.find({ email: String(email).toLowerCase() }).exec(cb)
|
|
498
|
-
},
|
|
499
|
-
findByEmail: async function (email) {
|
|
500
|
-
try {
|
|
501
|
-
if (!isEmail(email)) {
|
|
502
|
-
throw new Error(`Invalid email format: ${email}`)
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
return await this.findOne({
|
|
506
|
-
email: String(email).toLowerCase(),
|
|
507
|
-
user_status: 1
|
|
508
|
-
}).exec()
|
|
509
|
-
} catch (err) {
|
|
510
|
-
debug('ERR:findByEmail:%o', email)
|
|
511
|
-
throw err
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
})
|
|
515
|
-
|
|
516
|
-
UserProfileSchema.static({
|
|
517
|
-
createProfile: function (profileObj, cb) {
|
|
518
|
-
debug('createProfile:%o', profileObj)
|
|
519
|
-
if (!profileObj['user_id']) {
|
|
520
|
-
return cb(new Error('Missing User Id'))
|
|
521
|
-
} else if (mongoose.Types.ObjectId.isValid(profileObj['user_id']) === false) {
|
|
522
|
-
return cb(new Error('Invalid User Id'))
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
this.create(profileObj, function (err, profileObj) {
|
|
526
|
-
if (err) return cb(err)
|
|
527
|
-
|
|
528
|
-
return cb(null, profileObj)
|
|
529
|
-
})
|
|
530
|
-
},
|
|
531
|
-
updateProfileByUserId: function (userId, updateData, cb) {
|
|
532
|
-
debug(updateData)
|
|
533
|
-
this.findOneAndUpdate(
|
|
534
|
-
{ user_id: userId },
|
|
535
|
-
{ $set: updateData },
|
|
536
|
-
{ new: true }).exec(cb)
|
|
537
|
-
},
|
|
538
|
-
updateProfile: async function (userId, updateProfileData) {
|
|
539
|
-
try {
|
|
540
|
-
return await this.findOneAndUpdate({
|
|
541
|
-
user_id: mongoose.Types.ObjectId(userId)
|
|
542
|
-
}, {
|
|
543
|
-
'$set': updateProfileData
|
|
544
|
-
}, { new: true }).exec()
|
|
545
|
-
} catch (err) {
|
|
546
|
-
debug('ERR:updateProfile:%o', err)
|
|
547
|
-
throw err
|
|
548
|
-
}
|
|
549
|
-
},
|
|
550
|
-
getUserProfile: function (userId, cb) {
|
|
551
|
-
this.getUserProfilePromise(userId)
|
|
552
|
-
.then(userData => cb(null, userData))
|
|
553
|
-
.catch(err => cb(err))
|
|
554
|
-
},
|
|
555
|
-
getUserProfilePromise: async function (userId) {
|
|
556
|
-
let selectField = [
|
|
557
|
-
'full_name',
|
|
558
|
-
'profile_image_url',
|
|
559
|
-
'profile_thumb_url',
|
|
560
|
-
'first_name',
|
|
561
|
-
'last_name',
|
|
562
|
-
'title',
|
|
563
|
-
'gender',
|
|
564
|
-
'date_joined'
|
|
565
|
-
].join(' ')
|
|
566
|
-
|
|
567
|
-
const profileData= await this.findOne({ user_id: userId })
|
|
568
|
-
.select(selectField)
|
|
569
|
-
.exec()
|
|
570
|
-
return profileData
|
|
571
|
-
},
|
|
572
|
-
getUserProfileDetail: function (userId, cb) {
|
|
573
|
-
if (!cb) {
|
|
574
|
-
return this.findOne({ user_id: userId }).exec()
|
|
575
|
-
}
|
|
576
|
-
this.findOne({ user_id: userId }).exec(cb)
|
|
577
|
-
},
|
|
578
|
-
getUserProfileByCondition: function (condition, cb) {
|
|
579
|
-
this.findOne(condition).exec(cb)
|
|
580
|
-
}
|
|
581
|
-
})
|
|
582
|
-
|
|
583
|
-
const jamupLitePattern = new RegExp('JamUp.+Lite\/([0-9.]+)')
|
|
584
|
-
const biasAmpPattern = new RegExp('Bias\/([0-9.]+)')
|
|
585
|
-
const biasAmpiPhonePattern = new RegExp('Bias.+iPhone\/([0-9.]+)')
|
|
586
|
-
const biasFxPattern = new RegExp('BIAS.+FX\/([0-9.]+).+iPad')
|
|
587
|
-
const biasPedalPattern = new RegExp('BIAS.+Pedal\/([0-9.]+).+iPad')
|
|
588
|
-
UserProductSchema.static({
|
|
589
|
-
detectUserProduct: function (userAgent) {
|
|
590
|
-
let userMeta = {}
|
|
591
|
-
const preUserAgent = String(userAgent)
|
|
592
|
-
|
|
593
|
-
if (preUserAgent.match(jamupLitePattern)) {
|
|
594
|
-
userMeta = {
|
|
595
|
-
product: 'jamup-lite',
|
|
596
|
-
platform: 'iOS'
|
|
597
|
-
}
|
|
598
|
-
} else if (preUserAgent.match(biasAmpPattern)) {
|
|
599
|
-
userMeta = {
|
|
600
|
-
product: 'biasamp',
|
|
601
|
-
platform: 'iOS'
|
|
602
|
-
}
|
|
603
|
-
} else if (preUserAgent.match(biasAmpiPhonePattern)) {
|
|
604
|
-
userMeta = {
|
|
605
|
-
product: 'biasamp',
|
|
606
|
-
platform: 'iOS'
|
|
607
|
-
}
|
|
608
|
-
} else if (preUserAgent.match(biasFxPattern)) {
|
|
609
|
-
userMeta = {
|
|
610
|
-
product: 'biasfx',
|
|
611
|
-
platform: 'iOS'
|
|
612
|
-
}
|
|
613
|
-
} else if (preUserAgent.match(biasPedalPattern)) {
|
|
614
|
-
userMeta = {
|
|
615
|
-
product: 'pedal',
|
|
616
|
-
platform: 'iOS'
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
return (_.isEmpty(userMeta)) ? false : userMeta
|
|
621
|
-
}
|
|
622
|
-
})
|
|
623
|
-
|
|
624
|
-
// Virtual
|
|
625
|
-
UserSchema.virtual('id')
|
|
626
|
-
.get(function () {
|
|
627
|
-
return this._id.toHexString()
|
|
628
|
-
})
|
|
629
|
-
|
|
630
|
-
mongoose.model('User', UserSchema)
|
|
631
|
-
mongoose.model('UserProfile', UserProfileSchema)
|
|
632
|
-
mongoose.model('ApiKey', ApikeySchema)
|
|
633
|
-
mongoose.model('UserProduct', UserProductSchema)
|
|
634
|
-
mongoose.model('UserProductTracker', UserProductTrackerSchema)
|
|
635
|
-
mongoose.model('UserReferral', UserReferralSchema)
|
|
636
|
-
mongoose.model('UserEmailStatus', UserEmailStatusSchema)
|
|
637
|
-
mongoose.model('UserToken', UserTokenSchema)
|
|
638
|
-
mongoose.model('UserFollow', UserFollowSchema)
|
|
639
|
-
}
|