task-svr/src/models/Account.ts
2024-01-17 15:49:18 +08:00

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 })