122 lines
3.2 KiB
TypeScript
122 lines
3.2 KiB
TypeScript
import { getModelForClass, index, modelOptions, mongoose, prop, ReturnModelType, Severity } from '@typegoose/typegoose'
|
|
import { dbconn } from 'decorators/dbconn'
|
|
import { Base, TimeStamps } from '@typegoose/typegoose/lib/defaultClasses'
|
|
import { BaseModule } from './Base'
|
|
import { genRandomString, sha512 } from 'zutils/utils/security.util'
|
|
import { PlatEnum } from '../enums/PlatEnum'
|
|
/**
|
|
* copy from wallet-svr
|
|
*/
|
|
/**
|
|
* 生成密码的salt和hash
|
|
* @param userpassword
|
|
* @return {{salt: any, passwordHash: string}}
|
|
*/
|
|
export function saltHashPassword(userpassword: string) {
|
|
let salt = genRandomString(16)
|
|
return sha512(userpassword, salt)
|
|
}
|
|
|
|
/**
|
|
* 验证密码
|
|
* @param userpassword
|
|
* @param passwordDb
|
|
* @param salt
|
|
* @return {boolean}
|
|
*/
|
|
export function verifyPass(userpassword: string, passwordDb: string, salt: string) {
|
|
let passwordData = sha512(userpassword, salt)
|
|
return passwordData.passwordHash === passwordDb
|
|
}
|
|
|
|
export interface AccountClass extends Base, TimeStamps {}
|
|
@dbconn('wallet')
|
|
@index({ plat: 1, openId: 1 }, { unique: true })
|
|
@modelOptions({ schemaOptions: { collection: 'account', timestamps: true }, options: { allowMixed: Severity.ALLOW } })
|
|
export class AccountClass extends BaseModule {
|
|
@prop({ enum: PlatEnum, default: PlatEnum.GOOGLE })
|
|
public plat!: PlatEnum
|
|
@prop({ required: true })
|
|
public openId!: string
|
|
@prop()
|
|
public nickname?: string
|
|
@prop()
|
|
public avatar?: string
|
|
/**
|
|
* 第三方登录信息中返回的email, 会根据返回信息更新
|
|
* 实际使用中使用下面的 emailReal
|
|
*/
|
|
@prop()
|
|
public email?: string
|
|
|
|
@prop()
|
|
public password?: string
|
|
|
|
@prop()
|
|
public salt?: string
|
|
/**
|
|
* 第三方登录信息中返回的email认证信息
|
|
*/
|
|
@prop({ required: true, default: false })
|
|
public emailVerified: boolean
|
|
@prop({ default: 0 })
|
|
public sex?: string
|
|
@prop()
|
|
public locale?: string
|
|
@prop({ default: false })
|
|
public locked: boolean
|
|
@prop()
|
|
public lockedTime?: Date
|
|
@prop()
|
|
public comment?: string
|
|
@prop()
|
|
public lastLogin?: Date
|
|
@prop()
|
|
public accessToken?: string
|
|
@prop()
|
|
public accessTokenExpire?: number
|
|
@prop()
|
|
public refreshToken?: string
|
|
@prop()
|
|
public refreshTokenExpire?: number
|
|
@prop({ type: mongoose.Schema.Types.Mixed })
|
|
public scope?: any
|
|
/**
|
|
* 是否通过了邮件认证(我们发起的)
|
|
*/
|
|
@prop({ required: true, default: false })
|
|
public verified: boolean
|
|
/**
|
|
* 认证后的email
|
|
*/
|
|
@prop()
|
|
public emailReal?: string
|
|
|
|
@prop()
|
|
public emailVerifyTime?: number
|
|
// 用于标识该账号是否已经重置过
|
|
@prop({ default: 0 })
|
|
public accountVersion: number
|
|
|
|
@prop()
|
|
public platform: string
|
|
|
|
public static async findByEmail(this: ReturnModelType<typeof AccountClass>, email) {
|
|
return this.findOne({ email, plat: PlatEnum.EMAIL }).exec()
|
|
}
|
|
|
|
public updatePassword(password: string) {
|
|
if (password) {
|
|
let passData = saltHashPassword(password)
|
|
this.password = passData.passwordHash
|
|
this.salt = passData.salt
|
|
}
|
|
}
|
|
|
|
public verifyPassword(password: string) {
|
|
return verifyPass(password, this.password, this.salt)
|
|
}
|
|
}
|
|
|
|
export const Account = getModelForClass(AccountClass, { existingConnection: AccountClass.db })
|