114 lines
3.2 KiB
TypeScript
114 lines
3.2 KiB
TypeScript
import AccountRepository from "App/Repositories/User/AccountRepository"
|
|
import Hash from "@ioc:Adonis/Core/Hash"
|
|
import * as jwt from 'jsonwebtoken'
|
|
import DefaultException from "App/Exceptions/DefaultException"
|
|
import moment from 'moment'
|
|
import Base64 from 'base-64'
|
|
import Env from '@ioc:Adonis/Core/Env'
|
|
import Mail from "@ioc:Adonis/Addons/Mail"
|
|
|
|
export default class AuthService {
|
|
accountRepository = new AccountRepository()
|
|
|
|
async login (credentials: any, auth: any, rememberMe: boolean) {
|
|
try {
|
|
const user = await this.accountRepository.findByEmail(credentials.email)
|
|
if (!user || !(await Hash.verify(user.pwd, credentials.password))) {
|
|
throw new DefaultException('Invalid email or password!')
|
|
}
|
|
if (user.is_ban) {
|
|
throw new DefaultException('User banned!')
|
|
}
|
|
await user.load("role");
|
|
return await this.generateToken(auth, user, rememberMe)
|
|
} catch (error) {
|
|
throw error
|
|
}
|
|
}
|
|
|
|
async forgotPassword (credential, request) {
|
|
try {
|
|
const user = await this.accountRepository.findByEmail(credential)
|
|
if (!user) {
|
|
throw new DefaultException('User not found')
|
|
}
|
|
|
|
const token = await this.generateRestorePasswordToken(user)
|
|
const restoreUrlWithToken = request.header('origin') + 'reset-password?token=' + token
|
|
|
|
await this.sendEmailRestorePassword(user.email, restoreUrlWithToken)
|
|
} catch (error) {
|
|
throw error
|
|
}
|
|
}
|
|
|
|
async restorePassword (request) {
|
|
try {
|
|
const { expiresIn, credential } = await this.decryptToken(request.token)
|
|
if (!this.checkExpirationToken(expiresIn)) {
|
|
throw new DefaultException('Token expired')
|
|
}
|
|
|
|
const user = await this.accountRepository.findByEmail(credential)
|
|
await this.accountRepository.update(user.id, {
|
|
pwd: await Hash.make(request.pwd)
|
|
})
|
|
} catch (error) {
|
|
throw error
|
|
}
|
|
}
|
|
|
|
async generateToken(auth: any, user: any, rememberMe: boolean) {
|
|
try {
|
|
const expiresIn = rememberMe ? '7days' : '4hours'
|
|
const token = await auth.use('api').generate(user, {expiresIn})
|
|
const jwtToken = jwt.sign({user}, 'PeSgVkYp3s6v9y$B&E)H@McQfTjWnZq4', {expiresIn: rememberMe ? '7d' : '4h'})
|
|
return { token: token.token, jwtToken }
|
|
} catch (error) {
|
|
throw error
|
|
}
|
|
}
|
|
|
|
async generateRestorePasswordToken (user) {
|
|
try {
|
|
const expiresIn = moment().add(30, 'm')
|
|
const token = Base64.encode(expiresIn + ';' + user.email)
|
|
return token
|
|
} catch (error) {
|
|
throw error
|
|
}
|
|
}
|
|
|
|
async decryptToken (token) {
|
|
try {
|
|
const encrypt = Base64.decode(token).split(';')
|
|
const result = {
|
|
expiresIn: encrypt[0],
|
|
credential: encrypt[1]
|
|
}
|
|
return result
|
|
} catch (error) {
|
|
throw error
|
|
}
|
|
}
|
|
|
|
async sendEmailRestorePassword (email, token) {
|
|
try {
|
|
await Mail.send((message) => {
|
|
message
|
|
.from(Env.get('SMTP_USERNAME'), 'Me')
|
|
.to(email)
|
|
.subject('Restore Password!')
|
|
.htmlView('emails/restore_password', { token })
|
|
})
|
|
} catch (error) {
|
|
throw error
|
|
}
|
|
}
|
|
|
|
checkExpirationToken (expiresIn) {
|
|
return expiresIn > moment()
|
|
}
|
|
|
|
}
|