diff --git a/app/components/auth/signUp.scheme.ts b/app/components/auth/signUp.scheme.ts
index 6227695..ffc2ee7 100644
--- a/app/components/auth/signUp.scheme.ts
+++ b/app/components/auth/signUp.scheme.ts
@@ -34,12 +34,8 @@ export const signUpScheme: FastifySchema = {
export const signUpConfirmScheme: FastifySchema = {
- params: {
- type: 'object',
- required: ['code'],
- properties: {
- code: {type: 'string'}
- },
+ querystring: {
+ code: {type: 'string'}
},
response: {
200: {
diff --git a/app/components/auth/signUp.ts b/app/components/auth/signUp.ts
index 6028302..b1ebcab 100644
--- a/app/components/auth/signUp.ts
+++ b/app/components/auth/signUp.ts
@@ -5,6 +5,7 @@ import {createTransport} from 'nodemailer';
import {SMTPOpt} from '@/assist/mail';
import {randomBytes} from 'crypto';
import {env} from '@/envConfig';
+import * as crypto from 'crypto';
interface IBody {
email: string
@@ -24,13 +25,15 @@ export const signUp = async (server: FastifyInstance) => {
if (rowCount) {
const transporter = createTransport(SMTPOpt);
- const link = `http://${env.nodeEnv === 'dev' ? 'localhost:3000' : '51.15.71.195'}/confirm-email/` + linkCode;
+ const link = `http://${env.nodeEnv === 'development' ? 'localhost:3000' : '51.15.71.195'}/signup/confirm/?code=${linkCode}`;
const mailOptions = {
to: email,
subject: 'Confirmation of registration',
html: `
Hello.
Please click on the link to confirm your registration.
`
};
+
const sent = await transporter.sendMail(mailOptions);
+
if (sent) {
return reply.status(201).send('An email has been sent to your email address');
} else {
@@ -43,17 +46,17 @@ export const signUp = async (server: FastifyInstance) => {
);
};
-interface IParams {
+interface IQuerystring {
code: string
}
export const signUpConfirm = async (server: FastifyInstance) => {
- server.get<{Params: IParams}>(
- '/confirm-email/:code',
+ server.get<{Querystring: IQuerystring}>(
+ '/signup/confirm/',
{schema: signUpConfirmScheme},
async (req, reply) => {
- const {code} = req.params;
- const {rowCount} = await server.pg.query('UPDATE root.users SET confirmed = true, code = NULL WHERE code = $1 AND confirmed = false', [code]);
+ const {code} = req.query;
+ const {rowCount} = await server.pg.query('UPDATE root.users SET confirmed = true, code = NULL WHERE code = $1 AND confirmed = false', [code]);
if (rowCount) {
reply.type('text/html').send('Registration has been successfully confirmed!
');
} else {
diff --git a/app/components/users/passRecovery.scheme.ts b/app/components/users/passRecovery.scheme.ts
index 4d749a2..4d3dc8e 100644
--- a/app/components/users/passRecovery.scheme.ts
+++ b/app/components/users/passRecovery.scheme.ts
@@ -1,39 +1,51 @@
import {FastifySchema} from 'fastify';
import {emailRegex, passRegex} from '@/validation/regex';
-export const passRecoveryScheme: FastifySchema = {
+export const passResetScheme: FastifySchema = {
body: {
type: 'object',
- oneOf: [
- {
- required: ['email'],
- properties: {
- email: {
- type: 'string',
- pattern: emailRegex,
- },
- },
+ required: ['email'],
+ properties: {
+ email: {
+ type: 'string',
+ pattern: emailRegex,
},
- {
- required: ['code', 'password', 'confirmPassword'],
- properties: {
- email: {
- type: 'string',
- pattern: emailRegex,
- },
- password: {
- type: 'string',
- pattern: passRegex,
- },
- confirmPassword: {
- type: 'string',
- const: {
- $data: '1/password'
- }
- },
- },
+ },
+ },
+ response: {
+ 200: {
+ type: 'string',
+ },
+ 500: {
+ type: 'string',
+ },
+ },
+};
+
+
+export const usersPasswordScheme: FastifySchema = {
+ body: {
+ type: 'object',
+ required: ['email', 'code', 'password', 'confirmPassword'],
+ properties: {
+ email: {
+ type: 'string',
+ pattern: emailRegex,
+ },
+ code: {
+ type: 'string',
},
- ]
+ password: {
+ type: 'string',
+ pattern: passRegex,
+ },
+ confirmPassword: {
+ type: 'string',
+ const: {
+ $data: '1/password'
+ }
+ },
+ },
},
response: {
200: {
@@ -45,3 +57,5 @@ export const passRecoveryScheme: FastifySchema = {
},
};
+
+
diff --git a/app/components/users/passRecovery.ts b/app/components/users/passRecovery.ts
index f0a370f..e7801aa 100644
--- a/app/components/users/passRecovery.ts
+++ b/app/components/users/passRecovery.ts
@@ -1,55 +1,61 @@
import {FastifyInstance} from 'fastify';
import {randomBytes} from 'crypto';
-import {passRecoveryScheme} from '@/components/users/passRecovery.scheme';
+import {passResetScheme, usersPasswordScheme} from '@/components/users/passRecovery.scheme'
import {createTransport} from 'nodemailer';
import {SMTPOpt} from '@/assist/mail';
import {sha256} from '@/components/auth/assistant';
-interface IBody {
- email?: string,
- code?: string,
- password?: string,
- confirmPassword?: string
+interface IBodyPassReset {
+ email: string,
+}
+interface IBodyUsersPassword {
+ email: string,
+ code: string,
+ password: string,
+ confirmPassword: string
}
export const passRecovery = async (server: FastifyInstance) => {
- server.patch<{Body: IBody}>(
- '/users/password-recovery',
- {schema: passRecoveryScheme},
+ server.patch<{Body: IBodyPassReset}>(
+ '/password-reset',
+ {schema: passResetScheme},
async (req, reply) => {
- const {email, code, password, confirmPassword} = req.body;
+ const {email} = req.body;
- if (email) {
- const recoveryCode = randomBytes(48).toString('hex').substring(0, 63);
- const {rowCount} = await server.pg.query('UPDATE root.users SET code = $1 WHERE email = $2', [recoveryCode, email]);
+ const recoveryCode = Math.floor(Math.random() * 10000000).toString();
+ const {rowCount} = await server.pg.query('UPDATE root.users SET code = $1 WHERE email = $2', [recoveryCode, email]);
- if (rowCount) {
- const transporter = createTransport(SMTPOpt);
- const mailOptions = {
- to: email,
- subject: 'Password recovery',
- html: `Your recovery code:
${recoveryCode}
Please copy it to the app
`
- };
- const sent = await transporter.sendMail(mailOptions);
+ if (rowCount) {
+ const transporter = createTransport(SMTPOpt);
+ const mailOptions = {
+ to: email,
+ subject: 'Password recovery',
+ html: `Your recovery code: ${recoveryCode}
Please copy it to the app
`
+ };
+ const sent = await transporter.sendMail(mailOptions);
- if (sent) {
- return reply.status(200).send('An email has been sent to your email address');
- } else {
- return reply.status(500).send('Couldn\'t send email.');
- }
+ if (sent) {
+ return reply.status(200).send('An email has been sent to your email address');
} else {
- return reply.status(500).send('Failed to write to the database');
+ return reply.status(500).send('Couldn\'t send email.');
}
+ } else {
+ return reply.status(500).send('Failed to write to the database');
}
+ });
+
+ server.patch<{Body: IBodyUsersPassword}>(
+ '/users/password',
+ {schema: usersPasswordScheme},
+ async (req, reply) => {
+ const {email, code, password} = req.body;
- if (code && password && confirmPassword) {
- const hash = sha256(password);
- const {rowCount} = await server.pg.query('UPDATE root.users SET code = NULL, password_hash = $1 WHERE code = $2', [hash, code]);
+ const hash = sha256(password);
+ const {rowCount} = await server.pg.query('UPDATE root.users SET code = NULL, password_hash = $1 WHERE code = $2 AND email=$3', [hash, code, email]);
- if (rowCount) {
- return reply.send('You have successfully changed your password!');
- } else {
- return reply.status(500).send('Something went wrong. Check the code');
- }
+ if (rowCount) {
+ return reply.send('You have successfully changed your password!');
+ } else {
+ return reply.status(500).send('Something went wrong. Check the code');
}
});
};
diff --git a/app/envConfig.ts b/app/envConfig.ts
index f402aee..ff1965e 100644
--- a/app/envConfig.ts
+++ b/app/envConfig.ts
@@ -20,5 +20,5 @@ export const env:TEnv = {
mailClientId: process.env.MAIL_OAUTH_CLIENTID as string,
mailClientSecret: process.env.MAIL_OAUTH_CLIENT_SECRET as string,
mailRefreshToken: process.env.MAIL_OAUTH_REFRESH_TOKEN as string,
- mailAccessToken: process.env.MAIL_OAUTH_ACCESS_TOKEN as string
+ mailAccessToken: process.env.MAIL_OAUTH_ACCESS_TOKEN as string,
};
diff --git a/package.json b/package.json
index 904e1bb..dd050ef 100644
--- a/package.json
+++ b/package.json
@@ -6,7 +6,8 @@
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node -r dotenv/config dist/app.js",
- "build": "webpack && ts-node dev-helpers/create-package.ts",
+ "build:dev": "webpack --mode=development && ts-node dev-helpers/create-package.ts",
+ "build:prod": "webpack --mode=production && ts-node dev-helpers/create-package.ts",
"lint": "eslint .",
"lint:fix": "eslint --fix --ext .ts, app/app.ts",
"prepare": "husky install"
diff --git a/webpack.config.ts b/webpack.config.ts
index b2acec2..75e98ba 100644
--- a/webpack.config.ts
+++ b/webpack.config.ts
@@ -5,7 +5,6 @@ import {externals} from './dev-helpers/dependencies';
export default {
target: 'node',
- mode: 'production',
entry: resolve('app/app.ts'),
output: {
path: resolve('dist'),