tangled
alpha
login
or
join now
moth11.net
/
88x31
0
fork
atom
tiny 88x31 lexicon for atproto
0
fork
atom
overview
issues
pulls
pipelines
lets see if this is any good
moth11.net
1 month ago
2088e1c6
6bcfba6e
+95
-1
5 changed files
expand all
collapse all
unified
split
db
lexicon.go
handler
handler.go
upload.go
oauth
client.go
tmpl
button.html
+7
db/lexicon.go
···
236
`, uri)
237
return err
238
}
0
0
0
0
0
0
0
···
236
`, uri)
237
return err
238
}
239
+
240
+
func (s *Store) DeleteButton(uri string, ctx context.Context) error {
241
+
_, err := s.pool.Exec(ctx, `
242
+
DELETE FROM buttons WHERE uri = $1
243
+
`, uri)
244
+
return err
245
+
}
+1
handler/handler.go
···
45
mux.HandleFunc("POST /logout", h.oauthMiddleware(h.logout))
46
mux.HandleFunc("GET /upload", h.oauthMiddleware(getupload))
47
mux.HandleFunc("POST /upload", h.oauthMiddleware(h.upload))
0
48
mux.HandleFunc("POST /like", h.oauthMiddleware(h.like))
49
mux.HandleFunc("POST /unlike", h.oauthMiddleware(h.unlike))
50
mux.HandleFunc("GET /button", h.oauthMiddleware(h.getbutton))
···
45
mux.HandleFunc("POST /logout", h.oauthMiddleware(h.logout))
46
mux.HandleFunc("GET /upload", h.oauthMiddleware(getupload))
47
mux.HandleFunc("POST /upload", h.oauthMiddleware(h.upload))
48
+
mux.HandleFunc("POST /delete", h.oauthMiddleware(h.delete))
49
mux.HandleFunc("POST /like", h.oauthMiddleware(h.like))
50
mux.HandleFunc("POST /unlike", h.oauthMiddleware(h.unlike))
51
mux.HandleFunc("GET /button", h.oauthMiddleware(h.getbutton))
+69
handler/upload.go
···
118
http.Redirect(w, r, fmt.Sprintf("/button?uri=%s", uri), http.StatusSeeOther)
119
}
120
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
121
func (h *Handler) upload(cs *oauth.ClientSession, w http.ResponseWriter, r *http.Request) {
122
if cs == nil {
123
http.Error(w, "upload requires auth", http.StatusUnauthorized)
···
118
http.Redirect(w, r, fmt.Sprintf("/button?uri=%s", uri), http.StatusSeeOther)
119
}
120
121
+
func (h *Handler) delete(cs *oauth.ClientSession, w http.ResponseWriter, r *http.Request) {
122
+
if cs == nil {
123
+
http.Error(w, "deletion requires auth", http.StatusUnauthorized)
124
+
return
125
+
}
126
+
err := r.ParseForm()
127
+
if err != nil {
128
+
http.Error(w, "form failed to parse", http.StatusBadRequest)
129
+
return
130
+
}
131
+
uri := r.FormValue("uri")
132
+
if uri == "" {
133
+
http.Error(w, "must provide uri, don't tamper with form", http.StatusBadRequest)
134
+
return
135
+
}
136
+
aturi, err := syntax.ParseATURI(uri)
137
+
if err != nil {
138
+
http.Error(w, "uri should parse", http.StatusBadRequest)
139
+
return
140
+
}
141
+
cid := r.FormValue("cid")
142
+
if cid == "" {
143
+
http.Error(w, "must provide a cid, don't tamper with form", http.StatusBadRequest)
144
+
return
145
+
}
146
+
ll, err := h.db.GetMyLikesFor(uri, cid, cs.Data.AccountDID.String(), r.Context())
147
+
if err == nil {
148
+
for _, likeuricid := range ll {
149
+
arr := strings.Split(likeuricid, " ")
150
+
if len(arr) != 2 {
151
+
http.Error(w, "invalid likeuricid", http.StatusInternalServerError)
152
+
return
153
+
}
154
+
likeuri := arr[0]
155
+
likecid := arr[1]
156
+
aturi, err := syntax.ParseATURI(likeuri)
157
+
if err != nil {
158
+
http.Error(w, "uri doesn't parse, don't tamper with form", http.StatusBadRequest)
159
+
return
160
+
}
161
+
err = myoauth.DeleteLike(cs, aturi.RecordKey().String(), likecid, r.Context())
162
+
if err != nil {
163
+
log.Println(err)
164
+
http.Error(w, "error deleting like", http.StatusInternalServerError)
165
+
return
166
+
}
167
+
err = h.db.DeleteLike(likeuri, r.Context())
168
+
if err != nil {
169
+
log.Println(err)
170
+
http.Error(w, "error deleting cached like", http.StatusInternalServerError)
171
+
return
172
+
}
173
+
}
174
+
}
175
+
err = myoauth.DeleteButton(cs, aturi.RecordKey().String(), cid, r.Context())
176
+
if err != nil {
177
+
log.Println(err)
178
+
http.Error(w, "failed to delete button", http.StatusInternalServerError)
179
+
return
180
+
}
181
+
err = h.db.DeleteButton(uri, r.Context())
182
+
if err != nil {
183
+
log.Println(err)
184
+
http.Error(w, "error deleting cached button", http.StatusInternalServerError)
185
+
return
186
+
}
187
+
http.Redirect(w, r, "/", http.StatusSeeOther)
188
+
}
189
+
190
func (h *Handler) upload(cs *oauth.ClientSession, w http.ResponseWriter, r *http.Request) {
191
if cs == nil {
192
http.Error(w, "upload requires auth", http.StatusUnauthorized)
+17
oauth/client.go
···
67
return
68
}
69
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
70
func CreateLike(cs *oauth.ClientSession, like *lex.LikeRecord, ctx context.Context) (uri string, cid string, err error) {
71
c := cs.APIClient()
72
body := map[string]any{
···
67
return
68
}
69
70
+
func DeleteButton(cs *oauth.ClientSession, rkey string, cid string, ctx context.Context) error {
71
+
c := cs.APIClient()
72
+
body := map[string]any{
73
+
"collection": "store.88x31.button",
74
+
"repo": *c.AccountDID,
75
+
"rkey": rkey,
76
+
"swapRecord": cid,
77
+
}
78
+
var out atproto.RepoDeleteRecord_Output
79
+
err := c.Post(ctx, "com.atproto.repo.deleteRecord", body, &out)
80
+
if err != nil {
81
+
err = errors.New("oops! failed to delete a button: " + err.Error())
82
+
return err
83
+
}
84
+
return nil
85
+
}
86
+
87
func CreateLike(cs *oauth.ClientSession, like *lex.LikeRecord, ctx context.Context) (uri string, cid string, err error) {
88
c := cs.APIClient()
89
body := map[string]any{
+1
-1
tmpl/button.html
···
15
</form>
16
{{end}}
17
{{if eq .Button.DID (deref .DID)}}
18
-
<form action="/unlike" method="POST">
19
<input type="text" name="uri" value="{{.Button.URI}}" hidden />
20
<input type="text" name="cid" value="{{.Button.CID}}" hidden />
21
<input type="submit" value='delete (permanent, one click)'/>
···
15
</form>
16
{{end}}
17
{{if eq .Button.DID (deref .DID)}}
18
+
<form action="/delete" method="POST">
19
<input type="text" name="uri" value="{{.Button.URI}}" hidden />
20
<input type="text" name="cid" value="{{.Button.CID}}" hidden />
21
<input type="submit" value='delete (permanent, one click)'/>