2019-05-29 05:21:06 -04:00
|
|
|
const Settings = require('settings-sharelatex')
|
2019-11-18 09:03:20 -05:00
|
|
|
const mongoose = require('../infrastructure/Mongoose')
|
2021-03-31 05:28:19 -04:00
|
|
|
const TokenGenerator = require('../Features/TokenGenerator/TokenGenerator')
|
2019-05-29 05:21:06 -04:00
|
|
|
const { Schema } = mongoose
|
|
|
|
const { ObjectId } = Schema
|
|
|
|
|
|
|
|
// See https://stackoverflow.com/questions/386294/what-is-the-maximum-length-of-a-valid-email-address/574698#574698
|
|
|
|
const MAX_EMAIL_LENGTH = 254
|
|
|
|
|
2020-07-21 10:29:08 -04:00
|
|
|
const AuditLogEntrySchema = new Schema({
|
|
|
|
_id: false,
|
|
|
|
info: { type: Object },
|
|
|
|
initiatorId: { type: Schema.Types.ObjectId },
|
|
|
|
ipAddress: { type: String },
|
|
|
|
operation: { type: String },
|
|
|
|
userId: { type: Schema.Types.ObjectId },
|
|
|
|
timestamp: { type: Date }
|
|
|
|
})
|
|
|
|
|
2019-05-29 05:21:06 -04:00
|
|
|
const UserSchema = new Schema({
|
|
|
|
email: { type: String, default: '', maxlength: MAX_EMAIL_LENGTH },
|
|
|
|
emails: [
|
|
|
|
{
|
|
|
|
email: { type: String, default: '', maxlength: MAX_EMAIL_LENGTH },
|
|
|
|
reversedHostname: { type: String, default: '' },
|
|
|
|
createdAt: {
|
|
|
|
type: Date,
|
|
|
|
default() {
|
|
|
|
return new Date()
|
|
|
|
}
|
|
|
|
},
|
2019-10-07 11:23:45 -04:00
|
|
|
confirmedAt: { type: Date },
|
2020-02-20 11:08:40 -05:00
|
|
|
samlProviderId: { type: String },
|
2020-11-30 09:57:18 -05:00
|
|
|
affiliationUnchecked: { type: Boolean },
|
|
|
|
reconfirmedAt: { type: Date }
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
],
|
|
|
|
first_name: { type: String, default: '' },
|
|
|
|
last_name: { type: String, default: '' },
|
|
|
|
role: { type: String, default: '' },
|
|
|
|
institution: { type: String, default: '' },
|
|
|
|
hashedPassword: String,
|
|
|
|
isAdmin: { type: Boolean, default: false },
|
|
|
|
staffAccess: {
|
|
|
|
publisherMetrics: { type: Boolean, default: false },
|
|
|
|
publisherManagement: { type: Boolean, default: false },
|
|
|
|
institutionMetrics: { type: Boolean, default: false },
|
|
|
|
institutionManagement: { type: Boolean, default: false },
|
|
|
|
groupMetrics: { type: Boolean, default: false },
|
2019-08-12 03:43:50 -04:00
|
|
|
groupManagement: { type: Boolean, default: false },
|
|
|
|
adminMetrics: { type: Boolean, default: false }
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
|
|
|
signUpDate: {
|
|
|
|
type: Date,
|
|
|
|
default() {
|
|
|
|
return new Date()
|
|
|
|
}
|
|
|
|
},
|
|
|
|
lastLoggedIn: { type: Date },
|
|
|
|
lastLoginIp: { type: String, default: '' },
|
|
|
|
loginCount: { type: Number, default: 0 },
|
|
|
|
holdingAccount: { type: Boolean, default: false },
|
|
|
|
ace: {
|
|
|
|
mode: { type: String, default: 'none' },
|
|
|
|
theme: { type: String, default: 'textmate' },
|
|
|
|
overallTheme: { type: String, default: '' },
|
|
|
|
fontSize: { type: Number, default: '12' },
|
|
|
|
autoComplete: { type: Boolean, default: true },
|
|
|
|
autoPairDelimiters: { type: Boolean, default: true },
|
|
|
|
spellCheckLanguage: { type: String, default: 'en' },
|
|
|
|
pdfViewer: { type: String, default: 'pdfjs' },
|
|
|
|
syntaxValidation: { type: Boolean },
|
|
|
|
fontFamily: { type: String },
|
|
|
|
lineHeight: { type: String }
|
|
|
|
},
|
|
|
|
features: {
|
|
|
|
collaborators: {
|
|
|
|
type: Number,
|
|
|
|
default: Settings.defaultFeatures.collaborators
|
|
|
|
},
|
|
|
|
versioning: { type: Boolean, default: Settings.defaultFeatures.versioning },
|
|
|
|
dropbox: { type: Boolean, default: Settings.defaultFeatures.dropbox },
|
|
|
|
github: { type: Boolean, default: Settings.defaultFeatures.github },
|
|
|
|
gitBridge: { type: Boolean, default: Settings.defaultFeatures.gitBridge },
|
|
|
|
compileTimeout: {
|
|
|
|
type: Number,
|
|
|
|
default: Settings.defaultFeatures.compileTimeout
|
|
|
|
},
|
|
|
|
compileGroup: {
|
|
|
|
type: String,
|
|
|
|
default: Settings.defaultFeatures.compileGroup
|
|
|
|
},
|
|
|
|
templates: { type: Boolean, default: Settings.defaultFeatures.templates },
|
|
|
|
references: { type: Boolean, default: Settings.defaultFeatures.references },
|
|
|
|
trackChanges: {
|
|
|
|
type: Boolean,
|
|
|
|
default: Settings.defaultFeatures.trackChanges
|
|
|
|
},
|
|
|
|
mendeley: { type: Boolean, default: Settings.defaultFeatures.mendeley },
|
|
|
|
zotero: { type: Boolean, default: Settings.defaultFeatures.zotero },
|
|
|
|
referencesSearch: {
|
|
|
|
type: Boolean,
|
|
|
|
default: Settings.defaultFeatures.referencesSearch
|
|
|
|
}
|
|
|
|
},
|
2019-12-02 08:51:57 -05:00
|
|
|
featuresOverrides: [
|
|
|
|
{
|
|
|
|
createdAt: {
|
|
|
|
type: Date,
|
|
|
|
default() {
|
|
|
|
return new Date()
|
|
|
|
}
|
|
|
|
},
|
|
|
|
expiresAt: { type: Date },
|
|
|
|
note: { type: String },
|
|
|
|
features: {
|
|
|
|
collaborators: { type: Number },
|
|
|
|
versioning: { type: Boolean },
|
|
|
|
dropbox: { type: Boolean },
|
|
|
|
github: { type: Boolean },
|
|
|
|
gitBridge: { type: Boolean },
|
|
|
|
compileTimeout: { type: Number },
|
|
|
|
compileGroup: { type: String },
|
|
|
|
templates: { type: Boolean },
|
|
|
|
trackChanges: { type: Boolean },
|
|
|
|
mendeley: { type: Boolean },
|
|
|
|
zotero: { type: Boolean },
|
|
|
|
referencesSearch: { type: Boolean }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
],
|
2019-06-18 04:36:04 -04:00
|
|
|
// when auto-merged from SL and must-reconfirm is set, we may end up using
|
|
|
|
// `sharelatexHashedPassword` to recover accounts...
|
|
|
|
sharelatexHashedPassword: String,
|
2019-05-29 05:21:06 -04:00
|
|
|
must_reconfirm: { type: Boolean, default: false },
|
|
|
|
referal_id: {
|
|
|
|
type: String,
|
|
|
|
default() {
|
2021-03-31 05:28:19 -04:00
|
|
|
return TokenGenerator.generateReferralId()
|
2019-05-29 05:21:06 -04:00
|
|
|
}
|
|
|
|
},
|
|
|
|
refered_users: [{ type: ObjectId, ref: 'User' }],
|
|
|
|
refered_user_count: { type: Number, default: 0 },
|
|
|
|
refProviders: {
|
2020-10-21 05:48:16 -04:00
|
|
|
// The actual values are managed by third-party-references.
|
|
|
|
mendeley: Schema.Types.Mixed,
|
|
|
|
zotero: Schema.Types.Mixed
|
2019-05-29 05:21:06 -04:00
|
|
|
},
|
2020-06-19 04:22:22 -04:00
|
|
|
alphaProgram: { type: Boolean, default: false }, // experimental features
|
2019-05-29 05:21:06 -04:00
|
|
|
betaProgram: { type: Boolean, default: false },
|
|
|
|
overleaf: {
|
|
|
|
id: { type: Number },
|
|
|
|
accessToken: { type: String },
|
|
|
|
refreshToken: { type: String }
|
|
|
|
},
|
|
|
|
awareOfV2: { type: Boolean, default: false },
|
2019-09-12 10:01:12 -04:00
|
|
|
samlIdentifiers: { type: Array, default: [] },
|
2019-05-29 05:21:06 -04:00
|
|
|
thirdPartyIdentifiers: { type: Array, default: [] },
|
2020-04-07 06:27:33 -04:00
|
|
|
migratedAt: { type: Date },
|
|
|
|
twoFactorAuthentication: {
|
|
|
|
createdAt: { type: Date },
|
|
|
|
enrolledAt: { type: Date },
|
|
|
|
secret: { type: String }
|
2020-07-13 07:23:39 -04:00
|
|
|
},
|
2020-07-21 10:29:08 -04:00
|
|
|
onboardingEmailSentAt: { type: Date },
|
|
|
|
auditLog: [AuditLogEntrySchema]
|
2019-05-29 05:21:06 -04:00
|
|
|
})
|
|
|
|
|
2019-11-18 09:03:20 -05:00
|
|
|
exports.User = mongoose.model('User', UserSchema)
|
2019-07-18 10:18:56 -04:00
|
|
|
exports.UserSchema = UserSchema
|