import * as bcrypt from 'bcrypt-nodejs'; import * as mongoose from 'mongoose'; import { Utils } from '../../Utils'; type comparePasswordFunction = (candidatePassword: string, cb: (err: Error, isMatch: boolean) => void) => void; export type DashUserModel = mongoose.Document & { email?: string | null | undefined; password?: string | null | undefined; passwordResetToken?: string | null | undefined; passwordResetExpires?: Date | null | undefined; dropboxRefresh?: string | null | undefined; dropboxToken?: string | null | undefined; userDocumentId?: string | null | undefined; sharingDocumentId?: string | null | undefined; linkDatabaseId?: string | null | undefined; cacheDocumentIds?: string | null | undefined; profile?: | { name?: string | null | undefined; gender?: string | null | undefined; location?: string | null | undefined; website?: string | null | undefined; picture?: string | null | undefined; } | null | undefined; comparePassword?: comparePasswordFunction | null | undefined; }; export type AuthToken = { accessToken: string; kind: string; }; const userSchema = new mongoose.Schema( { email: String, password: String, passwordResetToken: String, passwordResetExpires: Date, dropboxRefresh: String, dropboxToken: String, userDocumentId: String, // id that identifies a document which hosts all of a user's account data sharingDocumentId: String, // id that identifies a document that stores documents shared to a user, their user color, and any additional info needed to communicate between users linkDatabaseId: String, cacheDocumentIds: String, // set of document ids to retreive on startup facebook: String, twitter: String, google: String, profile: { name: String, gender: String, location: String, website: String, picture: String, }, }, { timestamps: true } ); /** * Password hash middleware. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any userSchema.pre('save', function save(next: any) { if (!this.isModified('password')) { return next(); } bcrypt.genSalt( 10, ((err: Error, salt: string) => { if (err) { return next(err); } bcrypt.hash( this.password ?? '', salt, () => {}, (cryptErr: mongoose.Error, hash: string) => { if (cryptErr) { return next(cryptErr); } this.password = hash; next(); return undefined; } ); return undefined; }).bind(this) ); return undefined; }); const comparePassword: comparePasswordFunction = function (this: DashUserModel, candidatePassword, cb) { // Choose one of the following bodies for authentication logic. // secure (expected, default) this.password && bcrypt.compare(candidatePassword, this.password, cb); // bypass password (debugging) // cb(undefined, true); }; userSchema.methods.comparePassword = comparePassword; const User = mongoose.model('User', userSchema); export function initializeGuest() { new User({ email: 'guest', password: 'guest', userDocumentId: Utils.GuestID(), sharingDocumentId: '2', linkDatabaseId: '3', cacheDocumentIds: '', }).save(); } export default User;