StartAssertionOptions.java

1
// Copyright (c) 2018, Yubico AB
2
// All rights reserved.
3
//
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions are met:
6
//
7
// 1. Redistributions of source code must retain the above copyright notice, this
8
//    list of conditions and the following disclaimer.
9
//
10
// 2. Redistributions in binary form must reproduce the above copyright notice,
11
//    this list of conditions and the following disclaimer in the documentation
12
//    and/or other materials provided with the distribution.
13
//
14
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
25
package com.yubico.webauthn;
26
27
import com.yubico.webauthn.data.AssertionExtensionInputs;
28
import com.yubico.webauthn.data.ByteArray;
29
import com.yubico.webauthn.data.PublicKeyCredentialDescriptor;
30
import com.yubico.webauthn.data.PublicKeyCredentialHint;
31
import com.yubico.webauthn.data.PublicKeyCredentialRequestOptions;
32
import com.yubico.webauthn.data.UserVerificationRequirement;
33
import java.util.Arrays;
34
import java.util.Collections;
35
import java.util.List;
36
import java.util.Optional;
37
import lombok.Builder;
38
import lombok.NonNull;
39
import lombok.Value;
40
41
/** Parameters for {@link RelyingParty#startAssertion(StartAssertionOptions)}. */
42
@Value
43
@Builder(toBuilder = true)
44
public class StartAssertionOptions {
45
46
  private final String username;
47
48
  private final ByteArray userHandle;
49
50
  /**
51
   * Extension inputs for this authentication operation.
52
   *
53
   * <p>If {@link RelyingParty#getAppId()} is set, {@link
54
   * RelyingParty#startAssertion(StartAssertionOptions)} will overwrite any {@link
55
   * AssertionExtensionInputs#getAppid() appId} extension input set herein.
56
   *
57
   * <p>The default specifies no extension inputs.
58
   */
59
  @NonNull @Builder.Default
60
  private final AssertionExtensionInputs extensions = AssertionExtensionInputs.builder().build();
61
62
  /**
63
   * The value for {@link PublicKeyCredentialRequestOptions#getUserVerification()} for this
64
   * authentication operation.
65
   *
66
   * <p>If set to {@link UserVerificationRequirement#REQUIRED}, then {@link
67
   * RelyingParty#finishAssertion(FinishAssertionOptions)} will enforce that <a
68
   * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408#user-verification">user
69
   * verification</a>was performed in this authentication ceremony.
70
   *
71
   * <p>The default is {@link UserVerificationRequirement#PREFERRED}.
72
   */
73
  private final UserVerificationRequirement userVerification;
74
75
  /**
76
   * The value for {@link PublicKeyCredentialRequestOptions#getTimeout()} for this authentication
77
   * operation.
78
   *
79
   * <p>This library does not take the timeout into account in any way, other than passing it
80
   * through to the {@link PublicKeyCredentialRequestOptions} so it can be used as an argument to
81
   * <code>navigator.credentials.get()</code> on the client side.
82
   *
83
   * <p>The default is empty.
84
   */
85
  private final Long timeout;
86
87
  /**
88
   * Zero or more hints, in descending order of preference, to guide the user agent in interacting
89
   * with the user during this authentication operation.
90
   *
91
   * <p>For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
92
   * client to emphasize the option of authenticating with an external security key, or the {@link
93
   * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
94
   * option of authenticating a built-in passkey provider.
95
   *
96
   * <p>These hints are not requirements, and do not bind the user-agent, but may guide it in
97
   * providing the best experience by using contextual information about the request.
98
   *
99
   * <p>Hints MAY contradict information contained in {@link
100
   * PublicKeyCredentialDescriptor#getTransports()}. When this occurs, the hints take precedence.
101
   *
102
   * <p>This library does not take these hints into account in any way, other than passing them
103
   * through to the {@link PublicKeyCredentialRequestOptions} so they can be used in the argument to
104
   * <code>navigator.credentials.get()</code> on the client side.
105
   *
106
   * <p>The default is empty.
107
   *
108
   * @see PublicKeyCredentialHint
109
   * @see PublicKeyCredentialRequestOptions#getHints()
110
   * @see StartAssertionOptionsBuilder#hints(List)
111
   * @see StartAssertionOptionsBuilder#hints(String...)
112
   * @see StartAssertionOptionsBuilder#hints(PublicKeyCredentialHint...)
113
   * @see <a
114
   *     href="https://www.w3.org/TR/2023/WD-webauthn-3-20230927/#dom-publickeycredentialrequestoptions-hints">PublicKeyCredentialRequestOptions.hints</a>
115
   * @see <a
116
   *     href="https://www.w3.org/TR/2023/WD-webauthn-3-20230927/#enumdef-publickeycredentialhints">§5.8.7.
117
   *     User-agent Hints Enumeration (enum PublicKeyCredentialHints)</a>
118
   */
119
  private final List<String> hints;
120
121
  private StartAssertionOptions(
122
      String username,
123
      ByteArray userHandle,
124 1 1. <init> : negated conditional → KILLED
      @NonNull AssertionExtensionInputs extensions,
125
      UserVerificationRequirement userVerification,
126
      Long timeout,
127
      List<String> hints) {
128
    this.username = username;
129
    this.userHandle = userHandle;
130
    this.extensions = extensions;
131
    this.userVerification = userVerification;
132
    this.timeout = timeout;
133 1 1. <init> : negated conditional → KILLED
    this.hints = hints == null ? Collections.emptyList() : Collections.unmodifiableList(hints);
134
  }
135
136
  /**
137
   * The username of the user to authenticate, if the user has already been identified.
138
   *
139
   * <p>Mutually exclusive with {@link #getUserHandle()}.
140
   *
141
   * <p>If this or {@link #getUserHandle()} is present, then {@link
142
   * RelyingParty#startAssertion(StartAssertionOptions)} will set {@link
143
   * PublicKeyCredentialRequestOptions#getAllowCredentials()} to the list of that user's
144
   * credentials.
145
   *
146
   * <p>If this and {@link #getUserHandle()} are both absent, that implies authentication with a
147
   * discoverable credential (passkey) - meaning identification of the user is deferred until after
148
   * receiving the response from the client.
149
   *
150
   * <p>The default is empty (absent).
151
   *
152
   * @see <a
153
   *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-side-discoverable-public-key-credential-source">Client-side-discoverable
154
   *     credential</a>
155
   * @see <a href="https://passkeys.dev/docs/reference/terms/#passkey">Passkey</a> in <a
156
   *     href="https://passkeys.dev">passkeys.dev</a> reference
157
   */
158
  public Optional<String> getUsername() {
159 1 1. getUsername : replaced return value with Optional.empty for com/yubico/webauthn/StartAssertionOptions::getUsername → KILLED
    return Optional.ofNullable(username);
160
  }
161
162
  /**
163
   * The user handle of the user to authenticate, if the user has already been identified.
164
   *
165
   * <p>Mutually exclusive with {@link #getUsername()}.
166
   *
167
   * <p>If this or {@link #getUsername()} is present, then {@link
168
   * RelyingParty#startAssertion(StartAssertionOptions)} will set {@link
169
   * PublicKeyCredentialRequestOptions#getAllowCredentials()} to the list of that user's
170
   * credentials.
171
   *
172
   * <p>If this and {@link #getUsername()} are both absent, that implies authentication with a
173
   * discoverable credential (passkey) - meaning identification of the user is deferred until after
174
   * receiving the response from the client.
175
   *
176
   * <p>The default is empty (absent).
177
   *
178
   * @see #getUsername()
179
   * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#user-handle">User Handle</a>
180
   * @see <a
181
   *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-side-discoverable-public-key-credential-source">Client-side-discoverable
182
   *     credential</a>
183
   * @see <a href="https://passkeys.dev/docs/reference/terms/#passkey">Passkey</a> in <a
184
   *     href="https://passkeys.dev">passkeys.dev</a> reference
185
   */
186
  public Optional<ByteArray> getUserHandle() {
187 1 1. getUserHandle : replaced return value with Optional.empty for com/yubico/webauthn/StartAssertionOptions::getUserHandle → KILLED
    return Optional.ofNullable(userHandle);
188
  }
189
190
  /**
191
   * The value for {@link PublicKeyCredentialRequestOptions#getUserVerification()} for this
192
   * authentication operation.
193
   *
194
   * <p>If set to {@link UserVerificationRequirement#REQUIRED}, then {@link
195
   * RelyingParty#finishAssertion(FinishAssertionOptions)} will enforce that <a
196
   * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408#user-verification">user
197
   * verification</a>was performed in this authentication ceremony.
198
   *
199
   * <p>The default is {@link UserVerificationRequirement#PREFERRED}.
200
   */
201
  public Optional<UserVerificationRequirement> getUserVerification() {
202 1 1. getUserVerification : replaced return value with Optional.empty for com/yubico/webauthn/StartAssertionOptions::getUserVerification → KILLED
    return Optional.ofNullable(userVerification);
203
  }
204
205
  /**
206
   * The value for {@link PublicKeyCredentialRequestOptions#getTimeout()} for this authentication
207
   * operation.
208
   *
209
   * <p>This library does not take the timeout into account in any way, other than passing it
210
   * through to the {@link PublicKeyCredentialRequestOptions} so it can be used as an argument to
211
   * <code>navigator.credentials.get()</code> on the client side.
212
   *
213
   * <p>The default is empty.
214
   */
215
  public Optional<Long> getTimeout() {
216 1 1. getTimeout : replaced return value with Optional.empty for com/yubico/webauthn/StartAssertionOptions::getTimeout → KILLED
    return Optional.ofNullable(timeout);
217
  }
218
219
  public static class StartAssertionOptionsBuilder {
220
    private String username = null;
221
    private ByteArray userHandle = null;
222
    private UserVerificationRequirement userVerification = null;
223
    private Long timeout = null;
224
225
    /**
226
     * The username of the user to authenticate, if the user has already been identified.
227
     *
228
     * <p>Mutually exclusive with {@link #userHandle(Optional)}. Setting this to a present value
229
     * will set {@link #userHandle(Optional)} to empty.
230
     *
231
     * <p>If this or {@link #userHandle(Optional)} is present, then {@link
232
     * RelyingParty#startAssertion(StartAssertionOptions)} will set {@link
233
     * PublicKeyCredentialRequestOptions#getAllowCredentials()} to the list of that user's
234
     * credentials.
235
     *
236
     * <p>If this and {@link #getUserHandle()} are both absent, that implies authentication with a
237
     * discoverable credential (passkey) - meaning identification of the user is deferred until
238
     * after receiving the response from the client.
239
     *
240
     * <p>The default is empty (absent).
241
     *
242
     * @see #username(String)
243
     * @see #userHandle(Optional)
244
     * @see #userHandle(ByteArray)
245
     * @see <a
246
     *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-side-discoverable-public-key-credential-source">Client-side-discoverable
247
     *     credential</a>
248
     * @see <a href="https://passkeys.dev/docs/reference/terms/#passkey">Passkey</a> in <a
249
     *     href="https://passkeys.dev">passkeys.dev</a> reference
250
     */
251 1 1. username : negated conditional → KILLED
    public StartAssertionOptionsBuilder username(@NonNull Optional<String> username) {
252
      this.username = username.orElse(null);
253 1 1. username : negated conditional → KILLED
      if (username.isPresent()) {
254
        this.userHandle = null;
255
      }
256 1 1. username : replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::username → KILLED
      return this;
257
    }
258
259
    /**
260
     * The username of the user to authenticate, if the user has already been identified.
261
     *
262
     * <p>Mutually exclusive with {@link #userHandle(Optional)}. Setting this to a non-null value
263
     * will set {@link #userHandle(Optional)} to empty.
264
     *
265
     * <p>If this or {@link #userHandle(Optional)} is present, then {@link
266
     * RelyingParty#startAssertion(StartAssertionOptions)} will set {@link
267
     * PublicKeyCredentialRequestOptions#getAllowCredentials()} to the list of that user's
268
     * credentials.
269
     *
270
     * <p>If this and {@link #getUserHandle()} are both absent, that implies authentication with a
271
     * discoverable credential (passkey) - meaning identification of the user is deferred until
272
     * after receiving the response from the client.
273
     *
274
     * <p>The default is empty (absent).
275
     *
276
     * @see #username(Optional)
277
     * @see #userHandle(Optional)
278
     * @see #userHandle(ByteArray)
279
     * @see <a
280
     *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-side-discoverable-public-key-credential-source">Client-side-discoverable
281
     *     credential</a>
282
     * @see <a href="https://passkeys.dev/docs/reference/terms/#passkey">Passkey</a> in <a
283
     *     href="https://passkeys.dev">passkeys.dev</a> reference
284
     */
285
    public StartAssertionOptionsBuilder username(String username) {
286 1 1. username : replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::username → KILLED
      return this.username(Optional.ofNullable(username));
287
    }
288
289
    /**
290
     * The user handle of the user to authenticate, if the user has already been identified.
291
     *
292
     * <p>Mutually exclusive with {@link #username(Optional)}. Setting this to a present value will
293
     * set {@link #username(Optional)} to empty.
294
     *
295
     * <p>If this or {@link #username(Optional)} is present, then {@link
296
     * RelyingParty#startAssertion(StartAssertionOptions)} will set {@link
297
     * PublicKeyCredentialRequestOptions#getAllowCredentials()} to the list of that user's
298
     * credentials.
299
     *
300
     * <p>If this and {@link #getUsername()} are both absent, that implies authentication with a
301
     * discoverable credential (passkey) - meaning identification of the user is deferred until
302
     * after receiving the response from the client.
303
     *
304
     * <p>The default is empty (absent).
305
     *
306
     * @see #username(String)
307
     * @see #username(Optional)
308
     * @see #userHandle(ByteArray)
309
     * @see <a href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#user-handle">User
310
     *     Handle</a>
311
     * @see <a
312
     *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-side-discoverable-public-key-credential-source">Client-side-discoverable
313
     *     credential</a>
314
     * @see <a href="https://passkeys.dev/docs/reference/terms/#passkey">Passkey</a> in <a
315
     *     href="https://passkeys.dev">passkeys.dev</a> reference
316
     */
317 1 1. userHandle : negated conditional → KILLED
    public StartAssertionOptionsBuilder userHandle(@NonNull Optional<ByteArray> userHandle) {
318
      this.userHandle = userHandle.orElse(null);
319 1 1. userHandle : negated conditional → KILLED
      if (userHandle.isPresent()) {
320
        this.username = null;
321
      }
322 1 1. userHandle : replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::userHandle → KILLED
      return this;
323
    }
324
325
    /**
326
     * The user handle of the user to authenticate, if the user has already been identified.
327
     *
328
     * <p>Mutually exclusive with {@link #username(Optional)}. Setting this to a non-null value will
329
     * set {@link #username(Optional)} to empty.
330
     *
331
     * <p>If this or {@link #username(Optional)} is present, then {@link
332
     * RelyingParty#startAssertion(StartAssertionOptions)} will set {@link
333
     * PublicKeyCredentialRequestOptions#getAllowCredentials()} to the list of that user's
334
     * credentials.
335
     *
336
     * <p>If this and {@link #getUsername()} are both absent, that implies authentication with a
337
     * discoverable credential (passkey) - meaning identification of the user is deferred until
338
     * after receiving the response from the client.
339
     *
340
     * <p>The default is empty (absent).
341
     *
342
     * @see #username(String)
343
     * @see #username(Optional)
344
     * @see #userHandle(Optional)
345
     * @see <a
346
     *     href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#client-side-discoverable-public-key-credential-source">Client-side-discoverable
347
     *     credential</a>
348
     * @see <a href="https://passkeys.dev/docs/reference/terms/#passkey">Passkey</a> in <a
349
     *     href="https://passkeys.dev">passkeys.dev</a> reference
350
     */
351
    public StartAssertionOptionsBuilder userHandle(ByteArray userHandle) {
352 1 1. userHandle : replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::userHandle → KILLED
      return this.userHandle(Optional.ofNullable(userHandle));
353
    }
354
355
    /**
356
     * The value for {@link PublicKeyCredentialRequestOptions#getUserVerification()} for this
357
     * authentication operation.
358
     *
359
     * <p>If set to {@link UserVerificationRequirement#REQUIRED}, then {@link
360
     * RelyingParty#finishAssertion(FinishAssertionOptions)} will enforce that <a
361
     * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#user-verification">user
362
     * verification</a>was performed in this authentication ceremony.
363
     *
364
     * <p>The default is {@link UserVerificationRequirement#PREFERRED}.
365
     */
366
    public StartAssertionOptionsBuilder userVerification(
367 1 1. userVerification : negated conditional → KILLED
        @NonNull Optional<UserVerificationRequirement> userVerification) {
368
      this.userVerification = userVerification.orElse(null);
369 1 1. userVerification : replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::userVerification → KILLED
      return this;
370
    }
371
372
    /**
373
     * The value for {@link PublicKeyCredentialRequestOptions#getUserVerification()} for this
374
     * authentication operation.
375
     *
376
     * <p>If set to {@link UserVerificationRequirement#REQUIRED}, then {@link
377
     * RelyingParty#finishAssertion(FinishAssertionOptions)} will enforce that <a
378
     * href="https://www.w3.org/TR/2021/REC-webauthn-2-20210408/#user-verification">user
379
     * verification</a>was performed in this authentication ceremony.
380
     *
381
     * <p>The default is {@link UserVerificationRequirement#PREFERRED}.
382
     */
383
    public StartAssertionOptionsBuilder userVerification(
384
        UserVerificationRequirement userVerification) {
385 1 1. userVerification : replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::userVerification → KILLED
      return this.userVerification(Optional.ofNullable(userVerification));
386
    }
387
388
    /**
389
     * The value for {@link PublicKeyCredentialRequestOptions#getTimeout()} for this authentication
390
     * operation.
391
     *
392
     * <p>This library does not take the timeout into account in any way, other than passing it
393
     * through to the {@link PublicKeyCredentialRequestOptions} so it can be used as an argument to
394
     * <code>navigator.credentials.get()</code> on the client side.
395
     *
396
     * <p>The default is empty.
397
     */
398 1 1. timeout : negated conditional → KILLED
    public StartAssertionOptionsBuilder timeout(@NonNull Optional<Long> timeout) {
399 3 1. timeout : changed conditional boundary → KILLED
2. timeout : negated conditional → KILLED
3. timeout : negated conditional → KILLED
      if (timeout.isPresent() && timeout.get() <= 0) {
400
        throw new IllegalArgumentException("timeout must be positive, was: " + timeout.get());
401
      }
402
      this.timeout = timeout.orElse(null);
403 1 1. timeout : replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::timeout → KILLED
      return this;
404
    }
405
406
    /**
407
     * The value for {@link PublicKeyCredentialRequestOptions#getTimeout()} for this authentication
408
     * operation.
409
     *
410
     * <p>This library does not take the timeout into account in any way, other than passing it
411
     * through to the {@link PublicKeyCredentialRequestOptions} so it can be used as an argument to
412
     * <code>navigator.credentials.get()</code> on the client side.
413
     *
414
     * <p>The default is empty.
415
     */
416
    public StartAssertionOptionsBuilder timeout(long timeout) {
417 1 1. timeout : replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::timeout → KILLED
      return this.timeout(Optional.of(timeout));
418
    }
419
420
    /*
421
     * Workaround, see: https://github.com/rzwitserloot/lombok/issues/2623#issuecomment-714816001
422
     * Consider reverting this workaround if Lombok fixes that issue.
423
     */
424
    private StartAssertionOptionsBuilder timeout(Long timeout) {
425 1 1. timeout : replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::timeout → KILLED
      return this.timeout(Optional.ofNullable(timeout));
426
    }
427
428
    /**
429
     * Zero or more hints, in descending order of preference, to guide the user agent in interacting
430
     * with the user during this authentication operation.
431
     *
432
     * <p>Setting this property multiple times overwrites any value set previously.
433
     *
434
     * <p>For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
435
     * client to emphasize the option of authenticating with an external security key, or the {@link
436
     * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
437
     * option of authenticating a built-in passkey provider.
438
     *
439
     * <p>These hints are not requirements, and do not bind the user-agent, but may guide it in
440
     * providing the best experience by using contextual information about the request.
441
     *
442
     * <p>Hints MAY contradict information contained in {@link
443
     * PublicKeyCredentialDescriptor#getTransports()}. When this occurs, the hints take precedence.
444
     *
445
     * <p>This library does not take these hints into account in any way, other than passing them
446
     * through to the {@link PublicKeyCredentialRequestOptions} so they can be used in the argument
447
     * to <code>navigator.credentials.get()</code> on the client side.
448
     *
449
     * <p>The default is empty.
450
     *
451
     * @see PublicKeyCredentialHint
452
     * @see PublicKeyCredentialRequestOptions#getHints()
453
     * @see StartAssertionOptions#getHints()
454
     * @see StartAssertionOptionsBuilder#hints(List)
455
     * @see StartAssertionOptionsBuilder#hints(PublicKeyCredentialHint...)
456
     * @see <a
457
     *     href="https://www.w3.org/TR/2023/WD-webauthn-3-20230927/#dom-publickeycredentialrequestoptions-hints">PublicKeyCredentialRequestOptions.hints</a>
458
     * @see <a
459
     *     href="https://www.w3.org/TR/2023/WD-webauthn-3-20230927/#enumdef-publickeycredentialhints">§5.8.7.
460
     *     User-agent Hints Enumeration (enum PublicKeyCredentialHints)</a>
461
     */
462 1 1. hints : negated conditional → KILLED
    public StartAssertionOptionsBuilder hints(@NonNull String... hints) {
463
      this.hints = Arrays.asList(hints);
464 1 1. hints : replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::hints → KILLED
      return this;
465
    }
466
467
    /**
468
     * Zero or more hints, in descending order of preference, to guide the user agent in interacting
469
     * with the user during this authentication operation.
470
     *
471
     * <p>Setting this property multiple times overwrites any value set previously.
472
     *
473
     * <p>For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
474
     * client to emphasize the option of authenticating with an external security key, or the {@link
475
     * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
476
     * option of authenticating a built-in passkey provider.
477
     *
478
     * <p>These hints are not requirements, and do not bind the user-agent, but may guide it in
479
     * providing the best experience by using contextual information about the request.
480
     *
481
     * <p>Hints MAY contradict information contained in {@link
482
     * PublicKeyCredentialDescriptor#getTransports()}. When this occurs, the hints take precedence.
483
     *
484
     * <p>This library does not take these hints into account in any way, other than passing them
485
     * through to the {@link PublicKeyCredentialRequestOptions} so they can be used in the argument
486
     * to <code>navigator.credentials.get()</code> on the client side.
487
     *
488
     * <p>The default is empty.
489
     *
490
     * @see PublicKeyCredentialHint
491
     * @see PublicKeyCredentialRequestOptions#getHints()
492
     * @see StartAssertionOptions#getHints()
493
     * @see StartAssertionOptionsBuilder#hints(List)
494
     * @see StartAssertionOptionsBuilder#hints(String...)
495
     * @see <a
496
     *     href="https://www.w3.org/TR/2023/WD-webauthn-3-20230927/#dom-publickeycredentialrequestoptions-hints">PublicKeyCredentialRequestOptions.hints</a>
497
     * @see <a
498
     *     href="https://www.w3.org/TR/2023/WD-webauthn-3-20230927/#enumdef-publickeycredentialhints">§5.8.7.
499
     *     User-agent Hints Enumeration (enum PublicKeyCredentialHints)</a>
500
     */
501 1 1. hints : negated conditional → KILLED
    public StartAssertionOptionsBuilder hints(@NonNull PublicKeyCredentialHint... hints) {
502 1 1. hints : replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::hints → KILLED
      return this.hints(
503 1 1. lambda$hints$0 : replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::lambda$hints$0 → KILLED
          Arrays.stream(hints).map(PublicKeyCredentialHint::getValue).toArray(String[]::new));
504
    }
505
506
    /**
507
     * Zero or more hints, in descending order of preference, to guide the user agent in interacting
508
     * with the user during this authentication operation.
509
     *
510
     * <p>Setting this property multiple times overwrites any value set previously.
511
     *
512
     * <p>For example, the {@link PublicKeyCredentialHint#SECURITY_KEY} hint may be used to ask the
513
     * client to emphasize the option of authenticating with an external security key, or the {@link
514
     * PublicKeyCredentialHint#CLIENT_DEVICE} hint may be used to ask the client to emphasize the
515
     * option of authenticating a built-in passkey provider.
516
     *
517
     * <p>These hints are not requirements, and do not bind the user-agent, but may guide it in
518
     * providing the best experience by using contextual information about the request.
519
     *
520
     * <p>Hints MAY contradict information contained in {@link
521
     * PublicKeyCredentialDescriptor#getTransports()}. When this occurs, the hints take precedence.
522
     *
523
     * <p>This library does not take these hints into account in any way, other than passing them
524
     * through to the {@link PublicKeyCredentialRequestOptions} so they can be used in the argument
525
     * to <code>navigator.credentials.get()</code> on the client side.
526
     *
527
     * <p>The default is empty.
528
     *
529
     * @see PublicKeyCredentialHint
530
     * @see PublicKeyCredentialRequestOptions#getHints()
531
     * @see StartAssertionOptions#getHints()
532
     * @see StartAssertionOptionsBuilder#hints(String...)
533
     * @see StartAssertionOptionsBuilder#hints(PublicKeyCredentialHint...)
534
     * @see <a
535
     *     href="https://www.w3.org/TR/2023/WD-webauthn-3-20230927/#dom-publickeycredentialrequestoptions-hints">PublicKeyCredentialRequestOptions.hints</a>
536
     * @see <a
537
     *     href="https://www.w3.org/TR/2023/WD-webauthn-3-20230927/#enumdef-publickeycredentialhints">§5.8.7.
538
     *     User-agent Hints Enumeration (enum PublicKeyCredentialHints)</a>
539
     */
540 1 1. hints : negated conditional → KILLED
    public StartAssertionOptionsBuilder hints(@NonNull List<String> hints) {
541
      this.hints = hints;
542 1 1. hints : replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::hints → KILLED
      return this;
543
    }
544
  }
545
}

