An Elixir toolkit for the AT Protocol. hexdocs.pm/atex
elixir bluesky atproto decentralization
25
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 126 lines 3.1 kB view raw
1defmodule ExampleOAuthPlug do 2 require Logger 3 use Plug.Router 4 use Plug.ErrorHandler 5 alias Atex.OAuth 6 alias Atex.XRPC 7 8 plug :put_secret_key_base 9 10 plug Plug.Session, 11 store: :cookie, 12 key: "atex-oauth", 13 signing_salt: "signing-salt" 14 15 plug :match 16 plug :dispatch 17 18 forward "/oauth", 19 to: Atex.OAuth.Plug, 20 init_opts: [ 21 callback: {__MODULE__, :oauth_callback, []}, 22 logout_callback: {__MODULE__, :logout_callback, []} 23 ] 24 25 def oauth_callback(conn) do 26 IO.inspect(conn, label: "callback from oauth!") 27 28 conn 29 |> put_resp_header("Location", "/whoami") 30 |> resp(307, "") 31 |> send_resp() 32 end 33 34 def logout_callback(conn) do 35 conn 36 |> put_resp_header("Location", "/") 37 |> resp(302, "") 38 |> send_resp() 39 end 40 41 get "/whoami" do 42 conn = fetch_session(conn) 43 44 case XRPC.OAuthClient.from_conn(conn) do 45 {:ok, client} -> 46 did = XRPC.OAuthClient.did(client) 47 send_resp(conn, 200, "hello #{did}") 48 49 :error -> 50 send_resp(conn, 401, "Unauthorized") 51 end 52 end 53 54 get "/create-post" do 55 conn = fetch_session(conn) 56 57 with {:ok, client} <- XRPC.OAuthClient.from_conn(conn), 58 {:ok, response, client} <- 59 XRPC.post(client, "com.atproto.repo.createRecord", 60 json: %{ 61 repo: client.did, 62 collection: "app.bsky.feed.post", 63 rkey: Atex.TID.now() |> to_string(), 64 record: %{ 65 "$type": "app.bsky.feed.post", 66 text: "Hello world from atex!", 67 createdAt: DateTime.to_iso8601(DateTime.utc_now()) 68 } 69 } 70 ) do 71 IO.inspect(response, label: "output") 72 73 send_resp(conn, 200, response.body.uri) 74 else 75 :error -> 76 send_resp(conn, 401, "Unauthorized") 77 78 {:error, :reauth} -> 79 send_resp(conn, 401, "session expired but still in your cookie") 80 81 err -> 82 IO.inspect(err, label: "xrpc failed") 83 send_resp(conn, 500, "xrpc failed") 84 end 85 end 86 87 match _ do 88 send_resp(conn, 404, "oops") 89 end 90 91 def put_secret_key_base(conn, _) do 92 put_in( 93 conn.secret_key_base, 94 # Don't use this in production 95 "5ef1078e1617463a3eb3feb9b152e76587a75a6809e0485a125b6bb7ae468f086680771f700d77ff61dfdc8d8ee8a5c7848024a41cf5ad4b6eb3115f74ce6e46" 96 ) 97 end 98 99 # Error handler for OAuth exceptions 100 @impl Plug.ErrorHandler 101 def handle_errors(conn, %{kind: :error, reason: %Atex.OAuth.Error{} = error, stack: _stack}) do 102 status = 103 case error.reason do 104 reason 105 when reason in [ 106 :missing_handle, 107 :invalid_handle, 108 :invalid_callback_request, 109 :issuer_mismatch 110 ] -> 111 400 112 113 _ -> 114 500 115 end 116 117 conn 118 |> put_resp_content_type("text/plain") 119 |> send_resp(status, error.message) 120 end 121 122 # Fallback for other errors 123 def handle_errors(conn, %{kind: _kind, reason: _reason, stack: _stack}) do 124 send_resp(conn, conn.status, "Something went wrong") 125 end 126end