Skip to content
This repository has been archived by the owner on Nov 29, 2021. It is now read-only.

Commit

Permalink
feat: update validateTOTP
Browse files Browse the repository at this point in the history
  • Loading branch information
YanceyOfficial committed Mar 27, 2020
1 parent 2fd8b45 commit 0150ee7
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 0 deletions.
6 changes: 6 additions & 0 deletions schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ input LoginInput {
type Mutation {
register(input: RegisterInput!): AuthModel!
createTOTP(userId: ID!): TOTPModel!
validateTOTP(input: ValidateTOTPInput!): TOTPModel!
createAnnouncement(input: CreateAnnouncementInput!): AnnouncementModel!
updateAnnouncementById(input: UpdateAnnouncementInput!): AnnouncementModel!
deleteAnnouncementById(id: ID!): AnnouncementModel!
Expand Down Expand Up @@ -357,6 +358,11 @@ type ValidateSMSRes {
success: Boolean!
}

input ValidateTOTPInput {
userId: String!
token: String!
}

type YanceyMusicModel {
_id: ID!
title: String!
Expand Down
6 changes: 6 additions & 0 deletions src/auth/auth.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { AuthModel } from './models/auth.model'
import { TOTPModel } from './models/totp.model'
import { LoginInput } from './dtos/login.input'
import { RegisterInput } from './dtos/register.input'
import { ValidateTOTPInput } from './dtos/validate-totp.input'

@Resolver(() => AuthModel)
export class AuthResolver {
Expand All @@ -25,4 +26,9 @@ export class AuthResolver {
public async createTOTP(@Args({ name: 'userId', type: () => ID }) userId: string) {
return this.authService.createTOTP(userId)
}

@Mutation(() => TOTPModel)
public async validateTOTP(@Args('input') input: ValidateTOTPInput) {
return this.authService.validateTOTP(input)
}
}
15 changes: 15 additions & 0 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { UsersService } from '../users/users.service'
import { Roles, User } from '../users/interfaces/user.interface'
import { LoginInput } from './dtos/login.input'
import { RegisterInput } from './dtos/register.input'
import { ValidateTOTPInput } from './dtos/validate-totp.input'

@Injectable()
export class AuthService {
Expand Down Expand Up @@ -68,4 +69,18 @@ export class AuthService {

return generateQRCode(otpauth_url)
}

public async validateTOTP(input: ValidateTOTPInput) {
const { userId, token } = input

const { twoFactorSecret } = await this.usersService.findOneById(userId)

const verified = speakeasy.totp.verify({
secret: twoFactorSecret,
encoding: 'base32',
token,
})

return verified
}
}
16 changes: 16 additions & 0 deletions src/auth/dtos/validate-totp.input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { InputType, Field } from '@nestjs/graphql'
import { IsNotEmpty, IsUUID, IsNumberString, Length } from 'class-validator'

@InputType()
export class ValidateTOTPInput {
@Field()
@IsUUID()
@IsNotEmpty()
public readonly userId: string

@Field()
@IsNumberString()
@IsNotEmpty()
@Length(6)
public readonly token: string
}
4 changes: 4 additions & 0 deletions src/users/users.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export class UsersService {
return this.UserModel.estimatedDocumentCount()
}

public async findOneById(id: string): Promise<User> {
return this.UserModel.findById(id)
}

public async findOneByEmail(email: string): Promise<User> {
return this.UserModel.findOne({ email })
}
Expand Down

0 comments on commit 0150ee7

Please sign in to comment.