11import { type Injector } from 'graphql-modules' ;
22import type { Request , Response , NextFunction } from 'express' ;
3- import validator from 'validator' ;
43import 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+ }
514
615function getHtml ( title : string , body : string ) {
716 return `
@@ -30,62 +39,93 @@ export const infosMiddleware = (req: Request, _res: Response, next: NextFunction
3039 next ( ) ;
3140} ;
3241
33- export const verifyEmail =
42+ export const verifyEmail = [
43+ param ( 'token' ) . isString ( ) . notEmpty ( ) ,
3444 ( 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+ `
5057 <h3>The email address has been successfully verified.</h3>
5158 `
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+ `
6067 <h3>The email address couldn't be verified: ${ err . message ?? 'unknown error' } </h3>
6168 `
62- )
63- ) ;
64- }
65- } ;
69+ )
70+ ) ;
71+ }
72+ } ,
73+ ] ;
6674
67- export const resetPassword =
75+ export const resetPassword = [
76+ body ( 'token' ) . isString ( ) . notEmpty ( ) ,
77+ body ( 'newPassword' ) . isString ( ) . notEmpty ( ) ,
6878 ( 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+ ) ;
77105 }
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 ) ;
83114 res . send (
84115 getHtml (
85- 'Password successfully changed ' ,
116+ 'Reset password ' ,
86117 `
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+ `
89129 )
90130 ) ;
91131 } catch ( err : any ) {
@@ -99,23 +139,5 @@ export const resetPassword =
99139 )
100140 ) ;
101141 }
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