Something went wrong. Try again.
📰 A single-page application to manage standard.site publication on the AT Protocol cuducos.tngl.io/std-pub
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161module Dpop exposing ( PendingAction(..) , SignParams , actionFromId , actionId , dpopDecoder , sessionEncoder , sha256Decoder , signFor , xrpcSignInput )
import Json.Decode as Decodeimport Json.Encode as Encodeimport Portsimport Types exposing (Session)
type PendingAction = ActionPAR | ActionToken | ActionRefresh | ActionListPublications | ActionListDocuments | ActionCreatePublication | ActionPutPublication String | ActionUploadIcon
type alias SignParams = { htm : String , htu : String , nonce : Maybe String , accessToken : Maybe String }
actionId : PendingAction -> StringactionId action = case action of ActionPAR -> "par"
ActionToken -> "token"
ActionRefresh -> "refresh"
ActionListPublications -> "listPubs"
ActionListDocuments -> "listDocs"
ActionCreatePublication -> "createPub"
ActionPutPublication rkey -> "putPub:" ++ rkey
ActionUploadIcon -> "uploadIcon"
actionFromId : String -> Maybe PendingActionactionFromId id = if id == "par" then Just ActionPAR
else if id == "token" then Just ActionToken
else if id == "refresh" then Just ActionRefresh
else if id == "listPubs" then Just ActionListPublications
else if id == "listDocs" then Just ActionListDocuments
else if id == "createPub" then Just ActionCreatePublication
else if id == "uploadIcon" then Just ActionUploadIcon
else if String.startsWith "putPub:" id then Just (ActionPutPublication (String.dropLeft 7 id))
else Nothing
signFor : PendingAction -> SignParams -> Cmd msgsignFor action params = let fields : List ( String, Encode.Value ) fields = [ ( "id", Encode.string (actionId action) ) , ( "htm", Encode.string params.htm ) , ( "htu", Encode.string params.htu ) ] ++ (params.nonce |> Maybe.map (\n -> [ ( "nonce", Encode.string n ) ]) |> Maybe.withDefault []) ++ (params.accessToken |> Maybe.map (\t -> [ ( "accessToken", Encode.string t ) ]) |> Maybe.withDefault []) in Ports.signDpop (Encode.object fields)
xrpcSignInput : Session -> String -> SignParamsxrpcSignInput session method = { htm = if method == "listRecords" then "GET"
else "POST" , htu = session.pdsEndpoint ++ "/xrpc/com.atproto.repo." ++ method , nonce = Nothing , accessToken = Just session.accessToken }
dpopDecoder : Decode.Decoder (Result String { id : String, jwt : String })dpopDecoder = Decode.field "id" Decode.string |> Decode.andThen (\id -> Decode.field "error" (Decode.nullable Decode.string) |> Decode.andThen (\maybeErr -> case maybeErr of Just e -> Decode.succeed (Err e)
Nothing -> Decode.field "jwt" Decode.string |> Decode.map (\jwt -> Ok { id = id, jwt = jwt }) ) )
sha256Decoder : Decode.Decoder { id : String, v : String }sha256Decoder = Decode.map2 (\id v -> { id = id, v = v }) (Decode.field "id" Decode.string) (Decode.field "value" Decode.string)
sessionEncoder : Session -> Encode.ValuesessionEncoder s = Encode.object [ ( "did", Encode.string s.did ) , ( "handle", Encode.string s.handle ) , ( "pdsEndpoint", Encode.string s.pdsEndpoint ) , ( "tokenEndpoint", Encode.string s.tokenEndpoint ) , ( "accessToken", Encode.string s.accessToken ) , ( "refreshToken", s.refreshToken |> Maybe.map Encode.string |> Maybe.withDefault Encode.null ) ]