Mutations

124

1.1
Location : <init>
Killed by : com.yubico.webauthn.StartAssertionOptionsTest.itHasTheseBuilderMethods(com.yubico.webauthn.StartAssertionOptionsTest)
negated conditional → KILLED

133

1.1
Location : <init>
Killed by : com.yubico.webauthn.StartAssertionOptionsTest.itHasTheseBuilderMethods(com.yubico.webauthn.StartAssertionOptionsTest)
negated conditional → KILLED

159

1.1
Location : getUsername
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
replaced return value with Optional.empty for com/yubico/webauthn/StartAssertionOptions::getUsername → KILLED

187

1.1
Location : getUserHandle
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
replaced return value with Optional.empty for com/yubico/webauthn/StartAssertionOptions::getUserHandle → KILLED

202

1.1
Location : getUserVerification
Killed by : com.yubico.webauthn.RelyingPartyV2AssertionSpec
replaced return value with Optional.empty for com/yubico/webauthn/StartAssertionOptions::getUserVerification → KILLED

216

1.1
Location : getTimeout
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
replaced return value with Optional.empty for com/yubico/webauthn/StartAssertionOptions::getTimeout → KILLED

251

1.1
Location : username
Killed by : com.yubico.webauthn.StartAssertionOptionsTest.itHasTheseBuilderMethods(com.yubico.webauthn.StartAssertionOptionsTest)
negated conditional → KILLED

