[java-idp-plugin-webauthn] branch main updated: Fix view HTML structure

Phil Smart philip.smart at jisc.ac.uk
Fri Feb 16 14:06:48 UTC 2024


This is an automated email from the git hooks/post-receive script.

philsmart pushed a commit to branch main
in repository java-idp-plugin-webauthn.

View the commit online:
http://git.shibboleth.net/view/?p=java-idp-plugin-webauthn.git;a=commit;h=54567dac111af5e7a846887c67405b6fcb505633

The following commit(s) were added to refs/heads/main by this push:
     new 54567da  Fix view HTML structure
54567da is described below

commit 54567dac111af5e7a846887c67405b6fcb505633
Author: Phil Smart <philip.smart at jisc.ac.uk>
AuthorDate: Fri Feb 16 14:06:45 2024 +0000

    Fix view HTML structure
---
 .../webauthn-registration-flow.xml                 |   4 +-
 .../idp/flows/authn/WebAuthn/webauthn-flow.xml     |   7 -
 .../plugin/authn/webauthn/views/webauthn-authn.vm  | 146 ++++++------
 .../authn/webauthn/views/webauthn-register.vm      | 248 ++++++++++-----------
 .../authn/webauthn/views/webauthn-registered.vm    |   4 +-
 5 files changed, 199 insertions(+), 210 deletions(-)

diff --git a/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-flow.xml b/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-flow.xml
index d484692..410cff8 100644
--- a/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-flow.xml
+++ b/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/admin/webauthn-registration/webauthn-registration-flow.xml
@@ -72,6 +72,7 @@
             <evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="viewScope.response" />
         </on-render>
         
+       <transition on="finish" to="RegistrationComplete" />
        <transition on="addKey" to="AddKey" />
        <transition on="deleteKey" to="DeleteKey" />
        
@@ -115,7 +116,8 @@
             <evaluate expression="flowRequestContext.getExternalContext().getNativeRequest()" result="viewScope.request" />
             <evaluate expression="flowRequestContext.getExternalContext().getNativeResponse()" result="viewScope.response" />
         </on-render>
-            
+        
+        <transition on="registerAnother" to="GeneratePublicKeyCredentialCreationOptions" />
         <transition on="proceed" to="RegistrationComplete" />
      </view-state>
      
diff --git a/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/WebAuthn/webauthn-flow.xml b/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/WebAuthn/webauthn-flow.xml
index 2fb53a0..add3992 100644
--- a/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/WebAuthn/webauthn-flow.xml
+++ b/webauthn-impl/src/main/resources/META-INF/net/shibboleth/idp/flows/authn/WebAuthn/webauthn-flow.xml
@@ -78,13 +78,6 @@
         <transition on="proceed" to="GenerateAuthenticationCeremonyOptions" />    
     </action-state>
     
-    <!-- Test if we are operating as a first (and possibly only) factor -->
-    <!-- <decision-state id="DetermineUsernamelessOrPasswordlessLogin">
-        <if test="IsDiscoverableCredentialRequired.test(opensamlProfileRequestContext)"
-            then="UsernamelessLogin" 
-            else="PasswordlessLogin" />        
-    </decision-state> -->
-    
     <!-- 
         Second Factor login. If we are running after a first factor, perform 2FA only. Needs existing username.
      -->
diff --git a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-authn.vm b/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-authn.vm
index 05c002a..5fef529 100644
--- a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-authn.vm
+++ b/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-authn.vm
@@ -22,7 +22,6 @@
 ##
 <!DOCTYPE html>
 <html>
-
     <head>
         <title>#springMessageText("idp.title", "Web Login Service")</title>
         <meta charset="UTF-8" />
@@ -30,16 +29,15 @@
         <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0">
         <script type="text/javascript" src="$request.getContextPath()/js/webauthn/webauthn-support.js"></script>
         <link rel="stylesheet" type="text/css" href="$request.getContextPath()#springMessageText("
-            idp.css", "/css/placeholder.css" )">
+        idp.css", "/css/placeholder.css" )">
         <link rel="stylesheet" type="text/css" href="$request.getContextPath()/css/webauthn.css">
         <script type="module">
