001package Torello.Browser.BrowserAPI; 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.Browser.BrowserEvent; 013import Torello.Browser.JavaScriptAPI.*; 014import Torello.Browser.helper.*; 015 016import Torello.Java.Additional.*; 017import Torello.Java.JSON.*; 018 019import static Torello.Java.JSON.JFlag.*; 020 021import Torello.Java.StrCmpr; 022import Torello.JavaDoc.StaticFunctional; 023import Torello.JavaDoc.JDHeaderBackgroundImg; 024import Torello.JavaDoc.Excuse; 025 026/** 027 * <SPAN CLASS=COPIEDJDK><B>This domain allows configuring virtual authenticators to test the WebAuthn 028 * API.</B></SPAN> 029 * 030 * <EMBED CLASS='external-html' DATA-FILE-ID=CODE_GEN_NOTE> 031 */ 032@StaticFunctional(Excused={"counter"}, Excuses={Excuse.CONFIGURATION}) 033@JDHeaderBackgroundImg(EmbedTagFileID="WOOD_PLANK_NOTE") 034public class WebAuthn 035{ 036 // ******************************************************************************************** 037 // ******************************************************************************************** 038 // Class Header Stuff 039 // ******************************************************************************************** 040 // ******************************************************************************************** 041 042 043 // No Pubic Constructors 044 private WebAuthn () { } 045 046 // These two Vector's are used by all the "Methods" exported by this class. java.lang.reflect 047 // is used to generate the JSON String's. It saves thousands of lines of Auto-Generated Code. 048 private static final Map<String, Vector<String>> parameterNames = new HashMap<>(); 049 private static final Map<String, Vector<Class<?>>> parameterTypes = new HashMap<>(); 050 051 // Some Methods do not take any parameters - for instance all the "enable()" and "disable()" 052 // I simply could not get ride of RAW-TYPES and UNCHECKED warnings... so there are now, 053 // offically, two empty-vectors. One for String's, and the other for Classes. 054 055 private static final Vector<String> EMPTY_VEC_STR = new Vector<>(); 056 private static final Vector<Class<?>> EMPTY_VEC_CLASS = new Vector<>(); 057 058 static 059 { 060 for (Method m : WebAuthn.class.getMethods()) 061 { 062 // This doesn't work! The parameter names are all "arg0" ... "argN" 063 // It works for java.lang.reflect.Field, BUT NOT java.lang.reflect.Parameter! 064 // 065 // Vector<String> parameterNamesList = new Vector<>(); -- NOPE! 066 067 Vector<Class<?>> parameterTypesList = new Vector<>(); 068 069 for (Parameter p : m.getParameters()) parameterTypesList.add(p.getType()); 070 071 parameterTypes.put( 072 m.getName(), 073 (parameterTypesList.size() > 0) ? parameterTypesList : EMPTY_VEC_CLASS 074 ); 075 } 076 } 077 078 static 079 { 080 Vector<String> v = null; 081 082 v = new Vector<String>(1); 083 parameterNames.put("enable", v); 084 Collections.addAll(v, new String[] 085 { "enableUI", }); 086 087 parameterNames.put("disable", EMPTY_VEC_STR); 088 089 v = new Vector<String>(1); 090 parameterNames.put("addVirtualAuthenticator", v); 091 Collections.addAll(v, new String[] 092 { "options", }); 093 094 v = new Vector<String>(4); 095 parameterNames.put("setResponseOverrideBits", v); 096 Collections.addAll(v, new String[] 097 { "authenticatorId", "isBogusSignature", "isBadUV", "isBadUP", }); 098 099 v = new Vector<String>(1); 100 parameterNames.put("removeVirtualAuthenticator", v); 101 Collections.addAll(v, new String[] 102 { "authenticatorId", }); 103 104 v = new Vector<String>(2); 105 parameterNames.put("addCredential", v); 106 Collections.addAll(v, new String[] 107 { "authenticatorId", "credential", }); 108 109 v = new Vector<String>(2); 110 parameterNames.put("getCredential", v); 111 Collections.addAll(v, new String[] 112 { "authenticatorId", "credentialId", }); 113 114 v = new Vector<String>(1); 115 parameterNames.put("getCredentials", v); 116 Collections.addAll(v, new String[] 117 { "authenticatorId", }); 118 119 v = new Vector<String>(2); 120 parameterNames.put("removeCredential", v); 121 Collections.addAll(v, new String[] 122 { "authenticatorId", "credentialId", }); 123 124 v = new Vector<String>(1); 125 parameterNames.put("clearCredentials", v); 126 Collections.addAll(v, new String[] 127 { "authenticatorId", }); 128 129 v = new Vector<String>(2); 130 parameterNames.put("setUserVerified", v); 131 Collections.addAll(v, new String[] 132 { "authenticatorId", "isUserVerified", }); 133 134 v = new Vector<String>(2); 135 parameterNames.put("setAutomaticPresenceSimulation", v); 136 Collections.addAll(v, new String[] 137 { "authenticatorId", "enabled", }); 138 139 v = new Vector<String>(4); 140 parameterNames.put("setCredentialProperties", v); 141 Collections.addAll(v, new String[] 142 { "authenticatorId", "credentialId", "backupEligibility", "backupState", }); 143 } 144 145 146 // ******************************************************************************************** 147 // ******************************************************************************************** 148 // Types - Static Inner Classes 149 // ******************************************************************************************** 150 // ******************************************************************************************** 151 152 // public static class AuthenticatorId => String 153 154 /** <CODE>[No Description Provided by Google]</CODE> */ 155 public static final String[] AuthenticatorProtocol = 156 { "u2f", "ctap2", }; 157 158 /** <CODE>[No Description Provided by Google]</CODE> */ 159 public static final String[] Ctap2Version = 160 { "ctap2_0", "ctap2_1", }; 161 162 /** <CODE>[No Description Provided by Google]</CODE> */ 163 public static final String[] AuthenticatorTransport = 164 { "usb", "nfc", "ble", "cable", "internal", }; 165 166 /** <CODE>[No Description Provided by Google]</CODE> */ 167 public static class VirtualAuthenticatorOptions 168 extends BaseType 169 implements java.io.Serializable 170 { 171 /** For Object Serialization. java.io.Serializable */ 172 protected static final long serialVersionUID = 1; 173 174 public boolean[] optionals() 175 { return new boolean[] { false, true, false, true, true, true, true, true, true, true, true, true, true, }; } 176 177 /** <CODE>[No Description Provided by Google]</CODE> */ 178 public final String protocol; 179 180 /** 181 * Defaults to ctap2_0. Ignored if |protocol| == u2f. 182 * <BR /><B CLASS=Opt>OPTIONAL</B> 183 */ 184 public final String ctap2Version; 185 186 /** <CODE>[No Description Provided by Google]</CODE> */ 187 public final String transport; 188 189 /** 190 * Defaults to false. 191 * <BR /><B CLASS=Opt>OPTIONAL</B> 192 */ 193 public final Boolean hasResidentKey; 194 195 /** 196 * Defaults to false. 197 * <BR /><B CLASS=Opt>OPTIONAL</B> 198 */ 199 public final Boolean hasUserVerification; 200 201 /** 202 * If set to true, the authenticator will support the largeBlob extension. 203 * https://w3c.github.io/webauthn#largeBlob 204 * Defaults to false. 205 * <BR /><B CLASS=Opt>OPTIONAL</B> 206 */ 207 public final Boolean hasLargeBlob; 208 209 /** 210 * If set to true, the authenticator will support the credBlob extension. 211 * https://fidoalliance.org/specs/fido-v2.1-rd-20201208/fido-client-to-authenticator-protocol-v2.1-rd-20201208.html#sctn-credBlob-extension 212 * Defaults to false. 213 * <BR /><B CLASS=Opt>OPTIONAL</B> 214 */ 215 public final Boolean hasCredBlob; 216 217 /** 218 * If set to true, the authenticator will support the minPinLength extension. 219 * https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-minpinlength-extension 220 * Defaults to false. 221 * <BR /><B CLASS=Opt>OPTIONAL</B> 222 */ 223 public final Boolean hasMinPinLength; 224 225 /** 226 * If set to true, the authenticator will support the prf extension. 227 * https://w3c.github.io/webauthn/#prf-extension 228 * Defaults to false. 229 * <BR /><B CLASS=Opt>OPTIONAL</B> 230 */ 231 public final Boolean hasPrf; 232 233 /** 234 * If set to true, tests of user presence will succeed immediately. 235 * Otherwise, they will not be resolved. Defaults to true. 236 * <BR /><B CLASS=Opt>OPTIONAL</B> 237 */ 238 public final Boolean automaticPresenceSimulation; 239 240 /** 241 * Sets whether User Verification succeeds or fails for an authenticator. 242 * Defaults to false. 243 * <BR /><B CLASS=Opt>OPTIONAL</B> 244 */ 245 public final Boolean isUserVerified; 246 247 /** 248 * Credentials created by this authenticator will have the backup 249 * eligibility (BE) flag set to this value. Defaults to false. 250 * https://w3c.github.io/webauthn/#sctn-credential-backup 251 * <BR /><B CLASS=Opt>OPTIONAL</B> 252 */ 253 public final Boolean defaultBackupEligibility; 254 255 /** 256 * Credentials created by this authenticator will have the backup state 257 * (BS) flag set to this value. Defaults to false. 258 * https://w3c.github.io/webauthn/#sctn-credential-backup 259 * <BR /><B CLASS=Opt>OPTIONAL</B> 260 */ 261 public final Boolean defaultBackupState; 262 263 /** 264 * Constructor 265 * 266 * @param protocol - 267 * 268 * @param ctap2Version Defaults to ctap2_0. Ignored if |protocol| == u2f. 269 * <BR /><B CLASS=Opt>OPTIONAL</B> 270 * 271 * @param transport - 272 * 273 * @param hasResidentKey Defaults to false. 274 * <BR /><B CLASS=Opt>OPTIONAL</B> 275 * 276 * @param hasUserVerification Defaults to false. 277 * <BR /><B CLASS=Opt>OPTIONAL</B> 278 * 279 * @param hasLargeBlob 280 * If set to true, the authenticator will support the largeBlob extension. 281 * https://w3c.github.io/webauthn#largeBlob 282 * Defaults to false. 283 * <BR /><B CLASS=Opt>OPTIONAL</B> 284 * 285 * @param hasCredBlob 286 * If set to true, the authenticator will support the credBlob extension. 287 * https://fidoalliance.org/specs/fido-v2.1-rd-20201208/fido-client-to-authenticator-protocol-v2.1-rd-20201208.html#sctn-credBlob-extension 288 * Defaults to false. 289 * <BR /><B CLASS=Opt>OPTIONAL</B> 290 * 291 * @param hasMinPinLength 292 * If set to true, the authenticator will support the minPinLength extension. 293 * https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-20210615.html#sctn-minpinlength-extension 294 * Defaults to false. 295 * <BR /><B CLASS=Opt>OPTIONAL</B> 296 * 297 * @param hasPrf 298 * If set to true, the authenticator will support the prf extension. 299 * https://w3c.github.io/webauthn/#prf-extension 300 * Defaults to false. 301 * <BR /><B CLASS=Opt>OPTIONAL</B> 302 * 303 * @param automaticPresenceSimulation 304 * If set to true, tests of user presence will succeed immediately. 305 * Otherwise, they will not be resolved. Defaults to true. 306 * <BR /><B CLASS=Opt>OPTIONAL</B> 307 * 308 * @param isUserVerified 309 * Sets whether User Verification succeeds or fails for an authenticator. 310 * Defaults to false. 311 * <BR /><B CLASS=Opt>OPTIONAL</B> 312 * 313 * @param defaultBackupEligibility 314 * Credentials created by this authenticator will have the backup 315 * eligibility (BE) flag set to this value. Defaults to false. 316 * https://w3c.github.io/webauthn/#sctn-credential-backup 317 * <BR /><B CLASS=Opt>OPTIONAL</B> 318 * 319 * @param defaultBackupState 320 * Credentials created by this authenticator will have the backup state 321 * (BS) flag set to this value. Defaults to false. 322 * https://w3c.github.io/webauthn/#sctn-credential-backup 323 * <BR /><B CLASS=Opt>OPTIONAL</B> 324 */ 325 public VirtualAuthenticatorOptions( 326 String protocol, String ctap2Version, String transport, Boolean hasResidentKey, 327 Boolean hasUserVerification, Boolean hasLargeBlob, Boolean hasCredBlob, 328 Boolean hasMinPinLength, Boolean hasPrf, Boolean automaticPresenceSimulation, 329 Boolean isUserVerified, Boolean defaultBackupEligibility, Boolean defaultBackupState 330 ) 331 { 332 // Exception-Check(s) to ensure that if any parameters which are not declared as 333 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 334 335 if (protocol == null) THROWS.throwNPE("protocol"); 336 if (transport == null) THROWS.throwNPE("transport"); 337 338 // Exception-Check(s) to ensure that if any parameters which must adhere to a 339 // provided List of Enumerated Values, fails, then IllegalArgumentException shall throw. 340 341 THROWS.checkIAE("protocol", protocol, "WebAuthn.AuthenticatorProtocol", WebAuthn.AuthenticatorProtocol); 342 THROWS.checkIAE("ctap2Version", ctap2Version, "WebAuthn.Ctap2Version", WebAuthn.Ctap2Version); 343 THROWS.checkIAE("transport", transport, "WebAuthn.AuthenticatorTransport", WebAuthn.AuthenticatorTransport); 344 345 this.protocol = protocol; 346 this.ctap2Version = ctap2Version; 347 this.transport = transport; 348 this.hasResidentKey = hasResidentKey; 349 this.hasUserVerification = hasUserVerification; 350 this.hasLargeBlob = hasLargeBlob; 351 this.hasCredBlob = hasCredBlob; 352 this.hasMinPinLength = hasMinPinLength; 353 this.hasPrf = hasPrf; 354 this.automaticPresenceSimulation = automaticPresenceSimulation; 355 this.isUserVerified = isUserVerified; 356 this.defaultBackupEligibility = defaultBackupEligibility; 357 this.defaultBackupState = defaultBackupState; 358 } 359 360 /** 361 * JSON Object Constructor 362 * @param jo A Json-Object having data about an instance of {@code 'VirtualAuthenticatorOptions'}. 363 */ 364 public VirtualAuthenticatorOptions (JsonObject jo) 365 { 366 this.protocol = ReadJSON.getString(jo, "protocol", false, true); 367 this.ctap2Version = ReadJSON.getString(jo, "ctap2Version", true, false); 368 this.transport = ReadJSON.getString(jo, "transport", false, true); 369 this.hasResidentKey = ReadBoxedJSON.getBoolean(jo, "hasResidentKey", true); 370 this.hasUserVerification = ReadBoxedJSON.getBoolean(jo, "hasUserVerification", true); 371 this.hasLargeBlob = ReadBoxedJSON.getBoolean(jo, "hasLargeBlob", true); 372 this.hasCredBlob = ReadBoxedJSON.getBoolean(jo, "hasCredBlob", true); 373 this.hasMinPinLength = ReadBoxedJSON.getBoolean(jo, "hasMinPinLength", true); 374 this.hasPrf = ReadBoxedJSON.getBoolean(jo, "hasPrf", true); 375 this.automaticPresenceSimulation = ReadBoxedJSON.getBoolean(jo, "automaticPresenceSimulation", true); 376 this.isUserVerified = ReadBoxedJSON.getBoolean(jo, "isUserVerified", true); 377 this.defaultBackupEligibility = ReadBoxedJSON.getBoolean(jo, "defaultBackupEligibility", true); 378 this.defaultBackupState = ReadBoxedJSON.getBoolean(jo, "defaultBackupState", true); 379 } 380 381 382 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 383 public boolean equals(Object other) 384 { 385 if (this == other) return true; 386 if (other == null) return false; 387 if (other.getClass() != this.getClass()) return false; 388 389 VirtualAuthenticatorOptions o = (VirtualAuthenticatorOptions) other; 390 391 return 392 Objects.equals(this.protocol, o.protocol) 393 && Objects.equals(this.ctap2Version, o.ctap2Version) 394 && Objects.equals(this.transport, o.transport) 395 && Objects.equals(this.hasResidentKey, o.hasResidentKey) 396 && Objects.equals(this.hasUserVerification, o.hasUserVerification) 397 && Objects.equals(this.hasLargeBlob, o.hasLargeBlob) 398 && Objects.equals(this.hasCredBlob, o.hasCredBlob) 399 && Objects.equals(this.hasMinPinLength, o.hasMinPinLength) 400 && Objects.equals(this.hasPrf, o.hasPrf) 401 && Objects.equals(this.automaticPresenceSimulation, o.automaticPresenceSimulation) 402 && Objects.equals(this.isUserVerified, o.isUserVerified) 403 && Objects.equals(this.defaultBackupEligibility, o.defaultBackupEligibility) 404 && Objects.equals(this.defaultBackupState, o.defaultBackupState); 405 } 406 407 /** Generates a Hash-Code for {@code 'this'} instance */ 408 public int hashCode() 409 { 410 return 411 Objects.hashCode(this.protocol) 412 + Objects.hashCode(this.ctap2Version) 413 + Objects.hashCode(this.transport) 414 + Objects.hashCode(this.hasResidentKey) 415 + Objects.hashCode(this.hasUserVerification) 416 + Objects.hashCode(this.hasLargeBlob) 417 + Objects.hashCode(this.hasCredBlob) 418 + Objects.hashCode(this.hasMinPinLength) 419 + Objects.hashCode(this.hasPrf) 420 + Objects.hashCode(this.automaticPresenceSimulation) 421 + Objects.hashCode(this.isUserVerified) 422 + Objects.hashCode(this.defaultBackupEligibility) 423 + Objects.hashCode(this.defaultBackupState); 424 } 425 } 426 427 /** <CODE>[No Description Provided by Google]</CODE> */ 428 public static class Credential 429 extends BaseType 430 implements java.io.Serializable 431 { 432 /** For Object Serialization. java.io.Serializable */ 433 protected static final long serialVersionUID = 1; 434 435 public boolean[] optionals() 436 { return new boolean[] { false, false, true, false, true, false, true, true, true, true, true, }; } 437 438 /** <CODE>[No Description Provided by Google]</CODE> */ 439 public final String credentialId; 440 441 /** <CODE>[No Description Provided by Google]</CODE> */ 442 public final boolean isResidentCredential; 443 444 /** 445 * Relying Party ID the credential is scoped to. Must be set when adding a 446 * credential. 447 * <BR /><B CLASS=Opt>OPTIONAL</B> 448 */ 449 public final String rpId; 450 451 /** The ECDSA P-256 private key in PKCS#8 format. (Encoded as a base64 string when passed over JSON) */ 452 public final String privateKey; 453 454 /** 455 * An opaque byte sequence with a maximum size of 64 bytes mapping the 456 * credential to a specific user. (Encoded as a base64 string when passed over JSON) 457 * <BR /><B CLASS=Opt>OPTIONAL</B> 458 */ 459 public final String userHandle; 460 461 /** 462 * Signature counter. This is incremented by one for each successful 463 * assertion. 464 * See https://w3c.github.io/webauthn/#signature-counter 465 */ 466 public final int signCount; 467 468 /** 469 * The large blob associated with the credential. 470 * See https://w3c.github.io/webauthn/#sctn-large-blob-extension (Encoded as a base64 string when passed over JSON) 471 * <BR /><B CLASS=Opt>OPTIONAL</B> 472 */ 473 public final String largeBlob; 474 475 /** 476 * Assertions returned by this credential will have the backup eligibility 477 * (BE) flag set to this value. Defaults to the authenticator's 478 * defaultBackupEligibility value. 479 * <BR /><B CLASS=Opt>OPTIONAL</B> 480 */ 481 public final Boolean backupEligibility; 482 483 /** 484 * Assertions returned by this credential will have the backup state (BS) 485 * flag set to this value. Defaults to the authenticator's 486 * defaultBackupState value. 487 * <BR /><B CLASS=Opt>OPTIONAL</B> 488 */ 489 public final Boolean backupState; 490 491 /** 492 * The credential's user.name property. Equivalent to empty if not set. 493 * https://w3c.github.io/webauthn/#dom-publickeycredentialentity-name 494 * <BR /><B CLASS=Opt>OPTIONAL</B> 495 */ 496 public final String userName; 497 498 /** 499 * The credential's user.displayName property. Equivalent to empty if 500 * not set. 501 * https://w3c.github.io/webauthn/#dom-publickeycredentialuserentity-displayname 502 * <BR /><B CLASS=Opt>OPTIONAL</B> 503 */ 504 public final String userDisplayName; 505 506 /** 507 * Constructor 508 * 509 * @param credentialId - 510 * 511 * @param isResidentCredential - 512 * 513 * @param rpId 514 * Relying Party ID the credential is scoped to. Must be set when adding a 515 * credential. 516 * <BR /><B CLASS=Opt>OPTIONAL</B> 517 * 518 * @param privateKey The ECDSA P-256 private key in PKCS#8 format. (Encoded as a base64 string when passed over JSON) 519 * 520 * @param userHandle 521 * An opaque byte sequence with a maximum size of 64 bytes mapping the 522 * credential to a specific user. (Encoded as a base64 string when passed over JSON) 523 * <BR /><B CLASS=Opt>OPTIONAL</B> 524 * 525 * @param signCount 526 * Signature counter. This is incremented by one for each successful 527 * assertion. 528 * See https://w3c.github.io/webauthn/#signature-counter 529 * 530 * @param largeBlob 531 * The large blob associated with the credential. 532 * See https://w3c.github.io/webauthn/#sctn-large-blob-extension (Encoded as a base64 string when passed over JSON) 533 * <BR /><B CLASS=Opt>OPTIONAL</B> 534 * 535 * @param backupEligibility 536 * Assertions returned by this credential will have the backup eligibility 537 * (BE) flag set to this value. Defaults to the authenticator's 538 * defaultBackupEligibility value. 539 * <BR /><B CLASS=Opt>OPTIONAL</B> 540 * 541 * @param backupState 542 * Assertions returned by this credential will have the backup state (BS) 543 * flag set to this value. Defaults to the authenticator's 544 * defaultBackupState value. 545 * <BR /><B CLASS=Opt>OPTIONAL</B> 546 * 547 * @param userName 548 * The credential's user.name property. Equivalent to empty if not set. 549 * https://w3c.github.io/webauthn/#dom-publickeycredentialentity-name 550 * <BR /><B CLASS=Opt>OPTIONAL</B> 551 * 552 * @param userDisplayName 553 * The credential's user.displayName property. Equivalent to empty if 554 * not set. 555 * https://w3c.github.io/webauthn/#dom-publickeycredentialuserentity-displayname 556 * <BR /><B CLASS=Opt>OPTIONAL</B> 557 */ 558 public Credential( 559 String credentialId, boolean isResidentCredential, String rpId, String privateKey, 560 String userHandle, int signCount, String largeBlob, Boolean backupEligibility, 561 Boolean backupState, String userName, String userDisplayName 562 ) 563 { 564 // Exception-Check(s) to ensure that if any parameters which are not declared as 565 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 566 567 if (credentialId == null) THROWS.throwNPE("credentialId"); 568 if (privateKey == null) THROWS.throwNPE("privateKey"); 569 570 this.credentialId = credentialId; 571 this.isResidentCredential = isResidentCredential; 572 this.rpId = rpId; 573 this.privateKey = privateKey; 574 this.userHandle = userHandle; 575 this.signCount = signCount; 576 this.largeBlob = largeBlob; 577 this.backupEligibility = backupEligibility; 578 this.backupState = backupState; 579 this.userName = userName; 580 this.userDisplayName = userDisplayName; 581 } 582 583 /** 584 * JSON Object Constructor 585 * @param jo A Json-Object having data about an instance of {@code 'Credential'}. 586 */ 587 public Credential (JsonObject jo) 588 { 589 this.credentialId = ReadJSON.getString(jo, "credentialId", false, true); 590 this.isResidentCredential = ReadPrimJSON.getBoolean(jo, "isResidentCredential"); 591 this.rpId = ReadJSON.getString(jo, "rpId", true, false); 592 this.privateKey = ReadJSON.getString(jo, "privateKey", false, true); 593 this.userHandle = ReadJSON.getString(jo, "userHandle", true, false); 594 this.signCount = ReadPrimJSON.getInt(jo, "signCount"); 595 this.largeBlob = ReadJSON.getString(jo, "largeBlob", true, false); 596 this.backupEligibility = ReadBoxedJSON.getBoolean(jo, "backupEligibility", true); 597 this.backupState = ReadBoxedJSON.getBoolean(jo, "backupState", true); 598 this.userName = ReadJSON.getString(jo, "userName", true, false); 599 this.userDisplayName = ReadJSON.getString(jo, "userDisplayName", true, false); 600 } 601 602 603 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 604 public boolean equals(Object other) 605 { 606 if (this == other) return true; 607 if (other == null) return false; 608 if (other.getClass() != this.getClass()) return false; 609 610 Credential o = (Credential) other; 611 612 return 613 Objects.equals(this.credentialId, o.credentialId) 614 && (this.isResidentCredential == o.isResidentCredential) 615 && Objects.equals(this.rpId, o.rpId) 616 && Objects.equals(this.privateKey, o.privateKey) 617 && Objects.equals(this.userHandle, o.userHandle) 618 && (this.signCount == o.signCount) 619 && Objects.equals(this.largeBlob, o.largeBlob) 620 && Objects.equals(this.backupEligibility, o.backupEligibility) 621 && Objects.equals(this.backupState, o.backupState) 622 && Objects.equals(this.userName, o.userName) 623 && Objects.equals(this.userDisplayName, o.userDisplayName); 624 } 625 626 /** Generates a Hash-Code for {@code 'this'} instance */ 627 public int hashCode() 628 { 629 return 630 Objects.hashCode(this.credentialId) 631 + (this.isResidentCredential ? 1 : 0) 632 + Objects.hashCode(this.rpId) 633 + Objects.hashCode(this.privateKey) 634 + Objects.hashCode(this.userHandle) 635 + this.signCount 636 + Objects.hashCode(this.largeBlob) 637 + Objects.hashCode(this.backupEligibility) 638 + Objects.hashCode(this.backupState) 639 + Objects.hashCode(this.userName) 640 + Objects.hashCode(this.userDisplayName); 641 } 642 } 643 644 /** Triggered when a credential is added to an authenticator. */ 645 public static class credentialAdded 646 extends BrowserEvent 647 implements java.io.Serializable 648 { 649 /** For Object Serialization. java.io.Serializable */ 650 protected static final long serialVersionUID = 1; 651 652 public boolean[] optionals() 653 { return new boolean[] { false, false, }; } 654 655 /** <CODE>[No Description Provided by Google]</CODE> */ 656 public final String authenticatorId; 657 658 /** <CODE>[No Description Provided by Google]</CODE> */ 659 public final WebAuthn.Credential credential; 660 661 /** 662 * Constructor 663 * 664 * @param authenticatorId - 665 * 666 * @param credential - 667 */ 668 public credentialAdded(String authenticatorId, WebAuthn.Credential credential) 669 { 670 super("WebAuthn", "credentialAdded", 2); 671 672 // Exception-Check(s) to ensure that if any parameters which are not declared as 673 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 674 675 if (authenticatorId == null) THROWS.throwNPE("authenticatorId"); 676 if (credential == null) THROWS.throwNPE("credential"); 677 678 this.authenticatorId = authenticatorId; 679 this.credential = credential; 680 } 681 682 /** 683 * JSON Object Constructor 684 * @param jo A Json-Object having data about an instance of {@code 'credentialAdded'}. 685 */ 686 public credentialAdded (JsonObject jo) 687 { 688 super("WebAuthn", "credentialAdded", 2); 689 690 this.authenticatorId = ReadJSON.getString(jo, "authenticatorId", false, true); 691 this.credential = ReadJSON.getObject(jo, "credential", WebAuthn.Credential.class, false, true); 692 } 693 694 695 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 696 public boolean equals(Object other) 697 { 698 if (this == other) return true; 699 if (other == null) return false; 700 if (other.getClass() != this.getClass()) return false; 701 702 credentialAdded o = (credentialAdded) other; 703 704 return 705 Objects.equals(this.authenticatorId, o.authenticatorId) 706 && Objects.equals(this.credential, o.credential); 707 } 708 709 /** Generates a Hash-Code for {@code 'this'} instance */ 710 public int hashCode() 711 { 712 return 713 Objects.hashCode(this.authenticatorId) 714 + this.credential.hashCode(); 715 } 716 } 717 718 /** 719 * Triggered when a credential is deleted, e.g. through 720 * PublicKeyCredential.signalUnknownCredential(). 721 */ 722 public static class credentialDeleted 723 extends BrowserEvent 724 implements java.io.Serializable 725 { 726 /** For Object Serialization. java.io.Serializable */ 727 protected static final long serialVersionUID = 1; 728 729 public boolean[] optionals() 730 { return new boolean[] { false, false, }; } 731 732 /** <CODE>[No Description Provided by Google]</CODE> */ 733 public final String authenticatorId; 734 735 /** <CODE>[No Description Provided by Google]</CODE> */ 736 public final String credentialId; 737 738 /** 739 * Constructor 740 * 741 * @param authenticatorId - 742 * 743 * @param credentialId - 744 */ 745 public credentialDeleted(String authenticatorId, String credentialId) 746 { 747 super("WebAuthn", "credentialDeleted", 2); 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) THROWS.throwNPE("authenticatorId"); 753 if (credentialId == null) THROWS.throwNPE("credentialId"); 754 755 this.authenticatorId = authenticatorId; 756 this.credentialId = credentialId; 757 } 758 759 /** 760 * JSON Object Constructor 761 * @param jo A Json-Object having data about an instance of {@code 'credentialDeleted'}. 762 */ 763 public credentialDeleted (JsonObject jo) 764 { 765 super("WebAuthn", "credentialDeleted", 2); 766 767 this.authenticatorId = ReadJSON.getString(jo, "authenticatorId", false, true); 768 this.credentialId = ReadJSON.getString(jo, "credentialId", false, true); 769 } 770 771 772 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 773 public boolean equals(Object other) 774 { 775 if (this == other) return true; 776 if (other == null) return false; 777 if (other.getClass() != this.getClass()) return false; 778 779 credentialDeleted o = (credentialDeleted) other; 780 781 return 782 Objects.equals(this.authenticatorId, o.authenticatorId) 783 && Objects.equals(this.credentialId, o.credentialId); 784 } 785 786 /** Generates a Hash-Code for {@code 'this'} instance */ 787 public int hashCode() 788 { 789 return 790 Objects.hashCode(this.authenticatorId) 791 + Objects.hashCode(this.credentialId); 792 } 793 } 794 795 /** 796 * Triggered when a credential is updated, e.g. through 797 * PublicKeyCredential.signalCurrentUserDetails(). 798 */ 799 public static class credentialUpdated 800 extends BrowserEvent 801 implements java.io.Serializable 802 { 803 /** For Object Serialization. java.io.Serializable */ 804 protected static final long serialVersionUID = 1; 805 806 public boolean[] optionals() 807 { return new boolean[] { false, false, }; } 808 809 /** <CODE>[No Description Provided by Google]</CODE> */ 810 public final String authenticatorId; 811 812 /** <CODE>[No Description Provided by Google]</CODE> */ 813 public final WebAuthn.Credential credential; 814 815 /** 816 * Constructor 817 * 818 * @param authenticatorId - 819 * 820 * @param credential - 821 */ 822 public credentialUpdated(String authenticatorId, WebAuthn.Credential credential) 823 { 824 super("WebAuthn", "credentialUpdated", 2); 825 826 // Exception-Check(s) to ensure that if any parameters which are not declared as 827 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 828 829 if (authenticatorId == null) THROWS.throwNPE("authenticatorId"); 830 if (credential == null) THROWS.throwNPE("credential"); 831 832 this.authenticatorId = authenticatorId; 833 this.credential = credential; 834 } 835 836 /** 837 * JSON Object Constructor 838 * @param jo A Json-Object having data about an instance of {@code 'credentialUpdated'}. 839 */ 840 public credentialUpdated (JsonObject jo) 841 { 842 super("WebAuthn", "credentialUpdated", 2); 843 844 this.authenticatorId = ReadJSON.getString(jo, "authenticatorId", false, true); 845 this.credential = ReadJSON.getObject(jo, "credential", WebAuthn.Credential.class, false, true); 846 } 847 848 849 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 850 public boolean equals(Object other) 851 { 852 if (this == other) return true; 853 if (other == null) return false; 854 if (other.getClass() != this.getClass()) return false; 855 856 credentialUpdated o = (credentialUpdated) other; 857 858 return 859 Objects.equals(this.authenticatorId, o.authenticatorId) 860 && Objects.equals(this.credential, o.credential); 861 } 862 863 /** Generates a Hash-Code for {@code 'this'} instance */ 864 public int hashCode() 865 { 866 return 867 Objects.hashCode(this.authenticatorId) 868 + this.credential.hashCode(); 869 } 870 } 871 872 /** Triggered when a credential is used in a webauthn assertion. */ 873 public static class credentialAsserted 874 extends BrowserEvent 875 implements java.io.Serializable 876 { 877 /** For Object Serialization. java.io.Serializable */ 878 protected static final long serialVersionUID = 1; 879 880 public boolean[] optionals() 881 { return new boolean[] { false, false, }; } 882 883 /** <CODE>[No Description Provided by Google]</CODE> */ 884 public final String authenticatorId; 885 886 /** <CODE>[No Description Provided by Google]</CODE> */ 887 public final WebAuthn.Credential credential; 888 889 /** 890 * Constructor 891 * 892 * @param authenticatorId - 893 * 894 * @param credential - 895 */ 896 public credentialAsserted(String authenticatorId, WebAuthn.Credential credential) 897 { 898 super("WebAuthn", "credentialAsserted", 2); 899 900 // Exception-Check(s) to ensure that if any parameters which are not declared as 901 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 902 903 if (authenticatorId == null) THROWS.throwNPE("authenticatorId"); 904 if (credential == null) THROWS.throwNPE("credential"); 905 906 this.authenticatorId = authenticatorId; 907 this.credential = credential; 908 } 909 910 /** 911 * JSON Object Constructor 912 * @param jo A Json-Object having data about an instance of {@code 'credentialAsserted'}. 913 */ 914 public credentialAsserted (JsonObject jo) 915 { 916 super("WebAuthn", "credentialAsserted", 2); 917 918 this.authenticatorId = ReadJSON.getString(jo, "authenticatorId", false, true); 919 this.credential = ReadJSON.getObject(jo, "credential", WebAuthn.Credential.class, false, true); 920 } 921 922 923 /** Checks whether {@code 'this'} equals an input Java-{@code Object} */ 924 public boolean equals(Object other) 925 { 926 if (this == other) return true; 927 if (other == null) return false; 928 if (other.getClass() != this.getClass()) return false; 929 930 credentialAsserted o = (credentialAsserted) other; 931 932 return 933 Objects.equals(this.authenticatorId, o.authenticatorId) 934 && Objects.equals(this.credential, o.credential); 935 } 936 937 /** Generates a Hash-Code for {@code 'this'} instance */ 938 public int hashCode() 939 { 940 return 941 Objects.hashCode(this.authenticatorId) 942 + this.credential.hashCode(); 943 } 944 } 945 946 947 // Counter for keeping the WebSocket Request ID's distinct. 948 private static int counter = 1; 949 950 /** 951 * Enable the WebAuthn domain and start intercepting credential storage and 952 * retrieval with a virtual authenticator. 953 * 954 * @param enableUI 955 * Whether to enable the WebAuthn user interface. Enabling the UI is 956 * recommended for debugging and demo purposes, as it is closer to the real 957 * experience. Disabling the UI is recommended for automated testing. 958 * Supported at the embedder's discretion if UI is available. 959 * Defaults to false. 960 * <BR /><B CLASS=Opt>OPTIONAL</B> 961 * 962 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 963 * {@link Ret0}></CODE> 964 * 965 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 966 * browser receives the invocation-request. 967 * 968 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 969 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 970 * {@code >} to ensure the Browser Function has run to completion. 971 */ 972 public static Script<String, JsonObject, Ret0> enable(Boolean enableUI) 973 { 974 final int webSocketID = 47000000 + counter++; 975 final boolean[] optionals = { true, }; 976 977 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 978 String requestJSON = WriteJSON.get( 979 parameterTypes.get("enable"), 980 parameterNames.get("enable"), 981 optionals, webSocketID, 982 "WebAuthn.enable", 983 enableUI 984 ); 985 986 // This Remote Command does not have a Return-Value. 987 return new Script<> 988 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 989 } 990 991 /** 992 * Disable the WebAuthn domain. 993 * 994 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 995 * {@link Ret0}></CODE> 996 * 997 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 998 * browser receives the invocation-request. 999 * 1000 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 1001 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 1002 * {@code >} to ensure the Browser Function has run to completion. 1003 */ 1004 public static Script<String, JsonObject, Ret0> disable() 1005 { 1006 final int webSocketID = 47001000 + counter++; 1007 final boolean[] optionals = new boolean[0]; 1008 1009 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1010 String requestJSON = WriteJSON.get( 1011 parameterTypes.get("disable"), 1012 parameterNames.get("disable"), 1013 optionals, webSocketID, 1014 "WebAuthn.disable" 1015 ); 1016 1017 // This Remote Command does not have a Return-Value. 1018 return new Script<> 1019 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 1020 } 1021 1022 /** 1023 * Creates and adds a virtual authenticator. 1024 * 1025 * @param options - 1026 * 1027 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1028 * String></CODE> 1029 * 1030 * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using 1031 * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE><JsonObject, 1032 * String></CODE> will be returned. 1033 * 1034 * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>, 1035 * using {@link Promise#await()}, <I>and the returned result of this Browser Function may 1036 * may be retrieved.</I> 1037 * 1038 * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B> 1039 * <BR /><BR /><UL CLASS=JDUL> 1040 * <LI><CODE>String (<B>authenticatorId</B></CODE>) 1041 * <BR />- 1042 * </LI> 1043 * </UL> */ 1044 public static Script<String, JsonObject, String> addVirtualAuthenticator 1045 (WebAuthn.VirtualAuthenticatorOptions options) 1046 { 1047 // Exception-Check(s) to ensure that if any parameters which are not declared as 1048 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1049 1050 if (options == null) THROWS.throwNPE("options"); 1051 1052 final int webSocketID = 47002000 + counter++; 1053 final boolean[] optionals = { false, }; 1054 1055 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1056 String requestJSON = WriteJSON.get( 1057 parameterTypes.get("addVirtualAuthenticator"), 1058 parameterNames.get("addVirtualAuthenticator"), 1059 optionals, webSocketID, 1060 "WebAuthn.addVirtualAuthenticator", 1061 options 1062 ); 1063 1064 // 'JSON Binding' ... Converts Browser Response-JSON to 'String' 1065 Function<JsonObject, String> responseProcessor = (JsonObject jo) -> 1066 ReadJSON.getString(jo, "authenticatorId", false, true); 1067 1068 return new Script<>(webSocketID, requestJSON, responseProcessor); 1069 } 1070 1071 /** 1072 * Resets parameters isBogusSignature, isBadUV, isBadUP to false if they are not present. 1073 * 1074 * @param authenticatorId - 1075 * 1076 * @param isBogusSignature 1077 * If isBogusSignature is set, overrides the signature in the authenticator response to be zero. 1078 * Defaults to false. 1079 * <BR /><B CLASS=Opt>OPTIONAL</B> 1080 * 1081 * @param isBadUV 1082 * If isBadUV is set, overrides the UV bit in the flags in the authenticator response to 1083 * be zero. Defaults to false. 1084 * <BR /><B CLASS=Opt>OPTIONAL</B> 1085 * 1086 * @param isBadUP 1087 * If isBadUP is set, overrides the UP bit in the flags in the authenticator response to 1088 * be zero. Defaults to false. 1089 * <BR /><B CLASS=Opt>OPTIONAL</B> 1090 * 1091 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1092 * {@link Ret0}></CODE> 1093 * 1094 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 1095 * browser receives the invocation-request. 1096 * 1097 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 1098 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 1099 * {@code >} to ensure the Browser Function has run to completion. 1100 */ 1101 public static Script<String, JsonObject, Ret0> setResponseOverrideBits 1102 (String authenticatorId, Boolean isBogusSignature, Boolean isBadUV, Boolean isBadUP) 1103 { 1104 // Exception-Check(s) to ensure that if any parameters which are not declared as 1105 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1106 1107 if (authenticatorId == null) THROWS.throwNPE("authenticatorId"); 1108 1109 final int webSocketID = 47003000 + counter++; 1110 final boolean[] optionals = { false, true, true, true, }; 1111 1112 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1113 String requestJSON = WriteJSON.get( 1114 parameterTypes.get("setResponseOverrideBits"), 1115 parameterNames.get("setResponseOverrideBits"), 1116 optionals, webSocketID, 1117 "WebAuthn.setResponseOverrideBits", 1118 authenticatorId, isBogusSignature, isBadUV, isBadUP 1119 ); 1120 1121 // This Remote Command does not have a Return-Value. 1122 return new Script<> 1123 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 1124 } 1125 1126 /** 1127 * Removes the given authenticator. 1128 * 1129 * @param authenticatorId - 1130 * 1131 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1132 * {@link Ret0}></CODE> 1133 * 1134 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 1135 * browser receives the invocation-request. 1136 * 1137 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 1138 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 1139 * {@code >} to ensure the Browser Function has run to completion. 1140 */ 1141 public static Script<String, JsonObject, Ret0> removeVirtualAuthenticator 1142 (String authenticatorId) 1143 { 1144 // Exception-Check(s) to ensure that if any parameters which are not declared as 1145 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1146 1147 if (authenticatorId == null) THROWS.throwNPE("authenticatorId"); 1148 1149 final int webSocketID = 47004000 + counter++; 1150 final boolean[] optionals = { false, }; 1151 1152 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1153 String requestJSON = WriteJSON.get( 1154 parameterTypes.get("removeVirtualAuthenticator"), 1155 parameterNames.get("removeVirtualAuthenticator"), 1156 optionals, webSocketID, 1157 "WebAuthn.removeVirtualAuthenticator", 1158 authenticatorId 1159 ); 1160 1161 // This Remote Command does not have a Return-Value. 1162 return new Script<> 1163 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 1164 } 1165 1166 /** 1167 * Adds the credential to the specified authenticator. 1168 * 1169 * @param authenticatorId - 1170 * 1171 * @param credential - 1172 * 1173 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1174 * {@link Ret0}></CODE> 1175 * 1176 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 1177 * browser receives the invocation-request. 1178 * 1179 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 1180 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 1181 * {@code >} to ensure the Browser Function has run to completion. 1182 */ 1183 public static Script<String, JsonObject, Ret0> addCredential 1184 (String authenticatorId, WebAuthn.Credential credential) 1185 { 1186 // Exception-Check(s) to ensure that if any parameters which are not declared as 1187 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1188 1189 if (authenticatorId == null) THROWS.throwNPE("authenticatorId"); 1190 if (credential == null) THROWS.throwNPE("credential"); 1191 1192 final int webSocketID = 47005000 + counter++; 1193 final boolean[] optionals = { false, false, }; 1194 1195 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1196 String requestJSON = WriteJSON.get( 1197 parameterTypes.get("addCredential"), 1198 parameterNames.get("addCredential"), 1199 optionals, webSocketID, 1200 "WebAuthn.addCredential", 1201 authenticatorId, credential 1202 ); 1203 1204 // This Remote Command does not have a Return-Value. 1205 return new Script<> 1206 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 1207 } 1208 1209 /** 1210 * Returns a single credential stored in the given virtual authenticator that 1211 * matches the credential ID. 1212 * 1213 * @param authenticatorId - 1214 * 1215 * @param credentialId - 1216 * 1217 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1218 * {@link WebAuthn.Credential}></CODE> 1219 * 1220 * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using 1221 * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE><JsonObject, 1222 * {@link WebAuthn.Credential}></CODE> will be returned. 1223 * 1224 * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>, 1225 * using {@link Promise#await()}, <I>and the returned result of this Browser Function may 1226 * may be retrieved.</I> 1227 * 1228 * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B> 1229 * <BR /><BR /><UL CLASS=JDUL> 1230 * <LI><CODE>{@link WebAuthn.Credential} (<B>credential</B></CODE>) 1231 * <BR />- 1232 * </LI> 1233 * </UL> */ 1234 public static Script<String, JsonObject, WebAuthn.Credential> getCredential 1235 (String authenticatorId, String credentialId) 1236 { 1237 // Exception-Check(s) to ensure that if any parameters which are not declared as 1238 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1239 1240 if (authenticatorId == null) THROWS.throwNPE("authenticatorId"); 1241 if (credentialId == null) THROWS.throwNPE("credentialId"); 1242 1243 final int webSocketID = 47006000 + counter++; 1244 final boolean[] optionals = { false, false, }; 1245 1246 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1247 String requestJSON = WriteJSON.get( 1248 parameterTypes.get("getCredential"), 1249 parameterNames.get("getCredential"), 1250 optionals, webSocketID, 1251 "WebAuthn.getCredential", 1252 authenticatorId, credentialId 1253 ); 1254 1255 // 'JSON Binding' ... Converts Browser Response-JSON to 'WebAuthn.Credential' 1256 Function<JsonObject, WebAuthn.Credential> responseProcessor = (JsonObject jo) -> 1257 ReadJSON.getObject(jo, "credential", WebAuthn.Credential.class, false, true); 1258 1259 return new Script<>(webSocketID, requestJSON, responseProcessor); 1260 } 1261 1262 /** 1263 * Returns all the credentials stored in the given virtual authenticator. 1264 * 1265 * @param authenticatorId - 1266 * 1267 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1268 * {@link WebAuthn.Credential}[]></CODE> 1269 * 1270 * <BR /><BR />This <B>script</B> may be <B STYLE='color: red'>executed</B>, using 1271 * {@link Script#exec()}, and afterwards, a {@link Promise}<CODE><JsonObject, 1272 * {@link WebAuthn.Credential}[]></CODE> will be returned. 1273 * 1274 * <BR /><BR />Finally, the <B>{@code Promise}</B> may be <B STYLE='color: red'>awaited</B>, 1275 * using {@link Promise#await()}, <I>and the returned result of this Browser Function may 1276 * may be retrieved.</I> 1277 * 1278 * <BR /><BR />This Browser Function <B STYLE='color: red'>returns</B> 1279 * <BR /><BR /><UL CLASS=JDUL> 1280 * <LI><CODE>{@link WebAuthn.Credential}[] (<B>credentials</B></CODE>) 1281 * <BR />- 1282 * </LI> 1283 * </UL> */ 1284 public static Script<String, JsonObject, WebAuthn.Credential[]> getCredentials 1285 (String authenticatorId) 1286 { 1287 // Exception-Check(s) to ensure that if any parameters which are not declared as 1288 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1289 1290 if (authenticatorId == null) THROWS.throwNPE("authenticatorId"); 1291 1292 final int webSocketID = 47007000 + counter++; 1293 final boolean[] optionals = { false, }; 1294 1295 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1296 String requestJSON = WriteJSON.get( 1297 parameterTypes.get("getCredentials"), 1298 parameterNames.get("getCredentials"), 1299 optionals, webSocketID, 1300 "WebAuthn.getCredentials", 1301 authenticatorId 1302 ); 1303 1304 // 'JSON Binding' ... Converts Browser Response-JSON to 'WebAuthn.Credential[]' 1305 Function<JsonObject, WebAuthn.Credential[]> responseProcessor = (JsonObject jo) -> 1306 (jo.getJsonArray("credentials") == null) 1307 ? null 1308 : RJArrIntoStream.objArr(jo.getJsonArray("credentials"), null, 0, WebAuthn.Credential.class).toArray(WebAuthn.Credential[]::new); 1309 1310 return new Script<>(webSocketID, requestJSON, responseProcessor); 1311 } 1312 1313 /** 1314 * Removes a credential from the authenticator. 1315 * 1316 * @param authenticatorId - 1317 * 1318 * @param credentialId - 1319 * 1320 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1321 * {@link Ret0}></CODE> 1322 * 1323 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 1324 * browser receives the invocation-request. 1325 * 1326 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 1327 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 1328 * {@code >} to ensure the Browser Function has run to completion. 1329 */ 1330 public static Script<String, JsonObject, Ret0> removeCredential 1331 (String authenticatorId, String credentialId) 1332 { 1333 // Exception-Check(s) to ensure that if any parameters which are not declared as 1334 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1335 1336 if (authenticatorId == null) THROWS.throwNPE("authenticatorId"); 1337 if (credentialId == null) THROWS.throwNPE("credentialId"); 1338 1339 final int webSocketID = 47008000 + counter++; 1340 final boolean[] optionals = { false, false, }; 1341 1342 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1343 String requestJSON = WriteJSON.get( 1344 parameterTypes.get("removeCredential"), 1345 parameterNames.get("removeCredential"), 1346 optionals, webSocketID, 1347 "WebAuthn.removeCredential", 1348 authenticatorId, credentialId 1349 ); 1350 1351 // This Remote Command does not have a Return-Value. 1352 return new Script<> 1353 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 1354 } 1355 1356 /** 1357 * Clears all the credentials from the specified device. 1358 * 1359 * @param authenticatorId - 1360 * 1361 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1362 * {@link Ret0}></CODE> 1363 * 1364 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 1365 * browser receives the invocation-request. 1366 * 1367 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 1368 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 1369 * {@code >} to ensure the Browser Function has run to completion. 1370 */ 1371 public static Script<String, JsonObject, Ret0> clearCredentials(String authenticatorId) 1372 { 1373 // Exception-Check(s) to ensure that if any parameters which are not declared as 1374 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1375 1376 if (authenticatorId == null) THROWS.throwNPE("authenticatorId"); 1377 1378 final int webSocketID = 47009000 + counter++; 1379 final boolean[] optionals = { false, }; 1380 1381 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1382 String requestJSON = WriteJSON.get( 1383 parameterTypes.get("clearCredentials"), 1384 parameterNames.get("clearCredentials"), 1385 optionals, webSocketID, 1386 "WebAuthn.clearCredentials", 1387 authenticatorId 1388 ); 1389 1390 // This Remote Command does not have a Return-Value. 1391 return new Script<> 1392 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 1393 } 1394 1395 /** 1396 * Sets whether User Verification succeeds or fails for an authenticator. 1397 * The default is true. 1398 * 1399 * @param authenticatorId - 1400 * 1401 * @param isUserVerified - 1402 * 1403 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1404 * {@link Ret0}></CODE> 1405 * 1406 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 1407 * browser receives the invocation-request. 1408 * 1409 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 1410 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 1411 * {@code >} to ensure the Browser Function has run to completion. 1412 */ 1413 public static Script<String, JsonObject, Ret0> setUserVerified 1414 (String authenticatorId, boolean isUserVerified) 1415 { 1416 // Exception-Check(s) to ensure that if any parameters which are not declared as 1417 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1418 1419 if (authenticatorId == null) THROWS.throwNPE("authenticatorId"); 1420 1421 final int webSocketID = 47010000 + counter++; 1422 final boolean[] optionals = { false, false, }; 1423 1424 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1425 String requestJSON = WriteJSON.get( 1426 parameterTypes.get("setUserVerified"), 1427 parameterNames.get("setUserVerified"), 1428 optionals, webSocketID, 1429 "WebAuthn.setUserVerified", 1430 authenticatorId, isUserVerified 1431 ); 1432 1433 // This Remote Command does not have a Return-Value. 1434 return new Script<> 1435 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 1436 } 1437 1438 /** 1439 * Sets whether tests of user presence will succeed immediately (if true) or fail to resolve (if false) for an authenticator. 1440 * The default is true. 1441 * 1442 * @param authenticatorId - 1443 * 1444 * @param enabled - 1445 * 1446 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1447 * {@link Ret0}></CODE> 1448 * 1449 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 1450 * browser receives the invocation-request. 1451 * 1452 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 1453 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 1454 * {@code >} to ensure the Browser Function has run to completion. 1455 */ 1456 public static Script<String, JsonObject, Ret0> setAutomaticPresenceSimulation 1457 (String authenticatorId, boolean enabled) 1458 { 1459 // Exception-Check(s) to ensure that if any parameters which are not declared as 1460 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1461 1462 if (authenticatorId == null) THROWS.throwNPE("authenticatorId"); 1463 1464 final int webSocketID = 47011000 + counter++; 1465 final boolean[] optionals = { false, false, }; 1466 1467 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1468 String requestJSON = WriteJSON.get( 1469 parameterTypes.get("setAutomaticPresenceSimulation"), 1470 parameterNames.get("setAutomaticPresenceSimulation"), 1471 optionals, webSocketID, 1472 "WebAuthn.setAutomaticPresenceSimulation", 1473 authenticatorId, enabled 1474 ); 1475 1476 // This Remote Command does not have a Return-Value. 1477 return new Script<> 1478 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 1479 } 1480 1481 /** 1482 * Allows setting credential properties. 1483 * https://w3c.github.io/webauthn/#sctn-automation-set-credential-properties 1484 * 1485 * @param authenticatorId - 1486 * 1487 * @param credentialId - 1488 * 1489 * @param backupEligibility - 1490 * <BR /><B CLASS=Opt>OPTIONAL</B> 1491 * 1492 * @param backupState - 1493 * <BR /><B CLASS=Opt>OPTIONAL</B> 1494 * 1495 * @return An instance of <CODE>{@link Script}<String, {@link JsonObject}, 1496 * {@link Ret0}></CODE> 1497 * 1498 * <BR /><BR />This {@code Script} instance must be <B STYLE='color:red'>executed</B> before the 1499 * browser receives the invocation-request. 1500 * 1501 * <BR /><BR />This Browser-Function <I>does not have</I> a return-value. You may choose to 1502 * <B STYLE='color: red'>await</B> the {@link Promise}{@code <JsonObject,} {@link Ret0} 1503 * {@code >} to ensure the Browser Function has run to completion. 1504 */ 1505 public static Script<String, JsonObject, Ret0> setCredentialProperties( 1506 String authenticatorId, String credentialId, Boolean backupEligibility, 1507 Boolean backupState 1508 ) 1509 { 1510 // Exception-Check(s) to ensure that if any parameters which are not declared as 1511 // 'Optional', but have a 'null' value anyway, that a NullPointerException shall throw. 1512 1513 if (authenticatorId == null) THROWS.throwNPE("authenticatorId"); 1514 if (credentialId == null) THROWS.throwNPE("credentialId"); 1515 1516 final int webSocketID = 47012000 + counter++; 1517 final boolean[] optionals = { false, false, true, true, }; 1518 1519 // Convert Method Parameters into JSON. Build the JSON Request-Object (as a String) 1520 String requestJSON = WriteJSON.get( 1521 parameterTypes.get("setCredentialProperties"), 1522 parameterNames.get("setCredentialProperties"), 1523 optionals, webSocketID, 1524 "WebAuthn.setCredentialProperties", 1525 authenticatorId, credentialId, backupEligibility, backupState 1526 ); 1527 1528 // This Remote Command does not have a Return-Value. 1529 return new Script<> 1530 (webSocketID, requestJSON, VOID_RETURN.NoReturnValues); 1531 } 1532 1533}