253

1.1
Location : username
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
negated conditional → KILLED

256

1.1
Location : username
Killed by : com.yubico.webauthn.StartAssertionOptionsTest.itHasTheseBuilderMethods(com.yubico.webauthn.StartAssertionOptionsTest)
replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::username → KILLED

286

1.1
Location : username
Killed by : com.yubico.webauthn.StartAssertionOptionsTest.itHasTheseBuilderMethods(com.yubico.webauthn.StartAssertionOptionsTest)
replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::username → KILLED

317

1.1
Location : userHandle
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
negated conditional → KILLED

319

1.1
Location : userHandle
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
negated conditional → KILLED

322

1.1
Location : userHandle
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::userHandle → KILLED

352

1.1
Location : userHandle
Killed by : com.yubico.webauthn.RelyingPartyUserIdentificationSpec
replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::userHandle → KILLED

367

1.1
Location : userVerification
Killed by : com.yubico.webauthn.StartAssertionOptionsTest.itHasTheseBuilderMethods(com.yubico.webauthn.StartAssertionOptionsTest)
negated conditional → KILLED

369

1.1
Location : userVerification
Killed by : com.yubico.webauthn.StartAssertionOptionsTest.itHasTheseBuilderMethods(com.yubico.webauthn.StartAssertionOptionsTest)
replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::userVerification → KILLED

