1
1
import { type Injector } from 'graphql-modules' ;
2
2
import type { Request , Response , NextFunction } from 'express' ;
3
- import validator from 'validator' ;
4
3
import AccountsPassword from '../accounts-password' ;
4
+ import { body , matchedData , param , validationResult } from 'express-validator' ;
5
+
6
+ function matchOrThrow < T extends Record < string , any > = Record < string , any > > (
7
+ ...args : Parameters < typeof matchedData >
8
+ ) : T {
9
+ if ( ! validationResult ( args [ 0 ] ) . isEmpty ( ) ) {
10
+ throw new Error ( 'Validation error' ) ;
11
+ }
12
+ return matchedData ( ...args ) as T ;
13
+ }
5
14
6
15
function getHtml ( title : string , body : string ) {
7
16
return `
@@ -30,62 +39,93 @@ export const infosMiddleware = (req: Request, _res: Response, next: NextFunction
30
39
next ( ) ;
31
40
} ;
32
41
33
- export const verifyEmail =
42
+ export const verifyEmail = [
43
+ param ( 'token' ) . isString ( ) . notEmpty ( ) ,
34
44
( accountsPasswordOrInjector : Injector | AccountsPassword ) =>
35
- async ( req : Request , res : Response ) => {
36
- try {
37
- const { token } = req . params ;
38
- if ( token == null ) {
39
- throw new Error ( 'Token is missing' ) ;
40
- }
41
- const accountsPassword =
42
- accountsPasswordOrInjector instanceof AccountsPassword
43
- ? accountsPasswordOrInjector
44
- : accountsPasswordOrInjector . get ( AccountsPassword ) ;
45
- await accountsPassword . verifyEmail ( token ) ;
46
- res . send (
47
- getHtml (
48
- 'Email successfully verified' ,
49
- `
45
+ async ( req : Request , res : Response ) => {
46
+ try {
47
+ const { token } = matchOrThrow < { token : string } > ( req ) ;
48
+ const accountsPassword =
49
+ accountsPasswordOrInjector instanceof AccountsPassword
50
+ ? accountsPasswordOrInjector
51
+ : accountsPasswordOrInjector . get ( AccountsPassword ) ;
52
+ await accountsPassword . verifyEmail ( token ) ;
53
+ res . send (
54
+ getHtml (
55
+ 'Email successfully verified' ,
56
+ `
50
57
<h3>The email address has been successfully verified.</h3>
51
58
`
52
- )
53
- ) ;
54
- } catch ( err : any ) {
55
- res . send (
56
- //codeql[js/xss-through-exception]
57
- getHtml (
58
- 'Email verification error' ,
59
- `
59
+ )
60
+ ) ;
61
+ } catch ( err : any ) {
62
+ res . send (
63
+ //codeql[js/xss-through-exception]
64
+ getHtml (
65
+ 'Email verification error' ,
66
+ `
60
67
<h3>The email address couldn't be verified: ${ err . message ?? 'unknown error' } </h3>
61
68
`
62
- )
63
- ) ;
64
- }
65
- } ;
69
+ )
70
+ ) ;
71
+ }
72
+ } ,
73
+ ] ;
66
74
67
- export const resetPassword =
75
+ export const resetPassword = [
76
+ body ( 'token' ) . isString ( ) . notEmpty ( ) ,
77
+ body ( 'newPassword' ) . isString ( ) . notEmpty ( ) ,
68
78
( accountsPasswordOrInjector : Injector | AccountsPassword ) =>
69
- async ( req : Request , res : Response ) => {
70
- try {
71
- const { token, newPassword } = req . body ;
72
- if ( token == null ) {
73
- throw new Error ( 'Token is missing' ) ;
74
- }
75
- if ( newPassword == null ) {
76
- throw new Error ( 'New password is missing' ) ;
79
+ async ( req : Request , res : Response ) => {
80
+ try {
81
+ const { token, newPassword } = matchOrThrow < { token : string ; newPassword : string } > ( req ) ;
82
+ const accountsPassword =
83
+ accountsPasswordOrInjector instanceof AccountsPassword
84
+ ? accountsPasswordOrInjector
85
+ : accountsPasswordOrInjector . get ( AccountsPassword ) ;
86
+ await accountsPassword . resetPassword ( token , newPassword , req . infos ) ;
87
+ res . send (
88
+ getHtml (
89
+ 'Password successfully changed' ,
90
+ `
91
+ <h3>The password has been successfully changed.</h3>
92
+ `
93
+ )
94
+ ) ;
95
+ } catch ( err : any ) {
96
+ //codeql[js/xss-through-exception]
97
+ res . send (
98
+ getHtml (
99
+ 'Password reset error' ,
100
+ `
101
+ <h3>The password couldn't be changed: ${ err . message ?? 'unknown error' } </h3>
102
+ `
103
+ )
104
+ ) ;
77
105
}
78
- const accountsPassword =
79
- accountsPasswordOrInjector instanceof AccountsPassword
80
- ? accountsPasswordOrInjector
81
- : accountsPasswordOrInjector . get ( AccountsPassword ) ;
82
- await accountsPassword . resetPassword ( token , newPassword , req . infos ) ;
106
+ } ,
107
+ ] ;
108
+
109
+ export const resetPasswordForm = [
110
+ param ( 'token' ) . isString ( ) . notEmpty ( ) . escape ( ) ,
111
+ ( req : Request , res : Response ) => {
112
+ try {
113
+ const { token } = matchOrThrow < { token : string } > ( req ) ;
83
114
res . send (
84
115
getHtml (
85
- 'Password successfully changed ' ,
116
+ 'Reset password ' ,
86
117
`
87
- <h3>The password has been successfully changed.</h3>
88
- `
118
+ <div class="container">
119
+ <h1>Reset your password</h1>
120
+ <form action="/resetPassword" method="POST">
121
+ <input type="hidden" name="token" value=${ token } />
122
+ <div class="form-group">
123
+ <label for="newPassword">New password</label>
124
+ <input type="text" class="form-control" id="newPassword" value="" placeholder="Enter your new password" name="newPassword">
125
+ </div>
126
+ <button type="submit" class="btn btn-primary">Submit</button>
127
+ </form>
128
+ `
89
129
)
90
130
) ;
91
131
} catch ( err : any ) {
@@ -99,23 +139,5 @@ export const resetPassword =
99
139
)
100
140
) ;
101
141
}
102
- } ;
103
-
104
- export const resetPasswordForm = ( req : Request , res : Response ) : Response =>
105
- res . send (
106
- getHtml (
107
- 'Reset password' ,
108
- `
109
- <div class="container">
110
- <h1>Reset your password</h1>
111
- <form action="/resetPassword" method="POST">
112
- <input type="hidden" name="token" value=${ validator . escape ( req . params . token ) } />
113
- <div class="form-group">
114
- <label for="newPassword">New password</label>
115
- <input type="text" class="form-control" id="newPassword" value="" placeholder="Enter your new password" name="newPassword">
116
- </div>
117
- <button type="submit" class="btn btn-primary">Submit</button>
118
- </form>
119
- `
120
- )
121
- ) ;
142
+ } ,
143
+ ] ;
0 commit comments