|
| 1 | +<?php declare(strict_types=1); |
| 2 | + |
| 3 | +use SimpleSAML\Module; |
| 4 | + |
| 5 | +$this->data['u2fAvailable'] = !empty($this->data['u2fSignRequest']); |
| 6 | +$this->data['webauthnAvailable'] = !empty($this->data['webAuthnSignRequest']); |
| 7 | +$this->data['pushAvailable'] = $this->data['pushAvailable'] ?? false; |
| 8 | + |
| 9 | +$this->data['mode'] = ($this->data['mode'] ?? null) ?: 'otp'; |
| 10 | +$this->data['noAlternatives'] = true; |
| 11 | +foreach (['webauthn', 'otp', 'push', 'u2f'] as $mode) { |
| 12 | + if ($mode !== $this->data['mode'] && $this->data[$mode . 'Available']) { |
| 13 | + $this->data['noAlternatives'] = false; |
| 14 | + break; |
| 15 | + } |
| 16 | +} |
| 17 | + |
| 18 | +// Set default scenario if isn't set |
| 19 | +if (!empty($this->data['authProcFilterScenario'])) { |
| 20 | + if (empty($this->data['username'])) { |
| 21 | + $this->data['username'] = ''; |
| 22 | + } |
| 23 | +} else { |
| 24 | + $this->data['authProcFilterScenario'] = 0; |
| 25 | +} |
| 26 | + |
| 27 | +// Set the right text shown in otp/pass field(s) |
| 28 | +$otpHint = $this->data['otpFieldHint'] ?? $this->t('{privacyidea:privacyidea:otp}'); |
| 29 | +$passHint = $this->data['passFieldHint'] ?? $this->t('{privacyidea:privacyidea:password}'); |
| 30 | + |
| 31 | +$this->data['header'] = $this->t('{privacyidea:privacyidea:login_title_challenge}'); |
| 32 | + |
| 33 | +// Prepare next settings |
| 34 | +if (!empty($this->data['username'])) { |
| 35 | + $this->data['autofocus'] = 'password'; |
| 36 | +} else { |
| 37 | + $this->data['autofocus'] = 'username'; |
| 38 | +} |
| 39 | + |
| 40 | +$this->data['head'] .= '<link rel="stylesheet" href="' |
| 41 | + . htmlspecialchars(Module::getModuleUrl('privacyidea/css/loginform.css'), ENT_QUOTES) |
| 42 | + . '" media="screen" />'; |
| 43 | + |
| 44 | +$this->includeAtTemplateBase('includes/header.php'); |
| 45 | + |
| 46 | +// Prepare error case to show it in UI if needed |
| 47 | +if (null !== $this->data['errorCode']) { |
| 48 | + ?> |
| 49 | + <div class="alert alert-dismissable alert-danger" role="alert"> |
| 50 | + <button type="button" class="close" data-dismiss="alert" aria-label="Close"> |
| 51 | + <span aria-hidden="true">×</span> |
| 52 | + </button> |
| 53 | + <h2 class="alert-heading"><?php echo $this->t('{login:error_header}'); ?></h2> |
| 54 | + <p> |
| 55 | + <?php |
| 56 | + echo htmlspecialchars( |
| 57 | + sprintf('%s%s: %s', $this->t( |
| 58 | + '{privacyidea:privacyidea:error}' |
| 59 | + ), $this->data['errorCode'] ? (' ' . $this->data['errorCode']) : '', $this->data['errorMessage']) |
| 60 | + ); ?> |
| 61 | + </p> |
| 62 | + </div> |
| 63 | + |
| 64 | + <?php |
| 65 | +} // end of errorcode |
| 66 | +?> |
| 67 | +<p><?php echo $this->t('{perun:privacyidea:info_text}'); ?></p> |
| 68 | +<form action="FormReceiver.php" method="POST" id="piLoginForm" name="piLoginForm" class="loginForm"> |
| 69 | + <div class="row"> |
| 70 | + <?php if ($this->data['webauthnAvailable']) { ?> |
| 71 | + <div class="<?php echo (!$this->data['noAlternatives']) ? 'col-md-6' : 'col-sm-12'; ?>"> |
| 72 | + <h2><?php echo $this->t('{perun:privacyidea:webauthn}'); ?></h2> |
| 73 | + <div> |
| 74 | + <button id="useWebAuthnButton" name="useWebAuthnButton" class="btn btn-primary btn-block text-nowrap" type="button"><?php echo $this->t('{perun:privacyidea:webauthn_btn}'); ?></button> |
| 75 | + </div> |
| 76 | + <div id="message" role="alert"> |
| 77 | + <?php |
| 78 | + $messageOverride = $this->data['messageOverride'] ?? null; |
| 79 | + if (null === $messageOverride || is_string($messageOverride)) { |
| 80 | + echo htmlspecialchars($messageOverride ?? $this->data['message'] ?? '', ENT_QUOTES); |
| 81 | + } elseif (is_callable($messageOverride)) { |
| 82 | + echo call_user_func($messageOverride, $this->data['message'] ?? ''); |
| 83 | + } |
| 84 | + ?> |
| 85 | + </div> |
| 86 | + </div> |
| 87 | + <?php } ?> |
| 88 | + |
| 89 | + <?php if ($this->data['otpAvailable'] ?? true) { ?> |
| 90 | + <div class="<?php echo (!$this->data['noAlternatives']) ? 'col-md-6' : 'col-sm-12'; ?>"> |
| 91 | + <h2><?php echo $this->t('{privacyidea:privacyidea:otp}'); ?></h2> |
| 92 | + <p><?php echo $this->t('{perun:privacyidea:otp_help}'); ?></p> |
| 93 | + <div class="form-row"> |
| 94 | + <div class="form-group col-sm-12 <?php echo (!$this->data['noAlternatives']) ? '' : 'col-md-6'; ?>"> |
| 95 | + <label for="otp" class="sr-only"><?php echo $this->t('{perun:privacyidea:otp}'); ?></label> |
| 96 | + <input id="otp" name="otp" tabindex="1" value="" class="form-control" autocomplete="one-time-code" type="text" inputmode="numeric" pattern="[0-9]{6,}" required placeholder="<?php echo htmlspecialchars($otpHint, ENT_QUOTES); ?>"/> |
| 97 | + </div> |
| 98 | + <div class="form-group col-sm-12 <?php echo (!$this->data['noAlternatives']) ? '' : 'col-md-6'; ?>"> |
| 99 | + <button id="submitButton" tabindex="1" class="btn btn-primary btn-block text-nowrap" type="submit" name="Submit"><?php echo htmlspecialchars($this->t('{perun:privacyidea:otp_submit_btn}'), ENT_QUOTES); ?></button> |
| 100 | + </div> |
| 101 | + </div> |
| 102 | + </div> |
| 103 | + <?php } ?> |
| 104 | + </div> |
| 105 | + |
| 106 | + <!-- Undefined index is suppressed and the default is used for these values --> |
| 107 | + <input id="mode" type="hidden" name="mode" value="otp" data-preferred="<?php echo htmlspecialchars($this->data['mode'], ENT_QUOTES); ?>"/> |
| 108 | + <input id="pushAvailable" type="hidden" name="pushAvailable" value="<?php echo ($this->data['pushAvailable'] ?? false) ? 'true' : ''; ?>"/> |
| 109 | + <input id="otpAvailable" type="hidden" name="otpAvailable" value="<?php echo ($this->data['otpAvailable'] ?? true) ? 'true' : ''; ?>"/> |
| 110 | + <input id="webAuthnSignRequest" type="hidden" name="webAuthnSignRequest" value='<?php echo htmlspecialchars($this->data['webAuthnSignRequest'] ?? '', ENT_QUOTES); ?>'/> |
| 111 | + <input id="u2fSignRequest" type="hidden" name="u2fSignRequest" value='<?php echo htmlspecialchars($this->data['u2fSignRequest'] ?? '', ENT_QUOTES); ?>'/> |
| 112 | + <input id="modeChanged" type="hidden" name="modeChanged" value=""/> |
| 113 | + <input id="step" type="hidden" name="step" value="<?php echo htmlspecialchars(strval(($this->data['step'] ?? null) ?: 2), ENT_QUOTES); ?>"/> |
| 114 | + <input id="webAuthnSignResponse" type="hidden" name="webAuthnSignResponse" value=""/> |
| 115 | + <input id="u2fSignResponse" type="hidden" name="u2fSignResponse" value=""/> |
| 116 | + <input id="origin" type="hidden" name="origin" value=""/> |
| 117 | + <input id="loadCounter" type="hidden" name="loadCounter" value="<?php echo htmlspecialchars(strval(($this->data['loadCounter'] ?? null) ?: 1), ENT_QUOTES); ?>"/> |
| 118 | + |
| 119 | + <!-- Additional input to persist the message --> |
| 120 | + <input type="hidden" name="message" value="<?php echo htmlspecialchars($this->data['message'] ?? '', ENT_QUOTES); ?>"/> |
| 121 | +</form> |
| 122 | +<script src="<?php echo htmlspecialchars(Module::getModuleUrl('privacyidea/js/pi-webauthn.js'), ENT_QUOTES); ?>"> |
| 123 | +</script> |
| 124 | + |
| 125 | +<script src="<?php echo htmlspecialchars(Module::getModuleUrl('privacyidea/js/u2f-api.js'), ENT_QUOTES); ?>"> |
| 126 | +</script> |
| 127 | + |
| 128 | +<meta id="privacyidea-step" name="privacyidea-step" content="<?php echo $this->data['step']; ?>"> |
| 129 | + |
| 130 | +<meta id="privacyidea-translations" name="privacyidea-translations" content="<?php |
| 131 | +$translations = []; |
| 132 | +$translation_keys = [ |
| 133 | + 'webauthn_insecure_context', |
| 134 | + 'webauthn_library_unavailable', |
| 135 | + 'webauthn_AbortError', |
| 136 | + 'webauthn_InvalidStateError', |
| 137 | + 'webauthn_NotAllowedError', |
| 138 | + 'webauthn_NotSupportedError', |
| 139 | + 'webauthn_TypeError', |
| 140 | + 'webauthn_other_error', |
| 141 | + 'webauthn_in_progress', |
| 142 | + 'webauthn_success', |
| 143 | + 'u2f_insecure_context', |
| 144 | + 'u2f_unavailable', |
| 145 | + 'u2f_sign_request_error', |
| 146 | + 'try_again', |
| 147 | +]; |
| 148 | +foreach ($translation_keys as $translation_key) { |
| 149 | + $translations[$translation_key] = $this->t(sprintf('{privacyidea:privacyidea:%s}', $translation_key)); |
| 150 | +} |
| 151 | +echo htmlspecialchars(json_encode($translations)); |
| 152 | +?>"> |
| 153 | + |
| 154 | +<script src="<?php echo htmlspecialchars(Module::getModuleUrl('privacyidea/js/loginform.js'), ENT_QUOTES); ?>"></script> |
| 155 | +<script src="<?php echo htmlspecialchars(Module::getModuleUrl('perun/js/privacy-idea-loginform.js'), ENT_QUOTES); ?>"></script> |
| 156 | + |
| 157 | +<?php |
| 158 | +$this->includeAtTemplateBase('includes/footer.php'); |
| 159 | +?> |
0 commit comments