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}