Vibe-guided bskyoauth and custom repo example code in Golang 馃 probably not safe to use in prod
1package bskyoauth
2
3import (
4 "crypto/ecdsa"
5 "net/http"
6 "time"
7)
8
9// Client is the main entry point for the Bluesky OAuth library.
10// It manages OAuth flows, session storage, and API interactions.
11type Client struct {
12 // BaseURL is the base URL of the OAuth client (e.g., "http://localhost:8181")
13 BaseURL string
14
15 // ClientID is the OAuth client identifier (typically BaseURL + "/oauth-client-metadata.json")
16 ClientID string
17
18 // RedirectURI is where the OAuth provider redirects after authorization
19 RedirectURI string
20
21 // ClientName is the display name for the OAuth client
22 ClientName string
23
24 // ApplicationType is the type of OAuth client ("web" or "native")
25 ApplicationType string
26
27 // Scopes are the OAuth scopes to request (defaults to "atproto transition:generic")
28 Scopes []string
29
30 // SessionStore is the storage backend for sessions
31 SessionStore SessionStore
32}
33
34// ClientOptions contains configuration options for creating a new Client.
35type ClientOptions struct {
36 // BaseURL is the base URL of the OAuth client (required)
37 BaseURL string
38
39 // ClientName is the display name for the OAuth client (optional, defaults to "Bluesky OAuth Client")
40 ClientName string
41
42 // ApplicationType is the type of OAuth client (optional, defaults to "web")
43 // Valid values: ApplicationTypeWeb ("web") or ApplicationTypeNative ("native")
44 ApplicationType string
45
46 // Scopes are the OAuth scopes to request (optional, defaults to ["atproto", "transition:generic"])
47 Scopes []string
48
49 // SessionStore is the storage backend for sessions (optional, defaults to in-memory store)
50 SessionStore SessionStore
51
52 // HTTPClient is a custom HTTP client to use for all requests (optional, defaults to client with 30s timeout)
53 // Use this to customize timeouts, transport settings, or proxy configuration
54 HTTPClient *http.Client
55}
56
57// Session represents an authenticated user session with Bluesky.
58type Session struct {
59 // DID is the decentralized identifier for the user
60 DID string
61
62 // AccessToken is the OAuth access token
63 AccessToken string
64
65 // RefreshToken is used to obtain new access tokens
66 RefreshToken string
67
68 // DPoPKey is the private key used for DPoP proof generation
69 DPoPKey *ecdsa.PrivateKey
70
71 // PDS is the Personal Data Server endpoint for this user
72 PDS string
73
74 // DPoPNonce is the server-provided nonce for DPoP proofs
75 DPoPNonce string
76
77 // AccessTokenExpiresAt is when the access token expires
78 AccessTokenExpiresAt time.Time
79
80 // RefreshTokenExpiresAt is when the refresh token expires (optional, may be zero)
81 RefreshTokenExpiresAt time.Time
82}
83
84// AuthFlowState contains the state information for an OAuth flow.
85type AuthFlowState struct {
86 // State is the OAuth state parameter for CSRF protection
87 State string
88
89 // CodeVerifier is the PKCE code verifier
90 CodeVerifier string
91
92 // DPoPKey is the private key for this authentication flow
93 DPoPKey *ecdsa.PrivateKey
94
95 // AuthURL is the authorization URL to redirect the user to
96 AuthURL string
97
98 // DID is the user's decentralized identifier
99 DID string
100}
101
102// SessionStore is an interface for storing and retrieving sessions.
103// Implement this interface to provide custom session storage (e.g., Redis, database).
104type SessionStore interface {
105 // Get retrieves a session by ID
106 Get(sessionID string) (*Session, error)
107
108 // Set stores a session with the given ID
109 Set(sessionID string, session *Session) error
110
111 // Delete removes a session by ID
112 Delete(sessionID string) error
113}
114
115// AuthServerMetadata contains OAuth authorization server metadata.
116type AuthServerMetadata struct {
117 AuthorizationEndpoint string `json:"authorization_endpoint"`
118 TokenEndpoint string `json:"token_endpoint"`
119 Issuer string `json:"issuer"`
120 JWKSURI string `json:"jwks_uri"`
121}
122
123// ListRecordsOptions contains optional parameters for listing records.
124type ListRecordsOptions struct {
125 // Repo is the DID of the repository to list from (defaults to session's DID if empty)
126 Repo string
127
128 // Limit is the maximum number of records to return (default 50, max 100)
129 Limit int
130
131 // Cursor is the pagination cursor for fetching the next page
132 Cursor string
133
134 // Reverse returns results in reverse chronological order when true
135 Reverse bool
136}
137
138// ListRecordsResult contains the result of listing records.
139type ListRecordsResult struct {
140 // Records contains the list of records
141 Records []RecordEntry
142
143 // Cursor is the pagination cursor for the next page, empty if no more results
144 Cursor string
145}
146
147// RecordEntry represents a single record in a list response.
148type RecordEntry struct {
149 // URI is the AT URI of the record (at://did/collection/rkey)
150 URI string
151
152 // CID is the content identifier of the record
153 CID string
154
155 // Value is the record data
156 Value interface{}
157}