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