A vibe coded tangled fork which supports pijul.
at 7eddbe6fa386ab08474d9319c8ad7e348b830e9c 169 lines 3.7 kB view raw
1package oauth 2 3import ( 4 "encoding/json" 5 "errors" 6 "net/http" 7 "time" 8) 9 10const MaxAccounts = 20 11 12var ErrMaxAccountsReached = errors.New("maximum number of linked accounts reached") 13 14type AccountInfo struct { 15 Did string `json:"did"` 16 Handle string `json:"handle"` 17 SessionId string `json:"session_id"` 18 AddedAt int64 `json:"added_at"` 19} 20 21type AccountRegistry struct { 22 Accounts []AccountInfo `json:"accounts"` 23} 24 25type MultiAccountUser struct { 26 Active User 27 Accounts []AccountInfo 28} 29 30func (m *MultiAccountUser) Did() string { 31 return m.Active.Did 32} 33 34func (o *OAuth) GetAccounts(r *http.Request) *AccountRegistry { 35 session, err := o.SessStore.Get(r, AccountsName) 36 if err != nil || session.IsNew { 37 return &AccountRegistry{Accounts: []AccountInfo{}} 38 } 39 40 data, ok := session.Values["accounts"].(string) 41 if !ok { 42 return &AccountRegistry{Accounts: []AccountInfo{}} 43 } 44 45 var registry AccountRegistry 46 if err := json.Unmarshal([]byte(data), &registry); err != nil { 47 return &AccountRegistry{Accounts: []AccountInfo{}} 48 } 49 50 return &registry 51} 52 53func (o *OAuth) saveAccounts(w http.ResponseWriter, r *http.Request, registry *AccountRegistry) error { 54 session, err := o.SessStore.Get(r, AccountsName) 55 if err != nil { 56 return err 57 } 58 59 data, err := json.Marshal(registry) 60 if err != nil { 61 return err 62 } 63 64 session.Values["accounts"] = string(data) 65 session.Options.MaxAge = 60 * 60 * 24 * 365 66 session.Options.HttpOnly = true 67 session.Options.Secure = !o.Config.Core.Dev 68 session.Options.SameSite = http.SameSiteLaxMode 69 70 return session.Save(r, w) 71} 72 73func (r *AccountRegistry) AddAccount(did, handle, sessionId string) error { 74 for i, acc := range r.Accounts { 75 if acc.Did == did { 76 r.Accounts[i].SessionId = sessionId 77 r.Accounts[i].Handle = handle 78 return nil 79 } 80 } 81 82 if len(r.Accounts) >= MaxAccounts { 83 return ErrMaxAccountsReached 84 } 85 86 r.Accounts = append(r.Accounts, AccountInfo{ 87 Did: did, 88 Handle: handle, 89 SessionId: sessionId, 90 AddedAt: time.Now().Unix(), 91 }) 92 return nil 93} 94 95func (r *AccountRegistry) RemoveAccount(did string) { 96 filtered := make([]AccountInfo, 0, len(r.Accounts)) 97 for _, acc := range r.Accounts { 98 if acc.Did != did { 99 filtered = append(filtered, acc) 100 } 101 } 102 r.Accounts = filtered 103} 104 105func (r *AccountRegistry) FindAccount(did string) *AccountInfo { 106 for i := range r.Accounts { 107 if r.Accounts[i].Did == did { 108 return &r.Accounts[i] 109 } 110 } 111 return nil 112} 113 114func (o *OAuth) GetMultiAccountUser(r *http.Request) *MultiAccountUser { 115 sess, err := o.ResumeSession(r) 116 if err != nil { 117 return nil 118 } 119 120 registry := o.GetAccounts(r) 121 return &MultiAccountUser{ 122 Active: User{ 123 Did: sess.Data.AccountDID.String(), 124 }, 125 Accounts: registry.Accounts, 126 } 127} 128 129type AuthReturnInfo struct { 130 ReturnURL string 131} 132 133func (o *OAuth) SetAuthReturn(w http.ResponseWriter, r *http.Request, returnURL string) error { 134 session, err := o.SessStore.Get(r, AuthReturnName) 135 if err != nil { 136 return err 137 } 138 139 session.Values[AuthReturnURL] = returnURL 140 session.Options.MaxAge = 60 * 30 141 session.Options.HttpOnly = true 142 session.Options.Secure = !o.Config.Core.Dev 143 session.Options.SameSite = http.SameSiteLaxMode 144 145 return session.Save(r, w) 146} 147 148func (o *OAuth) GetAuthReturn(r *http.Request) *AuthReturnInfo { 149 session, err := o.SessStore.Get(r, AuthReturnName) 150 if err != nil || session.IsNew { 151 return &AuthReturnInfo{} 152 } 153 154 returnURL, _ := session.Values[AuthReturnURL].(string) 155 156 return &AuthReturnInfo{ 157 ReturnURL: returnURL, 158 } 159} 160 161func (o *OAuth) ClearAuthReturn(w http.ResponseWriter, r *http.Request) error { 162 session, err := o.SessStore.Get(r, AuthReturnName) 163 if err != nil { 164 return err 165 } 166 167 session.Options.MaxAge = -1 168 return session.Save(r, w) 169}