1package pds
2
3import (
4 "context"
5 "crypto/rand"
6 "encoding/base64"
7 "fmt"
8 "time"
9
10 "github.com/bluesky-social/indigo/xrpc"
11 "github.com/lestrrat-go/jwx/v2/jwa"
12 "github.com/lestrrat-go/jwx/v2/jwt"
13)
14
15func makeToken(subject string, scope string, exp time.Time) jwt.Token {
16 tok := jwt.New()
17 tok.Set("scope", scope)
18 tok.Set("sub", subject)
19 tok.Set("iat", time.Now().Unix())
20 tok.Set("exp", exp.Unix())
21
22 return tok
23}
24
25func (s *Server) createAuthTokenForUser(ctx context.Context, handle, did string) (*xrpc.AuthInfo, error) {
26 accessTok := makeToken(did, "com.atproto.access", time.Now().Add(24*time.Hour))
27 refreshTok := makeToken(did, "com.atproto.refresh", time.Now().Add(7*24*time.Hour))
28
29 rval := make([]byte, 10)
30 rand.Read(rval)
31 refreshTok.Set("jti", base64.StdEncoding.EncodeToString(rval))
32
33 accSig, err := jwt.Sign(accessTok, jwt.WithKey(jwa.HS256, s.jwtSigningKey))
34 if err != nil {
35 return nil, fmt.Errorf("signing access token: %w", err)
36 }
37
38 refSig, err := jwt.Sign(refreshTok, jwt.WithKey(jwa.HS256, s.jwtSigningKey))
39 if err != nil {
40 return nil, fmt.Errorf("signing refresh token: %w", err)
41 }
42
43 return &xrpc.AuthInfo{
44 AccessJwt: string(accSig),
45 RefreshJwt: string(refSig),
46 Handle: handle,
47 Did: did,
48 }, nil
49}