module Fedi.Actor where import Data.Aeson qualified as A import Fedi.Types data Actor = Actor { actorId :: Url , actorName :: String , actorPreferredUsername :: String , actorSummary :: String , actorIcon :: Url , actorPublicKey :: PublicKey } deriving Show type ActorId = Url data ActorType = Person deriving Show data PublicKey = PublicKey { pkId :: Url , pkOwner :: Url , pkPublicKeyPem :: Pem } deriving Show makeActor :: UserDetails -> Actor makeActor details = let url = "https://" <> details.domain actorUrl = url <> "/" <> details.username in Actor { actorId = actorUrl , actorName = details.name , actorPreferredUsername = details.username , actorSummary = details.summary , actorIcon = details.icon , actorPublicKey = PublicKey { pkId = actorUrl <> "#main-key" , pkOwner = actorUrl , pkPublicKeyPem = details.pem } } instance A.ToJSON Actor where toJSON actor = A.object [ "@context" A..= [ "https://www.w3.org/ns/activitystreams" :: String , "https://w3id.org/security/v1" ] , "id" A..= actor.actorId , "type" A..= Person , "name" A..= actor.actorName , "preferredUsername" A..= actor.actorPreferredUsername , "summary" A..= actor.actorSummary , "icon" A..= A.object [ "type" A..= ("Image" :: String) , "mediaType" A..= ("image/png" :: String) , "url" A..= actor.actorIcon ] , "inbox" A..= (actor.actorId <> "/inbox") , "outbox" A..= (actor.actorId <> "/outbox") , "publicKey" A..= actor.actorPublicKey ] instance A.ToJSON ActorType where toJSON Person = A.String "Person" instance A.ToJSON PublicKey where toJSON pk = A.object [ "id" A..= pk.pkId , "owner" A..= pk.pkOwner , "publicKeyPem" A..= pk.pkPublicKeyPem ]