-    
             import {
                 get,
                 parseRequestOptionsFromJSON,
                 supported,
             } from "$request.getContextPath()/js/webauthn/webauthn-json.browser-ponyfill.js";
-    
+            
             async function authenticate() {
                 // Some UI changes
                 try {               
@@ -82,83 +80,77 @@
                     console.error(e);
                 }
             });
-    
+            
         </script>
     </head>
     <body>
         <main class="main">
-            <header>
-                <img class="main-logo" src="$request.getContextPath()#springMessageText("
-                    idp.logo", "/images/placeholder-logo.png" )" alt="#springMessageText(" idp.logo.alt-text", "logo" )" />
-    
-                #set ($serviceName = $rpUIContext.serviceName)
-                #if ($serviceName && !$rpContext.getRelyingPartyId().contains($serviceName))
-                <h1>#springMessageText("idp.login.loginTo", "Login to") $encoder.encodeForHTML($serviceName)</h1>
-                #end
-            </header>
-    
-            <section>
-                #*
-                //
-                // SP Description & Logo (optional)
-                // These idpui lines will display added information (if available
-                // in the metadata) about the Service Provider (SP) that requested
-                // authentication. These idpui lines are "active" in this example
-                // (not commented out) - this extra SP info will be displayed.
-                // Remove or comment out these lines to stop the display of the
-                // added SP information.
-                //
-                *#
-                #set ($logo = $rpUIContext.getLogo())
-                #if ($logo)
-                <img class="service-logo" src="$encoder.encodeForHTMLAttribute($logo)"
-                    alt="$encoder.encodeForHTMLAttribute($serviceName)">
-                #end
-                #set ($desc = $rpUIContext.getServiceDescription())
-                #if ($desc)
-                <p>$encoder.encodeForHTML($desc)</p>
-                #end
-                <div id="supportedDiv">
-                    <div class="content">
-                        <div class="column one">
-                            <form id="authenticatorAssertionForm" action="$flowExecutionUrl" method="post">
-                                #parse("csrf/csrf.vm")
-                                <input type="hidden" id="publicKeyAssertion" name="publicKeyAssertion" />
-                                <button class="hidden" id="authenticationSubmit" type="submit"
-                                    name="_eventId_proceed">#springMessageText("idp.webauthn.authn.submit", "Submit
-                                    Authentication")</button>
-                            </form>
-                            <div class="centre">
-                                    <button id="authenticate"
-                                        class="form-element form-button">#springMessageText("idp.webauthn.authn.authenticate",
-                                        "Login with passkey or security key")</button>
-                            </div>                        
-                            #if($debug == "true")
-                                <hr />
-                                <button type="button" class="collapsible">#springMessageText("idp.webauthn.debug.title",
-                                    "Debugging")</button>    
-                                <div class="debug" id="debug-div">
-                                    <label for="publicKeyCredentialCreation">#springMessageText("idp.webauthn.debug.request",
-                                        "Request Options")</label>
-                                    <textarea id="publicKeyCredentialRequestOptions" name="publicKeyCredentialRequestOptions"
-                                        rows="20" cols="50">
-                                        $webauthnContext.publicKeyCredentialRequestOptionsJSON</textarea>
-                                </div>
-                            #end
-                        </div>
+        <header>
+            <img class="main-logo" src="$request.getContextPath()#springMessageText("
+            idp.logo", "/images/placeholder-logo.png" )" alt="#springMessageText(" idp.logo.alt-text", "logo" )" />
+            #set ($serviceName = $rpUIContext.serviceName)
+            #if ($serviceName && !$rpContext.getRelyingPartyId().contains($serviceName))
+            <h1>#springMessageText("idp.login.loginTo", "Login to") $encoder.encodeForHTML($serviceName)</h1>
+            #end
+        </header>
+        <section>
+            #*
+            //
+            // SP Description & Logo (optional)
+            // These idpui lines will display added information (if available
+            // in the metadata) about the Service Provider (SP) that requested
+            // authentication. These idpui lines are "active" in this example
+            // (not commented out) - this extra SP info will be displayed.
+            // Remove or comment out these lines to stop the display of the
+            // added SP information.
+            //
+            *#
+            #set ($logo = $rpUIContext.getLogo())
+            #if ($logo)
+            <img class="service-logo" src="$encoder.encodeForHTMLAttribute($logo)"
+                alt="$encoder.encodeForHTMLAttribute($serviceName)">
+            #end
+            #set ($desc = $rpUIContext.getServiceDescription())
+            #if ($desc)
+            <p>$encoder.encodeForHTML($desc)</p>
+            #end
+            <div id="supportedDiv">
+                <div class="content">
+                    <form id="authenticatorAssertionForm" action="$flowExecutionUrl" method="post">
+                        #parse("csrf/csrf.vm")
+                        <input type="hidden" id="publicKeyAssertion" name="publicKeyAssertion" />
+                        <button class="hidden" id="authenticationSubmit" type="submit"
+                            name="_eventId_proceed">#springMessageText("idp.webauthn.authn.submit", "Submit
+                        Authentication")</button>
+                    </form>
+                    <div class="centre">
+                        <button id="authenticate"
+                            class="form-element form-button">#springMessageText("idp.webauthn.authn.authenticate",
+                        "Login with passkey or security key")</button>
                     </div>
