Skip to content

Commit

Permalink
refactor(auth): refactoring crypt logic
Browse files Browse the repository at this point in the history
  • Loading branch information
nichenqin committed Aug 31, 2023
1 parent f2a1e95 commit 8badf41
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 30 deletions.
12 changes: 11 additions & 1 deletion apps/backend/src/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,26 @@ import {
NestRegisterCommandHandler,
NestUpdateProfileCommandHandler,
} from './commands/index.js'
import { CryptService } from './crypt.service.js'
import { JwtStrategy } from './jwt.strategy.js'
import { LocalStrategy } from './local.strategy.js'
import { NestGetMeQueryHandler } from './queries/index.js'
import { NestUserService } from './user.service.js'

const CommandHandlers = [NestLgoinCommandHandler, NestRegisterCommandHandler, NestUpdateProfileCommandHandler]
const QueryHandlers = [NestGetMeQueryHandler]

@Module({
imports: [CqrsModule, UserModule, AuthzModule, PassportModule, MemberModule],
providers: [AuthService, LocalStrategy, JwtStrategy, ...CommandHandlers, ...QueryHandlers],
providers: [
AuthService,
LocalStrategy,
JwtStrategy,
...CommandHandlers,
...QueryHandlers,
CryptService,
NestUserService,
],
exports: [AuthService],
controllers: [AuthController],
})
Expand Down
23 changes: 8 additions & 15 deletions apps/backend/src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ import { Injectable } from '@nestjs/common'
import { type ConfigType } from '@nestjs/config'
import { CommandBus, QueryBus } from '@nestjs/cqrs'
import type { IQueryUser } from '@undb/core'
import { UserFactory, WithUserColor, WithUserEmail, WithUserId, WithUserPassword, WithUsername } from '@undb/core'
import { WithUserEmail } from '@undb/core'
import { GetMeQuery, LoginCommand, RegisterCommand, UpdateProfileCommand } from '@undb/cqrs'
import * as bcrypt from 'bcrypt'
import { NestMemberCreateService } from '../authz/member/member-create.service.js'
import type { authConfig } from '../configs/auth.config.js'
import { InjectAuthConfig } from '../configs/auth.config.js'
import { UserService } from '../core/user/user.service.js'
import { CryptService } from './crypt.service.js'
import { InvalidPassword } from './errors/invalid-password.error.js'
import { UserNotFound } from './errors/user-not-found.error.js'
import { NestUserService } from './user.service.js'

@Injectable()
export class AuthService {
Expand All @@ -21,6 +22,8 @@ export class AuthService {
@InjectAuthConfig()
private readonly config: ConfigType<typeof authConfig>,
private readonly memberService: NestMemberCreateService,
private readonly userService: NestUserService,
private readonly crypt: CryptService,
) {}

async validateUser(email: string, pass: string): Promise<IQueryUser> {
Expand All @@ -29,16 +32,15 @@ export class AuthService {
throw new UserNotFound()
}

const isPasswordMatch = await bcrypt.compare(pass, user.password)
const isPasswordMatch = await this.crypt.compare(pass, user.password)
if (!isPasswordMatch) {
throw new InvalidPassword()
}
return user.toQuery()
}

async register(email: string, password: string) {
const hashedPassword = await bcrypt.hash(password, 10)
return this.commandBus.execute(new RegisterCommand({ email, password: hashedPassword }))
return this.commandBus.execute(new RegisterCommand({ email, password }))
}

async login(user: IQueryUser) {
Expand All @@ -60,16 +62,7 @@ export class AuthService {
const exists = await this.usersService.exists(email)
if (exists) return

const hashedPassword = await bcrypt.hash(admin.password, 10)
const user = UserFactory.create(
WithUserEmail.fromString(admin.email),
WithUserPassword.fromString(hashedPassword),
WithUserId.create(),
WithUsername.fromEmail(admin.email),
WithUserColor.random(),
)

await this.usersService.insert(user)
const user = await this.userService.register(admin.email, admin.password)
await this.memberService.grantDefault(user)
}
}
Expand Down
4 changes: 3 additions & 1 deletion apps/backend/src/auth/commands/register.command.handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@ import { type IUserRepository } from '@undb/core'
import { RegisterCommand, RegisterCommandHandler } from '@undb/cqrs'
import { NestMemberCreateService } from '../../authz/member/member-create.service.js'
import { InjectUserRepository } from '../../core/user/adapters/index.js'
import { NestUserService } from '../user.service.js'

@CommandHandler(RegisterCommand)
export class NestRegisterCommandHandler extends RegisterCommandHandler {
constructor(
@InjectUserRepository()
protected readonly repo: IUserRepository,
protected readonly memberService: NestMemberCreateService,
protected readonly userService: NestUserService,
) {
super(repo, memberService)
super(repo, memberService, userService)
}
}
14 changes: 14 additions & 0 deletions apps/backend/src/auth/crypt.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Injectable } from '@nestjs/common'
import type { PasswordCryptor } from '@undb/core'
import * as bcrypt from 'bcrypt'

