001package Torello.Browser; 002 003import java.util.*; 004import javax.json.*; 005import javax.json.stream.*; 006import java.io.*; 007 008import java.lang.reflect.Method; 009import java.lang.reflect.Parameter; 010import java.util.function.Function; 011 012import Torello.Java.Additional.*; 013 014import static Torello.Java.Additional.JFlag.*; 015 016import Torello.Java.StrCmpr; 017import Torello.JavaDoc.StaticFunctional; 018import Torello.JavaDoc.JDHeaderBackgroundImg; 019import Torello.JavaDoc.Excuse; 020 021/** 022 * <SPAN CLASS=CopiedJDK><B>This domain allows configuring virtual authenticators to test the WebAuthn 023 * API.</B></SPAN> 024 * 025 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE> 026 */ 027@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION}) 028@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE") 029public class WebAuthn 030{ 031 // ******************************************************************************************** 032 // ******************************************************************************************** 033 // Class Header Stuff 034 // ******************************************************************************************** 035 // ******************************************************************************************** 036 037 038 // No Pubic Constructors 039 private WebAuthn () { } 040 041 // These two Vector's are used by all the "Methods" exported by this class. java.lang.reflect 042 // is used to generate the JSON String's. It saves thousands of lines of Auto-Generated Code. 043 private static final Map<String, Vector<String>> parameterNames = new HashMap<>(); 044 private static final Map<String, Vector<Class<?>>> parameterTypes = new HashMap<>(); 045 046 // Some Methods do not take any parameters - for instance all the "enable()" and "disable()" 047 // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now, 048 // offically, two empty-vectors. One for String's, and the other for Classes. 049 050 private static final Vector<String> EMPTY_VEC_STR = new Vector<>(); 051 private static final Vector<Class<?>> EMPTY_VEC_CLASS = new Vector<>(); 052 053 static 054 { 055 for (Method m : WebAuthn.class.getMethods()) 056 { 057 // This doesn't work! The parameter names are all "arg0" ... "argN" 058 // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter! 059 // 060 // Vector<String> parameterNamesList = new Vector<>(); -- NOPE! 061 062 Vector<Class<?>> parameterTypesList = new Vector<>(); 063 064 for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType()); 065 066 parameterTypes.put( 067 m.getName(), 068 (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS 069 ); 070 } 071 } 072 073 static 074 { 075 Vector<String> v = null; 076 077 parameterNames.put("enable", EMPTY_VEC_STR); 078 079 parameterNames.put("disable", EMPTY_VEC_STR); 080 081 v = new Vector<String>(1); 082 parameterNames.put("addVirtualAuthenticator", v); 083 Collections.addAll(v, new String[] 084 { "options", }); 085 086 v = new Vector<String>(1); 087 parameterNames.put("removeVirtualAuthenticator", v); 088 Collections.addAll(v, new String[] 089 { "authenticatorId", }); 090 091 v = new Vector<String>(2); 092 parameterNames.put("addCredential", v); 093 Collections.addAll(v, new String[] 094 { "authenticatorId", "credential", }); 095 096 v = new Vector<String>(2); 097 parameterNames.put("getCredential", v); 098 Collections.addAll(v, new String[] 099 { "authenticatorId", "credentialId", }); 100 101 v = new Vector<String>(1); 102 parameterNames.put("getCredentials", v); 103 Collections.addAll(v, new String[] 104 { "authenticatorId", }); 105 106 v = new Vector<String>(2); 107 parameterNames.put("removeCredential", v); 108 Collections.addAll(v, new String[] 109 { "authenticatorId", "credentialId", }); 110 111 v = new Vector<String>(1); 112 parameterNames.put("clearCredentials", v); 113 Collections.addAll(v, new String[] 114 { "authenticatorId", }); 115 116 v = new Vector<String>(2); 117 parameterNames.put("setUserVerified", v); 118 Collections.addAll(v, new String[] 119 { "authenticatorId", "isUserVerified", }); 120 121 v = new Vector<String>(2); 122 parameterNames.put("setAutomaticPresenceSimulation", v); 123 Collections.addAll(v, new String[] 124 { "authenticatorId", "enabled", }); 125 } 126 127 128 // ******************************************************************************************** 129 // ******************************************************************************************** 130 // Types - Static Inner Classes 131 // ******************************************************************************************** 132 // ******************************************************************************************** 133 134 // public static class AuthenticatorId => String 135 136 /** <CODE>[No Description Provided by Google]</CODE> */ 137 public static final String[] AuthenticatorProtocol = 138 { "u2f", "ctap2", }; 139 140 /** <CODE>[No Description Provided by Google]</CODE> */ 141 public static final String[] Ctap2Version = 142 { "ctap2_0", "ctap2_1", }; 143 144 /** <CODE>[No Description Provided by Google]</CODE> */ 145 public static final String[] AuthenticatorTransport = 146 { "usb", "nfc", "ble", "cable", "internal", }; 147 148 /** <CODE>[No Description Provided by Google]</CODE> */ 149 public static class VirtualAuthenticatorOptions extends BaseType 150 { 151 /** For Object Serialization. java.io.Serializable */ 152 protected static final long serialVersionUID = 1; 153 154 public boolean[] optionals() 155 { return new boolean[] { false, true, false, true, true, true, true, true, true, }; } 156 157 /** <CODE>[No Description Provided by Google]</CODE> */ 158 public final String protocol; 159 160 /** 161 * Defaults to ctap2_0. Ignored if |protocol| == u2f. 162 * <BR /> 163 * <BR /><B>OPTIONAL</B> 164 */ 165 public final String ctap2Version; 166 167 /** <CODE>[No Description Provided by Google]</CODE> */ 168 public final String transport; 169 170 /** 171 * Defaults to false. 172 * <BR /> 173 * <BR /><B>OPTIONAL</B> 174 */ 175 public final Boolean hasResidentKey; 176 177 /** 178 * Defaults to false. 179 * <BR /> 180 * <BR /><B>OPTIONAL</B> 181 */ 182 public final Boolean hasUserVerification; 183 184 /** 185 * If set to true, the authenticator will support the largeBlob extension. 186 * https://w3c.github.io/webauthn#largeBlob 187 * Defaults to false. 188 * <BR /> 189 * <BR /><B>OPTIONAL</B> 190 */ 191 public final Boolean hasLargeBlob; 192 193 /** 194 * If set to true, the authenticator will support the credBlob extension. 195 * https://fidoalliance.org/specs/fido-v2.1-rd-20201208/fido-client-to-authenticator-protocol-v2.1-rd-20201208.html#sctn-credBlob-extension 196 * Defaults to false. 197 * <BR /> 198 * <BR /><B>OPTIONAL</B> 199 */ 200 public final Boolean hasCredBlob; 201 202 /** 203 * If set to true, tests of user presence will succeed immediately. 204 * Otherwise, they will not be resolved. Defaults to true. 205 * <BR /> 206 * <BR /><B>OPTIONAL</B> 207 */ 208 public final Boolean automaticPresenceSimulation; 209 210 /** 211 * Sets whether User Verification succeeds or fails for an authenticator. 212 * Defaults to false. 213 * <BR /> 214 * <BR /><B>OPTIONAL</B> 215 */ 216 public final Boolean isUserVerified; 217 218 /** 219 * Constructor 220 * 221 * @param protocol - 222 * 223 * @param ctap2Version Defaults to ctap2_0. Ignored if |protocol| == u2f. 224 * <BR /><B>OPTIONAL</B> 225 * 226 * @param transport - 227 * 228 * @param hasResidentKey Defaults to false. 229 * <BR /><B>OPTIONAL</B> 230 * 231 * @param hasUserVerification Defaults to false. 232 * <BR /><B>OPTIONAL</B> 233 * 234 * @param hasLargeBlob 235 * If set to true, the authenticator will support the largeBlob extension. 236 * https://w3c.github.io/webauthn#largeBlob 237 * Defaults to false. 238 * <BR /><B>OPTIONAL</B> 239 * 240 * @param hasCredBlob 241 * If set to true, the authenticator will support the credBlob extension. 242 * https://fidoalliance.org/specs/fido-v2.1-rd-20201208/fido-client-to-authenticator-protocol-v2.1-rd-20201208.html#sctn-credBlob-extension 243 * Defaults to false. 244 * <BR /><B>OPTIONAL</B> 245 * 246 * @param automaticPresenceSimulation 247 * If set to true, tests of user presence will succeed immediately. 248 * Otherwise, they will not be resolved. Defaults to true. 249 * <BR /><B>OPTIONAL</B> 250 * 251 * @param isUserVerified 252 * Sets whether User Verification succeeds or fails for an authenticator. 253 * Defaults to false. 254 * <BR /><B>OPTIONAL</B> 255 */ 256 public VirtualAuthenticatorOptions( 257 String protocol, String ctap2Version, String transport, Boolean hasResidentKey, 258 Boolean hasUserVerification, Boolean hasLargeBlob, Boolean hasCredBlob, 259 Boolean automaticPresenceSimulation, Boolean isUserVerified 260 ) 261 { 262 // Exception-Check(s) to ensure that if any parameters which are not declared as 263 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 264 265 if (protocol == null) BRDPC.throwNPE("protocol"); 266 if (transport == null) BRDPC.throwNPE("transport"); 267 268 // Exception-Check(s) to ensure that if any parameters which must adhere to a 269 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 270 271 BRDPC.checkIAE("protocol", protocol, "WebAuthn.AuthenticatorProtocol", WebAuthn.AuthenticatorProtocol); 272 BRDPC.checkIAE("ctap2Version", ctap2Version, "WebAuthn.Ctap2Version", WebAuthn.Ctap2Version); 273 BRDPC.checkIAE("transport", transport, "WebAuthn.AuthenticatorTransport", WebAuthn.AuthenticatorTransport); 274 275 this.protocol = protocol; 276 this.ctap2Version = ctap2Version; 277 this.transport = transport; 278 this.hasResidentKey = hasResidentKey; 279 this.hasUserVerification = hasUserVerification; 280 this.hasLargeBlob = hasLargeBlob; 281 this.hasCredBlob = hasCredBlob; 282 this.automaticPresenceSimulation = automaticPresenceSimulation; 283 this.isUserVerified = isUserVerified; 284 } 285 286 /** 287 * JSON Object Constructor 288 * @param jo A Json-Object having data about an instance of {@code 'VirtualAuthenticatorOptions'}. 289 */ 290 public VirtualAuthenticatorOptions (JsonObject jo) 291 { 292 this.protocol = ReadJSON.getString(jo, "protocol", false, true); 293 this.ctap2Version = ReadJSON.getString(jo, "ctap2Version", true, false); 294 this.transport = ReadJSON.getString(jo, "transport", false, true); 295 this.hasResidentKey = ReadJSON.getBOOLEAN(jo, "hasResidentKey", true); 296 this.hasUserVerification = ReadJSON.getBOOLEAN(jo, "hasUserVerification", true); 297 this.hasLargeBlob = ReadJSON.getBOOLEAN(jo, "hasLargeBlob", true); 298 this.hasCredBlob = ReadJSON.getBOOLEAN(jo, "hasCredBlob", true); 299 this.automaticPresenceSimulation = ReadJSON.getBOOLEAN(jo, "automaticPresenceSimulation", true); 300 this.isUserVerified = ReadJSON.getBOOLEAN(jo, "isUserVerified", true); 301 } 302 303 } 304 305 /** <CODE>[No Description Provided by Google]</CODE> */ 306 public static class Credential extends BaseType 307 { 308 /** For Object Serialization. java.io.Serializable */ 309 protected static final long serialVersionUID = 1; 310 311 public boolean[] optionals() 312 { return new boolean[] { false, false, true, false, true, false, true, }; } 313 314 /** <CODE>[No Description Provided by Google]</CODE> */ 315 public final String credentialId; 316 317 /** <CODE>[No Description Provided by Google]</CODE> */ 318 public final boolean isResidentCredential; 319 320 /** 321 * Relying Party ID the credential is scoped to. Must be set when adding a 322 * credential. 323 * <BR /> 324 * <BR /><B>OPTIONAL</B> 325 */ 326 public final String rpId; 327 328 /** The ECDSA P-256 private key in PKCS#8 format. (Encoded as a base64 string when passed over JSON) */ 329 public final String privateKey; 330 331 /** 332 * An opaque byte sequence with a maximum size of 64 bytes mapping the 333 * credential to a specific user. (Encoded as a base64 string when passed over JSON) 334 * <BR /> 335 * <BR /><B>OPTIONAL</B> 336 */ 337 public final String userHandle; 338 339 /** 340 * Signature counter. This is incremented by one for each successful 341 * assertion. 342 * See https://w3c.github.io/webauthn/#signature-counter 343 */ 344 public final int signCount; 345 346 /** 347 * The large blob associated with the credential. 348 * See https://w3c.github.io/webauthn/#sctn-large-blob-extension (Encoded as a base64 string when passed over JSON) 349 * <BR /> 350 * <BR /><B>OPTIONAL</B> 351 */ 352 public final String largeBlob; 353 354 /** 355 * Constructor 356 * 357 * @param credentialId - 358 * 359 * @param isResidentCredential - 360 * 361 * @param rpId 362 * Relying Party ID the credential is scoped to. Must be set when adding a 363 * credential. 364 * <BR /><B>OPTIONAL</B> 365 * 366 * @param privateKey The ECDSA P-256 private key in PKCS#8 format. (Encoded as a base64 string when passed over JSON) 367 * 368 * @param userHandle 369 * An opaque byte sequence with a maximum size of 64 bytes mapping the 370 * credential to a specific user. (Encoded as a base64 string when passed over JSON) 371 * <BR /><B>OPTIONAL</B> 372 * 373 * @param signCount 374 * Signature counter. This is incremented by one for each successful 375 * assertion. 376 * See https://w3c.github.io/webauthn/#signature-counter 377 * 378 * @param largeBlob 379 * The large blob associated with the credential. 380 * See https://w3c.github.io/webauthn/#sctn-large-blob-extension (Encoded as a base64 string when passed over JSON) 381 * <BR /><B>OPTIONAL</B> 382 */ 383 public Credential( 384 String credentialId, boolean isResidentCredential, String rpId, String privateKey, 385 String userHandle, int signCount, String largeBlob 386 ) 387 { 388 // Exception-Check(s) to ensure that if any parameters which are not declared as 389 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 390 391 if (credentialId == null) BRDPC.throwNPE("credentialId"); 392 if (privateKey == null) BRDPC.throwNPE("privateKey"); 393 394 this.credentialId = credentialId; 395 this.isResidentCredential = isResidentCredential; 396 this.rpId = rpId; 397 this.privateKey = privateKey; 398 this.userHandle = userHandle; 399 this.signCount = signCount; 400 this.largeBlob = largeBlob; 401 } 402 403 /** 404 * JSON Object Constructor 405 * @param jo A Json-Object having data about an instance of {@code 'Credential'}. 406 */ 407 public Credential (JsonObject jo) 408 { 409 this.credentialId = ReadJSON.getString(jo, "credentialId", false, true); 410 this.isResidentCredential = ReadJSON.getBoolean(jo, "isResidentCredential"); 411 this.rpId = ReadJSON.getString(jo, "rpId", true, false); 412 this.privateKey = ReadJSON.getString(jo, "privateKey", false, true); 413 this.userHandle = ReadJSON.getString(jo, "userHandle", true, false); 414 this.signCount = ReadJSON.getInt(jo, "signCount"); 415 this.largeBlob = ReadJSON.getString(jo, "largeBlob", true, false); 416 } 417 418 } 419 420 421 // Counter for keeping the WebSocket Request ID's distinct. 422 private static int counter = 1; 423 424 /** 425 * Enable the WebAuthn domain and start intercepting credential storage and 426 * retrieval with a virtual authenticator. 427 * 428 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 429 * {@link Ret0}></CODE> 430 * 431 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 432 * browser receives the invocation-request. 433 * 434 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 435 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 436 * {@code >} to ensure the Browser Function has run to completion. 437 */ 438 public static Script<String, JsonObject, Ret0> enable() 439 { 440 final int webSocketID = 44000000 + counter++; 441 final boolean[] optionals = new boolean[0]; 442 443 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 444 String requestJSON = WriteJSON.get( 445 parameterTypes.get("enable"), 446 parameterNames.get("enable"), 447 optionals, webSocketID, 448 "WebAuthn.enable" 449 ); 450 451 // This Remote Command does not have a Return-Value. 452 return new Script<> 453 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 454 } 455 456 /** 457 * Disable the WebAuthn domain. 458 * 459 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 460 * {@link Ret0}></CODE> 461 * 462 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 463 * browser receives the invocation-request. 464 * 465 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 466 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 467 * {@code >} to ensure the Browser Function has run to completion. 468 */ 469 public static Script<String, JsonObject, Ret0> disable() 470 { 471 final int webSocketID = 44001000 + counter++; 472 final boolean[] optionals = new boolean[0]; 473 474 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 475 String requestJSON = WriteJSON.get( 476 parameterTypes.get("disable"), 477 parameterNames.get("disable"), 478 optionals, webSocketID, 479 "WebAuthn.disable" 480 ); 481 482 // This Remote Command does not have a Return-Value. 483 return new Script<> 484 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 485 } 486 487 /** 488 * Creates and adds a virtual authenticator. 489 * 490 * @param options - 491 * 492 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 493 * String></CODE> 494 * 495 * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using 496 * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE><JsonObject, 497 * String></CODE> will be returned. 498 * 499 * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>, 500 * using {@link Promise#await()}, <I>and the returned result of this Browser Function may 501 * may be retrieved.</I> 502 * 503 * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B> 504 * <BR /><BR /><UL CLASS=JDUL> 505 * <LI><CODE>String (<B>authenticatorId</B></CODE>) 506 * <BR />- 507 * </LI> 508 * </UL> */ 509 public static Script<String, JsonObject, String> addVirtualAuthenticator 510 (WebAuthn.VirtualAuthenticatorOptions options) 511 { 512 // Exception-Check(s) to ensure that if any parameters which are not declared as 513 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 514 515 if (options == null) BRDPC.throwNPE("options"); 516 517 final int webSocketID = 44002000 + counter++; 518 final boolean[] optionals = { false, }; 519 520 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 521 String requestJSON = WriteJSON.get( 522 parameterTypes.get("addVirtualAuthenticator"), 523 parameterNames.get("addVirtualAuthenticator"), 524 optionals, webSocketID, 525 "WebAuthn.addVirtualAuthenticator", 526 options 527 ); 528 529 // 'JSON Binding' ... Converts Browser Response-JSON to 'String' 530 Function<JsonObject, String> responseProcessor = (JsonObject jo) -> 531 ReadJSON.getString(jo, "authenticatorId", false, true); 532 533 // Pass the 'defaultSender' to Script-Constructor 534 // The sender that is used can be changed before executing script. 535 return new Script<>(BRDPC.defaultSender, webSocketID, requestJSON, responseProcessor); 536 } 537 538 /** 539 * Removes the given authenticator. 540 * 541 * @param authenticatorId - 542 * 543 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 544 * {@link Ret0}></CODE> 545 * 546 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 547 * browser receives the invocation-request. 548 * 549 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 550 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 551 * {@code >} to ensure the Browser Function has run to completion. 552 */ 553 public static Script<String, JsonObject, Ret0> removeVirtualAuthenticator 554 (String authenticatorId) 555 { 556 // Exception-Check(s) to ensure that if any parameters which are not declared as 557 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 558 559 if (authenticatorId == null) BRDPC.throwNPE("authenticatorId"); 560 561 final int webSocketID = 44003000 + counter++; 562 final boolean[] optionals = { false, }; 563 564 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 565 String requestJSON = WriteJSON.get( 566 parameterTypes.get("removeVirtualAuthenticator"), 567 parameterNames.get("removeVirtualAuthenticator"), 568 optionals, webSocketID, 569 "WebAuthn.removeVirtualAuthenticator", 570 authenticatorId 571 ); 572 573 // This Remote Command does not have a Return-Value. 574 return new Script<> 575 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 576 } 577 578 /** 579 * Adds the credential to the specified authenticator. 580 * 581 * @param authenticatorId - 582 * 583 * @param credential - 584 * 585 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 586 * {@link Ret0}></CODE> 587 * 588 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 589 * browser receives the invocation-request. 590 * 591 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 592 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 593 * {@code >} to ensure the Browser Function has run to completion. 594 */ 595 public static Script<String, JsonObject, Ret0> addCredential 596 (String authenticatorId, WebAuthn.Credential credential) 597 { 598 // Exception-Check(s) to ensure that if any parameters which are not declared as 599 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 600 601 if (authenticatorId == null) BRDPC.throwNPE("authenticatorId"); 602 if (credential == null) BRDPC.throwNPE("credential"); 603 604 final int webSocketID = 44004000 + counter++; 605 final boolean[] optionals = { false, false, }; 606 607 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 608 String requestJSON = WriteJSON.get( 609 parameterTypes.get("addCredential"), 610 parameterNames.get("addCredential"), 611 optionals, webSocketID, 612 "WebAuthn.addCredential", 613 authenticatorId, credential 614 ); 615 616 // This Remote Command does not have a Return-Value. 617 return new Script<> 618 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 619 } 620 621 /** 622 * Returns a single credential stored in the given virtual authenticator that 623 * matches the credential ID. 624 * 625 * @param authenticatorId - 626 * 627 * @param credentialId - 628 * 629 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 630 * {@link WebAuthn.Credential}></CODE> 631 * 632 * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using 633 * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE><JsonObject, 634 * {@link WebAuthn.Credential}></CODE> will be returned. 635 * 636 * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>, 637 * using {@link Promise#await()}, <I>and the returned result of this Browser Function may 638 * may be retrieved.</I> 639 * 640 * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B> 641 * <BR /><BR /><UL CLASS=JDUL> 642 * <LI><CODE>{@link WebAuthn.Credential} (<B>credential</B></CODE>) 643 * <BR />- 644 * </LI> 645 * </UL> */ 646 public static Script<String, JsonObject, WebAuthn.Credential> getCredential 647 (String authenticatorId, String credentialId) 648 { 649 // Exception-Check(s) to ensure that if any parameters which are not declared as 650 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 651 652 if (authenticatorId == null) BRDPC.throwNPE("authenticatorId"); 653 if (credentialId == null) BRDPC.throwNPE("credentialId"); 654 655 final int webSocketID = 44005000 + counter++; 656 final boolean[] optionals = { false, false, }; 657 658 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 659 String requestJSON = WriteJSON.get( 660 parameterTypes.get("getCredential"), 661 parameterNames.get("getCredential"), 662 optionals, webSocketID, 663 "WebAuthn.getCredential", 664 authenticatorId, credentialId 665 ); 666 667 // 'JSON Binding' ... Converts Browser Response-JSON to 'WebAuthn.Credential' 668 Function<JsonObject, WebAuthn.Credential> responseProcessor = (JsonObject jo) -> 669 ReadJSON.XL.getObject(jo, "credential", WebAuthn.Credential.class, false, true); 670 671 // Pass the 'defaultSender' to Script-Constructor 672 // The sender that is used can be changed before executing script. 673 return new Script<>(BRDPC.defaultSender, webSocketID, requestJSON, responseProcessor); 674 } 675 676 /** 677 * Returns all the credentials stored in the given virtual authenticator. 678 * 679 * @param authenticatorId - 680 * 681 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 682 * {@link WebAuthn.Credential}[]></CODE> 683 * 684 * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using 685 * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE><JsonObject, 686 * {@link WebAuthn.Credential}[]></CODE> will be returned. 687 * 688 * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>, 689 * using {@link Promise#await()}, <I>and the returned result of this Browser Function may 690 * may be retrieved.</I> 691 * 692 * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B> 693 * <BR /><BR /><UL CLASS=JDUL> 694 * <LI><CODE>{@link WebAuthn.Credential}[] (<B>credentials</B></CODE>) 695 * <BR />- 696 * </LI> 697 * </UL> */ 698 public static Script<String, JsonObject, WebAuthn.Credential[]> getCredentials 699 (String authenticatorId) 700 { 701 // Exception-Check(s) to ensure that if any parameters which are not declared as 702 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 703 704 if (authenticatorId == null) BRDPC.throwNPE("authenticatorId"); 705 706 final int webSocketID = 44006000 + counter++; 707 final boolean[] optionals = { false, }; 708 709 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 710 String requestJSON = WriteJSON.get( 711 parameterTypes.get("getCredentials"), 712 parameterNames.get("getCredentials"), 713 optionals, webSocketID, 714 "WebAuthn.getCredentials", 715 authenticatorId 716 ); 717 718 // 'JSON Binding' ... Converts Browser Response-JSON to 'WebAuthn.Credential[]' 719 Function<JsonObject, WebAuthn.Credential[]> responseProcessor = (JsonObject jo) -> 720 (jo.getJsonArray("credentials") == null) 721 ? null 722 : ReadArrJSON.DimN.objArr(jo.getJsonArray("credentials"), null, 0, WebAuthn.Credential[].class); 723 724 // Pass the 'defaultSender' to Script-Constructor 725 // The sender that is used can be changed before executing script. 726 return new Script<>(BRDPC.defaultSender, webSocketID, requestJSON, responseProcessor); 727 } 728 729 /** 730 * Removes a credential from the authenticator. 731 * 732 * @param authenticatorId - 733 * 734 * @param credentialId - 735 * 736 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 737 * {@link Ret0}></CODE> 738 * 739 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 740 * browser receives the invocation-request. 741 * 742 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 743 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 744 * {@code >} to ensure the Browser Function has run to completion. 745 */ 746 public static Script<String, JsonObject, Ret0> removeCredential 747 (String authenticatorId, String credentialId) 748 { 749 // Exception-Check(s) to ensure that if any parameters which are not declared as 750 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 751 752 if (authenticatorId == null) BRDPC.throwNPE("authenticatorId"); 753 if (credentialId == null) BRDPC.throwNPE("credentialId"); 754 755 final int webSocketID = 44007000 + counter++; 756 final boolean[] optionals = { false, false, }; 757 758 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 759 String requestJSON = WriteJSON.get( 760 parameterTypes.get("removeCredential"), 761 parameterNames.get("removeCredential"), 762 optionals, webSocketID, 763 "WebAuthn.removeCredential", 764 authenticatorId, credentialId 765 ); 766 767 // This Remote Command does not have a Return-Value. 768 return new Script<> 769 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 770 } 771 772 /** 773 * Clears all the credentials from the specified device. 774 * 775 * @param authenticatorId - 776 * 777 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 778 * {@link Ret0}></CODE> 779 * 780 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 781 * browser receives the invocation-request. 782 * 783 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 784 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 785 * {@code >} to ensure the Browser Function has run to completion. 786 */ 787 public static Script<String, JsonObject, Ret0> clearCredentials(String authenticatorId) 788 { 789 // Exception-Check(s) to ensure that if any parameters which are not declared as 790 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 791 792 if (authenticatorId == null) BRDPC.throwNPE("authenticatorId"); 793 794 final int webSocketID = 44008000 + counter++; 795 final boolean[] optionals = { false, }; 796 797 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 798 String requestJSON = WriteJSON.get( 799 parameterTypes.get("clearCredentials"), 800 parameterNames.get("clearCredentials"), 801 optionals, webSocketID, 802 "WebAuthn.clearCredentials", 803 authenticatorId 804 ); 805 806 // This Remote Command does not have a Return-Value. 807 return new Script<> 808 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 809 } 810 811 /** 812 * Sets whether User Verification succeeds or fails for an authenticator. 813 * The default is true. 814 * 815 * @param authenticatorId - 816 * 817 * @param isUserVerified - 818 * 819 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 820 * {@link Ret0}></CODE> 821 * 822 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 823 * browser receives the invocation-request. 824 * 825 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 826 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 827 * {@code >} to ensure the Browser Function has run to completion. 828 */ 829 public static Script<String, JsonObject, Ret0> setUserVerified 830 (String authenticatorId, boolean isUserVerified) 831 { 832 // Exception-Check(s) to ensure that if any parameters which are not declared as 833 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 834 835 if (authenticatorId == null) BRDPC.throwNPE("authenticatorId"); 836 837 final int webSocketID = 44009000 + counter++; 838 final boolean[] optionals = { false, false, }; 839 840 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 841 String requestJSON = WriteJSON.get( 842 parameterTypes.get("setUserVerified"), 843 parameterNames.get("setUserVerified"), 844 optionals, webSocketID, 845 "WebAuthn.setUserVerified", 846 authenticatorId, isUserVerified 847 ); 848 849 // This Remote Command does not have a Return-Value. 850 return new Script<> 851 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 852 } 853 854 /** 855 * Sets whether tests of user presence will succeed immediately (if true) or fail to resolve (if false) for an authenticator. 856 * The default is true. 857 * 858 * @param authenticatorId - 859 * 860 * @param enabled - 861 * 862 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 863 * {@link Ret0}></CODE> 864 * 865 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 866 * browser receives the invocation-request. 867 * 868 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 869 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 870 * {@code >} to ensure the Browser Function has run to completion. 871 */ 872 public static Script<String, JsonObject, Ret0> setAutomaticPresenceSimulation 873 (String authenticatorId, boolean enabled) 874 { 875 // Exception-Check(s) to ensure that if any parameters which are not declared as 876 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 877 878 if (authenticatorId == null) BRDPC.throwNPE("authenticatorId"); 879 880 final int webSocketID = 44010000 + counter++; 881 final boolean[] optionals = { false, false, }; 882 883 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 884 String requestJSON = WriteJSON.get( 885 parameterTypes.get("setAutomaticPresenceSimulation"), 886 parameterNames.get("setAutomaticPresenceSimulation"), 887 optionals, webSocketID, 888 "WebAuthn.setAutomaticPresenceSimulation", 889 authenticatorId, enabled 890 ); 891 892 // This Remote Command does not have a Return-Value. 893 return new Script<> 894 (BRDPC.defaultSender, webSocketID, requestJSON, BRDPC.NoReturnValues); 895 } 896 897}