Something went wrong. Try again.
Monorepo for Tangled
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155package oauth
import ( "encoding/json" "errors" "net/http" "time")
const MaxAccounts = 20
var ErrMaxAccountsReached = errors.New("maximum number of linked accounts reached")
type AccountInfo struct { Did string `json:"did"` SessionId string `json:"session_id"` AddedAt int64 `json:"added_at"`}
type AccountRegistry struct { Accounts []AccountInfo `json:"accounts"`}
type MultiAccountUser struct { Did string Accounts []AccountInfo}
func (o *OAuth) GetAccounts(r *http.Request) *AccountRegistry { session, err := o.SessStore.Get(r, AccountsName) if err != nil || session.IsNew { return &AccountRegistry{Accounts: []AccountInfo{}} }
data, ok := session.Values["accounts"].(string) if !ok { return &AccountRegistry{Accounts: []AccountInfo{}} }
var registry AccountRegistry if err := json.Unmarshal([]byte(data), ®istry); err != nil { return &AccountRegistry{Accounts: []AccountInfo{}} }
return ®istry}
func (o *OAuth) saveAccounts(w http.ResponseWriter, r *http.Request, registry *AccountRegistry) error { session, err := o.SessStore.Get(r, AccountsName) if err != nil { o.Logger.Warn("failed to decode existing accounts cookie, will create new", "err", err) }
data, err := json.Marshal(registry) if err != nil { return err }
session.Values["accounts"] = string(data) session.Options.MaxAge = 60 * 60 * 24 * 365 session.Options.HttpOnly = true session.Options.Secure = !o.Config.Core.Dev session.Options.SameSite = http.SameSiteLaxMode
return session.Save(r, w)}
func (r *AccountRegistry) AddAccount(did, handle, sessionId string) error { for i, acc := range r.Accounts { if acc.Did == did { r.Accounts[i].SessionId = sessionId return nil } }
if len(r.Accounts) >= MaxAccounts { return ErrMaxAccountsReached }
r.Accounts = append(r.Accounts, AccountInfo{ Did: did, SessionId: sessionId, AddedAt: time.Now().Unix(), }) return nil}
func (r *AccountRegistry) RemoveAccount(did string) { filtered := make([]AccountInfo, 0, len(r.Accounts)) for _, acc := range r.Accounts { if acc.Did != did { filtered = append(filtered, acc) } } r.Accounts = filtered}
func (r *AccountRegistry) FindAccount(did string) *AccountInfo { for i := range r.Accounts { if r.Accounts[i].Did == did { return &r.Accounts[i] } } return nil}
func (o *OAuth) GetMultiAccountUser(r *http.Request) *MultiAccountUser { sess, err := o.ResumeSession(r) if err != nil { return nil }
registry := o.GetAccounts(r) return &MultiAccountUser{ Did: sess.Data.AccountDID.String(), Accounts: registry.Accounts, }}
func (o *OAuth) SetAuthReturn(w http.ResponseWriter, r *http.Request, returnURL string) error { session, err := o.SessStore.Get(r, AuthReturnName) if err != nil { return err }
session.Values[AuthReturnURL] = returnURL session.Options.MaxAge = 60 * 30 session.Options.HttpOnly = true session.Options.Secure = !o.Config.Core.Dev session.Options.SameSite = http.SameSiteLaxMode
return session.Save(r, w)}
func (o *OAuth) GetAuthReturn(r *http.Request) string { session, err := o.SessStore.Get(r, AuthReturnName) if err != nil || session.IsNew { return "" }
returnURL, _ := session.Values[AuthReturnURL].(string)
return returnURL}
func (o *OAuth) ClearAuthReturn(w http.ResponseWriter, r *http.Request) error { session, err := o.SessStore.Get(r, AuthReturnName) if err != nil { return err }
session.Options.MaxAge = -1 return session.Save(r, w)}