#84 added change password end points

parent 1721c38d
export const FRONTEND_URL = 'localhost:3000'
\ No newline at end of file
...@@ -82,12 +82,16 @@ export const taskFinderById = async (taskId:string):Promise<null | Task>=>{ ...@@ -82,12 +82,16 @@ export const taskFinderById = async (taskId:string):Promise<null | Task>=>{
export let transporter = nodemailer.createTransport({ export let transporter = nodemailer.createTransport({
host: "smtp.yandex.ru", service:'Yandex',
port: 465, // host: "smtp.yandex.ru",
secure: true, // true for 465, false for other ports // port: 465,
// secure: true, // true for 465, false for other ports
auth: { auth: {
user: "planner45", // generated ethereal user user: "planner45@yandex.ru", // generated ethereal user
pass: "newPlannerProject123" // generated ethereal password pass: "newPlannerProject123" // generated ethereal password
} }
}) })
\ No newline at end of file
export const FRONTEND_URL = 'localhost:3000'
\ No newline at end of file
...@@ -5,6 +5,7 @@ import { ...@@ -5,6 +5,7 @@ import {
BaseEntity, BaseEntity,
OneToOne, OneToOne,
CreateDateColumn, CreateDateColumn,
JoinColumn,
} from 'typeorm'; } from 'typeorm';
import { User } from './User'; import { User } from './User';
...@@ -23,13 +24,14 @@ import { User } from './User'; ...@@ -23,13 +24,14 @@ import { User } from './User';
@CreateDateColumn({ name: 'created_at', type: Date, default: new Date() }) @CreateDateColumn({ name: 'created_at', type: Date, default: new Date() })
createdAt!: Date; createdAt!: Date;
@Column({ name: 'token', type:String, nullable:false}) @Column({ name: 'token', type: 'varchar',length:100, unique: true, nullable:true })
token!: string; token!: string;
@OneToOne(()=>User, (user:{passwordRecovery:PasswordRecovery})=>user.passwordRecovery) @OneToOne(()=>User,{nullable: false, eager:true})
@JoinColumn()
user!:User; user!:User;
@Column({ name: 'enabled', type:'boolean', default:false}) @Column({ name: 'enabled', type:'boolean', default:true})
enabled!: boolean; enabled!: boolean;
} }
\ No newline at end of file
...@@ -50,7 +50,7 @@ import { DateTimeTask } from './DateTimeTask'; ...@@ -50,7 +50,7 @@ import { DateTimeTask } from './DateTimeTask';
dateTimeDeadLine!: Date; dateTimeDeadLine!: Date;
@Column({ name: 'dateTimeFactDeadLine', type: Date,nullable: true }) @Column({ name: 'dateTimeFactDeadLine', type: Date,nullable: true })
dateTimeFactDeadLine!: Date; dateTimeFactDeadLine!: Date;
@Column({ name: 'archive', type: 'varchar', length:50,nullable: false, default:false }) @Column({ name: 'archive', type: 'boolean',nullable: false, default:false })
archive!: boolean archive!: boolean
@Column({ @Column({
......
...@@ -17,7 +17,7 @@ import {Task} from './Task'; ...@@ -17,7 +17,7 @@ import {Task} from './Task';
import {Member} from './Member'; import {Member} from './Member';
import { PasswordRecovery } from './PasswordRecovery'; import { PasswordRecovery } from './PasswordRecovery';
const SALT_WORK_FACTOR= 10; export const SALT_WORK_FACTOR= 10;
export enum UserRole {USER="user" ,DIRECTOR= "director",SUPERUSER="superuser"} export enum UserRole {USER="user" ,DIRECTOR= "director",SUPERUSER="superuser"}
...@@ -34,7 +34,6 @@ interface IUser { ...@@ -34,7 +34,6 @@ interface IUser {
createdAt: Date; createdAt: Date;
createdTasks:Task[]; createdTasks:Task[];
members: Member[]; members: Member[];
passwordRecovery:PasswordRecovery;
} }
...@@ -84,8 +83,7 @@ export class User extends BaseEntity implements IUser { ...@@ -84,8 +83,7 @@ export class User extends BaseEntity implements IUser {
@OneToMany(() => Member, (member: { user: User }) => member.user) @OneToMany(() => Member, (member: { user: User }) => member.user)
members!: Member[]; members!: Member[];
@OneToOne(()=>PasswordRecovery, (passwordRecovery:{user:User})=>passwordRecovery.user)
passwordRecovery!:PasswordRecovery;
@BeforeInsert() @BeforeInsert()
protected async beforeInserthashPassword():Promise<void> { protected async beforeInserthashPassword():Promise<void> {
......
...@@ -4,7 +4,9 @@ import {myDataSource} from '../app-data-source'; ...@@ -4,7 +4,9 @@ import {myDataSource} from '../app-data-source';
import { nanoid } from 'nanoid'; import { nanoid } from 'nanoid';
import { PasswordRecovery } from '../models/PasswordRecovery'; import { PasswordRecovery } from '../models/PasswordRecovery';
import { transporter } from '../helpers'; import { transporter } from '../helpers';
import {FRONTEND_URL} from "../helpers";
import {SALT_WORK_FACTOR} from "../models/User";
import bcrypt from 'bcrypt';
const router:Router = express.Router(); const router:Router = express.Router();
const dataSource = myDataSource; const dataSource = myDataSource;
...@@ -21,12 +23,12 @@ router.post ('/', async (req:Request, res:Response):Promise<void |Response>=>{ ...@@ -21,12 +23,12 @@ router.post ('/', async (req:Request, res:Response):Promise<void |Response>=>{
}) })
if (!user) return res.status(404).send({message:'user not found'}) if (!user) return res.status(404).send({message:'user not found'})
const token = nanoid(); const token = nanoid();
const url = `${process.env.FRONTEND_URL}/reset-password/${token}`;
try{ try{
const passwordRecovery = await new PasswordRecovery() const passwordRecovery = new PasswordRecovery()
passwordRecovery.user= user passwordRecovery.user= user;
passwordRecovery.token=token passwordRecovery.token=token;
passwordRecovery.save() await passwordRecovery.save()
const url = `${FRONTEND_URL}/reset-password/${token}`;
await transporter.sendMail({ await transporter.sendMail({
from:"planner45@yandex.com", from:"planner45@yandex.com",
to: `${email}`, to: `${email}`,
...@@ -34,27 +36,54 @@ router.post ('/', async (req:Request, res:Response):Promise<void |Response>=>{ ...@@ -34,27 +36,54 @@ router.post ('/', async (req:Request, res:Response):Promise<void |Response>=>{
text:`Вы отправили запрос на восстановление пароля, text:`Вы отправили запрос на восстановление пароля,
перейдите по ссылке плз:{url}`, перейдите по ссылке плз:{url}`,
html:`Вы отправили запрос на восстановление пароля, html:`Вы отправили запрос на восстановление пароля,
перейдите по ссылке плз: <br><a> href="${url} ">${url}</a>`}); перейдите по ссылке плз: <br><a> href="${url}">${url}</a>`});
return res.send({message:'Email succeffuly send'}) return res.send({message:'Email successffuly send'})
} catch (e){ } catch (e){
console.log(e) console.log(e)
res.status(502).send({message:'mail got stuck'}) res.status(502).send({message:'mail got stuck in ', e })
} }
}) })
/**validate token t*/
router.get("/validate", async(req: Request, res: Response):Promise<Response>=>{ /**reset token in password recovery */
router.get('/', async(req: Request, res: Response):Promise<Response|void>=>{
const token = req.query.token; const token = req.query.token;
// if (!token) return res.send({message:'token is not valid'}) if(!token) return res.status(401).send({Message:'token not exists'})
// const passwordRecovery = await dataSource const passwordRecovery = await dataSource
// .getRepository(PasswordRecovery) .createQueryBuilder()
// .findOne({ .from(PasswordRecovery,'passwordRecovery')
// where:{ .select('passwordRecovery')
// token: token .innerJoinAndSelect('passwordRecovery.user', 'user')
// } .where(' passwordRecovery.token=:token',{token})
// }) .getOne()
// if (!passwordRecovery) return res.send({message:'link is not valid'}) if(!passwordRecovery || !passwordRecovery.enabled) return res.status(404).send({message:"Token is not valid"})
return res.send(token); res.send(passwordRecovery)
passwordRecovery.enabled=false;
try{
await passwordRecovery.save();
} catch(e){
console.log(e)
}
}) })
export default router;
\ No newline at end of file /**change password */
router.patch('/:id/change-password', async (req: Request, res: Response):Promise<Response|void>=>{
const user = await dataSource
.getRepository(User)
.findOneBy({id:req.params.id})
if(!user) return res.status(404).send({Message:'user not found'})
const salt = await bcrypt.genSalt(SALT_WORK_FACTOR);
let newPassword:string = await bcrypt.hash(req.body.password, salt);
user.password = newPassword
try{
await user.save()
res.send({message:"Password saved"})
} catch (e){
res.status(502).send({message:"error in saving new psasword"})
}
})
export default router;
\ No newline at end of file
...@@ -5,7 +5,7 @@ import tasks from './routers/tasks'; ...@@ -5,7 +5,7 @@ import tasks from './routers/tasks';
import projects from './routers/projects'; import projects from './routers/projects';
import {myDataSource} from './app-data-source'; import {myDataSource} from './app-data-source';
import copyTasks from './routers/copyTasks'; import copyTasks from './routers/copyTasks';
import passwordRev import passwordRecovery from './routers/passwordRecovery';
myDataSource myDataSource
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment