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}&lt;String, {@link JsonObject},
429     * {@link Ret0}&gt;</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}&lt;String, {@link JsonObject},
460     * {@link Ret0}&gt;</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}&lt;String, {@link JsonObject},
493     * String&gt;</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>&lt;JsonObject,
497     * String&gt;</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}&lt;String, {@link JsonObject},
544     * {@link Ret0}&gt;</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}&lt;String, {@link JsonObject},
586     * {@link Ret0}&gt;</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}&lt;String, {@link JsonObject},
630     * {@link WebAuthn.Credential}&gt;</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>&lt;JsonObject,
634     * {@link WebAuthn.Credential}&gt;</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}&lt;String, {@link JsonObject},
682     * {@link WebAuthn.Credential}[]&gt;</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>&lt;JsonObject,
686     * {@link WebAuthn.Credential}[]&gt;</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}&lt;String, {@link JsonObject},
737     * {@link Ret0}&gt;</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}&lt;String, {@link JsonObject},
778     * {@link Ret0}&gt;</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}&lt;String, {@link JsonObject},
820     * {@link Ret0}&gt;</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}&lt;String, {@link JsonObject},
863     * {@link Ret0}&gt;</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}