Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
P
planner-team-one
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
21
Issues
21
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Евгений Положенцев
planner-team-one
Commits
1721c38d
Commit
1721c38d
authored
Dec 01, 2022
by
Евгений Положенцев
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
#84
added server set up
parent
fbf6bc53
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
115 additions
and
5 deletions
+115
-5
.env
.env
+1
-0
package-lock.json
planner-api/package-lock.json
+31
-0
package.json
planner-api/package.json
+2
-0
helpers.ts
planner-api/src/helpers.ts
+16
-1
PasswordRecovery.ts
planner-api/src/models/PasswordRecovery.ts
+3
-3
User.ts
planner-api/src/models/User.ts
+0
-1
passwordRecovery.ts
planner-api/src/routers/passwordRecovery.ts
+60
-0
server.ts
planner-api/src/server.ts
+2
-0
No files found.
.env
0 → 100644
View file @
1721c38d
export const FRONTEND_URL = 'localhost:3000'
\ No newline at end of file
planner-api/package-lock.json
View file @
1721c38d
...
@@ -12,6 +12,7 @@
...
@@ -12,6 +12,7 @@
"@types/bcrypt"
:
"^5.0.0"
,
"@types/bcrypt"
:
"^5.0.0"
,
"@types/cors"
:
"^2.8.12"
,
"@types/cors"
:
"^2.8.12"
,
"@types/express"
:
"^4.17.14"
,
"@types/express"
:
"^4.17.14"
,
"@types/nodemailer"
:
"^6.4.6"
,
"bcrypt"
:
"^5.1.0"
,
"bcrypt"
:
"^5.1.0"
,
"class-transformer"
:
"^0.5.1"
,
"class-transformer"
:
"^0.5.1"
,
"class-validator"
:
"^0.13.2"
,
"class-validator"
:
"^0.13.2"
,
...
@@ -20,6 +21,7 @@
...
@@ -20,6 +21,7 @@
"mongoose"
:
"^6.7.0"
,
"mongoose"
:
"^6.7.0"
,
"multer"
:
"^1.4.5-lts.1"
,
"multer"
:
"^1.4.5-lts.1"
,
"nanoid"
:
"^3.3.4"
,
"nanoid"
:
"^3.3.4"
,
"nodemailer"
:
"^6.8.0"
,
"path"
:
"^0.12.7"
,
"path"
:
"^0.12.7"
,
"pg"
:
"^8.8.0"
,
"pg"
:
"^8.8.0"
,
"reflect-metadata"
:
"^0.1.13"
,
"reflect-metadata"
:
"^0.1.13"
,
...
@@ -1712,6 +1714,14 @@
...
@@ -1712,6 +1714,14 @@
"resolved"
:
"https://registry.npmjs.org/@types/node/-/node-18.11.8.tgz"
,
"resolved"
:
"https://registry.npmjs.org/@types/node/-/node-18.11.8.tgz"
,
"integrity"
:
"sha512-uGwPWlE0Hj972KkHtCDVwZ8O39GmyjfMane1Z3GUBGGnkZ2USDq7SxLpVIiIHpweY9DS0QTDH0Nw7RNBsAAZ5A=="
"integrity"
:
"sha512-uGwPWlE0Hj972KkHtCDVwZ8O39GmyjfMane1Z3GUBGGnkZ2USDq7SxLpVIiIHpweY9DS0QTDH0Nw7RNBsAAZ5A=="
},
},
"node_modules/@types/nodemailer"
:
{
"version"
:
"6.4.6"
,
"resolved"
:
"https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.6.tgz"
,
"integrity"
:
"sha512-pD6fL5GQtUKvD2WnPmg5bC2e8kWCAPDwMPmHe/ohQbW+Dy0EcHgZ2oCSuPlWNqk74LS5BVMig1SymQbFMPPK3w=="
,
"dependencies"
:
{
"@types/node"
:
"*"
}
},
"node_modules/@types/qs"
:
{
"node_modules/@types/qs"
:
{
"version"
:
"6.9.7"
,
"version"
:
"6.9.7"
,
"resolved"
:
"https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz"
,
"resolved"
:
"https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz"
,
...
@@ -4488,6 +4498,14 @@
...
@@ -4488,6 +4498,14 @@
"webidl-conversions"
:
"^3.0.0"
"webidl-conversions"
:
"^3.0.0"
}
}
},
},
"node_modules/nodemailer"
:
{
"version"
:
"6.8.0"
,
"resolved"
:
"https://registry.npmjs.org/nodemailer/-/nodemailer-6.8.0.tgz"
,
"integrity"
:
"sha512-EjYvSmHzekz6VNkNd12aUqAco+bOkRe3Of5jVhltqKhEsjw/y0PYPJfp83+s9Wzh1dspYAkUW/YNQ350NATbSQ=="
,
"engines"
:
{
"node"
:
">=6.0.0"
}
},
"node_modules/nodemon"
:
{
"node_modules/nodemon"
:
{
"version"
:
"2.0.20"
,
"version"
:
"2.0.20"
,
"resolved"
:
"https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz"
,
"resolved"
:
"https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz"
,
...
@@ -7663,6 +7681,14 @@
...
@@ -7663,6 +7681,14 @@
"resolved"
:
"https://registry.npmjs.org/@types/node/-/node-18.11.8.tgz"
,
"resolved"
:
"https://registry.npmjs.org/@types/node/-/node-18.11.8.tgz"
,
"integrity"
:
"sha512-uGwPWlE0Hj972KkHtCDVwZ8O39GmyjfMane1Z3GUBGGnkZ2USDq7SxLpVIiIHpweY9DS0QTDH0Nw7RNBsAAZ5A=="
"integrity"
:
"sha512-uGwPWlE0Hj972KkHtCDVwZ8O39GmyjfMane1Z3GUBGGnkZ2USDq7SxLpVIiIHpweY9DS0QTDH0Nw7RNBsAAZ5A=="
},
},
"@types/nodemailer"
:
{
"version"
:
"6.4.6"
,
"resolved"
:
"https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.6.tgz"
,
"integrity"
:
"sha512-pD6fL5GQtUKvD2WnPmg5bC2e8kWCAPDwMPmHe/ohQbW+Dy0EcHgZ2oCSuPlWNqk74LS5BVMig1SymQbFMPPK3w=="
,
"requires"
:
{
"@types/node"
:
"*"
}
},
"@types/qs"
:
{
"@types/qs"
:
{
"version"
:
"6.9.7"
,
"version"
:
"6.9.7"
,
"resolved"
:
"https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz"
,
"resolved"
:
"https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz"
,
...
@@ -9721,6 +9747,11 @@
...
@@ -9721,6 +9747,11 @@
}
}
}
}
},
},
"nodemailer"
:
{
"version"
:
"6.8.0"
,
"resolved"
:
"https://registry.npmjs.org/nodemailer/-/nodemailer-6.8.0.tgz"
,
"integrity"
:
"sha512-EjYvSmHzekz6VNkNd12aUqAco+bOkRe3Of5jVhltqKhEsjw/y0PYPJfp83+s9Wzh1dspYAkUW/YNQ350NATbSQ=="
},
"nodemon"
:
{
"nodemon"
:
{
"version"
:
"2.0.20"
,
"version"
:
"2.0.20"
,
"resolved"
:
"https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz"
,
"resolved"
:
"https://registry.npmjs.org/nodemon/-/nodemon-2.0.20.tgz"
,
...
...
planner-api/package.json
View file @
1721c38d
...
@@ -29,6 +29,7 @@
...
@@ -29,6 +29,7 @@
"@types/bcrypt"
:
"^5.0.0"
,
"@types/bcrypt"
:
"^5.0.0"
,
"@types/cors"
:
"^2.8.12"
,
"@types/cors"
:
"^2.8.12"
,
"@types/express"
:
"^4.17.14"
,
"@types/express"
:
"^4.17.14"
,
"@types/nodemailer"
:
"^6.4.6"
,
"bcrypt"
:
"^5.1.0"
,
"bcrypt"
:
"^5.1.0"
,
"class-transformer"
:
"^0.5.1"
,
"class-transformer"
:
"^0.5.1"
,
"class-validator"
:
"^0.13.2"
,
"class-validator"
:
"^0.13.2"
,
...
@@ -37,6 +38,7 @@
...
@@ -37,6 +38,7 @@
"mongoose"
:
"^6.7.0"
,
"mongoose"
:
"^6.7.0"
,
"multer"
:
"^1.4.5-lts.1"
,
"multer"
:
"^1.4.5-lts.1"
,
"nanoid"
:
"^3.3.4"
,
"nanoid"
:
"^3.3.4"
,
"nodemailer"
:
"^6.8.0"
,
"path"
:
"^0.12.7"
,
"path"
:
"^0.12.7"
,
"pg"
:
"^8.8.0"
,
"pg"
:
"^8.8.0"
,
"reflect-metadata"
:
"^0.1.13"
,
"reflect-metadata"
:
"^0.1.13"
,
...
...
planner-api/src/helpers.ts
View file @
1721c38d
...
@@ -2,6 +2,8 @@ import express, { NextFunction, Request, Response, Router } from "express";
...
@@ -2,6 +2,8 @@ import express, { NextFunction, Request, Response, Router } from "express";
import
{
myDataSource
}
from
"./app-data-source"
;
import
{
myDataSource
}
from
"./app-data-source"
;
import
{
Task
}
from
"./models/Task"
;
import
{
Task
}
from
"./models/Task"
;
import
{
User
}
from
"./models/User"
;
import
{
User
}
from
"./models/User"
;
import
nodemailer
from
'nodemailer'
;
const
dataSource
=
myDataSource
;
const
dataSource
=
myDataSource
;
...
@@ -76,3 +78,16 @@ export const taskFinderById = async (taskId:string):Promise<null | Task>=>{
...
@@ -76,3 +78,16 @@ export const taskFinderById = async (taskId:string):Promise<null | Task>=>{
})
})
return
task
return
task
}
}
export
let
transporter
=
nodemailer
.
createTransport
({
host
:
"smtp.yandex.ru"
,
port
:
465
,
secure
:
true
,
// true for 465, false for other ports
auth
:
{
user
:
"planner45"
,
// generated ethereal user
pass
:
"newPlannerProject123"
// generated ethereal password
}
})
\ No newline at end of file
planner-api/src/models/PasswordRecovery.ts
View file @
1721c38d
...
@@ -9,10 +9,10 @@ import {
...
@@ -9,10 +9,10 @@ import {
import
{
User
}
from
'./User'
;
import
{
User
}
from
'./User'
;
interface
IPasswordRecovery
{
interface
IPasswordRecovery
{
user
:
User
;
createdAt
:
Date
;
token
:
string
;
token
:
string
;
user
:
User
;
enabled
:
boolean
;
enabled
:
boolean
;
createdAt
:
Date
;
}
}
@
Entity
({
name
:
'PasswordRecovery'
})
@
Entity
({
name
:
'PasswordRecovery'
})
...
@@ -23,7 +23,7 @@ import { User } from './User';
...
@@ -23,7 +23,7 @@ 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
:
String
,
nullable
:
false
})
token
!
:
string
;
token
!
:
string
;
@
OneToOne
(()
=>
User
,
(
user
:{
passwordRecovery
:
PasswordRecovery
})
=>
user
.
passwordRecovery
)
@
OneToOne
(()
=>
User
,
(
user
:{
passwordRecovery
:
PasswordRecovery
})
=>
user
.
passwordRecovery
)
...
...
planner-api/src/models/User.ts
View file @
1721c38d
...
@@ -38,7 +38,6 @@ interface IUser {
...
@@ -38,7 +38,6 @@ interface IUser {
}
}
@
Entity
({
name
:
'User'
})
@
Entity
({
name
:
'User'
})
export
class
User
extends
BaseEntity
implements
IUser
{
export
class
User
extends
BaseEntity
implements
IUser
{
@
PrimaryGeneratedColumn
(
"uuid"
)
@
PrimaryGeneratedColumn
(
"uuid"
)
...
...
planner-api/src/routers/passwordRecovery.ts
0 → 100644
View file @
1721c38d
import
express
,{
Router
,
Request
,
Response
}
from
'express'
;
import
{
User
}
from
'../models/User'
;
import
{
myDataSource
}
from
'../app-data-source'
;
import
{
nanoid
}
from
'nanoid'
;
import
{
PasswordRecovery
}
from
'../models/PasswordRecovery'
;
import
{
transporter
}
from
'../helpers'
;
const
router
:
Router
=
express
.
Router
();
const
dataSource
=
myDataSource
;
/**Make requiest to init recovery process */
router
.
post
(
'/'
,
async
(
req
:
Request
,
res
:
Response
):
Promise
<
void
|
Response
>=>
{
const
{
email
}
=
req
.
body
const
user
=
await
dataSource
.
getRepository
(
User
)
.
findOne
({
where
:{
email
:
email
}
})
if
(
!
user
)
return
res
.
status
(
404
).
send
({
message
:
'user not found'
})
const
token
=
nanoid
();
const
url
=
`
${
process
.
env
.
FRONTEND_URL
}
/reset-password/
${
token
}
`
;
try
{
const
passwordRecovery
=
await
new
PasswordRecovery
()
passwordRecovery
.
user
=
user
passwordRecovery
.
token
=
token
passwordRecovery
.
save
()
await
transporter
.
sendMail
({
from
:
"planner45@yandex.com"
,
to
:
`
${
email
}
`
,
subject
:
"Запрос на восстановление пароля"
,
text
:
`Вы отправили запрос на восстановление пароля,
перейдите по ссылке плз:{url}`
,
html
:
`Вы отправили запрос на восстановление пароля,
перейдите по ссылке плз: <br><a> href="
${
url
}
">
${
url
}
</a>`
});
return
res
.
send
({
message
:
'Email succeffuly send'
})
}
catch
(
e
){
console
.
log
(
e
)
res
.
status
(
502
).
send
({
message
:
'mail got stuck'
})
}
})
/**validate token t*/
router
.
get
(
"/validate"
,
async
(
req
:
Request
,
res
:
Response
):
Promise
<
Response
>=>
{
const
token
=
req
.
query
.
token
;
// if (!token) return res.send({message:'token is not valid'})
// const passwordRecovery = await dataSource
// .getRepository(PasswordRecovery)
// .findOne({
// where:{
// token: token
// }
// })
// if (!passwordRecovery) return res.send({message:'link is not valid'})
return
res
.
send
(
token
);
})
export
default
router
;
\ No newline at end of file
planner-api/src/server.ts
View file @
1721c38d
...
@@ -5,6 +5,7 @@ import tasks from './routers/tasks';
...
@@ -5,6 +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
myDataSource
myDataSource
...
@@ -25,6 +26,7 @@ app.use('/users',users)
...
@@ -25,6 +26,7 @@ app.use('/users',users)
app
.
use
(
'/tasks'
,
tasks
)
app
.
use
(
'/tasks'
,
tasks
)
app
.
use
(
'/copy-tasks'
,
copyTasks
)
app
.
use
(
'/copy-tasks'
,
copyTasks
)
app
.
use
(
'/projects'
,
projects
)
app
.
use
(
'/projects'
,
projects
)
app
.
use
(
'/password-recovery'
,
passwordRecovery
)
const
run
=
async
()
=>
{
const
run
=
async
()
=>
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment