{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeFamilies #-}

-- | Stability: internal
-- This module handles the encoding of structures passed to the
-- [create()](https://w3c.github.io/webappsec-credential-management/#dom-credentialscontainer-create)
-- and [get()](https://w3c.github.io/webappsec-credential-management/#dom-credentialscontainer-get)
-- methods while [Registering a New Credential](https://www.w3.org/TR/webauthn-2/#sctn-registering-a-new-credential)
-- and [Verifying an Authentication Assertion](https://www.w3.org/TR/webauthn-2/#sctn-verifying-assertion) respectively.
module Crypto.WebAuthn.Model.WebIDL.Internal.Encoding
  ( Encode (..),
  )
where

import qualified Crypto.WebAuthn.Cose.Algorithm as Cose
import qualified Crypto.WebAuthn.Model.Kinds as K
import qualified Crypto.WebAuthn.Model.Types as M
import qualified Crypto.WebAuthn.Model.WebIDL.Internal.Binary.Encoding as B
import Crypto.WebAuthn.Model.WebIDL.Internal.Convert (Convert (IDL))
import qualified Crypto.WebAuthn.Model.WebIDL.Types as IDL
import qualified Crypto.WebAuthn.WebIDL as IDL
import Data.Coerce (Coercible, coerce)
import qualified Data.Map as Map
import Data.Singletons (SingI)

-- | @'Encode' hs@ indicates that the Haskell-specific type @hs@ can be
-- encoded to the more generic JavaScript type @'IDL' hs@ with the 'encode' function.
class Convert a => Encode a where
  encode :: a -> IDL a
  default encode :: Coercible a (IDL a) => a -> IDL a
  encode = a -> IDL a
coerce

instance Encode hs => Encode (Maybe hs) where
  encode :: Maybe hs -> IDL (Maybe hs)
encode Maybe hs
Nothing = IDL (Maybe hs)
forall a. Maybe a
Nothing
  encode (Just hs
hs) = IDL hs -> Maybe (IDL hs)
forall a. a -> Maybe a
Just (IDL hs -> Maybe (IDL hs)) -> IDL hs -> Maybe (IDL hs)
forall a b. (a -> b) -> a -> b
$ hs -> IDL hs
forall a. Encode a => a -> IDL a
encode hs
hs

instance Encode M.RpId

instance Encode M.RelyingPartyName

instance Encode M.UserHandle

instance Encode M.UserAccountDisplayName

instance Encode M.UserAccountName

instance Encode M.Challenge

instance Encode M.Timeout

instance Encode M.CredentialId

instance Encode M.AuthenticationExtensionsClientInputs where
  -- TODO: Extensions are not implemented by this library, see the TODO in the
  -- module documentation of `Crypto.WebAuthn.Model` for more information.
  encode :: AuthenticationExtensionsClientInputs
-> IDL AuthenticationExtensionsClientInputs
encode M.AuthenticationExtensionsClientInputs {} = IDL AuthenticationExtensionsClientInputs
forall k a. Map k a
Map.empty

-- | <https://www.iana.org/assignments/cose/cose.xhtml#algorithms>
instance Encode Cose.CoseSignAlg where
  encode :: CoseSignAlg -> IDL CoseSignAlg
encode = CoseSignAlg -> IDL CoseSignAlg
forall p. Num p => CoseSignAlg -> p
Cose.fromCoseSignAlg

-- | <https://www.w3.org/TR/webauthn-2/#enum-credentialType>
instance Encode M.CredentialType where
  encode :: CredentialType -> IDL CredentialType
encode CredentialType
M.CredentialTypePublicKey = IDL CredentialType
"public-key"

-- | <https://www.w3.org/TR/webauthn-2/#enumdef-authenticatortransport>
instance Encode [M.AuthenticatorTransport] where
  encode :: [AuthenticatorTransport] -> IDL [AuthenticatorTransport]
encode = (AuthenticatorTransport -> DOMString)
-> [AuthenticatorTransport] -> [DOMString]
forall a b. (a -> b) -> [a] -> [b]
map AuthenticatorTransport -> DOMString
forall p. IsString p => AuthenticatorTransport -> p
encodeTransport
    where
      encodeTransport :: AuthenticatorTransport -> p
encodeTransport AuthenticatorTransport
M.AuthenticatorTransportUSB = p
"usb"
      encodeTransport AuthenticatorTransport
M.AuthenticatorTransportNFC = p
"nfc"
      encodeTransport AuthenticatorTransport
M.AuthenticatorTransportBLE = p
"ble"
      encodeTransport AuthenticatorTransport
M.AuthenticatorTransportInternal = p
"internal"

-- | <https://www.w3.org/TR/webauthn-2/#enumdef-authenticatorattachment>
instance Encode M.AuthenticatorAttachment where
  encode :: AuthenticatorAttachment -> IDL AuthenticatorAttachment
encode AuthenticatorAttachment
M.AuthenticatorAttachmentPlatform = IDL AuthenticatorAttachment
"platform"
  encode AuthenticatorAttachment
M.AuthenticatorAttachmentCrossPlatform = IDL AuthenticatorAttachment
"cross-platform"

-- | <https://www.w3.org/TR/webauthn-2/#enum-residentKeyRequirement>
instance Encode M.ResidentKeyRequirement where
  encode :: ResidentKeyRequirement -> IDL ResidentKeyRequirement
encode ResidentKeyRequirement
M.ResidentKeyRequirementDiscouraged = DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just DOMString
"discouraged"
  encode ResidentKeyRequirement
M.ResidentKeyRequirementPreferred = DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just DOMString
"preferred"
  encode ResidentKeyRequirement
M.ResidentKeyRequirementRequired = DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just DOMString
"required"

-- | <https://www.w3.org/TR/webauthn-2/#enum-userVerificationRequirement>
instance Encode M.UserVerificationRequirement where
  encode :: UserVerificationRequirement -> IDL UserVerificationRequirement
encode UserVerificationRequirement
M.UserVerificationRequirementRequired = DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just DOMString
"required"
  encode UserVerificationRequirement
M.UserVerificationRequirementPreferred = DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just DOMString
"preferred"
  encode UserVerificationRequirement
M.UserVerificationRequirementDiscouraged = DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just DOMString
"discouraged"

-- | <https://www.w3.org/TR/webauthn-2/#enum-attestation-convey>
instance Encode M.AttestationConveyancePreference where
  encode :: AttestationConveyancePreference
-> IDL AttestationConveyancePreference
encode AttestationConveyancePreference
M.AttestationConveyancePreferenceNone = DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just DOMString
"none"
  encode AttestationConveyancePreference
M.AttestationConveyancePreferenceIndirect = DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just DOMString
"indirect"
  encode AttestationConveyancePreference
M.AttestationConveyancePreferenceDirect = DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just DOMString
"direct"
  encode AttestationConveyancePreference
M.AttestationConveyancePreferenceEnterprise = DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just DOMString
"enterprise"

instance Encode M.CredentialRpEntity where
  encode :: CredentialRpEntity -> IDL CredentialRpEntity
encode M.CredentialRpEntity {Maybe RpId
RelyingPartyName
creName :: CredentialRpEntity -> RelyingPartyName
creId :: CredentialRpEntity -> Maybe RpId
creName :: RelyingPartyName
creId :: Maybe RpId
..} =
    PublicKeyCredentialRpEntity :: Maybe DOMString -> DOMString -> PublicKeyCredentialRpEntity
IDL.PublicKeyCredentialRpEntity
      { $sel:id:PublicKeyCredentialRpEntity :: Maybe DOMString
id = Maybe RpId -> IDL (Maybe RpId)
forall a. Encode a => a -> IDL a
encode Maybe RpId
creId,
        $sel:name:PublicKeyCredentialRpEntity :: DOMString
name = RelyingPartyName -> IDL RelyingPartyName
forall a. Encode a => a -> IDL a
encode RelyingPartyName
creName
      }

instance Encode M.CredentialUserEntity where
  encode :: CredentialUserEntity -> IDL CredentialUserEntity
encode M.CredentialUserEntity {UserAccountName
UserAccountDisplayName
UserHandle
cueName :: CredentialUserEntity -> UserAccountName
cueDisplayName :: CredentialUserEntity -> UserAccountDisplayName
cueId :: CredentialUserEntity -> UserHandle
cueName :: UserAccountName
cueDisplayName :: UserAccountDisplayName
cueId :: UserHandle
..} =
    PublicKeyCredentialUserEntity :: BufferSource
-> DOMString -> DOMString -> PublicKeyCredentialUserEntity
IDL.PublicKeyCredentialUserEntity
      { $sel:id:PublicKeyCredentialUserEntity :: BufferSource
id = UserHandle -> IDL UserHandle
forall a. Encode a => a -> IDL a
encode UserHandle
cueId,
        $sel:displayName:PublicKeyCredentialUserEntity :: DOMString
displayName = UserAccountDisplayName -> IDL UserAccountDisplayName
forall a. Encode a => a -> IDL a
encode UserAccountDisplayName
cueDisplayName,
        $sel:name:PublicKeyCredentialUserEntity :: DOMString
name = UserAccountName -> IDL UserAccountName
forall a. Encode a => a -> IDL a
encode UserAccountName
cueName
      }

instance Encode [M.CredentialParameters] where
  encode :: [CredentialParameters] -> IDL [CredentialParameters]
encode = (CredentialParameters -> PublicKeyCredentialParameters)
-> [CredentialParameters] -> [PublicKeyCredentialParameters]
forall a b. (a -> b) -> [a] -> [b]
map CredentialParameters -> PublicKeyCredentialParameters
encodeParameters
    where
      encodeParameters :: CredentialParameters -> PublicKeyCredentialParameters
encodeParameters M.CredentialParameters {CoseSignAlg
CredentialType
cpAlg :: CredentialParameters -> CoseSignAlg
cpTyp :: CredentialParameters -> CredentialType
cpAlg :: CoseSignAlg
cpTyp :: CredentialType
..} =
        PublicKeyCredentialParameters :: DOMString
-> COSEAlgorithmIdentifier -> PublicKeyCredentialParameters
IDL.PublicKeyCredentialParameters
          { $sel:littype:PublicKeyCredentialParameters :: DOMString
littype = CredentialType -> IDL CredentialType
forall a. Encode a => a -> IDL a
encode CredentialType
cpTyp,
            $sel:alg:PublicKeyCredentialParameters :: COSEAlgorithmIdentifier
alg = CoseSignAlg -> IDL CoseSignAlg
forall a. Encode a => a -> IDL a
encode CoseSignAlg
cpAlg
          }

instance Encode M.CredentialDescriptor where
  encode :: CredentialDescriptor -> IDL CredentialDescriptor
encode M.CredentialDescriptor {Maybe [AuthenticatorTransport]
CredentialId
CredentialType
cdTransports :: CredentialDescriptor -> Maybe [AuthenticatorTransport]
cdId :: CredentialDescriptor -> CredentialId
cdTyp :: CredentialDescriptor -> CredentialType
cdTransports :: Maybe [AuthenticatorTransport]
cdId :: CredentialId
cdTyp :: CredentialType
..} =
    PublicKeyCredentialDescriptor :: DOMString
-> BufferSource
-> Maybe [DOMString]
-> PublicKeyCredentialDescriptor
IDL.PublicKeyCredentialDescriptor
      { $sel:littype:PublicKeyCredentialDescriptor :: DOMString
littype = CredentialType -> IDL CredentialType
forall a. Encode a => a -> IDL a
encode CredentialType
cdTyp,
        $sel:id:PublicKeyCredentialDescriptor :: BufferSource
id = CredentialId -> IDL CredentialId
forall a. Encode a => a -> IDL a
encode CredentialId
cdId,
        $sel:transports:PublicKeyCredentialDescriptor :: Maybe [DOMString]
transports = Maybe [AuthenticatorTransport]
-> IDL (Maybe [AuthenticatorTransport])
forall a. Encode a => a -> IDL a
encode Maybe [AuthenticatorTransport]
cdTransports
      }

instance Encode M.AuthenticatorSelectionCriteria where
  encode :: AuthenticatorSelectionCriteria
-> IDL AuthenticatorSelectionCriteria
encode M.AuthenticatorSelectionCriteria {Maybe AuthenticatorAttachment
UserVerificationRequirement
ResidentKeyRequirement
ascUserVerification :: AuthenticatorSelectionCriteria -> UserVerificationRequirement
ascResidentKey :: AuthenticatorSelectionCriteria -> ResidentKeyRequirement
ascAuthenticatorAttachment :: AuthenticatorSelectionCriteria -> Maybe AuthenticatorAttachment
ascUserVerification :: UserVerificationRequirement
ascResidentKey :: ResidentKeyRequirement
ascAuthenticatorAttachment :: Maybe AuthenticatorAttachment
..} =
    AuthenticatorSelectionCriteria :: Maybe DOMString
-> Maybe DOMString
-> Maybe Boolean
-> Maybe DOMString
-> AuthenticatorSelectionCriteria
IDL.AuthenticatorSelectionCriteria
      { $sel:authenticatorAttachment:AuthenticatorSelectionCriteria :: Maybe DOMString
authenticatorAttachment = Maybe AuthenticatorAttachment
-> IDL (Maybe AuthenticatorAttachment)
forall a. Encode a => a -> IDL a
encode Maybe AuthenticatorAttachment
ascAuthenticatorAttachment,
        $sel:residentKey:AuthenticatorSelectionCriteria :: Maybe DOMString
residentKey = ResidentKeyRequirement -> IDL ResidentKeyRequirement
forall a. Encode a => a -> IDL a
encode ResidentKeyRequirement
ascResidentKey,
        -- [(spec)](https://www.w3.org/TR/webauthn-2/#dom-authenticatorselectioncriteria-requireresidentkey)
        -- Relying Parties SHOULD set it to true if, and only if, residentKey is set to required.
        $sel:requireResidentKey:AuthenticatorSelectionCriteria :: Maybe Boolean
requireResidentKey = Boolean -> Maybe Boolean
forall a. a -> Maybe a
Just (ResidentKeyRequirement
ascResidentKey ResidentKeyRequirement -> ResidentKeyRequirement -> Boolean
forall a. Eq a => a -> a -> Boolean
== ResidentKeyRequirement
M.ResidentKeyRequirementRequired),
        $sel:userVerification:AuthenticatorSelectionCriteria :: Maybe DOMString
userVerification = UserVerificationRequirement -> IDL UserVerificationRequirement
forall a. Encode a => a -> IDL a
encode UserVerificationRequirement
ascUserVerification
      }

instance Encode [M.CredentialDescriptor] where
  encode :: [CredentialDescriptor] -> IDL [CredentialDescriptor]
encode = [PublicKeyCredentialDescriptor]
-> Maybe [PublicKeyCredentialDescriptor]
forall a. a -> Maybe a
Just ([PublicKeyCredentialDescriptor]
 -> Maybe [PublicKeyCredentialDescriptor])
-> ([CredentialDescriptor] -> [PublicKeyCredentialDescriptor])
-> [CredentialDescriptor]
-> Maybe [PublicKeyCredentialDescriptor]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CredentialDescriptor -> PublicKeyCredentialDescriptor)
-> [CredentialDescriptor] -> [PublicKeyCredentialDescriptor]
forall a b. (a -> b) -> [a] -> [b]
map CredentialDescriptor -> PublicKeyCredentialDescriptor
forall a. Encode a => a -> IDL a
encode

instance Encode (M.CredentialOptions 'K.Registration) where
  encode :: CredentialOptions 'Registration
-> IDL (CredentialOptions 'Registration)
encode M.CredentialOptionsRegistration {[CredentialDescriptor]
[CredentialParameters]
Maybe AuthenticatorSelectionCriteria
Maybe AuthenticationExtensionsClientInputs
Maybe Timeout
CredentialUserEntity
CredentialRpEntity
Challenge
AttestationConveyancePreference
corExtensions :: CredentialOptions 'Registration
-> Maybe AuthenticationExtensionsClientInputs
corAttestation :: CredentialOptions 'Registration -> AttestationConveyancePreference
corAuthenticatorSelection :: CredentialOptions 'Registration
-> Maybe AuthenticatorSelectionCriteria
corExcludeCredentials :: CredentialOptions 'Registration -> [CredentialDescriptor]
corTimeout :: CredentialOptions 'Registration -> Maybe Timeout
corPubKeyCredParams :: CredentialOptions 'Registration -> [CredentialParameters]
corChallenge :: CredentialOptions 'Registration -> Challenge
corUser :: CredentialOptions 'Registration -> CredentialUserEntity
corRp :: CredentialOptions 'Registration -> CredentialRpEntity
corExtensions :: Maybe AuthenticationExtensionsClientInputs
corAttestation :: AttestationConveyancePreference
corAuthenticatorSelection :: Maybe AuthenticatorSelectionCriteria
corExcludeCredentials :: [CredentialDescriptor]
corTimeout :: Maybe Timeout
corPubKeyCredParams :: [CredentialParameters]
corChallenge :: Challenge
corUser :: CredentialUserEntity
corRp :: CredentialRpEntity
..} =
    PublicKeyCredentialCreationOptions :: PublicKeyCredentialRpEntity
-> PublicKeyCredentialUserEntity
-> BufferSource
-> [PublicKeyCredentialParameters]
-> Maybe UnsignedLong
-> Maybe [PublicKeyCredentialDescriptor]
-> Maybe AuthenticatorSelectionCriteria
-> Maybe DOMString
-> Maybe (Map DOMString Value)
-> PublicKeyCredentialCreationOptions
IDL.PublicKeyCredentialCreationOptions
      { $sel:rp:PublicKeyCredentialCreationOptions :: PublicKeyCredentialRpEntity
rp = CredentialRpEntity -> IDL CredentialRpEntity
forall a. Encode a => a -> IDL a
encode CredentialRpEntity
corRp,
        $sel:user:PublicKeyCredentialCreationOptions :: PublicKeyCredentialUserEntity
user = CredentialUserEntity -> IDL CredentialUserEntity
forall a. Encode a => a -> IDL a
encode CredentialUserEntity
corUser,
        $sel:challenge:PublicKeyCredentialCreationOptions :: BufferSource
challenge = Challenge -> IDL Challenge
forall a. Encode a => a -> IDL a
encode Challenge
corChallenge,
        $sel:pubKeyCredParams:PublicKeyCredentialCreationOptions :: [PublicKeyCredentialParameters]
pubKeyCredParams = [CredentialParameters] -> IDL [CredentialParameters]
forall a. Encode a => a -> IDL a
encode [CredentialParameters]
corPubKeyCredParams,
        $sel:timeout:PublicKeyCredentialCreationOptions :: Maybe UnsignedLong
timeout = Maybe Timeout -> IDL (Maybe Timeout)
forall a. Encode a => a -> IDL a
encode Maybe Timeout
corTimeout,
        $sel:excludeCredentials:PublicKeyCredentialCreationOptions :: Maybe [PublicKeyCredentialDescriptor]
excludeCredentials = [CredentialDescriptor] -> IDL [CredentialDescriptor]
forall a. Encode a => a -> IDL a
encode [CredentialDescriptor]
corExcludeCredentials,
        $sel:authenticatorSelection:PublicKeyCredentialCreationOptions :: Maybe AuthenticatorSelectionCriteria
authenticatorSelection = Maybe AuthenticatorSelectionCriteria
-> IDL (Maybe AuthenticatorSelectionCriteria)
forall a. Encode a => a -> IDL a
encode Maybe AuthenticatorSelectionCriteria
corAuthenticatorSelection,
        $sel:attestation:PublicKeyCredentialCreationOptions :: Maybe DOMString
attestation = AttestationConveyancePreference
-> IDL AttestationConveyancePreference
forall a. Encode a => a -> IDL a
encode AttestationConveyancePreference
corAttestation,
        $sel:extensions:PublicKeyCredentialCreationOptions :: Maybe (Map DOMString Value)
extensions = Maybe AuthenticationExtensionsClientInputs
-> IDL (Maybe AuthenticationExtensionsClientInputs)
forall a. Encode a => a -> IDL a
encode Maybe AuthenticationExtensionsClientInputs
corExtensions
      }

instance Encode (M.CredentialOptions 'K.Authentication) where
  encode :: CredentialOptions 'Authentication
-> IDL (CredentialOptions 'Authentication)
encode M.CredentialOptionsAuthentication {[CredentialDescriptor]
Maybe AuthenticationExtensionsClientInputs
Maybe Timeout
Maybe RpId
Challenge
UserVerificationRequirement
coaExtensions :: CredentialOptions 'Authentication
-> Maybe AuthenticationExtensionsClientInputs
coaUserVerification :: CredentialOptions 'Authentication -> UserVerificationRequirement
coaAllowCredentials :: CredentialOptions 'Authentication -> [CredentialDescriptor]
coaRpId :: CredentialOptions 'Authentication -> Maybe RpId
coaTimeout :: CredentialOptions 'Authentication -> Maybe Timeout
coaChallenge :: CredentialOptions 'Authentication -> Challenge
coaExtensions :: Maybe AuthenticationExtensionsClientInputs
coaUserVerification :: UserVerificationRequirement
coaAllowCredentials :: [CredentialDescriptor]
coaRpId :: Maybe RpId
coaTimeout :: Maybe Timeout
coaChallenge :: Challenge
..} =
    PublicKeyCredentialRequestOptions :: BufferSource
-> Maybe UnsignedLong
-> Maybe DOMString
-> Maybe [PublicKeyCredentialDescriptor]
-> Maybe DOMString
-> Maybe (Map DOMString Value)
-> PublicKeyCredentialRequestOptions
IDL.PublicKeyCredentialRequestOptions
      { $sel:challenge:PublicKeyCredentialRequestOptions :: BufferSource
challenge = Challenge -> IDL Challenge
forall a. Encode a => a -> IDL a
encode Challenge
coaChallenge,
        $sel:timeout:PublicKeyCredentialRequestOptions :: Maybe UnsignedLong
timeout = Maybe Timeout -> IDL (Maybe Timeout)
forall a. Encode a => a -> IDL a
encode Maybe Timeout
coaTimeout,
        $sel:rpId:PublicKeyCredentialRequestOptions :: Maybe DOMString
rpId = Maybe RpId -> IDL (Maybe RpId)
forall a. Encode a => a -> IDL a
encode Maybe RpId
coaRpId,
        $sel:allowCredentials:PublicKeyCredentialRequestOptions :: Maybe [PublicKeyCredentialDescriptor]
allowCredentials = [CredentialDescriptor] -> IDL [CredentialDescriptor]
forall a. Encode a => a -> IDL a
encode [CredentialDescriptor]
coaAllowCredentials,
        $sel:userVerification:PublicKeyCredentialRequestOptions :: Maybe DOMString
userVerification = UserVerificationRequirement -> IDL UserVerificationRequirement
forall a. Encode a => a -> IDL a
encode UserVerificationRequirement
coaUserVerification,
        $sel:extensions:PublicKeyCredentialRequestOptions :: Maybe (Map DOMString Value)
extensions = Maybe AuthenticationExtensionsClientInputs
-> IDL (Maybe AuthenticationExtensionsClientInputs)
forall a. Encode a => a -> IDL a
encode Maybe AuthenticationExtensionsClientInputs
coaExtensions
      }

-- | [(spec)](https://www.w3.org/TR/webauthn-2/#iface-pkcredential)
-- Encodes the PublicKeyCredential for attestation, this instance is mostly used in the tests where we emulate the
-- of the client.
instance Encode (M.Credential 'K.Registration 'True) where
  encode :: Credential 'Registration 'True
-> IDL (Credential 'Registration 'True)
encode M.Credential {AuthenticatorResponse 'Registration 'True
AuthenticationExtensionsClientOutputs
CredentialId
cClientExtensionResults :: forall (c :: CeremonyKind) (raw :: Boolean).
Credential c raw -> AuthenticationExtensionsClientOutputs
cResponse :: forall (c :: CeremonyKind) (raw :: Boolean).
Credential c raw -> AuthenticatorResponse c raw
cIdentifier :: forall (c :: CeremonyKind) (raw :: Boolean).
Credential c raw -> CredentialId
cClientExtensionResults :: AuthenticationExtensionsClientOutputs
cResponse :: AuthenticatorResponse 'Registration 'True
cIdentifier :: CredentialId
..} =
    PublicKeyCredential :: forall response.
BufferSource
-> response -> Map DOMString Value -> PublicKeyCredential response
IDL.PublicKeyCredential
      { $sel:rawId:PublicKeyCredential :: BufferSource
rawId = CredentialId -> IDL CredentialId
forall a. Encode a => a -> IDL a
encode CredentialId
cIdentifier,
        $sel:response:PublicKeyCredential :: AuthenticatorAttestationResponse
response = AuthenticatorResponse 'Registration 'True
-> IDL (AuthenticatorResponse 'Registration 'True)
forall a. Encode a => a -> IDL a
encode AuthenticatorResponse 'Registration 'True
cResponse,
        -- TODO: Extensions are not implemented by this library, see the TODO in the
        -- module documentation of `Crypto.WebAuthn.Model` for more information.
        $sel:clientExtensionResults:PublicKeyCredential :: Map DOMString Value
clientExtensionResults = Map DOMString Value
forall k a. Map k a
Map.empty
      }

-- | [(spec)](https://www.w3.org/TR/webauthn-2/#dom-authenticatorresponse-clientdatajson)
instance SingI c => Encode (M.CollectedClientData c 'True) where
  encode :: CollectedClientData c 'True -> IDL (CollectedClientData c 'True)
encode CollectedClientData c 'True
ccd = ByteString -> BufferSource
IDL.URLEncodedBase64 (ByteString -> BufferSource) -> ByteString -> BufferSource
forall a b. (a -> b) -> a -> b
$ CollectedClientData c 'True -> ByteString
forall (c :: CeremonyKind).
SingI c =>
CollectedClientData c 'True -> ByteString
B.encodeCollectedClientData CollectedClientData c 'True
ccd

instance Encode (M.AuthenticatorResponse 'K.Authentication 'True) where
  encode :: AuthenticatorResponse 'Authentication 'True
-> IDL (AuthenticatorResponse 'Authentication 'True)
encode M.AuthenticatorResponseAuthentication {Maybe UserHandle
AuthenticatorData 'Authentication 'True
CollectedClientData 'Authentication 'True
AssertionSignature
araUserHandle :: forall (raw :: Boolean).
AuthenticatorResponse 'Authentication raw -> Maybe UserHandle
araSignature :: forall (raw :: Boolean).
AuthenticatorResponse 'Authentication raw -> AssertionSignature
araAuthenticatorData :: forall (raw :: Boolean).
AuthenticatorResponse 'Authentication raw
-> AuthenticatorData 'Authentication raw
araClientData :: forall (raw :: Boolean).
AuthenticatorResponse 'Authentication raw
-> CollectedClientData 'Authentication raw
araUserHandle :: Maybe UserHandle
araSignature :: AssertionSignature
araAuthenticatorData :: AuthenticatorData 'Authentication 'True
araClientData :: CollectedClientData 'Authentication 'True
..} =
    AuthenticatorAssertionResponse :: BufferSource
-> BufferSource
-> BufferSource
-> Maybe BufferSource
-> AuthenticatorAssertionResponse
IDL.AuthenticatorAssertionResponse
      { $sel:clientDataJSON:AuthenticatorAssertionResponse :: BufferSource
clientDataJSON = CollectedClientData 'Authentication 'True
-> IDL (CollectedClientData 'Authentication 'True)
forall a. Encode a => a -> IDL a
encode CollectedClientData 'Authentication 'True
araClientData,
        $sel:authenticatorData:AuthenticatorAssertionResponse :: BufferSource
authenticatorData = ByteString -> BufferSource
IDL.URLEncodedBase64 (ByteString -> BufferSource) -> ByteString -> BufferSource
forall a b. (a -> b) -> a -> b
$ RawField 'True -> ByteString
M.unRaw (RawField 'True -> ByteString) -> RawField 'True -> ByteString
forall a b. (a -> b) -> a -> b
$ AuthenticatorData 'Authentication 'True -> RawField 'True
forall (c :: CeremonyKind) (raw :: Boolean).
AuthenticatorData c raw -> RawField raw
M.adRawData AuthenticatorData 'Authentication 'True
araAuthenticatorData,
        $sel:signature:AuthenticatorAssertionResponse :: BufferSource
signature = ByteString -> BufferSource
IDL.URLEncodedBase64 (ByteString -> BufferSource) -> ByteString -> BufferSource
forall a b. (a -> b) -> a -> b
$ AssertionSignature -> ByteString
M.unAssertionSignature AssertionSignature
araSignature,
        $sel:userHandle:AuthenticatorAssertionResponse :: Maybe BufferSource
userHandle = ByteString -> BufferSource
IDL.URLEncodedBase64 (ByteString -> BufferSource)
-> (UserHandle -> ByteString) -> UserHandle -> BufferSource
forall b c a. (b -> c) -> (a -> b) -> a -> c
. UserHandle -> ByteString
M.unUserHandle (UserHandle -> BufferSource)
-> Maybe UserHandle -> Maybe BufferSource
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe UserHandle
araUserHandle
      }

instance Encode (M.Credential 'K.Authentication 'True) where
  encode :: Credential 'Authentication 'True
-> IDL (Credential 'Authentication 'True)
encode M.Credential {AuthenticatorResponse 'Authentication 'True
AuthenticationExtensionsClientOutputs
CredentialId
cClientExtensionResults :: AuthenticationExtensionsClientOutputs
cResponse :: AuthenticatorResponse 'Authentication 'True
cIdentifier :: CredentialId
cClientExtensionResults :: forall (c :: CeremonyKind) (raw :: Boolean).
Credential c raw -> AuthenticationExtensionsClientOutputs
cResponse :: forall (c :: CeremonyKind) (raw :: Boolean).
Credential c raw -> AuthenticatorResponse c raw
cIdentifier :: forall (c :: CeremonyKind) (raw :: Boolean).
Credential c raw -> CredentialId
..} =
    PublicKeyCredential :: forall response.
BufferSource
-> response -> Map DOMString Value -> PublicKeyCredential response
IDL.PublicKeyCredential
      { $sel:rawId:PublicKeyCredential :: BufferSource
rawId = CredentialId -> IDL CredentialId
forall a. Encode a => a -> IDL a
encode CredentialId
cIdentifier,
        $sel:response:PublicKeyCredential :: AuthenticatorAssertionResponse
response = AuthenticatorResponse 'Authentication 'True
-> IDL (AuthenticatorResponse 'Authentication 'True)
forall a. Encode a => a -> IDL a
encode AuthenticatorResponse 'Authentication 'True
cResponse,
        -- TODO: Extensions are not implemented by this library, see the TODO in the
        -- module documentation of `Crypto.WebAuthn.Model` for more information.
        $sel:clientExtensionResults:PublicKeyCredential :: Map DOMString Value
clientExtensionResults = Map DOMString Value
forall k a. Map k a
Map.empty
      }

-- | [(spec)](https://www.w3.org/TR/webauthn-2/#iface-authenticatorresponse)
instance Encode (M.AuthenticatorResponse 'K.Registration 'True) where
  encode :: AuthenticatorResponse 'Registration 'True
-> IDL (AuthenticatorResponse 'Registration 'True)
encode M.AuthenticatorResponseRegistration {[AuthenticatorTransport]
AttestationObject 'True
CollectedClientData 'Registration 'True
arrTransports :: forall (raw :: Boolean).
AuthenticatorResponse 'Registration raw -> [AuthenticatorTransport]
arrAttestationObject :: forall (raw :: Boolean).
AuthenticatorResponse 'Registration raw -> AttestationObject raw
arrClientData :: forall (raw :: Boolean).
AuthenticatorResponse 'Registration raw
-> CollectedClientData 'Registration raw
arrTransports :: [AuthenticatorTransport]
arrAttestationObject :: AttestationObject 'True
arrClientData :: CollectedClientData 'Registration 'True
..} =
    AuthenticatorAttestationResponse :: BufferSource
-> BufferSource
-> Maybe [DOMString]
-> AuthenticatorAttestationResponse
IDL.AuthenticatorAttestationResponse
      { $sel:clientDataJSON:AuthenticatorAttestationResponse :: BufferSource
clientDataJSON = CollectedClientData 'Registration 'True
-> IDL (CollectedClientData 'Registration 'True)
forall a. Encode a => a -> IDL a
encode CollectedClientData 'Registration 'True
arrClientData,
        $sel:attestationObject:AuthenticatorAttestationResponse :: BufferSource
attestationObject = AttestationObject 'True -> IDL (AttestationObject 'True)
forall a. Encode a => a -> IDL a
encode AttestationObject 'True
arrAttestationObject,
        $sel:transports:AuthenticatorAttestationResponse :: Maybe [DOMString]
transports = [DOMString] -> Maybe [DOMString]
forall a. a -> Maybe a
Just ([DOMString] -> Maybe [DOMString])
-> [DOMString] -> Maybe [DOMString]
forall a b. (a -> b) -> a -> b
$ [AuthenticatorTransport] -> IDL [AuthenticatorTransport]
forall a. Encode a => a -> IDL a
encode [AuthenticatorTransport]
arrTransports
      }

-- | [(spec)](https://www.w3.org/TR/webauthn-2/#dom-authenticatorattestationresponse-attestationobject)
instance Encode (M.AttestationObject 'True) where
  encode :: AttestationObject 'True -> IDL (AttestationObject 'True)
encode AttestationObject 'True
ao = ByteString -> BufferSource
IDL.URLEncodedBase64 (ByteString -> BufferSource) -> ByteString -> BufferSource
forall a b. (a -> b) -> a -> b
$ AttestationObject 'True -> ByteString
B.encodeAttestationObject AttestationObject 'True
ao