+                    #if($debug == "true")
+                    <hr />
+                    <button type="button" class="collapsible">#springMessageText("idp.webauthn.debug.title",
+                    "Debugging")</button>    
+                    <div class="debug" id="debug-div">
+                        <label for="publicKeyCredentialCreation">#springMessageText("idp.webauthn.debug.request",
+                        "Request Options")</label>
+                        <textarea id="publicKeyCredentialRequestOptions" name="publicKeyCredentialRequestOptions"
+                            rows="20" cols="50">
+                        $webauthnContext.publicKeyCredentialRequestOptionsJSON</textarea>
+                    </div>
+                    #end
                 </div>
-                </div>
-                <div id="unsupportedDiv" class="hidden">
-                    #springMessageText("idp.webauthn.authn.unsupported", "Your browser is not WebAuthn compatible")
-                </div>
-            </section>
-    
-            <footer>
-                <div class="container container-footer">
-                    <p class="footer-text">#springMessageText("idp.footer", "Insert your footer text here.")</p>
-                </div>
-            </footer>
-            </div>    
+            </div>
+            <div id="unsupportedDiv" class="hidden">
+                #springMessageText("idp.webauthn.authn.unsupported", "Your browser is not WebAuthn compatible")
+            </div>
+        </section>
+        <footer>
+            <div class="container container-footer">
+                <p class="footer-text">#springMessageText("idp.footer", "Insert your footer text here.")</p>
+            </div>
+        </footer>
+        </div>    
     </body>
-</html>
+</html>
\ No newline at end of file
diff --git a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-register.vm b/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-register.vm
index bc8f980..339e6cd 100644
--- a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-register.vm
+++ b/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-register.vm
@@ -20,8 +20,7 @@
 ##
 <!DOCTYPE html>
 <html>
-
-    <head>
+   <head>
       <title>#springMessageText("idp.title", "Web Login Service")</title>
       <meta charset="UTF-8" />
       <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
@@ -30,133 +29,134 @@
       <link rel="stylesheet" type="text/css" href="$request.getContextPath()#springMessageText("idp.css", "/css/placeholder.css" )">
       <link rel="stylesheet" type="text/css" href="$request.getContextPath()/css/webauthn.css">
       <script type="module">
