Skip to content

Commit

Permalink
feature: multiple tokens exposed with comma separated meta content (#174
Browse files Browse the repository at this point in the history
)

closes #44
  • Loading branch information
g105b authored Sep 23, 2022
1 parent 7b02472 commit 30d67a6
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 11 deletions.
25 changes: 14 additions & 11 deletions src/HTMLDocumentProtector.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,17 +52,24 @@ public function protect(
string $tokenSharing = self::ONE_TOKEN_PER_PAGE
):string {
$forms = $this->document->forms;
$tokenArray = [];

if($forms->length > 0) {
$token = $this->tokenStore->generateNewToken();
$this->tokenStore->saveToken($token);
$token = null;

if($forms->length > 0) {
foreach($forms as $form) {
$formMethod = $form->getAttribute("method");
if(strtolower($formMethod) !== "post") {
continue;
}

if($tokenSharing === self::ONE_TOKEN_PER_FORM
|| is_null($token)) {
$token = $this->tokenStore->generateNewToken();
$this->tokenStore->saveToken($token);
array_push($tokenArray, $token);
}

$csrfElement = $this->document->createElement(
"input"
);
Expand All @@ -82,16 +89,13 @@ public function protect(
$csrfElement,
$form->firstChild
);

if($tokenSharing === self::ONE_TOKEN_PER_FORM) {
$token = $this->tokenStore->generateNewToken();
$this->tokenStore->saveToken($token);
}
}
}
else {

if(is_null($token)) {
$token = $this->tokenStore->generateNewToken();
$this->tokenStore->saveToken($token);
array_push($tokenArray, $token);
}

$meta = $this->document->querySelector(
Expand Down Expand Up @@ -123,8 +127,7 @@ public function protect(
$head->appendChild($meta);
}

$meta->setAttribute("content", $token);

$meta->setAttribute("content", implode(",", $tokenArray));
return $token;
}

Expand Down
13 changes: 13 additions & 0 deletions test/phpunit/HTMLDocumentProtectorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,19 @@ public function testProtect_metaTagAlreadyExists():void {
self::assertNotEquals($originalValue, $metaTag->content);
}

public function testProtect_metaTagMultipleForms():void {
$document = new HTMLDocument(self::THREE_FORMS);
$sut = new HTMLDocumentProtector($document, new ArrayTokenStore());
$sut->protect(HTMLDocumentProtector::ONE_TOKEN_PER_FORM);

$nodeList = $document->querySelectorAll("head meta[name='" . HTMLDocumentProtector::TOKEN_NAME . "']");
// There should still only be 1 meta tag...
self::assertCount(1, $nodeList);
// ... but the tag's content should have two values (one per POST form).
$tokenArray = explode(",", $nodeList[0]->content);
self::assertCount(2, $tokenArray);
}

public function testProtect_differentTokenName() {
$sut = new HTMLDocumentProtector(new HTMLDocument(self::HAS_META_ALREADY), new ArrayTokenStore());
$tokenName = HTMLDocumentProtector::TOKEN_NAME;
Expand Down

0 comments on commit 30d67a6

Please sign in to comment.