diff --git a/development/idp-local/config/authsources.php b/development/idp-local/config/authsources.php
index 2fb95e1b..a35db772 100644
--- a/development/idp-local/config/authsources.php
+++ b/development/idp-local/config/authsources.php
@@ -11,7 +11,7 @@
'core:AdminPassword',
],
-
+
// Set up example users for testing expirychecker module.
'example-userpass' => [
'exampleauth:UserPass',
@@ -448,6 +448,13 @@
'last_used_utc' => null,
'data' => [
// Response from "POST /webauthn/login" MFA API call.
+ "id" => 88,
+ "label" => "My Webauthn Key",
+ "last_used_utc" => null,
+ "created_utc" => "2022-12-15 19:42:37",
+ "publicKey" => [
+ "challenge" => "xxxxxxx",
+ ],
],
],
]
diff --git a/features/bootstrap/MfaContext.php b/features/bootstrap/MfaContext.php
index 988f1fb6..664b1590 100644
--- a/features/bootstrap/MfaContext.php
+++ b/features/bootstrap/MfaContext.php
@@ -208,7 +208,7 @@ protected function submitMfaValue($mfaValue)
public function iSubmitACorrectBackupCode()
{
if (! $this->pageContainsElementWithText('h1', 'Printable code')) {
- // find image of the backup code option presented in other_mfas.php
+ // find image of the backup code option presented in other_mfas.twig
$printableCodeOption = $this->session->getPage()->find('css', 'img[src=mfa-backupcode\002Esvg]');
$printableCodeOption->click();
}
diff --git a/modules/material/themes/material/default/other_mfas.twig b/modules/material/themes/material/default/other_mfas.twig
new file mode 100644
index 00000000..f333cddf
--- /dev/null
+++ b/modules/material/themes/material/default/other_mfas.twig
@@ -0,0 +1,27 @@
+{% if otherOptions|length > 0 %}
+
+ {# used type=button to avoid form submission on click since this is just used to display the ul #}
+
+
+
+{% endif %}
diff --git a/modules/material/themes/material/mfa/other_mfas.php b/modules/material/themes/material/mfa/other_mfas.php
deleted file mode 100644
index 7d466a59..00000000
--- a/modules/material/themes/material/mfa/other_mfas.php
+++ /dev/null
@@ -1,34 +0,0 @@
-data['otherOptions'];
-if (count($otherOptions) > 0) {
-?>
-
-
-
-
-
-
diff --git a/modules/material/themes/material/mfa/prompt-for-mfa-backupcode.php b/modules/material/themes/material/mfa/prompt-for-mfa-backupcode.php
deleted file mode 100644
index 7520467a..00000000
--- a/modules/material/themes/material/mfa/prompt-for-mfa-backupcode.php
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
-
- = $this->t('{material:mfa:title}') ?>
-
-
-
-
-
-
-
diff --git a/modules/material/themes/material/mfa/prompt-for-mfa-backupcode.twig b/modules/material/themes/material/mfa/prompt-for-mfa-backupcode.twig
new file mode 100644
index 00000000..a43b1783
--- /dev/null
+++ b/modules/material/themes/material/mfa/prompt-for-mfa-backupcode.twig
@@ -0,0 +1,83 @@
+
+
+
+ {{ '{mfa:title}'|trans }}
+
+ {% include 'header.twig' %}
+
+
+
+
+
diff --git a/modules/material/themes/material/mfa/prompt-for-mfa-manager.php b/modules/material/themes/material/mfa/prompt-for-mfa-manager.php
deleted file mode 100644
index e9899947..00000000
--- a/modules/material/themes/material/mfa/prompt-for-mfa-manager.php
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
- = $this->t('{material:mfa:title}') ?>
-
-
-
-
-
-
-
diff --git a/modules/material/themes/material/mfa/prompt-for-mfa-manager.twig b/modules/material/themes/material/mfa/prompt-for-mfa-manager.twig
new file mode 100644
index 00000000..dfe30757
--- /dev/null
+++ b/modules/material/themes/material/mfa/prompt-for-mfa-manager.twig
@@ -0,0 +1,83 @@
+
+
+
+ {{ '{mfa:title}'|trans }}
+
+ {% include 'header.twig' %}
+
+
+
+
+
diff --git a/modules/material/themes/material/mfa/prompt-for-mfa-totp.php b/modules/material/themes/material/mfa/prompt-for-mfa-totp.php
deleted file mode 100644
index b0d10248..00000000
--- a/modules/material/themes/material/mfa/prompt-for-mfa-totp.php
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-
- = $this->t('{material:mfa:title}') ?>
-
-
-
-
-
-
-
diff --git a/modules/material/themes/material/mfa/prompt-for-mfa-totp.twig b/modules/material/themes/material/mfa/prompt-for-mfa-totp.twig
new file mode 100644
index 00000000..7fd9a92e
--- /dev/null
+++ b/modules/material/themes/material/mfa/prompt-for-mfa-totp.twig
@@ -0,0 +1,81 @@
+
+
+
+ {{ '{mfa:title}'|trans }}
+
+ {% include 'header.twig' %}
+
+
+
+
+
diff --git a/modules/material/themes/material/mfa/prompt-for-mfa-webauthn.php b/modules/material/themes/material/mfa/prompt-for-mfa-webauthn.php
deleted file mode 100644
index 02fa6ff4..00000000
--- a/modules/material/themes/material/mfa/prompt-for-mfa-webauthn.php
+++ /dev/null
@@ -1,153 +0,0 @@
-
-
-
- = $this->t('{material:mfa:title}') ?>
-
-
-
-
-
-
-
-
-data['supportsWebAuthn']; ?>
-
-
-
-
-
diff --git a/modules/material/themes/material/mfa/prompt-for-mfa-webauthn.twig b/modules/material/themes/material/mfa/prompt-for-mfa-webauthn.twig
new file mode 100644
index 00000000..327d5ba1
--- /dev/null
+++ b/modules/material/themes/material/mfa/prompt-for-mfa-webauthn.twig
@@ -0,0 +1,148 @@
+
+
+
+ {{ '{mfa:title}'|trans }}
+
+ {% include 'header.twig' %}
+
+
+
+
+
+
+
+
+
+
diff --git a/modules/mfa/public/prompt-for-mfa.php b/modules/mfa/public/prompt-for-mfa.php
index 53b8bd32..c3a52f96 100644
--- a/modules/mfa/public/prompt-for-mfa.php
+++ b/modules/mfa/public/prompt-for-mfa.php
@@ -53,7 +53,7 @@
'event' => 'MFA ID missing in URL. Choosing one and doing a redirect.',
'employeeId' => $state['employeeId'],
]));
-
+
// Pick an MFA ID and do a redirect to put that into the URL.
$mfaOption = Mfa::getMfaOptionToUse($mfaOptions, $userAgent);
$moduleUrl = SimpleSAML\Module::getModuleURL('mfa/prompt-for-mfa.php', [
@@ -75,7 +75,7 @@
}
$rememberMe = filter_input(INPUT_POST, 'rememberMe') ?? false;
-
+
// NOTE: This will only return if validation fails.
$errorMessage = Mfa::validateMfaSubmission(
$mfaId,
@@ -87,7 +87,7 @@
$mfaOption['type'],
$state['rpOrigin']
);
-
+
$logger->warning(json_encode([
'event' => 'MFA validation result: failed',
'employeeId' => $state['employeeId'],
@@ -122,6 +122,7 @@
$t = new Template($globalConfig, $mfaTemplateToUse);
$t->data['errorMessage'] = $errorMessage ?? null;
$t->data['mfaOption'] = $mfaOption;
+$t->data['mfaOptionData'] = json_encode($mfaOption['data']);
$t->data['mfaOptions'] = $mfaOptions;
$t->data['stateId'] = $stateId;
$t->data['supportsWebAuthn'] = LoginBrowser::supportsWebAuthn($userAgent);
@@ -129,7 +130,8 @@
$t->data['browserJsPath'] = '/module.php/mfa/simplewebauthn/browser.js?v=' . $browserJsHash;
$t->data['managerEmail'] = $state['managerEmail'];
$t->data['otherOptions'] = $otherOptions;
-$t->show();
+$t->data['idpName'] = $globalConfig->getString('idp_display_name');
+$t->send();
$logger->info(json_encode([
'event' => 'Prompted user for MFA',
diff --git a/modules/mfa/src/Auth/Process/Mfa.php b/modules/mfa/src/Auth/Process/Mfa.php
index 8e6415ac..51c2ce60 100644
--- a/modules/mfa/src/Auth/Process/Mfa.php
+++ b/modules/mfa/src/Auth/Process/Mfa.php
@@ -297,10 +297,10 @@ public static function getNumBackupCodesUserHad(array $mfaOptions): int
public static function getTemplateFor(string $mfaType): string
{
$mfaOptionTemplates = [
- 'backupcode' => 'mfa:prompt-for-mfa-backupcode.php',
- 'totp' => 'mfa:prompt-for-mfa-totp.php',
- 'webauthn' => 'mfa:prompt-for-mfa-webauthn.php',
- 'manager' => 'mfa:prompt-for-mfa-manager.php',
+ 'backupcode' => 'mfa:prompt-for-mfa-backupcode',
+ 'totp' => 'mfa:prompt-for-mfa-totp',
+ 'webauthn' => 'mfa:prompt-for-mfa-webauthn',
+ 'manager' => 'mfa:prompt-for-mfa-manager',
];
$template = $mfaOptionTemplates[$mfaType] ?? null;