@Injectable()
export class CryptService implements PasswordCryptor {
hash(password: string): Promise<string> {
return bcrypt.hash(password, 10)
}

compare(p1: string, p2: string): Promise<boolean> {
return bcrypt.compare(p1, p2)
}
}
11 changes: 11 additions & 0 deletions apps/backend/src/auth/user.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Injectable } from '@nestjs/common'
import { UserService, type IUserRepository } from '@undb/core'
import { InjectUserRepository } from '../core/user/adapters/index.js'
import { CryptService } from './crypt.service.js'

@Injectable()
export class NestUserService extends UserService {
constructor(cryptor: CryptService, @InjectUserRepository() repo: IUserRepository) {
super(cryptor, repo)
}
}
1 change: 1 addition & 0 deletions packages/core/src/user/services/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './anonymous.service.js'
export * from './user.service.js'
40 changes: 40 additions & 0 deletions packages/core/src/user/services/user.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { WithUserColor } from '../specifications/user-color.js'
import { WithUserEmail } from '../specifications/user-email.specification.js'
import { WithUserId } from '../specifications/user-id.specification.js'
import { WithUserPassword } from '../specifications/user-password.specification.js'
import { WithUsername } from '../specifications/username.specification.js'
import { UserFactory } from '../user.factory.js'
import type { User } from '../user.js'
import type { IUserRepository } from '../user.repository.js'

export interface IUserService {
register(email: string, password: string): Promise<User>
}

export interface PasswordCryptor {
hash(password: string): Promise<string>
compare(p1: string, p2: string): Promise<boolean>
}

export class UserService implements IUserService {
constructor(
protected readonly cryptor: PasswordCryptor,
protected readonly repo: IUserRepository,
) {}

async register(email: string, password: string): Promise<User> {
const hashedPassword = await this.cryptor.hash(password)

const user = UserFactory.create(
WithUserEmail.fromString(email),
WithUserPassword.fromString(hashedPassword),
WithUserId.create(),
WithUsername.fromEmail(email),
WithUserColor.random(),
)

await this.repo.insert(user)

return user
}
}
2 changes: 1 addition & 1 deletion packages/cqrs/src/commands/login/login.command.handler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ICommandHandler } from '@undb/domain'
import { ILoginCommandOutput } from './login.command.interface.js'
import type { ILoginCommandOutput } from './login.command.interface.js'
import type { LoginCommand } from './login.command.js'

type ILoginCommandHandler = ICommandHandler<LoginCommand, ILoginCommandOutput>
Expand Down
16 changes: 4 additions & 12 deletions packages/cqrs/src/commands/register/register.command.handler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { IMemberCreateService } from '@undb/authz'
import type { IUserRepository } from '@undb/core'
import { UserFactory, WithUserColor, WithUserEmail, WithUserId, WithUserPassword, WithUsername } from '@undb/core'
import type { IUserRepository, IUserService } from '@undb/core'
import { WithUserEmail } from '@undb/core'
import type { ICommandHandler } from '@undb/domain'
import type { IRegisterCommandOutput } from './register.command.interface.js'
import type { RegisterCommand } from './register.command.js'
Expand All @@ -11,22 +11,14 @@ export class RegisterCommandHandler implements IRegisterCommandHandler {
constructor(
protected readonly repo: IUserRepository,
protected readonly memberService: IMemberCreateService,
protected readonly svc: IUserService,
) {}

async execute({ email, password }: RegisterCommand): Promise<IRegisterCommandOutput> {
const exists = await this.repo.exists(WithUserEmail.fromString(email))
if (exists) throw new Error('user already exists')

const user = UserFactory.create(
WithUserEmail.fromString(email),
WithUserPassword.fromString(password),
WithUserId.create(),
WithUsername.fromEmail(email),
WithUserColor.random(),
)

await this.repo.insert(user)
await this.memberService.grantDefault(user)
const user = await this.svc.register(email, password)

return { email, sub: user.userId.value }
}
Expand Down

0 comments on commit 8badf41

Please sign in to comment.