385

1.1
Location : userVerification
Killed by : com.yubico.webauthn.StartAssertionOptionsTest.itHasTheseBuilderMethods(com.yubico.webauthn.StartAssertionOptionsTest)
replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::userVerification → KILLED

398

1.1
Location : timeout
Killed by : com.yubico.webauthn.StartAssertionOptionsTest.itHasTheseBuilderMethods(com.yubico.webauthn.StartAssertionOptionsTest)
negated conditional → KILLED

399

1.1
Location : timeout
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
changed conditional boundary → KILLED

2.2
Location : timeout
Killed by : com.yubico.webauthn.StartAssertionOptionsTest.itHasTheseBuilderMethods(com.yubico.webauthn.StartAssertionOptionsTest)
negated conditional → KILLED

3.3
Location : timeout
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
negated conditional → KILLED

403

1.1
Location : timeout
Killed by : com.yubico.webauthn.StartAssertionOptionsTest.itHasTheseBuilderMethods(com.yubico.webauthn.StartAssertionOptionsTest)
replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::timeout → KILLED

417

1.1
Location : timeout
Killed by : com.yubico.webauthn.StartAssertionOptionsTest.itHasTheseBuilderMethods(com.yubico.webauthn.StartAssertionOptionsTest)
replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::timeout → KILLED

425

1.1
Location : timeout
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::timeout → KILLED

462

1.1
Location : hints
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
negated conditional → KILLED

464

1.1
Location : hints
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::hints → KILLED

501

1.1
Location : hints
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
negated conditional → KILLED

502

1.1
Location : hints
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::hints → KILLED

503

1.1
Location : lambda$hints$0
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::lambda$hints$0 → KILLED

540

1.1
Location : hints
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
negated conditional → KILLED

542

1.1
Location : hints
Killed by : com.yubico.webauthn.RelyingPartyStartOperationSpec
replaced return value with null for com/yubico/webauthn/StartAssertionOptions$StartAssertionOptionsBuilder::hints → KILLED

Active mutators

Tests examined


Report generated by PIT 1.15.0