An atproto PDS written in Go
at main 2.3 kB view raw
1package server 2 3import ( 4 "time" 5 6 "github.com/haileyok/cocoon/oauth" 7 "github.com/haileyok/cocoon/oauth/constants" 8 "github.com/haileyok/cocoon/oauth/provider" 9 "github.com/hako/durafmt" 10 "github.com/labstack/echo/v4" 11) 12 13func (s *Server) handleAccount(e echo.Context) error { 14 ctx := e.Request().Context() 15 repo, sess, err := s.getSessionRepoOrErr(e) 16 if err != nil { 17 return e.Redirect(303, "/account/signin") 18 } 19 20 oldestPossibleSession := time.Now().Add(constants.ConfidentialClientSessionLifetime) 21 22 var tokens []provider.OauthToken 23 if err := s.db.Raw("SELECT * FROM oauth_tokens WHERE sub = ? AND created_at < ? ORDER BY created_at ASC", nil, repo.Repo.Did, oldestPossibleSession).Scan(&tokens).Error; err != nil { 24 s.logger.Error("couldnt fetch oauth sessions for account", "did", repo.Repo.Did, "error", err) 25 sess.AddFlash("Unable to fetch sessions. See server logs for more details.", "error") 26 sess.Save(e.Request(), e.Response()) 27 return e.Render(200, "account.html", map[string]any{ 28 "flashes": getFlashesFromSession(e, sess), 29 }) 30 } 31 32 var filtered []provider.OauthToken 33 for _, t := range tokens { 34 ageRes := oauth.GetSessionAgeFromToken(t) 35 if ageRes.SessionExpired { 36 continue 37 } 38 filtered = append(filtered, t) 39 } 40 41 now := time.Now() 42 43 tokenInfo := []map[string]string{} 44 for _, t := range tokens { 45 ageRes := oauth.GetSessionAgeFromToken(t) 46 maxTime := constants.PublicClientSessionLifetime 47 if t.ClientAuth.Method != "none" { 48 maxTime = constants.ConfidentialClientSessionLifetime 49 } 50 51 var clientName string 52 metadata, err := s.oauthProvider.ClientManager.GetClient(ctx, t.ClientId) 53 if err != nil { 54 clientName = t.ClientId 55 } else { 56 clientName = metadata.Metadata.ClientName 57 } 58 59 tokenInfo = append(tokenInfo, map[string]string{ 60 "ClientName": clientName, 61 "Age": durafmt.Parse(ageRes.SessionAge).LimitFirstN(2).String(), 62 "LastUpdated": durafmt.Parse(now.Sub(t.UpdatedAt)).LimitFirstN(2).String(), 63 "ExpiresIn": durafmt.Parse(now.Add(maxTime).Sub(now)).LimitFirstN(2).String(), 64 "Token": t.Token, 65 "Ip": t.Ip, 66 }) 67 } 68 69 return e.Render(200, "account.html", map[string]any{ 70 "Repo": repo, 71 "Tokens": tokenInfo, 72 "flashes": getFlashesFromSession(e, sess), 73 }) 74}