-      
-            import {
-              parseCreationOptionsFromJSON,
-              create,
-              supported,
-            }  from "$request.getContextPath()/js/webauthn/webauthn-json.browser-ponyfill.js";
+         import {
+           parseCreationOptionsFromJSON,
+           create,
+           supported,
+         }  from "$request.getContextPath()/js/webauthn/webauthn-json.browser-ponyfill.js";
+         
+         async function register() {        
+             var pkCredOptions = $webauthnRegContext.publicKeyCredentialCreationOptionsJSON; 
+             var pkCredOptionsParsed = parseCreationOptionsFromJSON({ publicKey: pkCredOptions }); 
+             #if($debug == "true")
+                 console.log("Raw creation options", pkCredOptions);
+                 console.log("Parsed creation options", pkCredOptionsParsed);
+             #end             
+             await create(pkCredOptionsParsed)
+                     .then(function (attestation){
+                         var nickname = prompt("Credential Nickname");
+                         document.getElementById("credentialNickname").value = nickname;
+                         document.getElementById("authenticatorAttestation").value = JSON.stringify(attestation);    
+                         document.getElementById("registrationSubmit").click();
+                     }).catch(function (err){
+                         console.error(err)
+                    });   
+         
+          };
+         
+          function initButton() {
+               document.getElementById("registerButton").onclick = register;        
+               return false;
+          }
           
-            async function register() {        
-                var pkCredOptions = $webauthnRegContext.publicKeyCredentialCreationOptionsJSON; 
-                var pkCredOptionsParsed = parseCreationOptionsFromJSON({ publicKey: pkCredOptions }); 
-                #if($debug == "true")
-                    console.log("Raw creation options", pkCredOptions);
-                    console.log("Parsed creation options", pkCredOptionsParsed);
-                #end             
-                await create(pkCredOptionsParsed)
-                        .then(function (attestation){
-                            var nickname = prompt("Credential Nickname");
-                            document.getElementById("credentialNickname").value = nickname;
-                            document.getElementById("authenticatorAttestation").value = JSON.stringify(attestation);    
-                            document.getElementById("registrationSubmit").click();
-                        }).catch(function (err){
-                            console.error(err)
-                       });   
-        
-             };
-        
-             function initButton() {
-                  document.getElementById("registerButton").onclick = register;        
-                  return false;
-             }
+          window.addEventListener("load", () => {
+         try {
+           var isSupported = supported();
+           if (!isSupported){
+             document.getElementById('supportedDiv').classList.add('hidden')
+             document.getElementById("supportedDiv").disabled = true;
+             document.getElementById("authenticatorAttestationForm").disabled = true;        
+             document.getElementById("registrationSubmit").disabled = true;
              
-             window.addEventListener("load", () => {
-          try {
-              var isSupported = supported();
-              if (!isSupported){
-                document.getElementById('supportedDiv').classList.add('hidden')
-                document.getElementById("supportedDiv").disabled = true;
-                document.getElementById("authenticatorAttestationForm").disabled = true;        
-                document.getElementById("registrationSubmit").disabled = true;
-                
-                document.getElementById("unsupportedDiv").disabled = false;
-                document.getElementById('unsupportedDiv').classList.remove('hidden')
-              } else{
-                  initButton();
-              }     
-            
-          } catch (e) {
-            console.error(e);
-          }
-        });    
-        </script>      
-    </head>
-    <body>    
-        <main class="main">
-        <header>
+             document.getElementById("unsupportedDiv").disabled = false;
+             document.getElementById('unsupportedDiv').classList.remove('hidden')
+           } else{
+               initButton();
+           }     
+         
+         } catch (e) {
+         console.error(e);
+         }
+         });    
+      </script>      
+   </head>
+   <body>
+      <main class="main">
+         <header>
             <img class="main-logo" src="$request.getContextPath()#springMessageText(" idp.logo", "/images/placeholder-logo.png" )" alt="#springMessageText(" idp.logo.alt-text", "logo" )" />
-           
-        </header>    
-          <section>
+         </header>
+         <section>
             <div id="supportedDiv">
