Repository: logto-io/logto
File: packages/core/src/routes/experience/verification-routes/web-authn-verification.ts (TypeScript)

Code before:
            VerificationType.SignInWebAuthn,
            verificationId
          );
        } else {
          // Case II: Without identifier (discoverable passkey).
          // Retrieve challenge from interaction details, and create verification record.
          const details = await provider.interactionDetails(ctx.req, ctx.res);
          const authenticationOptionsParseResult =
            webAuthnAuthenticationOptionsInteractionStorageGuard.safeParse(details.result);

          assertThat(
            authenticationOptionsParseResult.success,
            new RequestError({ code: 'session.verification_session_not_found', status: 404 })
          );

          const { authenticationOptions } = authenticationOptionsParseResult.data.signInWebAuthn;

          // eslint-disable-next-line @silverhand/fp/no-mutation
          webAuthnVerification = new SignInWebAuthnVerification(libraries, queries, {
            id: generateStandardId(),
            type: VerificationType.SignInWebAuthn,
            verified: false,
            authenticationChallenge: authenticationOptions.challenge,
            authenticationRpId: authenticationOptions.rpId,
          });
        }

        verificationAuditLog.append({
          payload: {
            verificationId: webAuthnVerification.id,
            payload,
          },
        });

        await webAuthnVerification.verifyWebAuthnAuthentication(ctx, payload);

        experienceInteraction.setVerificationRecord(webAuthnVerification);

        await experienceInteraction.save();

        ctx.body = {
          verificationId: webAuthnVerification.id,
        };

        ctx.status = 200;

        return next();
      }
    );
  }
}

Review comment (security):
```suggestion
const webAuthnVerification: SignInWebAuthnVerification = verificationId
  ? experienceInteraction.getVerificationRecordByTypeAndId(
      VerificationType.SignInWebAuthn,
      verificationId
    )
  : await (async () => {
      // Without identifier (discoverable passkey).
      const details = await provider.interactionDetails(ctx.req, ctx.res);
      const authenticationOptionsParseResult =
        webAuthnAuthenticationOptionsInteractionStorageGuard.safeParse(details.result);

      assertThat(
        authenticationOptionsParseResult.success,
        new RequestError({ code: 'session.verification_session_not_found', status: 404 })
      );

      const { authenticationOptions } =
        authenticationOptionsParseResult.data.signInWebAuthn;

      return new SignInWebAuthnVerification(libraries, queries, {
        id: generateStandardId(),
        type: VerificationType.SignInWebAuthn,
        verified: false,
        authenticationChallenge: authenticationOptions.challenge,
        authenticationRpId: authenticationOptions.rpId,
      });
    })();
```

Code after:
              // Case II: Without identifier (discoverable passkey).
              // Retrieve challenge from interaction details, and create verification record.
              const details = await provider.interactionDetails(ctx.req, ctx.res);
              const authenticationOptionsParseResult =
                webAuthnAuthenticationOptionsInteractionStorageGuard.safeParse(details.result);

              assertThat(
                authenticationOptionsParseResult.success,
                new RequestError({ code: 'session.verification_session_not_found', status: 404 })
              );

              const { authenticationOptions } =
                authenticationOptionsParseResult.data.signInWebAuthn;

              return new SignInWebAuthnVerification(libraries, queries, {
                id: generateStandardId(),
                type: VerificationType.SignInWebAuthn,
                verified: false,
                authenticationChallenge: authenticationOptions.challenge,
                authenticationRpId: authenticationOptions.rpId,
              });
            })();

        verificationAuditLog.append({
          payload: {
            verificationId: webAuthnVerification.id,
            payload,
          },
        });

        await webAuthnVerification.verifyWebAuthnAuthentication(ctx, payload);

        experienceInteraction.setVerificationRecord(webAuthnVerification);

        await experienceInteraction.save();

        ctx.body = {
          verificationId: webAuthnVerification.id,
        };

        ctx.status = 200;

        return next();
      }
    );
  }
}
/* eslint-enable max-lines */