Skip to content

Commit

Permalink
'.'
Browse files Browse the repository at this point in the history
  • Loading branch information
ManucherKM committed Oct 18, 2023
1 parent eede669 commit 3bd0301
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 168 deletions.
4 changes: 3 additions & 1 deletion src/activation/activation.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
Res,
} from '@nestjs/common'
import { ApiTags } from '@nestjs/swagger'
import env from 'env-var'
import { ActivationService } from './activation.service'

@ApiTags('Activation')
Expand All @@ -17,8 +18,9 @@ export class ActivationController {
@Get(':key')
async activationAccount(@Param('key') key: string, @Res() res) {
try {
const CLIENT_URL = env.get('CLIENT_URL').required().asString()
await this.activationService.activationAccount(key)
res.status(302).redirect(process.env.CLIENT_URL + '/auth/login')
res.status(302).redirect(CLIENT_URL + '/accountConfirm')
return { success: true }
} catch (e) {
throw new HttpException({ message: e.message }, HttpStatus.BAD_REQUEST)
Expand Down
9 changes: 5 additions & 4 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { MailerModule } from '@nestjs-modules/mailer'
import { Module } from '@nestjs/common'
import { ConfigModule } from '@nestjs/config'
import { MongooseModule } from '@nestjs/mongoose'
import env from 'env-var'
import { ActivationModule } from './activation/activation.module'
import { ArchiveModule } from './archive/archive.module'
import { AuthModule } from './auth/auth.module'
Expand All @@ -15,13 +16,13 @@ import { ThemeModule } from './theme/theme.module'
@Module({
imports: [
ConfigModule.forRoot(),
MongooseModule.forRoot(process.env.MONGODB_URL),
MongooseModule.forRoot(env.get('MONGODB_URL').required().asString()),
MailerModule.forRoot({
transport: {
host: process.env.NODEMAILER_SMTP_HOST,
host: env.get('NODEMAILER_SMTP_HOST').required().asString(),
auth: {
user: process.env.NODEMAILER_USER,
pass: process.env.NODEMAILER_PASSWORD,
user: env.get('NODEMAILER_USER').required().asString(),
pass: env.get('NODEMAILER_PASSWORD').required().asString(),
},
},
}),
Expand Down
20 changes: 13 additions & 7 deletions src/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { GoogleUserService } from '@/google-user/google-user.service'
import { JwtService } from '@/jwt/jwt.service'
import { UserService } from '@/user/user.service'
import { getHash } from '@/utils/getHash'
import { getHTMLForConfirmAccount } from '@/utils/getHTMLForConfirmAccount'
import { VkUserService } from '@/vk-user/vk-user.service'
import { MailerService } from '@nestjs-modules/mailer'
import { BadRequestException, Injectable } from '@nestjs/common'
import axios from 'axios'
import { compare } from 'bcrypt'
import env from 'env-var'
import { verify } from 'hcaptcha'
import { v4 } from 'uuid'
import { LoginDto } from './dto/login.dto'
Expand Down Expand Up @@ -207,8 +209,8 @@ export class AuthService {
'https://oauth.vk.com/access_token',
{
params: {
client_id: process.env.VK_CLIENT_ID,
client_secret: process.env.VK_SECRET,
client_id: env.get('VK_CLIENT_ID').required().asString(),
client_secret: env.get('VK_SECRET').required().asString(),
redirect_uri: redirectUri,
code,
},
Expand All @@ -226,18 +228,22 @@ export class AuthService {
email: string,
activationKey: string,
) {
const activationLink =
process.env.API_URL + '/api/activation/' + activationKey
const API_URL = env.get('API_URL').required().asString()
const activationLink = API_URL + '/api/activation/' + activationKey

await this.mailerService.sendMail({
to: email,
from: process.env.NODEMAILER_USER,
from: env.get('NODEMAILER_USER').required().asString(),
subject: 'Cloud-Storage Account Confirmation.',
html: `<a href="${activationLink}">Click on the link.</a>`,
html: getHTMLForConfirmAccount(activationLink),
})
}

private async verifyHcaptcha(token: string) {
const { success } = await verify(process.env.HCAPTCHA_SECRET_KEY, token)
const { success } = await verify(
env.get('HCAPTCHA_SECRET_KEY').required().asString(),
token,
)
return success
}
}
7 changes: 4 additions & 3 deletions src/google-user/google-user.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { BadRequestException, Injectable } from '@nestjs/common'
import { InjectModel } from '@nestjs/mongoose'
import env from 'env-var'
import { google } from 'googleapis'
import { Model } from 'mongoose'
import { CreateGoogleUserDto } from './dto/create-google-user.dto'
Expand All @@ -8,9 +9,9 @@ import { GoogleUser } from './entities/google-user.entity'
@Injectable()
export class GoogleUserService {
private readonly Oauth2Client = new google.auth.OAuth2(
process.env.GOOGLE_CLIENT_ID,
process.env.GOOGLE_CLIENT_SECRET,
process.env.CLIENT_URL,
env.get('GOOGLE_CLIENT_ID').required().asString(),
env.get('GOOGLE_CLIENT_SECRET').required().asString(),
env.get('CLIENT_URL').required().asString(),
)

constructor(
Expand Down
21 changes: 15 additions & 6 deletions src/jwt/jwt.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { EVariantGetData, getDataByToken } from '@/utils/getDataByToken'
import { VkUserService } from '@/vk-user/vk-user.service'
import { BadRequestException, Injectable } from '@nestjs/common'
import { InjectModel } from '@nestjs/mongoose'
import env from 'env-var'
import * as jwt from 'jsonwebtoken'
import { Model } from 'mongoose'
import { CreateJwtDto } from './dto/create-jwt.dto'
Expand Down Expand Up @@ -49,15 +50,23 @@ export class JwtService {
}

getAccessToken(payload: IDataToken) {
return jwt.sign(payload, process.env.JWT_ACCESS_SECRET, {
expiresIn: 30 * 60, // 30m
})
return jwt.sign(
payload,
env.get('JWT_ACCESS_SECRET').required().asString(),
{
expiresIn: 30 * 60, // 30m
},
)
}

private getRefreshToken(payload: IDataToken) {
return jwt.sign(payload, process.env.JWT_REFRESH_SECRET, {
expiresIn: 30 * 24 * 60 * 60, // 30d
})
return jwt.sign(
payload,
env.get('JWT_REFRESH_SECRET').required().asString(),
{
expiresIn: 30 * 24 * 60 * 60, // 30d
},
)
}

async generateRefreshToken(payload: IDataToken) {
Expand Down
31 changes: 1 addition & 30 deletions src/otp/otp.controller.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,7 @@
import {
Body,
Controller,
HttpException,
HttpStatus,
Post,
} from '@nestjs/common'
import { ApiBody, ApiTags } from '@nestjs/swagger'
import { CreateOtpDto } from './dto/create-otp.dto'
import { Controller } from '@nestjs/common'
import { OtpService } from './otp.service'

@ApiTags('OTP')
@Controller('otp')
export class OtpController {
constructor(private readonly otpService: OtpService) {}

@ApiBody({
schema: {
type: 'object',
properties: {
email: {
default: '[email protected]',
},
},
},
})
@Post()
async create(@Body() createOtpDto: CreateOtpDto) {
try {
const otp = await this.otpService.create(createOtpDto)
return otp
} catch (e) {
throw new HttpException({ message: e.message }, HttpStatus.BAD_REQUEST)
}
}
}
6 changes: 4 additions & 2 deletions src/restore-account/restore-account.service.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { JwtService } from '@/jwt/jwt.service'
import { OtpService } from '@/otp/otp.service'
import { UserService } from '@/user/user.service'
import { getHTMLForOTP } from '@/utils/getHTMLForOTP'
import { MailerService } from '@nestjs-modules/mailer'
import { BadRequestException, Injectable } from '@nestjs/common'
import env from 'env-var'
import { CreateRestoreAccountDto } from './dto/create-restore-account.dto'
import { VerificationOtpDto } from './dto/verification-otp.dto'

Expand Down Expand Up @@ -32,9 +34,9 @@ export class RestoreAccountService {
async sendOtpToEmail(otp: number, email: string) {
return await this.mailerService.sendMail({
to: email,
from: process.env.NODEMAILER_USER,
from: env.get('NODEMAILER_USER').required().asString(),
subject: 'Cloud-Storage account restore.',
html: `OTP code: ${otp}`,
html: getHTMLForOTP(otp),
})
}

Expand Down
40 changes: 0 additions & 40 deletions src/user/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,12 @@ import { JwtAuthGuard } from '@/guard/jwt-auth.guard'
import {
Body,
Controller,
Delete,
HttpException,
HttpStatus,
Param,
Patch,
Post,
UseGuards,
} from '@nestjs/common'
import { ApiBearerAuth, ApiBody, ApiTags } from '@nestjs/swagger'
import { CreateUserDto } from './dto/create-user.dto'
import { UpdateUserDto } from './dto/update-user.dto'
import { UserService } from './user.service'

Expand All @@ -21,32 +17,6 @@ import { UserService } from './user.service'
export class UserController {
constructor(private readonly userService: UserService) {}

@ApiBody({
schema: {
type: 'object',
properties: {
email: {
default: '[email protected]',
},
password: {
default: 'Test123!?',
},
activationKey: {
default: 'YOUR_KEY',
},
},
},
})
@Post()
async create(@Body() createUserDto: CreateUserDto) {
try {
const createdUser = await this.userService.create(createUserDto)
return createdUser.toObject()
} catch (e) {
throw new HttpException({ message: e.message }, HttpStatus.BAD_REQUEST)
}
}

@ApiBody({
schema: {
type: 'object',
Expand Down Expand Up @@ -77,14 +47,4 @@ export class UserController {
throw new HttpException({ message: e.message }, HttpStatus.BAD_REQUEST)
}
}

@Delete(':id')
async remove(@Param('id') id: string) {
try {
const deletedUser = await this.userService.remove(id)
return { success: !!deletedUser.deletedCount }
} catch (e) {
throw new HttpException({ message: e.message }, HttpStatus.BAD_REQUEST)
}
}
}
51 changes: 51 additions & 0 deletions src/utils/getHTMLForConfirmAccount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
export function getHTMLForConfirmAccount(activationLink: string) {
return `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Please activate your account</title>
<!--[if mso]><style type="text/css">body, table, td, a { font-family: Arial, Helvetica, sans-serif !important; }</style><![endif]-->
</head>
<body style="font-family: Helvetica, Arial, sans-serif; margin: 0px; padding: 0px; background-color: #ffffff;">
<table role="presentation"
style="width: 100%; border-collapse: collapse; border: 0px; border-spacing: 0px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(36, 37, 38);">
<tbody>
<tr>
<td align="center" style="padding: 1rem 2rem; vertical-align: top; width: 100%;">
<table role="presentation" style="max-width: 600px; border-collapse: collapse; border: 0px; border-spacing: 0px; text-align: left;">
<tbody>
<tr>
<td style="padding: 40px 0px 0px;">
<div style="text-align: center;">
<div style="padding-bottom: 20px;"><img src="https://avatars.githubusercontent.com/u/91463158?v=4" alt="Cloud-storage"
style="width: 56px;"></div>
</div>
<div style="padding: 20px; background-color: rgb(47, 48, 49); border-radius: 12px;">
<div style="color: rgb(235, 237, 240); text-align: left;">
<h1 style="margin: 1rem 0; color: #BC98EA;">Final step...</h1>
<p style="padding-bottom: 16px">Follow this link to verify your email address.</p>
<p style="padding-bottom: 16px"><a href="${activationLink}" target="_blank"
style="padding: 12px 24px; border-radius: 4px; color: #000; background: #BC98EA;display: inline-block;margin: 0.5rem 0; text-decoration: none;">Confirm
now</a></p>
<p style="padding-bottom: 16px">If you didn’t ask to verify this address, you can ignore this email.</p>
<p style="padding-bottom: 16px">Best regards, Cloud-storage team.</p>
</div>
</div>
<div style="padding-top: 20px; color: rgb(115, 115, 115); text-align: center;">
<p style="padding-bottom: 16px">Made with Cloud-storage</p>
</div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</body>
</html>`
}
49 changes: 49 additions & 0 deletions src/utils/getHTMLForOTP.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
export function getHTMLForOTP(otp: number | string) {
return `<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Verify your login</title>
<!--[if mso]><style type="text/css">body, table, td, a { font-family: Arial, Helvetica, sans-serif !important; }</style><![endif]-->
</head>
<body style="font-family: Helvetica, Arial, sans-serif; margin: 0px; padding: 0px; background-color: #ffffff;">
<table role="presentation"
style="width: 100%; border-collapse: collapse; border: 0px; border-spacing: 0px; font-family: Arial, Helvetica, sans-serif; background-color: rgb(36, 37, 38);">
<tbody>
<tr>
<td align="center" style="padding: 1rem 2rem; vertical-align: top; width: 100%;">
<table role="presentation" style="max-width: 600px; border-collapse: collapse; border: 0px; border-spacing: 0px; text-align: left;">
<tbody>
<tr>
<td style="padding: 40px 0px 0px;">
<div style="text-align: center;">
<div style="padding-bottom: 20px;"><img src="https://avatars.githubusercontent.com/u/91463158?v=4" alt="Cloud-storage"
style="width: 56px;"></div>
</div>
<div style="padding: 20px; background-color: rgb(47, 48, 49); border-radius: 12px;">
<div style="color: rgb(235, 237, 240); text-align: left;">
<h1 style="margin: 1rem 0; color: #BC98EA;">Verification code</h1>
<p style="padding-bottom: 16px">Please use the verification code below to sign in.</p>
<p style="padding-bottom: 16px"><strong style="font-size: 130%; color: #BC98EA;">${otp}</strong></p>
<p style="padding-bottom: 16px">If you didn’t request this, you can ignore this email.</p>
<p style="padding-bottom: 16px">Best regards, Cloud-storage team.</p>
</div>
</div>
<div style="padding-top: 20px; color: rgb(115, 115, 115); text-align: center;">
<p style="padding-bottom: 16px">Made with Cloud-storage</p>
</div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</body>
</html>`
}
Loading

0 comments on commit 3bd0301

Please sign in to comment.