this repo has no description
1package auth 2 3import ( 4 "context" 5 "fmt" 6 "net/http" 7 "time" 8 9 comatproto "github.com/bluesky-social/indigo/api/atproto" 10 "github.com/bluesky-social/indigo/atproto/identity" 11 "github.com/bluesky-social/indigo/atproto/syntax" 12 "github.com/bluesky-social/indigo/xrpc" 13 "github.com/gorilla/sessions" 14 "github.com/whyrusleeping/go-did" 15) 16 17type Auth struct { 18 store sessions.Store 19} 20 21type AtSessionCreate struct { 22 comatproto.ServerCreateSession_Output 23 PDSEndpoint string 24} 25 26type AtSessionRefresh struct { 27 comatproto.ServerRefreshSession_Output 28 PDSEndpoint string 29} 30 31func Make() (*Auth, error) { 32 store := sessions.NewCookieStore([]byte("TODO_CHANGE_ME")) 33 return &Auth{store}, nil 34} 35 36func ResolveIdent(ctx context.Context, arg string) (*identity.Identity, error) { 37 id, err := syntax.ParseAtIdentifier(arg) 38 if err != nil { 39 return nil, err 40 } 41 42 dir := identity.DefaultDirectory() 43 return dir.Lookup(ctx, *id) 44} 45 46func (a *Auth) CreateInitialSession(ctx context.Context, username, appPassword string) (*comatproto.ServerCreateSession_Output, error) { 47 resolved, err := ResolveIdent(ctx, username) 48 if err != nil { 49 return nil, fmt.Errorf("invalid handle: %s", err) 50 } 51 52 pdsUrl := resolved.PDSEndpoint() 53 client := xrpc.Client{ 54 Host: pdsUrl, 55 } 56 57 atSession, err := comatproto.ServerCreateSession(ctx, &client, &comatproto.ServerCreateSession_Input{ 58 Identifier: resolved.DID.String(), 59 Password: appPassword, 60 }) 61 if err != nil { 62 return nil, fmt.Errorf("invalid app password") 63 } 64 65 return atSession, nil 66} 67 68func (a *Auth) StoreSession(r *http.Request, w http.ResponseWriter, atSession *comatproto.ServerCreateSession_Output) error { 69 didDoc, ok := (*atSession.DidDoc).(did.Document) 70 if !ok { 71 return fmt.Errorf("invalid did document for session") 72 } 73 74 pdsEndpoint := getPdsEndpoint(&didDoc) 75 76 if pdsEndpoint == "" { 77 return fmt.Errorf("no pds endpoint found") 78 } 79 80 clientSession, _ := a.store.Get(r, "appview-session") 81 clientSession.Values["handle"] = atSession.Handle 82 clientSession.Values["did"] = atSession.Did 83 clientSession.Values["pds"] = pdsEndpoint 84 clientSession.Values["accessJwt"] = atSession.AccessJwt 85 clientSession.Values["refreshJwt"] = atSession.RefreshJwt 86 clientSession.Values["expiry"] = time.Now().Add(time.Hour).String() 87 clientSession.Values["authenticated"] = true 88 89 return clientSession.Save(r, w) 90} 91 92func getPdsEndpoint(didDoc *did.Document) string { 93 fullId := didDoc.ID.String() 94 id := "#atproto_pds" 95 type_ := "AtprotoPersonalDataServer" 96 97 for _, service := range didDoc.Service { 98 serviceId := service.ID.String() 99 if serviceId == id || serviceId == fullId+id || service.Type == type_ { 100 return service.ServiceEndpoint 101 } 102 } 103 104 return "" 105}