77use Derhansen \FormCrshield \Service \ChallengeResponseService ;
88use Psr \Http \Message \ServerRequestInterface ;
99use Psr \Log \LoggerInterface ;
10+ use TYPO3 \CMS \Core \Attribute \AsEventListener ;
1011use TYPO3 \CMS \Core \Configuration \ExtensionConfiguration ;
1112use TYPO3 \CMS \Core \Context \Context ;
1213use TYPO3 \CMS \Core \Http \ApplicationType ;
1314use TYPO3 \CMS \Core \Utility \GeneralUtility ;
1415use TYPO3 \CMS \Extbase \Validation \Validator \NotEmptyValidator ;
1516use TYPO3 \CMS \Form \Domain \Model \FormElements \Page ;
1617use TYPO3 \CMS \Form \Domain \Runtime \FormRuntime ;
18+ use TYPO3 \CMS \Form \Event \AfterCurrentPageIsResolvedEvent ;
19+ use TYPO3 \CMS \Form \Event \BeforeRenderableIsValidatedEvent ;
1720use TYPO3 \CMS \Frontend \Cache \CacheLifetimeCalculator ;
1821use TYPO3 \CMS \Frontend \Page \PageInformation ;
1922
@@ -22,7 +25,6 @@ class Form
2225 private const FIELD_ID = 'cr-field ' ;
2326
2427 private int $ currentTimestamp ;
25- private int $ cacheTimeOutDefault = 86400 ;
2628 private array $ settings ;
2729
2830 public function __construct (
@@ -34,65 +36,63 @@ public function __construct(
3436 $ this ->settings = GeneralUtility::makeInstance (ExtensionConfiguration::class)->get ('form_crshield ' );
3537 }
3638
37- public function afterInitializeCurrentPage (FormRuntime $ runtime , ?Page $ currentPage , ?Page $ page , array $ args ): ?Page
39+ #[AsEventListener('derhansen/form_crshield/form/after-initialize-current-page ' )]
40+ public function afterInitializeCurrentPage (AfterCurrentPageIsResolvedEvent $ event ): void
3841 {
3942 // If the form is in preview mode or we are in backend context, do not add the cr-field
40- if (($ runtime ->getFormDefinition ()->getRenderingOptions ()['previewMode ' ] ?? false ) ||
41- ApplicationType::fromRequest ($ GLOBALS [ ' TYPO3_REQUEST ' ] )->isBackend ()
43+ if (($ event -> formRuntime ->getFormDefinition ()->getRenderingOptions ()['previewMode ' ] ?? false ) ||
44+ ApplicationType::fromRequest ($ event -> request )->isBackend ()
4245 ) {
43- return $ currentPage ;
46+ return ;
4447 }
4548
46- $ pageObject = $ currentPage ?? $ page ;
49+ $ pageObject = $ event -> currentPage ?? $ event -> lastDisplayedPage ;
4750
48- if ($ pageObject && !$ this ->crFieldHasBeenVerified ($ runtime )) {
51+ if ($ pageObject && !$ this ->crFieldHasBeenVerified ($ event -> formRuntime )) {
4952 // Set delay for initial form (no delay for re-submission of form)
50- $ delay = $ runtime ->getFormSession () === null ? (int )($ this ->settings ['crJavaScriptDelay ' ] ?? 3 ) : 0 ;
53+ $ delay = $ event -> formRuntime ->getFormSession () === null ? (int )($ this ->settings ['crJavaScriptDelay ' ] ?? 3 ) : 0 ;
5154 $ challenge = $ this ->challengeResponseService ->getChallenge (
5255 (string )($ this ->settings ['obfuscationMethod ' ] ?? '1 ' ),
53- $ this ->getPageExpirationTime ($ runtime ),
56+ $ this ->getPageExpirationTime ($ event -> formRuntime ),
5457 $ delay ,
55- $ this ->getHmacSalt ($ runtime )
58+ $ this ->getHmacSalt ($ event -> formRuntime )
5659 );
5760
5861 $ newElement = $ pageObject ->createElement (self ::FIELD_ID , 'Hidden ' );
5962 $ newElement ->addValidator (new NotEmptyValidator ());
6063 $ newElement ->setDefaultValue (base64_encode ($ challenge ));
6164 $ newElement ->setProperty ('fluidAdditionalAttributes ' , ['autocomplete ' => 'off ' ]);
6265 }
63-
64- return $ currentPage ;
6566 }
6667
67- public function afterSubmit (FormRuntime $ runtime , $ element , $ value , $ requestArguments )
68+ #[AsEventListener('derhansen/form_crshield/form/after-submit ' )]
69+ public function afterSubmit (BeforeRenderableIsValidatedEvent $ event ): void
6870 {
71+ $ requestArguments = $ event ->request ->getArguments ();
72+
6973 // Write all POST data for the current page to debug log
70- if (is_a ($ element , Page::class)) {
74+ if (is_a ($ event -> renderable , Page::class)) {
7175 $ this ->logger ->debug ('Submitted data ' , $ requestArguments );
7276 }
7377
74- if (!(is_a ($ element , Page::class) || $ element ->getIdentifier () === self ::FIELD_ID )) {
75- return $ value ;
78+ if (!(is_a ($ event -> renderable , Page::class) || $ event -> renderable ->getIdentifier () === self ::FIELD_ID )) {
79+ return ;
7680 }
7781
7882 $ submittedResponse = $ requestArguments [self ::FIELD_ID ] ?? '' ;
79- if (!$ this ->challengeResponseService ->isValidResponse ($ submittedResponse , $ this ->getHmacSalt ($ runtime ), ' 1 ' )) {
83+ if (!$ this ->challengeResponseService ->isValidResponse ($ submittedResponse , $ this ->getHmacSalt ($ event -> formRuntime ) )) {
8084 $ this ->logger ->debug ('CR response validation failed ' , $ requestArguments );
81- return '' ;
85+ $ event ->value = '' ;
86+ return ;
8287 }
8388
8489 // Save sha1 of HmacSalt to formstate for cr-field
85- if ($ runtime ->getFormState ()) {
86- $ runtime ->getFormState ()->setFormValue (self ::FIELD_ID , sha1 ($ this ->getHmacSalt ($ runtime )));
87- }
88-
89- return $ value ;
90+ $ event ->formRuntime ->getFormState ()?->setFormValue(self ::FIELD_ID , sha1 ($ this ->getHmacSalt ($ event ->formRuntime )));
9091 }
9192
9293 protected function crFieldHasBeenVerified (FormRuntime $ runtime ): bool
9394 {
94- return $ runtime ->getFormState () &&
95- $ runtime ->getFormState ()->getFormValue (self ::FIELD_ID ) === sha1 ($ this ->getHmacSalt ($ runtime ));
95+ return $ runtime ->getFormState ()?->getFormValue(self ::FIELD_ID ) === sha1 ($ this ->getHmacSalt ($ runtime ));
9696 }
9797
9898 protected function getPageExpirationTime (FormRuntime $ runtime ): int
@@ -122,7 +122,6 @@ protected function getCacheTimeout(ServerRequestInterface $request): int
122122 $ pageInformation ->getId (),
123123 $ pageInformation ->getPageRecord (),
124124 $ typoScriptConfigArray ,
125- $ this ->cacheTimeOutDefault ,
126125 $ this ->context
127126 );
128127 }
0 commit comments