An atproto PDS written in Go

fix listing of active oauth sessions

Changed files
+48 -12
oauth
server
+32
oauth/helpers.go
···
"errors"
"fmt"
"net/url"
+
"time"
"github.com/haileyok/cocoon/internal/helpers"
"github.com/haileyok/cocoon/oauth/constants"
+
"github.com/haileyok/cocoon/oauth/provider"
)
func GenerateCode() string {
···
return reqId, nil
}
+
+
type SessionAgeResult struct {
+
SessionAge time.Duration
+
RefreshAge time.Duration
+
SessionExpired bool
+
RefreshExpired bool
+
}
+
+
func GetSessionAgeFromToken(t provider.OauthToken) SessionAgeResult {
+
sessionLifetime := constants.PublicClientSessionLifetime
+
refreshLifetime := constants.PublicClientRefreshLifetime
+
if t.ClientAuth.Method != "none" {
+
sessionLifetime = constants.ConfidentialClientSessionLifetime
+
refreshLifetime = constants.ConfidentialClientRefreshLifetime
+
}
+
+
res := SessionAgeResult{}
+
+
res.SessionAge = time.Since(t.CreatedAt)
+
if res.SessionAge > sessionLifetime {
+
res.SessionExpired = true
+
}
+
+
refreshAge := time.Since(t.UpdatedAt)
+
if refreshAge > refreshLifetime {
+
res.RefreshExpired = true
+
}
+
+
return res
+
}
+13 -2
server/handle_account.go
···
import (
"time"
+
"github.com/haileyok/cocoon/oauth"
+
"github.com/haileyok/cocoon/oauth/constants"
"github.com/haileyok/cocoon/oauth/provider"
"github.com/labstack/echo/v4"
)
···
return e.Redirect(303, "/account/signin")
}
-
now := time.Now()
+
oldestPossibleSession := time.Now().Add(constants.ConfidentialClientSessionLifetime)
var tokens []provider.OauthToken
-
if err := s.db.Raw("SELECT * FROM oauth_tokens WHERE sub = ? AND expires_at >= ? ORDER BY created_at ASC", nil, repo.Repo.Did, now).Scan(&tokens).Error; err != nil {
+
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 {
s.logger.Error("couldnt fetch oauth sessions for account", "did", repo.Repo.Did, "error", err)
sess.AddFlash("Unable to fetch sessions. See server logs for more details.", "error")
sess.Save(e.Request(), e.Response())
return e.Render(200, "account.html", map[string]any{
"flashes": getFlashesFromSession(e, sess),
})
+
}
+
+
var filtered []provider.OauthToken
+
for _, t := range tokens {
+
ageRes := oauth.GetSessionAgeFromToken(t)
+
if ageRes.SessionExpired {
+
continue
+
}
+
filtered = append(filtered, t)
}
tokenInfo := []map[string]string{}
+3 -10
server/handle_oauth_token.go
···
return helpers.InputError(e, to.StringPtr("dpop proof does not match expected jkt"))
}
-
sessionLifetime := constants.PublicClientSessionLifetime
-
refreshLifetime := constants.PublicClientRefreshLifetime
-
if clientAuth.Method != "none" {
-
sessionLifetime = constants.ConfidentialClientSessionLifetime
-
refreshLifetime = constants.ConfidentialClientRefreshLifetime
-
}
+
ageRes := oauth.GetSessionAgeFromToken(oauthToken)
-
sessionAge := time.Since(oauthToken.CreatedAt)
-
if sessionAge > sessionLifetime {
+
if ageRes.SessionExpired {
return helpers.InputError(e, to.StringPtr("Session expired"))
}
-
refreshAge := time.Since(oauthToken.UpdatedAt)
-
if refreshAge > refreshLifetime {
+
if ageRes.RefreshExpired {
return helpers.InputError(e, to.StringPtr("Refresh token expired"))
}