-                <div class="content">
-                  <div class="column one centre"> 
-                    <div>
-                        <h1>Registered Keys</h1>
-                         #if ($webauthnRegContext.existingCredentials)
-                            <table>
-                                <tr>
-                                    <th>#springMessageText("idp.webauthn.register.table.keyName", "Key Name")</th>
-                                    <th>#springMessageText("idp.webauthn.register.table.transports", "Transports")</th>
-                                    <th>#springMessageText("idp.webauthn.register.table.passkey", "Passkey?")</th>
-                                    <th>#springMessageText("idp.webauthn.register.table.registrationTime", "Registration Time")</th>
-                                    <th>#springMessageText("idp.webauthn.register.table.action", "Action")</th>
-                                </tr>
-                                 #foreach($cred in $webauthnRegContext.existingCredentials)
-                                    <tr>
-                                        <td>$encoder.encodeForHTML($cred.nickname)</td>
-                                        <td>$encoder.encodeForHTML($webAuthnEncoder.formatTransports($cred.transports))</td>
-                                        <td>$encoder.encodeForHTML($webAuthnEncoder.formatDiscoverable($cred.isDiscoverable()))</td>
-                                        <td>$encoder.encodeForHTML($webAuthnEncoder.formatInstant($cred.registrationTime))</td>
-                                        <td>
-                                        <form id="deleteKeyForm" action="$flowExecutionUrl" method="post">
-                                            #parse("csrf/csrf.vm")
-                                            <input type="hidden" name="credentialId" value="$cred.credentialIdBase64Url"/>
-                                            <button class="webauthn-table-button" onclick="return confirm('#springMessageText("idp.webauthn.register.credential.remove.confirm", "Are you sure")');" id="removeButton" type="submit" name="_eventId_deleteKey">#springMessageText("idp.webauthn.register.credential.remove", "Remove")</button>
-                                        </form>
-                                        </td>
-                                    </tr>
-                                 #end   
-                            </table>
-                         #else
-                            <div><span>#springMessageText("idp.webauthn.register.registered.noKeys", "You have no registered keys")</span></div>                 
-                         #end
-                         <br/>
-                         <div>
-                            <button class="form-element form-button" id="registerButton">#springMessageText("idp.webauthn.register.addKey", "Add New Security Key")</button>
-                         </div>
-                         
-                          <form id="authenticatorAttestationForm" action="$flowExecutionUrl" method="post">
-                              #parse("csrf/csrf.vm")
-                              <input type="hidden" id="credentialNickname" name="credentialNickname"/>
-                              <input type="hidden" id="authenticatorAttestation" name="authenticatorAttestation"/>
-                              <button class="hidden" id="registrationSubmit" type="submit" name="_eventId_addKey">#springMessageText("idp.webauthn.register.submit", "Submit Registration")</button>
-                          </form>
-                    </div>                    
-                    #if($debug == "true")
-                        <hr/>                       
-                        <button type="button" class="collapsible">#springMessageText("idp.webauthn.register.debug.title", "Debugging")</button> 
-                        
-                        <div class="debug" id="debug-div">
-                            <label for="publicKeyCredentialCreation">#springMessageText("idp.webauthn.register.debug.registration", "Registration Options")</label>
-                            <textarea id="publicKeyCredentialCreation" name="publicKeyCredentialCreation" rows="20" cols="50">
-                            $webauthnRegContext.publicKeyCredentialCreationOptionsJSON</textarea>                   
-                        </div>
-                    #end            
+               <div class="centre">
+                  <div>
+                     <h1>Registered Keys</h1>
+                     #if ($webauthnRegContext.existingCredentials)
+                     <table>
+                        <tr>
+                           <th>#springMessageText("idp.webauthn.register.table.keyName", "Key Name")</th>
+                           <th>#springMessageText("idp.webauthn.register.table.transports", "Transports")</th>
+                           <th>#springMessageText("idp.webauthn.register.table.passkey", "Passkey?")</th>
+                           <th>#springMessageText("idp.webauthn.register.table.registrationTime", "Registration Time")</th>
+                           <th>#springMessageText("idp.webauthn.register.table.action", "Action")</th>
+                        </tr>
+                        #foreach($cred in $webauthnRegContext.existingCredentials)
+                        <tr>
+                           <td>$encoder.encodeForHTML($cred.nickname)</td>
+                           <td>$encoder.encodeForHTML($webAuthnEncoder.formatTransports($cred.transports))</td>
+                           <td>$encoder.encodeForHTML($webAuthnEncoder.formatDiscoverable($cred.isDiscoverable()))</td>
+                           <td>$encoder.encodeForHTML($webAuthnEncoder.formatInstant($cred.registrationTime))</td>
+                           <td>
+                              <form id="deleteKeyForm" action="$flowExecutionUrl" method="post">
+                                 #parse("csrf/csrf.vm")
+                                 <input type="hidden" name="credentialId" value="$cred.credentialIdBase64Url"/>
+                                 <button class="webauthn-table-button" onclick="return confirm('#springMessageText("idp.webauthn.register.credential.remove.confirm", "Are you sure")');" id="removeButton" type="submit" name="_eventId_deleteKey">#springMessageText("idp.webauthn.register.credential.remove", "Remove")</button>
+                              </form>
+                           </td>
+                        </tr>
+                        #end   
+                     </table>
+                     #else
+                     <div><span>#springMessageText("idp.webauthn.register.registered.noKeys", "You have no registered keys")</span></div>
+                     #end
+                     <br/>
+                     <div>
+                        <button class="form-element form-button" id="registerButton">#springMessageText("idp.webauthn.register.addKey", "Add New Security Key")</button>
+                     </div>
+                     <br />
+                     <div>
+                        <form id="finish_button_form" action="$flowExecutionUrl" method="post">
+                           #parse("csrf/csrf.vm")                           
+                           <button id="finish_button" type="submit" name="_eventId_finish">#springMessageText("idp.webauthn.register.finish", "Finish")</button>
+                        </form>
+                     </div>
+                     <form id="authenticatorAttestationForm" action="$flowExecutionUrl" method="post">
+                        #parse("csrf/csrf.vm")
+                        <input type="hidden" id="credentialNickname" name="credentialNickname"/>
+                        <input type="hidden" id="authenticatorAttestation" name="authenticatorAttestation"/>
+                        <button class="hidden" id="registrationSubmit" type="submit" name="_eventId_addKey">#springMessageText("idp.webauthn.register.submit", "Submit Registration")</button>
+                     </form>
                   </div>
