/* Ċ Ġ* ĠCopyright ĠÂ© Ġ 2 0 2 1 ĠPaul ĠAmb rose Ġ( p amb rose @ mac . com ) Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* ĠĠĠĠĠĠ Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ* Ċ Ġ*/ Ċ Ċ package Ġcom . github . reading bat . posts Ċ Ċ import Ġcom . github . p amb rose . common . util . encode Ċ import Ġcom . github . reading bat . common . Constants . INVALID _ RESET _ ID Ċ import Ġcom . github . reading bat . common . Constants . MSG Ċ import Ġcom . github . reading bat . common . Email er . send Email Ċ import Ġcom . github . reading bat . common . Endpoints . PASSWORD _ RESET _ ENDPOINT Ċ import Ġcom . github . reading bat . common . Form Fields . CONFIRM _ PASSWORD _ PARAM Ċ import Ġcom . github . reading bat . common . Form Fields . EMAIL _ PARAM Ċ import Ġcom . github . reading bat . common . Form Fields . NEW _ PASSWORD _ PARAM Ċ import Ġcom . github . reading bat . common . Form Fields . RESET _ ID _ PARAM Ċ import Ġcom . github . reading bat . common . Form Fields . RETURN _ PARAM Ċ import Ġcom . github . reading bat . common . Message Ċ import Ġcom . github . reading bat . common . Property Ċ import Ġcom . github . reading bat . common . User . Companion . isNot Registered Email Ċ import Ġcom . github . reading bat . common . User . Companion . query User By Email Ċ import Ġcom . github . reading bat . common . isNot Valid User Ċ import Ġcom . github . reading bat . common . isValid User Ċ import Ġcom . github . reading bat . dsl . is Db ms Enabled Ċ import Ġcom . github . reading bat . pages . Password Reset Page . password Reset Page Ċ import Ġcom . github . reading bat . posts . Create Account Post . check Password Ċ import Ġcom . github . reading bat . server . Email Ċ import Ġcom . github . reading bat . server . Email . Companion . getEmail Ċ import Ġcom . github . reading bat . server . Password . Companion . getPassword Ċ import Ġcom . github . reading bat . server . Password Re sets Table Ċ import Ġcom . github . reading bat . server . Pipeline Call Ċ import Ġcom . github . reading bat . server . Redirect Exception Ċ import Ġcom . github . reading bat . server . Reset Id Ċ import Ġcom . github . reading bat . server . Reset Id . Companion . EMPTY _ RESET _ ID Ċ import Ġcom . github . reading bat . server . Reset Id . Companion . get Reset Id Ċ import Ġcom . github . reading bat . server . Reset Id . Companion . new Reset Id Ċ import Ġcom . github . reading bat . server . Server Utils . query Param Ċ import Ġcom . google . common . util . concurrent . Rate Limiter Ċ import Ġcom . p amb rose . common . ex posed . get Ċ import Ġio . ktor . application .* Ċ import Ġio . ktor . features .* Ċ import Ġio . ktor . request .* Ċ import Ġmu . K Logging Ċ import Ġorg . jetbrains . ex posed . sql . select Ċ import Ġorg . jetbrains . ex posed . sql . transactions . transaction Ċ import Ġjava . io . IOException Ċ Ċ internal Ġobject ĠPassword Reset Post Ġ: ĠK Logging () Ġ{ ĊĠ Ġprivate Ġval Ġunknown User Limiter Ġ= ĠRate Limiter . create ( 0 . 5 ) Ġ// Ġrate Ġ 2 . 0 Ġis Ġ" 2 Ġpermit s Ġper Ġsecond " ĊĠ Ġprivate Ġval Ġunable ToSend Ġ= ĠMessage (" Unable Ġto Ġsend Ġpassword Ġreset Ġemail Ġ-- Ġmissing Ġemail Ġaddress ", Ġtrue ) ĊĊĠ Ġsuspend Ġfun ĠPipeline Call . send Password Reset (): ĠString Ġ{ ĊĠĠĠ Ġval Ġemail Ġ= Ġcall . receive Parameters (). getEmail ( EMAIL _ PARAM ) ĊĠĠĠ Ġval Ġremote Str Ġ= Ġcall . request . origin . remote Host ĊĠĠĠ Ġlogger . info Ġ{ Ġ" Password Ġchange Ġrequest Ġfor Ġ$ email Ġ- Ġ$ remote Str " Ġ} ĊĠĠĠ Ġval Ġuser Ġ= Ġquery User By Email ( email ) ĊĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠ Ġuser . isNot Valid User () Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ Ġunknown User Limiter . acquire () ĊĠĠĠĠĠĠĠ Ġpassword Reset Page ( EMPTY _ RESET _ ID , ĠMessage (" Invalid Ġuser : Ġ$ email ", Ġtrue )) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġemail . isBlank () Ġ-> Ġpassword Reset Page ( EMPTY _ RESET _ ID , Ġunable ToSend ) ĊĠĠĠĠĠ Ġemail . isNot Valid Email () Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ Ġpassword Reset Page ( EMPTY _ RESET _ ID , ĠMessage (" Invalid Ġemail Ġaddress : Ġ$ email ", Ġtrue )) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġis Not Registered Email ( email ) Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ Ġunknown User Limiter . acquire () ĊĠĠĠĠĠĠĠ Ġpassword Reset Page ( EMPTY _ RESET _ ID , ĠMessage (" Unknown Ġuser : Ġ$ email ", Ġtrue )) ĊĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġelse Ġ-> Ġ{ ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġval Ġnew Reset Id Ġ= Ġnew Reset Id () ĊĊĠĠĠĠĠĠĠĠĠ Ġ// ĠLookup Ġand Ġremove Ġprevious Ġvalue Ġif Ġit Ġexists ĊĠĠĠĠĠĠĠĠĠ Ġval Ġuser 2 Ġ= Ġquery User By Email ( email ) Ġ?: Ġthrow ĠReset Password Exception (" Unable Ġto Ġfind Ġ$ email ") ĊĠĠĠĠĠĠĠĠĠ Ġ// val Ġprevious Reset Id Ġ= Ġuser 2 . user Password Reset Id () ĊĠĠĠĠĠĠĠĠĠ Ġuser 2 . save Password Reset Id ( email , Ġnew Reset Id ) ĊĊĠĠĠĠĠĠĠĠĠ Ġlogger . info Ġ{ Ġ" Sending Ġpassword Ġreset Ġemail Ġto Ġ$ email Ġ- Ġ$ remote Str " Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmsg Ġ= ĠMessage (""" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ| This Ġis Ġa Ġpassword Ġreset Ġmessage Ġfor Ġthe ĠReading B at . com Ġaccount Ġfor Ġ'$ email ' ĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ| Go Ġto Ġthis ĠURL Ġto Ġset Ġa Ġnew Ġpassword : Ġ${ Property . SEND GRID _ PREFIX . getProperty ("") }$ PASSWORD _ RESET _ ENDPOINT ?$ RESET _ ID _ PARAM =$ new Reset Id ĠĊĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ| If Ġyou Ġdid Ġnot Ġrequest Ġto Ġreset Ġyour Ġpassword , Ġplease Ġignore Ġthis Ġmessage . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ""" . trim Margin ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsend Email ( to Ġ= Ġemail , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfrom Ġ= ĠEmail (" reset @ reading bat . com "), ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsubject Ġ= Ġ" Reading B at Ġpassword Ġreset ", ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmsg Ġ= Ġmsg ) ĊĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠIOException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogger . info ( e ) Ġ{ Ġe . message Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġthrow ĠReset Password Exception (" Unable Ġto Ġsend Ġemail ") ĊĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠ Ġval Ġreturn Path Ġ= Ġquery Param ( RETURN _ PARAM , Ġ"/") ĊĠĠĠĠĠĠĠĠĠ Ġthrow ĠRedirect Exception ("$ return Path ?$ MSG =${ " Password Ġreset Ġemail Ġsent Ġto Ġ$ email ". encode () }") ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠReset Password Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠ Ġlogger . info Ġ{ Ġe Ġ} ĊĠĠĠĠĠĠĠĠĠ Ġval Ġmsg Ġ= ĠMessage (" Unable Ġto Ġsend Ġpassword Ġreset Ġemail Ġto Ġ$ email ", Ġtrue ) ĊĠĠĠĠĠĠĠĠĠ Ġpassword Reset Page ( EMPTY _ RESET _ ID , Ġmsg ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĠ Ġ} ĊĊĠ Ġsuspend Ġfun ĠPipeline Call . update Password (): ĠString Ġ= ĊĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠ Ġval Ġparams Ġ= Ġcall . receive Parameters () ĊĠĠĠĠĠ Ġval Ġreset Id Ġ= Ġparams . get Reset Id ( RESET _ ID _ PARAM ) ĊĠĠĠĠĠ Ġval Ġnew Password Ġ= Ġparams . getPassword ( NEW _ PASSWORD _ PARAM ) ĊĠĠĠĠĠ Ġval Ġconfirm Password Ġ= Ġparams . getPassword ( CONFIRM _ PASSWORD _ PARAM ) ĊĠĠĠĠĠ Ġval Ġpassword Error Ġ= Ġcheck Password ( new Password , Ġconfirm Password ) ĊĊĠĠĠĠĠ Ġif Ġ(! is Db ms Enabled ()) ĊĠĠĠĠĠĠĠ Ġthrow ĠReset Password Exception (" Function Ġunavailable Ġwithout Ġdatabase Ġenabled ") ĊĊĠĠĠĠĠ Ġif Ġ( password Error . isNotBlank ) ĊĠĠĠĠĠĠĠ Ġthrow ĠReset Password Exception ( password Error . value , Ġreset Id ) ĊĊĠĠĠĠĠ Ġval Ġemail Ġ= ĊĠĠĠĠĠĠĠ Ġtransaction Ġ{ ĊĠĠĠĠĠĠĠĠĠ ĠPassword Re sets Table ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. slice ( Password Re sets Table . email ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. select Ġ{ ĠPassword Re sets Table . reset Id Ġeq Ġreset Id . value Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit [ 0 ] Ġas ĠString Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. first OrNull () Ġ?: Ġthrow ĠReset Password Exception ( INVALID _ RESET _ ID ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠ Ġval Ġuser Ġ= Ġquery User By Email ( Email ( email )) Ġ?: Ġthrow ĠReset Password Exception (" Unable Ġto Ġfind Ġ$ email ") ĊĠĠĠĠĠ Ġval Ġsalt Ġ= Ġuser . salt ĊĠĠĠĠĠ Ġval Ġnew Digest Ġ= Ġnew Password . sha 2 5 6 ( salt ) ĊĠĠĠĠĠ Ġval Ġold Digest Ġ= Ġuser . digest ĊĊĠĠĠĠĠ Ġif Ġ(! user . isValid User ()) ĊĠĠĠĠĠĠĠ Ġthrow ĠReset Password Exception (" Invalid Ġuser ", Ġreset Id ) ĊĊĠĠĠĠĠ Ġif Ġ( new Digest Ġ== Ġold Digest ) ĊĠĠĠĠĠĠĠ Ġthrow ĠReset Password Exception (" New Ġpassword Ġis Ġthe Ġsame Ġas Ġthe Ġcurrent Ġpassword ", Ġreset Id ) ĊĊĠĠĠĠĠ Ġuser . assign Digest ( new Digest ) Ġ Ġ// ĠSet Ġnew Ġpassword ĊĊĠĠĠĠĠ Ġthrow ĠRedirect Exception ("/ ?$ MSG =${ " Password Ġreset Ġfor Ġ$ email ". encode () }") ĊĠĠĠ Ġ} Ġcatch Ġ( e : ĠReset Password Exception ) Ġ{ ĊĠĠĠĠĠ Ġlogger . info Ġ{ Ġe Ġ} ĊĠĠĠĠĠ Ġpassword Reset Page ( e . reset Id , ĠMessage ( e . msg )) ĊĠĠĠ Ġ} ĊĊĠ Ġclass ĠReset Password Exception ( val Ġmsg : ĠString , Ġval Ġreset Id : ĠReset Id Ġ= ĠEMPTY _ RESET _ ID ) Ġ: ĠException ( msg ) Ċ }