Something went wrong. Try again.
search and/or read your saved and liked bluesky posts
wails go svelte sqlite desktop bluesky
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164package main
import ( "context" "fmt" "net/http" "sync" "time"
"github.com/bluesky-social/indigo/atproto/auth/oauth" "github.com/bluesky-social/indigo/atproto/syntax")
const oauthCallbackPort = 8787
var oauthScopes = []string{"atproto", "transition:generic"}
func oauthCallbackURL() string { return fmt.Sprintf("http://127.0.0.1:%d/callback", oauthCallbackPort)}
func oauthConfig() oauth.ClientConfig { return oauth.NewLocalhostConfig(oauthCallbackURL(), append([]string(nil), oauthScopes...))}
func newOAuthApp(store oauth.ClientAuthStore) *oauth.ClientApp { config := oauthConfig() return oauth.NewClientApp(&config, store)}
func authFromSessionData(sess *oauth.ClientSessionData, handle string) *Auth { if handle == "" { handle = sess.AccountDID.String() }
return &Auth{ DID: sess.AccountDID.String(), Handle: handle, AccessJWT: sess.AccessToken, RefreshJWT: sess.RefreshToken, PDSURL: sess.HostURL, SessionID: sess.SessionID, AuthServerURL: sess.AuthServerURL, AuthServerTokenEndpoint: sess.AuthServerTokenEndpoint, AuthServerRevocationEndpoint: sess.AuthServerRevocationEndpoint, DPoPAuthNonce: sess.DPoPAuthServerNonce, DPoPHostNonce: sess.DPoPHostNonce, DPoPPrivateKey: sess.DPoPPrivateKeyMultibase, UpdatedAt: time.Now(), }}
func sessionDataFromAuth(auth *Auth) (*oauth.ClientSessionData, error) { did, err := syntax.ParseDID(auth.DID) if err != nil { return nil, fmt.Errorf("invalid DID in database: %w", err) }
return &oauth.ClientSessionData{ AccountDID: did, SessionID: auth.SessionID, HostURL: auth.PDSURL, AuthServerURL: auth.AuthServerURL, AuthServerTokenEndpoint: auth.AuthServerTokenEndpoint, AuthServerRevocationEndpoint: auth.AuthServerRevocationEndpoint, Scopes: append([]string(nil), oauthScopes...), AccessToken: auth.AccessJWT, RefreshToken: auth.RefreshJWT, DPoPAuthServerNonce: auth.DPoPAuthNonce, DPoPHostNonce: auth.DPoPHostNonce, DPoPPrivateKeyMultibase: auth.DPoPPrivateKey, }, nil}
type SQLiteOAuthStore struct { requests map[string]oauth.AuthRequestData mu sync.Mutex}
func NewSQLiteOAuthStore() *SQLiteOAuthStore { return &SQLiteOAuthStore{ requests: make(map[string]oauth.AuthRequestData), }}
func (s *SQLiteOAuthStore) GetSession(ctx context.Context, did syntax.DID, sessionID string) (*oauth.ClientSessionData, error) { auth, err := GetAuthByDID(did.String()) if err != nil { return nil, err } if auth == nil || auth.SessionID != sessionID { return nil, fmt.Errorf("session not found: %s", did) }
return sessionDataFromAuth(auth)}
func (s *SQLiteOAuthStore) SaveSession(ctx context.Context, sess oauth.ClientSessionData) error { auth, err := GetAuthByDID(sess.AccountDID.String()) if err != nil { return err }
handle := "" if auth != nil { handle = auth.Handle }
return UpsertAuth(authFromSessionData(&sess, handle))}
func (s *SQLiteOAuthStore) DeleteSession(ctx context.Context, did syntax.DID, sessionID string) error { _, err := db.ExecContext(ctx, "DELETE FROM auth WHERE did = ? AND session_id = ?", did.String(), sessionID) return err}
func (s *SQLiteOAuthStore) GetAuthRequestInfo(ctx context.Context, state string) (*oauth.AuthRequestData, error) { s.mu.Lock() defer s.mu.Unlock()
info, ok := s.requests[state] if !ok { return nil, fmt.Errorf("request info not found: %s", state) } return &info, nil}
func (s *SQLiteOAuthStore) SaveAuthRequestInfo(ctx context.Context, info oauth.AuthRequestData) error { s.mu.Lock() defer s.mu.Unlock()
if _, ok := s.requests[info.State]; ok { return fmt.Errorf("auth request already saved for state %s", info.State) }
s.requests[info.State] = info return nil}
func (s *SQLiteOAuthStore) DeleteAuthRequestInfo(ctx context.Context, state string) error { s.mu.Lock() defer s.mu.Unlock()
delete(s.requests, state) return nil}
func listenerAddress() string { return fmt.Sprintf("127.0.0.1:%d", oauthCallbackPort)}
func closeCallbackServer(server *http.Server, listener httpCloser) { if server != nil { _ = server.Close() } if listener != nil { _ = listener.Close() }}
type httpCloser interface { Close() error}