Spaces:
Sleeping
Sleeping
| import { | |
| Entity, | |
| PrimaryGeneratedColumn, | |
| Column, | |
| CreateDateColumn, | |
| UpdateDateColumn, | |
| DeleteDateColumn, | |
| ManyToMany, | |
| JoinTable, | |
| OneToMany, | |
| BeforeInsert, | |
| BeforeUpdate, | |
| } from 'typeorm'; | |
| import type { Relation } from 'typeorm'; | |
| import { Exclude } from 'class-transformer'; | |
| import * as bcrypt from 'bcrypt'; | |
| import { Role } from './role.entity'; | |
| import { Session } from './session.entity'; | |
| import { PasswordReset } from './password-reset.entity'; | |
| import { TwoFactorAuth } from './two-factor-auth.entity'; | |
| export enum UserStatus { | |
| ACTIVE = 'active', | |
| INACTIVE = 'inactive', | |
| SUSPENDED = 'suspended', | |
| PENDING = 'pending', | |
| } | |
| ('users') | |
| export class User { | |
| ({ type: 'bigint', unsigned: true, name: 'user_id' }) | |
| userId: number; | |
| ({ unique: true, length: 100 }) | |
| email: string; | |
| ({ name: 'password_hash', length: 255 }) | |
| () | |
| passwordHash: string; | |
| ({ name: 'first_name', length: 50 }) | |
| firstName: string; | |
| ({ name: 'last_name', length: 50 }) | |
| lastName: string; | |
| ({ length: 20, nullable: true }) | |
| phone?: string; | |
| ({ name: 'profile_picture_url', type: 'text', nullable: true }) | |
| profilePictureUrl?: string; | |
| ({ type: 'text', nullable: true }) | |
| bio?: string; | |
| ({ name: 'social_links', type: 'json', nullable: true }) | |
| socialLinks?: Record<string, string>; | |
| ({ name: 'academic_interests', type: 'json', nullable: true }) | |
| academicInterests?: string[]; | |
| ({ name: 'skills', type: 'json', nullable: true }) | |
| skills?: string[]; | |
| ({ name: 'campus_id', nullable: true }) | |
| campusId?: number; | |
| ({ | |
| type: 'enum', | |
| enum: UserStatus, | |
| default: UserStatus.PENDING, | |
| }) | |
| status: UserStatus; | |
| ({ name: 'email_verified', default: false }) | |
| emailVerified: boolean; | |
| ({ name: 'last_login_at', type: 'datetime', nullable: true }) | |
| lastLoginAt?: Date; | |
| ({ name: 'created_at' }) | |
| createdAt: Date; | |
| ({ name: 'updated_at' }) | |
| updatedAt: Date; | |
| ({ name: 'deleted_at', nullable: true }) | |
| deletedAt?: Date; | |
| // Relationships | |
| (() => Role, (role) => role.users) | |
| ({ | |
| name: 'user_roles', | |
| joinColumn: { name: 'user_id', referencedColumnName: 'userId' }, | |
| inverseJoinColumn: { name: 'role_id', referencedColumnName: 'roleId' }, | |
| }) | |
| roles: Relation<Role>[]; | |
| (() => Session, (session) => session.user) | |
| sessions: Relation<Session>[]; | |
| (() => PasswordReset, (passwordReset) => passwordReset.user) | |
| passwordResets: Relation<PasswordReset>[]; | |
| (() => TwoFactorAuth, (twoFactorAuth) => twoFactorAuth.user) | |
| twoFactorAuths: Relation<TwoFactorAuth>[]; | |
| // Hooks for password hashing | |
| () | |
| () | |
| async hashPassword() { | |
| if (this.passwordHash && !this.passwordHash.startsWith('$2b$')) { | |
| this.passwordHash = await bcrypt.hash(this.passwordHash, 10); | |
| } | |
| } | |
| // Method to validate password | |
| async validatePassword(password: string): Promise<boolean> { | |
| return bcrypt.compare(password, this.passwordHash); | |
| } | |
| // Computed property for full name | |
| get fullName(): string { | |
| return `${this.firstName} ${this.lastName}`; | |
| } | |
| } | |