this repo has no description
2
fork

Configure Feed

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

feat(cmd/well-known): initial implementation

Dario Castañé 4abe71d8

+110
+107
cmd/well-known/main.go
··· 1 + package main 2 + 3 + import ( 4 + "encoding/json" 5 + "errors" 6 + "log" 7 + "log/slog" 8 + "net/http" 9 + "net/url" 10 + "os" 11 + "path/filepath" 12 + "strings" 13 + ) 14 + 15 + func wellKnownHandler(log *slog.Logger) http.HandlerFunc { 16 + root := os.Getenv("BSKYCAT_WELLKNOWN_ROOT") 17 + return func(w http.ResponseWriter, r *http.Request) { 18 + if r.Method != http.MethodGet { 19 + w.WriteHeader(http.StatusMethodNotAllowed) 20 + return 21 + } 22 + host := r.Host 23 + if !strings.HasSuffix(host, ".bsky.cat") { 24 + log.Error("invalid host", slog.String("host", host)) 25 + w.WriteHeader(http.StatusNotFound) 26 + return 27 + } 28 + hostData := strings.Split(host, ".") 29 + if len(hostData) != 3 { 30 + log.Error("invalid host", slog.String("host", host)) 31 + w.WriteHeader(http.StatusNotFound) 32 + return 33 + } 34 + did := filepath.Join(root, hostData[0]) 35 + data, err := os.Open(did) 36 + if err != nil { 37 + log.Error("failed to open file", slog.String("file", did), slog.String("error", err.Error())) 38 + w.WriteHeader(http.StatusNotFound) 39 + return 40 + } 41 + defer data.Close() 42 + _, _ = data.WriteTo(w) 43 + log.Info("well-known request", slog.String("host", host)) 44 + } 45 + } 46 + 47 + func addAccount(old, new string) error { 48 + validationURL, err := url.Parse("https://public.api.bsky.app/xrpc/com.atproto.identity.resolveHandle?handle=") 49 + if err != nil { 50 + return err 51 + } 52 + q := validationURL.Query() 53 + q.Set("handle", old) 54 + validationURL.RawQuery = q.Encode() 55 + r, err := http.Get(validationURL.String()) 56 + if err != nil { 57 + return err 58 + } 59 + if r.StatusCode != http.StatusOK { 60 + return errors.New("failed to validate old account, status code: " + r.Status) 61 + } 62 + var oldDid struct { 63 + Did string `json:"did"` 64 + } 65 + if err := json.NewDecoder(r.Body).Decode(&oldDid); err != nil { 66 + return err 67 + } 68 + root := os.Getenv("BSKYCAT_WELLKNOWN_ROOT") 69 + if root == "" { 70 + return errors.New("BSKYCAT_WELLKNOWN_ROOT is not set") 71 + } 72 + newPath := filepath.Join(root, new) 73 + f, err := os.OpenFile(newPath, os.O_CREATE|os.O_WRONLY, 0644) 74 + if err != nil { 75 + return err 76 + } 77 + defer f.Close() 78 + _, err = f.WriteString(oldDid.Did) 79 + if err != nil { 80 + return err 81 + } 82 + return nil 83 + } 84 + 85 + func main() { 86 + args := os.Args 87 + if len(args) < 2 { 88 + log.Fatalf("usage: %s <command>", args[0]) 89 + } 90 + switch args[1] { 91 + case "server": 92 + logger := slog.New(slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{ 93 + Level: slog.LevelInfo, 94 + })) 95 + http.Handle("/.well-known/atproto-did", wellKnownHandler(logger)) 96 + http.ListenAndServe("127.0.0.1:3001", nil) 97 + case "add-account": 98 + if len(args) != 4 { 99 + log.Fatalf("usage: %s add-account <old> <new>", args[0]) 100 + } 101 + old := args[2] 102 + new := args[3] 103 + if err := addAccount(old, new); err != nil { 104 + log.Fatalf("failed to add account: %s", err) 105 + } 106 + } 107 + }
+3
go.mod
··· 1 + module bsky.cat 2 + 3 + go 1.25.0
go.sum

This is a binary file and will not be displayed.