Skip to content

Instantly share code, notes, and snippets.

@daweido
Last active April 19, 2023 20:03
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daweido/6c47636edc97d8e5c7915613ead1afa1 to your computer and use it in GitHub Desktop.
Save daweido/6c47636edc97d8e5c7915613ead1afa1 to your computer and use it in GitHub Desktop.
SMS OTP - Partial User authentification
import { Controller, Get, Res, HttpStatus, Body, Post } from '@nestjs/common';
import { User } from './interfaces/user.interface';
import { UserService } from './user.service';
@Controller('user')
export class UserController {
constructor(private userService: UserService) {}
@Post('/login')
async loginUser(
@Body()
user: User,
@Res() res,
) {
const loginRes = await this.userService.loginUser(user);
let smsSent = false;
if (loginRes.success) {
smsSent = await this.userService.sendUserVerificationCode(
loginRes.retrievedUser,
);
}
res.status(HttpStatus.OK).send({
success: loginRes.success && smsSent,
userId: loginRes?.retrievedUser.userId,
});
}
}
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { UserEntity } from './entities/user.entity';
import { User } from './interfaces/user.interface';
import * as bcrypt from 'bcryptjs';
import * as phoneToken from 'generate-sms-verification-code';
import * as moment from 'moment';
import * as twilio from 'twilio';
const accountSid = process.env.TWILIO_ACCOUNT_SID; // Your Account SID from www.twilio.com/console
const authToken = process.env.TWILIO_AUTH_TOKEN; // Your Auth Token from www.twilio.com/console
const client = twilio(accountSid, authToken);
@Injectable()
export class UserService {
constructor(
@InjectRepository(UserEntity)
private userRepository: Repository<UserEntity>,
) {}
async loginUser(user: User) {
const retrievedUser = await this.userRepository.findOne({
where: { username: user.username },
});
if (retrievedUser) {
return {
success: await bcrypt.compare(user.password, retrievedUser.password),
retrievedUser,
};
} else {
return { success: false };
}
}
generateUserVerificationCode() {
return phoneToken(4);
}
async sendSMSToUser(user: User, body: string) {
const smsSent = await client.messages.create({
body,
to: user.phoneNumber,
from: process.env.TWILIO_PHONE_NUMBER,
});
return !!smsSent.sid;
}
async sendUserVerificationCode(user: User) {
const verificationCode = this.generateUserVerificationCode();
await this.userRepository.update(user.userId, {
smsOTP: verificationCode,
otpExpirationDate: moment().add(5, 'm').toDate(),
});
const smsSent = await this.sendSMSToUser(
user,
`Your verification code is: ${verificationCode}`,
);
return smsSent;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment