1package server
2
3import (
4 "context"
5 "time"
6
7 "github.com/golang-jwt/jwt/v4"
8 "github.com/google/uuid"
9 "github.com/haileyok/cocoon/models"
10)
11
12type Session struct {
13 AccessToken string
14 RefreshToken string
15}
16
17func (s *Server) createSession(ctx context.Context, repo *models.Repo) (*Session, error) {
18 now := time.Now()
19 accexp := now.Add(3 * time.Hour)
20 refexp := now.Add(7 * 24 * time.Hour)
21 jti := uuid.NewString()
22
23 accessClaims := jwt.MapClaims{
24 "scope": "com.atproto.access",
25 "aud": s.config.Did,
26 "sub": repo.Did,
27 "iat": now.UTC().Unix(),
28 "exp": accexp.UTC().Unix(),
29 "jti": jti,
30 }
31
32 accessToken := jwt.NewWithClaims(jwt.SigningMethodES256, accessClaims)
33 accessString, err := accessToken.SignedString(s.privateKey)
34 if err != nil {
35 return nil, err
36 }
37
38 refreshClaims := jwt.MapClaims{
39 "scope": "com.atproto.refresh",
40 "aud": s.config.Did,
41 "sub": repo.Did,
42 "iat": now.UTC().Unix(),
43 "exp": refexp.UTC().Unix(),
44 "jti": jti,
45 }
46
47 refreshToken := jwt.NewWithClaims(jwt.SigningMethodES256, refreshClaims)
48 refreshString, err := refreshToken.SignedString(s.privateKey)
49 if err != nil {
50 return nil, err
51 }
52
53 if err := s.db.Create(ctx, &models.Token{
54 Token: accessString,
55 Did: repo.Did,
56 RefreshToken: refreshString,
57 CreatedAt: now,
58 ExpiresAt: accexp,
59 }, nil).Error; err != nil {
60 return nil, err
61 }
62
63 if err := s.db.Create(ctx, &models.RefreshToken{
64 Token: refreshString,
65 Did: repo.Did,
66 CreatedAt: now,
67 ExpiresAt: refexp,
68 }, nil).Error; err != nil {
69 return nil, err
70 }
71
72 return &Session{
73 AccessToken: accessString,
74 RefreshToken: refreshString,
75 }, nil
76}