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