backend for xcvr appview
at main 164 lines 5.5 kB view raw
1package oauth 2 3import ( 4 "context" 5 "errors" 6 "fmt" 7 "github.com/bluesky-social/indigo/api/atproto" 8 "github.com/bluesky-social/indigo/atproto/client" 9 "github.com/bluesky-social/indigo/lex/util" 10 "os" 11 "rvcx/internal/lex" 12 "rvcx/internal/log" 13) 14 15type PasswordClient struct { 16 logger *log.Logger 17 xrpc *client.APIClient 18 accessjwt *string 19 refreshjwt *string 20 did *string 21} 22 23func NewPasswordClient(did string, host string, l *log.Logger) *PasswordClient { 24 return &PasswordClient{ 25 xrpc: client.NewAPIClient(host), 26 did: &did, 27 logger: l, 28 } 29} 30 31func (c *PasswordClient) CreateSession(ctx context.Context) error { 32 c.logger.Deprintln("creating session...") 33 secret := os.Getenv("MY_SECRET") 34 identity := os.Getenv("MY_IDENTITY") 35 input := atproto.ServerCreateSession_Input{ 36 Identifier: identity, 37 Password: secret, 38 } 39 var out atproto.ServerCreateSession_Output 40 err := c.xrpc.LexDo(ctx, "POST", "application/json", "com.atproto.server.createSession", nil, input, &out) 41 if err != nil { 42 return errors.New("I couldn't create a session: " + err.Error()) 43 } 44 c.accessjwt = &out.AccessJwt 45 c.refreshjwt = &out.RefreshJwt 46 c.logger.Deprintln("created session!") 47 return nil 48} 49 50func (c *PasswordClient) RefreshSession(ctx context.Context) error { 51 c.logger.Deprintln("refreshing session") 52 c.xrpc.Headers.Set("Authorization", fmt.Sprintf("Bearer %s", *c.refreshjwt)) 53 var out atproto.ServerRefreshSession_Output 54 err := c.xrpc.LexDo(ctx, "POST", "application/json", "com.atproto.server.refreshSession", nil, nil, &out) 55 if err != nil { 56 c.logger.Println("FAILED TO REFRESH RESSION") 57 return errors.New("failed to refresh session! " + err.Error()) 58 } 59 c.accessjwt = &out.AccessJwt 60 c.refreshjwt = &out.RefreshJwt 61 c.logger.Deprintln("refreshed session!") 62 return nil 63} 64 65func (c *PasswordClient) CreateXCVRMessage(message *lex.MessageRecord, ctx context.Context) (cid string, uri string, err error) { 66 input := atproto.RepoCreateRecord_Input{ 67 Collection: "org.xcvr.lrc.message", 68 Repo: *c.did, 69 Record: &util.LexiconTypeDecoder{Val: message}, 70 } 71 return c.createMyRecord(input, ctx) 72} 73 74func (c *PasswordClient) CreateXCVRSignet(signet *lex.SignetRecord, ctx context.Context) (cid string, uri string, err error) { 75 input := atproto.RepoCreateRecord_Input{ 76 Collection: "org.xcvr.lrc.signet", 77 Repo: *c.did, 78 Record: &util.LexiconTypeDecoder{Val: signet}, 79 } 80 return c.createMyRecord(input, ctx) 81} 82 83func (c *PasswordClient) CreateXCVRChannel(channel *lex.ChannelRecord, ctx context.Context) (cid string, uri string, err error) { 84 input := atproto.RepoCreateRecord_Input{ 85 Collection: "org.xcvr.feed.channel", 86 Repo: *c.did, 87 Record: &util.LexiconTypeDecoder{Val: channel}, 88 } 89 return c.createMyRecord(input, ctx) 90} 91 92func (c *PasswordClient) createMyRecord(input atproto.RepoCreateRecord_Input, ctx context.Context) (cid string, uri string, err error) { 93 if c.accessjwt == nil { 94 err = errors.New("must create a session first") 95 return 96 } 97 c.xrpc.Headers.Set("Authorization", fmt.Sprintf("Bearer %s", *c.accessjwt)) 98 var out atproto.RepoCreateRecord_Output 99 err = c.xrpc.LexDo(ctx, "POST", "application/json", "com.atproto.repo.createRecord", nil, input, &out) 100 if err != nil { 101 err1 := err.Error() 102 err = c.RefreshSession(ctx) 103 if err != nil { 104 err = errors.New(fmt.Sprintf("failed to refresh session while creating %s! first %s then %s", input.Collection, err1, err.Error())) 105 return 106 } 107 c.xrpc.Headers.Set("Authorization", fmt.Sprintf("Bearer %s", *c.accessjwt)) 108 out = atproto.RepoCreateRecord_Output{} 109 err = c.xrpc.LexDo(ctx, "POST", "application/json", "com.atproto.repo.createRecord", nil, input, &out) 110 if err != nil { 111 err = errors.New(fmt.Sprintf("not good, failed to create %s after failing then refreshing session! first %s then %s", input.Collection, err1, err.Error())) 112 return 113 } 114 cid = out.Cid 115 uri = out.Uri 116 return 117 } 118 cid = out.Cid 119 uri = out.Uri 120 return 121} 122 123func (c *PasswordClient) DeleteXCVRSignet(rkey string, ctx context.Context) (bool, error) { 124 getOut, err := atproto.RepoGetRecord(ctx, c.xrpc, "", "org.xcvr.lrc.signet", *c.did, rkey) 125 if err != nil { 126 return true, errors.New("nothing to delete :3") 127 } 128 input := atproto.RepoDeleteRecord_Input{ 129 Repo: *c.did, 130 Collection: "org.xcvr.lrc.signet", 131 Rkey: rkey, 132 SwapRecord: getOut.Cid, 133 } 134 err = c.deleteMyRecord(input, ctx) 135 if err != nil { 136 return false, errors.New("failed to delete") 137 } 138 return true, nil 139} 140 141func (c *PasswordClient) deleteMyRecord(input atproto.RepoDeleteRecord_Input, ctx context.Context) (err error) { 142 if c.accessjwt == nil { 143 err = errors.New("must create a session first") 144 return 145 } 146 c.xrpc.Headers.Set("Authorization", fmt.Sprintf("Bearer %s", *c.accessjwt)) 147 var out atproto.RepoDeleteRecord_Output 148 err = c.xrpc.LexDo(ctx, "POST", "application/json", "com.atproto.repo.deleteRecord", nil, input, &out) 149 if err != nil { 150 err1 := err.Error() 151 err = c.RefreshSession(ctx) 152 if err != nil { 153 err = errors.New(fmt.Sprintf("failed to refresh session while deleting %s! first %s then %s", input.Collection, err1, err.Error())) 154 return 155 } 156 c.xrpc.Headers.Set("Authorization", fmt.Sprintf("Bearer %s", *c.accessjwt)) 157 err = c.xrpc.LexDo(ctx, "POST", "application/json", "com.atproto.repo.deleteRecord", nil, input, &out) 158 if err != nil { 159 err = errors.New(fmt.Sprintf("not good, failed to delete %s after failing then refreshing session! first %s then %s", input.Collection, err1, err.Error())) 160 return 161 } 162 } 163 return 164}