{-# LANGUAGE RecordWildCards #-}
module Crypto.WebAuthn.Metadata.Service.Decode
( decodeMetadataPayload,
decodeMetadataEntry,
)
where
import qualified Crypto.WebAuthn.Metadata.Service.Types as ServiceTypes
import qualified Crypto.WebAuthn.Metadata.Service.WebIDL as ServiceIDL
import Crypto.WebAuthn.Metadata.Statement.Decode (decodeAAGUID, decodeCertificate, decodeMetadataStatement, decodeSubjectKeyIdentifier)
import qualified Crypto.WebAuthn.Metadata.WebIDL as IDL
import Data.Bifunctor (first)
import Data.Hourglass (Date, DateTime (dtDate), ISO8601_Date (ISO8601_Date), timeParse)
import Data.List.NonEmpty (NonEmpty)
import qualified Data.List.NonEmpty as NE
import Data.Maybe (mapMaybe)
import Data.Text (Text)
import qualified Data.Text as Text
decodeMetadataPayload :: ServiceIDL.MetadataBLOBPayload -> Either Text ServiceTypes.MetadataPayload
decodeMetadataPayload :: MetadataBLOBPayload -> Either DOMString MetadataPayload
decodeMetadataPayload ServiceIDL.MetadataBLOBPayload {Int
[MetadataBLOBPayloadEntry]
Maybe DOMString
DOMString
$sel:entries:MetadataBLOBPayload :: MetadataBLOBPayload -> [MetadataBLOBPayloadEntry]
$sel:nextUpdate:MetadataBLOBPayload :: MetadataBLOBPayload -> DOMString
$sel:no:MetadataBLOBPayload :: MetadataBLOBPayload -> Int
$sel:legalHeader:MetadataBLOBPayload :: MetadataBLOBPayload -> Maybe DOMString
entries :: [MetadataBLOBPayloadEntry]
nextUpdate :: DOMString
no :: Int
legalHeader :: Maybe DOMString
..} = do
let mpLegalHeader :: Maybe DOMString
mpLegalHeader = Maybe DOMString
legalHeader
mpNo :: Int
mpNo = Int
no
Date
mpNextUpdate <- DOMString -> Either DOMString Date
decodeDate DOMString
nextUpdate
[NonEmpty SomeMetadataEntry]
decodedEntries <- [Either DOMString (NonEmpty SomeMetadataEntry)]
-> Either DOMString [NonEmpty SomeMetadataEntry]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
sequence ([Either DOMString (NonEmpty SomeMetadataEntry)]
-> Either DOMString [NonEmpty SomeMetadataEntry])
-> [Either DOMString (NonEmpty SomeMetadataEntry)]
-> Either DOMString [NonEmpty SomeMetadataEntry]
forall a b. (a -> b) -> a -> b
$ (MetadataBLOBPayloadEntry
-> Maybe (Either DOMString (NonEmpty SomeMetadataEntry)))
-> [MetadataBLOBPayloadEntry]
-> [Either DOMString (NonEmpty SomeMetadataEntry)]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe MetadataBLOBPayloadEntry
-> Maybe (Either DOMString (NonEmpty SomeMetadataEntry))
decodeMetadataEntry [MetadataBLOBPayloadEntry]
entries
let mpEntries :: [SomeMetadataEntry]
mpEntries = (NonEmpty SomeMetadataEntry -> [SomeMetadataEntry])
-> [NonEmpty SomeMetadataEntry] -> [SomeMetadataEntry]
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap NonEmpty SomeMetadataEntry -> [SomeMetadataEntry]
forall a. NonEmpty a -> [a]
NE.toList [NonEmpty SomeMetadataEntry]
decodedEntries
MetadataPayload -> Either DOMString MetadataPayload
forall (f :: * -> *) a. Applicative f => a -> f a
pure MetadataPayload :: Maybe DOMString
-> Int -> Date -> [SomeMetadataEntry] -> MetadataPayload
ServiceTypes.MetadataPayload {Int
[SomeMetadataEntry]
Maybe DOMString
Date
mpEntries :: [SomeMetadataEntry]
mpNextUpdate :: Date
mpNo :: Int
mpLegalHeader :: Maybe DOMString
mpEntries :: [SomeMetadataEntry]
mpNextUpdate :: Date
mpNo :: Int
mpLegalHeader :: Maybe DOMString
..}
liftEitherMaybe :: Either (Maybe a) b -> Maybe (Either a b)
liftEitherMaybe :: forall a b. Either (Maybe a) b -> Maybe (Either a b)
liftEitherMaybe (Left Maybe a
Nothing) = Maybe (Either a b)
forall a. Maybe a
Nothing
liftEitherMaybe (Left (Just a
a)) = Either a b -> Maybe (Either a b)
forall a. a -> Maybe a
Just (Either a b -> Maybe (Either a b))
-> Either a b -> Maybe (Either a b)
forall a b. (a -> b) -> a -> b
$ a -> Either a b
forall a b. a -> Either a b
Left a
a
liftEitherMaybe (Right b
b) = Either a b -> Maybe (Either a b)
forall a. a -> Maybe a
Just (Either a b -> Maybe (Either a b))
-> Either a b -> Maybe (Either a b)
forall a b. (a -> b) -> a -> b
$ b -> Either a b
forall a b. b -> Either a b
Right b
b
decodeMetadataEntry :: ServiceIDL.MetadataBLOBPayloadEntry -> Maybe (Either Text (NonEmpty ServiceTypes.SomeMetadataEntry))
decodeMetadataEntry :: MetadataBLOBPayloadEntry
-> Maybe (Either DOMString (NonEmpty SomeMetadataEntry))
decodeMetadataEntry ServiceIDL.MetadataBLOBPayloadEntry {Maybe (NonEmpty DOMString)
Maybe (NonEmpty BiometricStatusReport)
Maybe AAID
Maybe MetadataStatement
Maybe AAGUID
DOMString
NonEmpty StatusReport
$sel:timeOfLastStatusChange:MetadataBLOBPayloadEntry :: MetadataBLOBPayloadEntry -> DOMString
$sel:statusReports:MetadataBLOBPayloadEntry :: MetadataBLOBPayloadEntry -> NonEmpty StatusReport
$sel:biometricStatusReports:MetadataBLOBPayloadEntry :: MetadataBLOBPayloadEntry -> Maybe (NonEmpty BiometricStatusReport)
$sel:metadataStatement:MetadataBLOBPayloadEntry :: MetadataBLOBPayloadEntry -> Maybe MetadataStatement
$sel:attestationCertificateKeyIdentifiers:MetadataBLOBPayloadEntry :: MetadataBLOBPayloadEntry -> Maybe (NonEmpty DOMString)
$sel:aaguid:MetadataBLOBPayloadEntry :: MetadataBLOBPayloadEntry -> Maybe AAGUID
$sel:aaid:MetadataBLOBPayloadEntry :: MetadataBLOBPayloadEntry -> Maybe AAID
timeOfLastStatusChange :: DOMString
statusReports :: NonEmpty StatusReport
biometricStatusReports :: Maybe (NonEmpty BiometricStatusReport)
metadataStatement :: Maybe MetadataStatement
attestationCertificateKeyIdentifiers :: Maybe (NonEmpty DOMString)
aaguid :: Maybe AAGUID
aaid :: Maybe AAID
..} = Either (Maybe DOMString) (NonEmpty SomeMetadataEntry)
-> Maybe (Either DOMString (NonEmpty SomeMetadataEntry))
forall a b. Either (Maybe a) b -> Maybe (Either a b)
liftEitherMaybe (Either (Maybe DOMString) (NonEmpty SomeMetadataEntry)
-> Maybe (Either DOMString (NonEmpty SomeMetadataEntry)))
-> Either (Maybe DOMString) (NonEmpty SomeMetadataEntry)
-> Maybe (Either DOMString (NonEmpty SomeMetadataEntry))
forall a b. (a -> b) -> a -> b
$
case (Maybe AAID
aaid, Maybe AAGUID
aaguid, Maybe (NonEmpty DOMString)
attestationCertificateKeyIdentifiers) of
(Just AAID
_aaid, Maybe AAGUID
Nothing, Maybe (NonEmpty DOMString)
Nothing) ->
Maybe DOMString
-> Either (Maybe DOMString) (NonEmpty SomeMetadataEntry)
forall a b. a -> Either a b
Left Maybe DOMString
forall a. Maybe a
Nothing
(Maybe AAID
Nothing, Just AAGUID
aaguid, Maybe (NonEmpty DOMString)
Nothing) -> do
AuthenticatorIdentifier 'Fido2
meIdentifier <- (DOMString -> Maybe DOMString)
-> Either DOMString (AuthenticatorIdentifier 'Fido2)
-> Either (Maybe DOMString) (AuthenticatorIdentifier 'Fido2)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just (Either DOMString (AuthenticatorIdentifier 'Fido2)
-> Either (Maybe DOMString) (AuthenticatorIdentifier 'Fido2))
-> Either DOMString (AuthenticatorIdentifier 'Fido2)
-> Either (Maybe DOMString) (AuthenticatorIdentifier 'Fido2)
forall a b. (a -> b) -> a -> b
$ AAGUID -> Either DOMString (AuthenticatorIdentifier 'Fido2)
decodeAAGUID AAGUID
aaguid
Maybe MetadataStatement
meMetadataStatement <- (MetadataStatement -> Either (Maybe DOMString) MetadataStatement)
-> Maybe MetadataStatement
-> Either (Maybe DOMString) (Maybe MetadataStatement)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse MetadataStatement -> Either (Maybe DOMString) MetadataStatement
decodeMetadataStatement Maybe MetadataStatement
metadataStatement
NonEmpty StatusReport
meStatusReports <- (DOMString -> Maybe DOMString)
-> Either DOMString (NonEmpty StatusReport)
-> Either (Maybe DOMString) (NonEmpty StatusReport)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just (Either DOMString (NonEmpty StatusReport)
-> Either (Maybe DOMString) (NonEmpty StatusReport))
-> Either DOMString (NonEmpty StatusReport)
-> Either (Maybe DOMString) (NonEmpty StatusReport)
forall a b. (a -> b) -> a -> b
$ (StatusReport -> Either DOMString StatusReport)
-> NonEmpty StatusReport
-> Either DOMString (NonEmpty StatusReport)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse StatusReport -> Either DOMString StatusReport
decodeStatusReport NonEmpty StatusReport
statusReports
Date
meTimeOfLastStatusChange <- (DOMString -> Maybe DOMString)
-> Either DOMString Date -> Either (Maybe DOMString) Date
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just (Either DOMString Date -> Either (Maybe DOMString) Date)
-> Either DOMString Date -> Either (Maybe DOMString) Date
forall a b. (a -> b) -> a -> b
$ DOMString -> Either DOMString Date
decodeDate DOMString
timeOfLastStatusChange
NonEmpty SomeMetadataEntry
-> Either (Maybe DOMString) (NonEmpty SomeMetadataEntry)
forall a b. b -> Either a b
Right (NonEmpty SomeMetadataEntry
-> Either (Maybe DOMString) (NonEmpty SomeMetadataEntry))
-> NonEmpty SomeMetadataEntry
-> Either (Maybe DOMString) (NonEmpty SomeMetadataEntry)
forall a b. (a -> b) -> a -> b
$ SomeMetadataEntry -> NonEmpty SomeMetadataEntry
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SomeMetadataEntry -> NonEmpty SomeMetadataEntry)
-> SomeMetadataEntry -> NonEmpty SomeMetadataEntry
forall a b. (a -> b) -> a -> b
$ MetadataEntry 'Fido2 -> SomeMetadataEntry
forall (p :: ProtocolKind).
SingI p =>
MetadataEntry p -> SomeMetadataEntry
ServiceTypes.SomeMetadataEntry MetadataEntry :: forall (p :: ProtocolKind).
AuthenticatorIdentifier p
-> Maybe MetadataStatement
-> NonEmpty StatusReport
-> Date
-> MetadataEntry p
ServiceTypes.MetadataEntry {Maybe MetadataStatement
NonEmpty StatusReport
Date
AuthenticatorIdentifier 'Fido2
meTimeOfLastStatusChange :: Date
meStatusReports :: NonEmpty StatusReport
meMetadataStatement :: Maybe MetadataStatement
meIdentifier :: AuthenticatorIdentifier 'Fido2
meTimeOfLastStatusChange :: Date
meStatusReports :: NonEmpty StatusReport
meMetadataStatement :: Maybe MetadataStatement
meIdentifier :: AuthenticatorIdentifier 'Fido2
..}
(Maybe AAID
Nothing, Maybe AAGUID
Nothing, Just NonEmpty DOMString
attestationCertificateKeyIdentifiers) -> do
NonEmpty (AuthenticatorIdentifier 'FidoU2F)
identifiers <- (DOMString -> Maybe DOMString)
-> Either DOMString (NonEmpty (AuthenticatorIdentifier 'FidoU2F))
-> Either
(Maybe DOMString) (NonEmpty (AuthenticatorIdentifier 'FidoU2F))
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just (Either DOMString (NonEmpty (AuthenticatorIdentifier 'FidoU2F))
-> Either
(Maybe DOMString) (NonEmpty (AuthenticatorIdentifier 'FidoU2F)))
-> Either DOMString (NonEmpty (AuthenticatorIdentifier 'FidoU2F))
-> Either
(Maybe DOMString) (NonEmpty (AuthenticatorIdentifier 'FidoU2F))
forall a b. (a -> b) -> a -> b
$ (DOMString -> Either DOMString (AuthenticatorIdentifier 'FidoU2F))
-> NonEmpty DOMString
-> Either DOMString (NonEmpty (AuthenticatorIdentifier 'FidoU2F))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse DOMString -> Either DOMString (AuthenticatorIdentifier 'FidoU2F)
decodeSubjectKeyIdentifier NonEmpty DOMString
attestationCertificateKeyIdentifiers
Maybe MetadataStatement
meMetadataStatement <- (MetadataStatement -> Either (Maybe DOMString) MetadataStatement)
-> Maybe MetadataStatement
-> Either (Maybe DOMString) (Maybe MetadataStatement)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse MetadataStatement -> Either (Maybe DOMString) MetadataStatement
decodeMetadataStatement Maybe MetadataStatement
metadataStatement
NonEmpty StatusReport
meStatusReports <- (DOMString -> Maybe DOMString)
-> Either DOMString (NonEmpty StatusReport)
-> Either (Maybe DOMString) (NonEmpty StatusReport)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just (Either DOMString (NonEmpty StatusReport)
-> Either (Maybe DOMString) (NonEmpty StatusReport))
-> Either DOMString (NonEmpty StatusReport)
-> Either (Maybe DOMString) (NonEmpty StatusReport)
forall a b. (a -> b) -> a -> b
$ (StatusReport -> Either DOMString StatusReport)
-> NonEmpty StatusReport
-> Either DOMString (NonEmpty StatusReport)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse StatusReport -> Either DOMString StatusReport
decodeStatusReport NonEmpty StatusReport
statusReports
Date
meTimeOfLastStatusChange <- (DOMString -> Maybe DOMString)
-> Either DOMString Date -> Either (Maybe DOMString) Date
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just (Either DOMString Date -> Either (Maybe DOMString) Date)
-> Either DOMString Date -> Either (Maybe DOMString) Date
forall a b. (a -> b) -> a -> b
$ DOMString -> Either DOMString Date
decodeDate DOMString
timeOfLastStatusChange
NonEmpty SomeMetadataEntry
-> Either (Maybe DOMString) (NonEmpty SomeMetadataEntry)
forall a b. b -> Either a b
Right (NonEmpty SomeMetadataEntry
-> Either (Maybe DOMString) (NonEmpty SomeMetadataEntry))
-> NonEmpty SomeMetadataEntry
-> Either (Maybe DOMString) (NonEmpty SomeMetadataEntry)
forall a b. (a -> b) -> a -> b
$ (AuthenticatorIdentifier 'FidoU2F -> SomeMetadataEntry)
-> NonEmpty (AuthenticatorIdentifier 'FidoU2F)
-> NonEmpty SomeMetadataEntry
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\AuthenticatorIdentifier 'FidoU2F
meIdentifier -> MetadataEntry 'FidoU2F -> SomeMetadataEntry
forall (p :: ProtocolKind).
SingI p =>
MetadataEntry p -> SomeMetadataEntry
ServiceTypes.SomeMetadataEntry MetadataEntry :: forall (p :: ProtocolKind).
AuthenticatorIdentifier p
-> Maybe MetadataStatement
-> NonEmpty StatusReport
-> Date
-> MetadataEntry p
ServiceTypes.MetadataEntry {Maybe MetadataStatement
NonEmpty StatusReport
Date
AuthenticatorIdentifier 'FidoU2F
meIdentifier :: AuthenticatorIdentifier 'FidoU2F
meTimeOfLastStatusChange :: Date
meStatusReports :: NonEmpty StatusReport
meMetadataStatement :: Maybe MetadataStatement
meTimeOfLastStatusChange :: Date
meStatusReports :: NonEmpty StatusReport
meMetadataStatement :: Maybe MetadataStatement
meIdentifier :: AuthenticatorIdentifier 'FidoU2F
..}) NonEmpty (AuthenticatorIdentifier 'FidoU2F)
identifiers
(Maybe AAID
Nothing, Maybe AAGUID
Nothing, Maybe (NonEmpty DOMString)
Nothing) ->
Maybe DOMString
-> Either (Maybe DOMString) (NonEmpty SomeMetadataEntry)
forall a b. a -> Either a b
Left (Maybe DOMString
-> Either (Maybe DOMString) (NonEmpty SomeMetadataEntry))
-> Maybe DOMString
-> Either (Maybe DOMString) (NonEmpty SomeMetadataEntry)
forall a b. (a -> b) -> a -> b
$ DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just DOMString
"None of aaid, aaguid or attestationCertificateKeyIdentifiers are set for this entry"
(Maybe AAID, Maybe AAGUID, Maybe (NonEmpty DOMString))
_ ->
Maybe DOMString
-> Either (Maybe DOMString) (NonEmpty SomeMetadataEntry)
forall a b. a -> Either a b
Left (Maybe DOMString
-> Either (Maybe DOMString) (NonEmpty SomeMetadataEntry))
-> Maybe DOMString
-> Either (Maybe DOMString) (NonEmpty SomeMetadataEntry)
forall a b. (a -> b) -> a -> b
$ DOMString -> Maybe DOMString
forall a. a -> Maybe a
Just DOMString
"Multiple of aaid, aaguid and/or attestationCertificateKeyIdentifiers are set for this entry"
decodeStatusReport :: ServiceIDL.StatusReport -> Either Text ServiceTypes.StatusReport
decodeStatusReport :: StatusReport -> Either DOMString StatusReport
decodeStatusReport ServiceIDL.StatusReport {Maybe UnsignedLong
Maybe DOMString
AuthenticatorStatus
$sel:certificationRequirementsVersion:StatusReport :: StatusReport -> Maybe DOMString
$sel:certificationPolicyVersion:StatusReport :: StatusReport -> Maybe DOMString
$sel:certificateNumber:StatusReport :: StatusReport -> Maybe DOMString
$sel:certificationDescriptor:StatusReport :: StatusReport -> Maybe DOMString
$sel:url:StatusReport :: StatusReport -> Maybe DOMString
$sel:certificate:StatusReport :: StatusReport -> Maybe DOMString
$sel:authenticatorVersion:StatusReport :: StatusReport -> Maybe UnsignedLong
$sel:effectiveDate:StatusReport :: StatusReport -> Maybe DOMString
$sel:status:StatusReport :: StatusReport -> AuthenticatorStatus
certificationRequirementsVersion :: Maybe DOMString
certificationPolicyVersion :: Maybe DOMString
certificateNumber :: Maybe DOMString
certificationDescriptor :: Maybe DOMString
url :: Maybe DOMString
certificate :: Maybe DOMString
authenticatorVersion :: Maybe UnsignedLong
effectiveDate :: Maybe DOMString
status :: AuthenticatorStatus
..} = do
let srStatus :: AuthenticatorStatus
srStatus = AuthenticatorStatus
status
Maybe Date
srEffectiveDate <- (DOMString -> Either DOMString Date)
-> Maybe DOMString -> Either DOMString (Maybe Date)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse DOMString -> Either DOMString Date
decodeDate Maybe DOMString
effectiveDate
let srAuthenticatorVersion :: Maybe UnsignedLong
srAuthenticatorVersion = Maybe UnsignedLong
authenticatorVersion
Maybe SignedCertificate
srCertificate <- (DOMString -> Either DOMString SignedCertificate)
-> Maybe DOMString -> Either DOMString (Maybe SignedCertificate)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse DOMString -> Either DOMString SignedCertificate
decodeCertificate Maybe DOMString
certificate
let srUrl :: Maybe DOMString
srUrl = Maybe DOMString
url
srCertificationDescriptor :: Maybe DOMString
srCertificationDescriptor = Maybe DOMString
certificationDescriptor
srCertificateNumber :: Maybe DOMString
srCertificateNumber = Maybe DOMString
certificateNumber
srCertificationPolicyVersion :: Maybe DOMString
srCertificationPolicyVersion = Maybe DOMString
certificationPolicyVersion
srCertificationRequirementsVersion :: Maybe DOMString
srCertificationRequirementsVersion = Maybe DOMString
certificationRequirementsVersion
StatusReport -> Either DOMString StatusReport
forall (f :: * -> *) a. Applicative f => a -> f a
pure StatusReport :: AuthenticatorStatus
-> Maybe Date
-> Maybe UnsignedLong
-> Maybe SignedCertificate
-> Maybe DOMString
-> Maybe DOMString
-> Maybe DOMString
-> Maybe DOMString
-> Maybe DOMString
-> StatusReport
ServiceTypes.StatusReport {Maybe UnsignedLong
Maybe DOMString
Maybe Date
Maybe SignedCertificate
AuthenticatorStatus
srCertificationRequirementsVersion :: Maybe DOMString
srCertificationPolicyVersion :: Maybe DOMString
srCertificateNumber :: Maybe DOMString
srCertificationDescriptor :: Maybe DOMString
srUrl :: Maybe DOMString
srCertificate :: Maybe SignedCertificate
srAuthenticatorVersion :: Maybe UnsignedLong
srEffectiveDate :: Maybe Date
srStatus :: AuthenticatorStatus
srCertificationRequirementsVersion :: Maybe DOMString
srCertificationPolicyVersion :: Maybe DOMString
srCertificateNumber :: Maybe DOMString
srCertificationDescriptor :: Maybe DOMString
srUrl :: Maybe DOMString
srCertificate :: Maybe SignedCertificate
srAuthenticatorVersion :: Maybe UnsignedLong
srEffectiveDate :: Maybe Date
srStatus :: AuthenticatorStatus
..}
decodeDate :: IDL.DOMString -> Either Text Date
decodeDate :: DOMString -> Either DOMString Date
decodeDate DOMString
text = case ISO8601_Date -> String -> Maybe DateTime
forall format.
TimeFormat format =>
format -> String -> Maybe DateTime
timeParse ISO8601_Date
ISO8601_Date (DOMString -> String
Text.unpack DOMString
text) of
Maybe DateTime
Nothing -> DOMString -> Either DOMString Date
forall a b. a -> Either a b
Left (DOMString -> Either DOMString Date)
-> DOMString -> Either DOMString Date
forall a b. (a -> b) -> a -> b
$ DOMString
"Could not parse ISO 8601 date: " DOMString -> DOMString -> DOMString
forall a. Semigroup a => a -> a -> a
<> DOMString
text
Just DateTime
dt -> Date -> Either DOMString Date
forall a b. b -> Either a b
Right (Date -> Either DOMString Date) -> Date -> Either DOMString Date
forall a b. (a -> b) -> a -> b
$ DateTime -> Date
dtDate DateTime
dt