-              </div>
+                  #if($debug == "true")
+                  <hr/>
+                  <button type="button" class="collapsible">#springMessageText("idp.webauthn.register.debug.title", "Debugging")</button> 
+                  <div class="debug" id="debug-div">
+                     <label for="publicKeyCredentialCreation">#springMessageText("idp.webauthn.register.debug.registration", "Registration Options")</label>
+                     <textarea id="publicKeyCredentialCreation" name="publicKeyCredentialCreation" rows="20" cols="50">
+                     $webauthnRegContext.publicKeyCredentialCreationOptionsJSON</textarea>                   
+                  </div>
+                  #end            
+               </div>
                <div id="unsupportedDiv" class="hidden">
-                    #springMessageText("idp.webauthn.register.unsupported", "Your browser is not WebAuthn compatible")
-                </div>        
-            </div>
-          </section>
-        </main>
-          <footer>
-            <div class="cc">
-                <p class="footer-text">#springMessageText("idp.footer", "Insert your footer text here.")</p>
+                  #springMessageText("idp.webauthn.register.unsupported", "Your browser is not WebAuthn compatible")
+               </div>
             </div>
-          </footer>
+         </section>
+      </main>
+      <footer>
+         <div class="cc">
+            <p class="footer-text">#springMessageText("idp.footer", "Insert your footer text here.")</p>
+         </div>
+      </footer>
       </div>    
-    </body>
-</html>
+   </body>
+</html>
\ No newline at end of file
diff --git a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-registered.vm b/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-registered.vm
index 419012e..c7c7a4b 100644
--- a/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-registered.vm
+++ b/webauthn-impl/src/main/resources/net/shibboleth/idp/plugin/authn/webauthn/views/webauthn-registered.vm
@@ -74,7 +74,9 @@
                     <br />
                     <form id="finish_button_form" action="$flowExecutionUrl" method="post">
                         #parse("csrf/csrf.vm")
-                        <button id="finish_button" type="submit" name="_eventId_proceed">#springMessageText("idp.webauthn.register.finish", "Done")</button>
+                        <button id="register_another_button" type="submit" name="_eventId_registerAnother">#springMessageText("idp.webauthn.register.another", "Register Another")</button>
+                    
+                        <button id="finish_button" type="submit" name="_eventId_proceed">#springMessageText("idp.webauthn.register.finish", "Finish")</button>
                     </form>
                 </div>   
             </section>

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list