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

Commit

Permalink
feat: update createTOTP
Browse files Browse the repository at this point in the history
  • Loading branch information
YanceyOfficial committed Mar 30, 2020
1 parent ea3dd60 commit 089148f
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 11 deletions.
8 changes: 7 additions & 1 deletion schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ input CreatePlayerInput {
isPublic: Boolean!
}

input CreateTOTPInput {
userId: ID!
email: String!
}

input CreateYanceyMusicInput {
title: String!
soundCloudUrl: String!
Expand Down Expand Up @@ -118,7 +123,7 @@ input LoginInput {

type Mutation {
register(input: RegisterInput!): UserModel!
createTOTP(userId: ID!): TOTPModel!
createTOTP(input: CreateTOTPInput!): TOTPModel!
validateTOTP(input: ValidateTOTPInput!): UserModel!
createRecoveryCodes(userId: ID!): RecoveryCodeModel!
validateRecoveryCode(input: ValidateTOTPInput!): UserModel!
Expand Down Expand Up @@ -272,6 +277,7 @@ type SMSModel {

type TOTPModel {
qrcode: String!
secretKey: String!
}

input UpdateAgendaInput {
Expand Down
8 changes: 3 additions & 5 deletions src/auth/auth.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { RecoveryCodeModel } from './models/recovery-code.model'
import { LoginInput } from './dtos/login.input'
import { RegisterInput } from './dtos/register.input'
import { ValidateTOTPInput } from './dtos/validate-totp.input'
import { CreateTOTPInput } from './dtos/create-totp.input'
import { GqlAuthGuard } from '../shared/guard/gqlAuth.guard'
import { ReqDecorator } from '../shared/decorators/req.decorator'

Expand All @@ -30,16 +31,13 @@ export class AuthResolver {

@Mutation(() => TOTPModel)
@UseGuards(GqlAuthGuard)
public async createTOTP(
@Args({ name: 'userId', type: () => ID }) userId: string,
@ReqDecorator() req: Request,
) {
public async createTOTP(@Args('input') input: CreateTOTPInput, @ReqDecorator() req: Request) {
const network = {
ip: requestIP.getClientIp(req),
userAgent: req.headers['user-agent'],
}

return this.authService.createTOTP(userId)
return this.authService.createTOTP(input)
}

@Mutation(() => UserModel)
Expand Down
12 changes: 9 additions & 3 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ 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'
import { CreateTOTPInput } from './dtos/create-totp.input'

@Injectable()
export class AuthService {
Expand Down Expand Up @@ -59,15 +60,20 @@ export class AuthService {
}
}

public async createTOTP(userId: string) {
const { base32, otpauth_url } = speakeasy.generateSecret({ name: 'Yancey Blog CMS' })
public async createTOTP(input: CreateTOTPInput) {
const { userId, email } = input
const { base32, otpauth_url } = speakeasy.generateSecret({
name: email,
})

await this.usersService.updateUser({
id: userId,
twoFactorSecret: base32,
})

return generateQRCode(otpauth_url)
const qrcode = await generateQRCode(`${otpauth_url}&issuer=Yancey%20Inc.`)

return { qrcode, secretKey: base32 }
}

public async validateTOTP(input: ValidateTOTPInput) {
Expand Down
15 changes: 15 additions & 0 deletions src/auth/dtos/create-totp.input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { InputType, Field, ID } from '@nestjs/graphql'
import { IsNotEmpty, IsUUID, IsEmail } from 'class-validator'

@InputType()
export class CreateTOTPInput {
@Field(() => ID)
@IsUUID()
@IsNotEmpty()
public readonly userId: string

@Field()
@IsEmail()
@IsNotEmpty()
public readonly email: string
}
3 changes: 3 additions & 0 deletions src/auth/models/totp.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@ import { Field, ObjectType } from '@nestjs/graphql'
export class TOTPModel {
@Field()
public readonly qrcode: string

@Field()
public readonly secretKey: string
}
3 changes: 1 addition & 2 deletions src/shared/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ export const jsonStringify = <T>(obj: T) => JSON.stringify(obj).replace(/"([^(")

export const generateQRCode = async (url: string) => {
try {
const qrcode = await QRCode.toDataURL(url)
return { qrcode }
return await QRCode.toDataURL(url)
} catch (err) {
throw new ApolloError('Generate QR code failed!')
}
Expand Down

0 comments on commit 089148f

Please sign in to comment.