+7
cmd/cocoon/main.go
+7
cmd/cocoon/main.go
···
9
9
"os"
10
10
"time"
11
11
12
+
"github.com/bluesky-social/go-util/pkg/telemetry"
12
13
"github.com/bluesky-social/indigo/atproto/atcrypto"
13
14
"github.com/bluesky-social/indigo/atproto/syntax"
14
15
"github.com/haileyok/cocoon/internal/helpers"
···
154
155
Name: "fallback-proxy",
155
156
EnvVars: []string{"COCOON_FALLBACK_PROXY"},
156
157
},
158
+
telemetry.CLIFlagDebug,
159
+
telemetry.CLIFlagMetricsListenAddress,
157
160
},
158
161
Commands: []*cli.Command{
159
162
runServe,
···
177
180
Flags: []cli.Flag{},
178
181
Action: func(cmd *cli.Context) error {
179
182
183
+
logger := telemetry.StartLogger(cmd)
184
+
telemetry.StartMetrics(cmd)
185
+
180
186
s, err := server.New(&server.Args{
187
+
Logger: logger,
181
188
Addr: cmd.String("addr"),
182
189
DbName: cmd.String("db-name"),
183
190
DbType: cmd.String("db-type"),
+14
-12
go.mod
+14
-12
go.mod
···
1
1
module github.com/haileyok/cocoon
2
2
3
-
go 1.24.1
3
+
go 1.24.5
4
4
5
5
require (
6
6
github.com/Azure/go-autorest/autorest/to v0.4.1
7
7
github.com/aws/aws-sdk-go v1.55.7
8
+
github.com/bluesky-social/go-util v0.0.0-20251012040650-2ebbf57f5934
8
9
github.com/bluesky-social/indigo v0.0.0-20251009212240-20524de167fe
9
10
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792
10
11
github.com/domodwyer/mailyak/v3 v3.6.2
11
12
github.com/go-pkgz/expirable-cache/v3 v3.0.0
12
13
github.com/go-playground/validator v9.31.0+incompatible
13
14
github.com/golang-jwt/jwt/v4 v4.5.2
14
-
github.com/google/uuid v1.4.0
15
+
github.com/google/uuid v1.6.0
15
16
github.com/gorilla/sessions v1.4.0
16
17
github.com/gorilla/websocket v1.5.1
17
18
github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b
···
26
27
github.com/labstack/echo/v4 v4.13.3
27
28
github.com/lestrrat-go/jwx/v2 v2.0.12
28
29
github.com/multiformats/go-multihash v0.2.3
30
+
github.com/prometheus/client_golang v1.23.2
29
31
github.com/samber/slog-echo v1.16.1
30
32
github.com/urfave/cli/v2 v2.27.6
31
33
github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e
32
34
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b
33
-
golang.org/x/crypto v0.38.0
35
+
golang.org/x/crypto v0.41.0
34
36
gorm.io/driver/postgres v1.5.7
35
37
gorm.io/driver/sqlite v1.5.7
36
38
gorm.io/gorm v1.25.12
···
57
59
github.com/gorilla/securecookie v1.1.2 // indirect
58
60
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect
59
61
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
60
-
github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
62
+
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
61
63
github.com/hashicorp/golang-lru v1.0.2 // indirect
62
64
github.com/ipfs/bbloom v0.0.4 // indirect
63
65
github.com/ipfs/go-blockservice v0.5.2 // indirect
···
103
105
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
104
106
github.com/opentracing/opentracing-go v1.2.0 // indirect
105
107
github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f // indirect
106
-
github.com/prometheus/client_golang v1.22.0 // indirect
107
108
github.com/prometheus/client_model v0.6.2 // indirect
108
-
github.com/prometheus/common v0.63.0 // indirect
109
+
github.com/prometheus/common v0.66.1 // indirect
109
110
github.com/prometheus/procfs v0.16.1 // indirect
110
111
github.com/russross/blackfriday/v2 v2.1.0 // indirect
111
112
github.com/samber/lo v1.49.1 // indirect
···
115
116
github.com/valyala/fasttemplate v1.2.2 // indirect
116
117
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
117
118
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect
118
-
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 // indirect
119
+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect
119
120
go.opentelemetry.io/otel v1.29.0 // indirect
120
121
go.opentelemetry.io/otel/metric v1.29.0 // indirect
121
122
go.opentelemetry.io/otel/trace v1.29.0 // indirect
122
123
go.uber.org/atomic v1.11.0 // indirect
123
124
go.uber.org/multierr v1.11.0 // indirect
124
125
go.uber.org/zap v1.26.0 // indirect
125
-
golang.org/x/net v0.40.0 // indirect
126
-
golang.org/x/sync v0.14.0 // indirect
127
-
golang.org/x/sys v0.33.0 // indirect
128
-
golang.org/x/text v0.25.0 // indirect
126
+
go.yaml.in/yaml/v2 v2.4.2 // indirect
127
+
golang.org/x/net v0.43.0 // indirect
128
+
golang.org/x/sync v0.16.0 // indirect
129
+
golang.org/x/sys v0.35.0 // indirect
130
+
golang.org/x/text v0.28.0 // indirect
129
131
golang.org/x/time v0.11.0 // indirect
130
132
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
131
-
google.golang.org/protobuf v1.36.6 // indirect
133
+
google.golang.org/protobuf v1.36.9 // indirect
132
134
gopkg.in/go-playground/assert.v1 v1.2.1 // indirect
133
135
gopkg.in/inf.v0 v0.9.1 // indirect
134
136
lukechampine.com/blake3 v1.2.1 // indirect
+42
-33
go.sum
+42
-33
go.sum
···
16
16
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
17
17
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY=
18
18
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k=
19
+
github.com/bluesky-social/go-util v0.0.0-20251012040650-2ebbf57f5934 h1:btHMur2kTRgWEnCHn6LaI3BE9YRgsqTpwpJ1UdB7VEk=
20
+
github.com/bluesky-social/go-util v0.0.0-20251012040650-2ebbf57f5934/go.mod h1:LWamyZfbQGW7PaVc5jumFfjgrshJ5mXgDUnR6fK7+BI=
19
21
github.com/bluesky-social/indigo v0.0.0-20251009212240-20524de167fe h1:VBhaqE5ewQgXbY5SfSWFZC/AwHFo7cHxZKFYi2ce9Yo=
20
22
github.com/bluesky-social/indigo v0.0.0-20251009212240-20524de167fe/go.mod h1:RuQVrCGm42QNsgumKaR6se+XkFKfCPNwdCiTvqKRUck=
21
23
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
···
39
41
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
40
42
github.com/domodwyer/mailyak/v3 v3.6.2 h1:x3tGMsyFhTCaxp6ycgR0FE/bu5QiNp+hetUuCOBXMn8=
41
43
github.com/domodwyer/mailyak/v3 v3.6.2/go.mod h1:lOm/u9CyCVWHeaAmHIdF4RiKVxKUT/H5XX10lIKAL6c=
44
+
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
45
+
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
42
46
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
43
47
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
44
48
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
···
77
81
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
78
82
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
79
83
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
80
-
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
81
-
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
84
+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
85
+
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
82
86
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
83
87
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
84
88
github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o=
···
95
99
github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b/go.mod h1:VzxiSdG6j1pi7rwGm/xYI5RbtpBgM8sARDXlvEvxlu0=
96
100
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
97
101
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
98
-
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
99
-
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
100
-
github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M=
101
-
github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
102
+
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
103
+
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
104
+
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
105
+
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
102
106
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
103
107
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
104
108
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
···
195
199
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
196
200
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
197
201
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
202
+
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
203
+
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
198
204
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
199
205
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
200
206
github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8=
···
206
212
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
207
213
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
208
214
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
215
+
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
216
+
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
209
217
github.com/labstack/echo-contrib v0.17.4 h1:g5mfsrJfJTKv+F5uNKCyrjLK7js+ZW6HTjg4FnDxxgk=
210
218
github.com/labstack/echo-contrib v0.17.4/go.mod h1:9O7ZPAHUeMGTOAfg80YqQduHzt0CzLak36PZRldYrZ0=
211
219
github.com/labstack/echo/v4 v4.13.3 h1:pwhpCPrTl5qry5HRdM5FwdXnhXSLSY+WE+YQSeCaafY=
···
289
297
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
290
298
github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f h1:VXTQfuJj9vKR4TCkEuWIckKvdHFeJH/huIFJ9/cXOB0=
291
299
github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw=
292
-
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
293
-
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
300
+
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
301
+
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
294
302
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
295
303
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
296
-
github.com/prometheus/common v0.63.0 h1:YR/EIY1o3mEFP/kZCD7iDMnLPlGyuU2Gb3HIcXnA98k=
297
-
github.com/prometheus/common v0.63.0/go.mod h1:VVFF/fBIoToEnWRVkYoXEkq3R3paCoxG9PXP74SnV18=
304
+
github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
305
+
github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
298
306
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
299
307
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
300
308
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
···
319
327
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
320
328
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
321
329
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
322
-
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
323
330
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
324
331
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
325
332
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
···
327
334
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
328
335
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
329
336
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
330
-
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
331
-
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
337
+
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
338
+
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
332
339
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
333
340
github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g=
334
341
github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
···
354
361
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b/go.mod h1:/y/V339mxv2sZmYYR64O07VuCpdNZqCTwO8ZcouTMI8=
355
362
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 h1:qwDnMxjkyLmAFgcfgTnfJrmYKWhHnci3GjDqcZp1M3Q=
356
363
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02/go.mod h1:JTnUj0mpYiAsuZLmKjTx/ex3AtMowcCgnE7YNyCEP0I=
357
-
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24=
358
-
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
364
+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk=
365
+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw=
359
366
go.opentelemetry.io/otel v1.29.0 h1:PdomN/Al4q/lN6iBJEN3AwPvUiHPMlt93c8bqTG5Llw=
360
367
go.opentelemetry.io/otel v1.29.0/go.mod h1:N/WtXPs1CNCUEx+Agz5uouwCba+i+bJGFicT8SR4NP8=
361
368
go.opentelemetry.io/otel/metric v1.29.0 h1:vPf/HFWTNkPu1aYeIsc98l4ktOQaL6LeSoeV2g+8YLc=
···
367
374
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
368
375
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
369
376
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
370
-
go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk=
371
-
go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo=
377
+
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
378
+
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
372
379
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
373
380
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
374
381
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
···
378
385
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
379
386
go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
380
387
go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
388
+
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
389
+
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
381
390
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
382
391
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
383
392
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
384
393
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
385
394
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
386
395
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
387
-
golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8=
388
-
golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw=
396
+
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
397
+
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
389
398
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ=
390
399
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE=
391
400
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
···
395
404
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
396
405
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
397
406
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
398
-
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
399
-
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
407
+
golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
408
+
golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ=
400
409
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
401
410
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
402
411
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
···
407
416
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
408
417
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
409
418
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
410
-
golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY=
411
-
golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds=
419
+
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
420
+
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
412
421
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
413
422
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
414
423
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
415
424
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
416
425
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
417
426
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
418
-
golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ=
419
-
golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
427
+
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
428
+
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
420
429
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
421
430
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
422
431
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
···
432
441
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
433
442
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
434
443
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
435
-
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
436
-
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
444
+
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
445
+
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
437
446
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
438
447
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
439
448
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
···
445
454
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
446
455
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
447
456
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
448
-
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
449
-
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
457
+
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
458
+
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
450
459
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
451
460
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
452
461
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
···
461
470
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
462
471
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
463
472
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
464
-
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
465
-
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
473
+
golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0=
474
+
golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw=
466
475
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
467
476
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
468
477
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
469
478
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
470
479
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
471
480
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
472
-
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
473
-
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
481
+
google.golang.org/protobuf v1.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
482
+
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
474
483
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
475
484
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
476
485
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+30
metrics/metrics.go
+30
metrics/metrics.go
···
1
+
package metrics
2
+
3
+
import (
4
+
"github.com/prometheus/client_golang/prometheus"
5
+
"github.com/prometheus/client_golang/prometheus/promauto"
6
+
)
7
+
8
+
const (
9
+
NAMESPACE = "cocoon"
10
+
)
11
+
12
+
var (
13
+
RelaysConnected = promauto.NewGaugeVec(prometheus.GaugeOpts{
14
+
Namespace: NAMESPACE,
15
+
Name: "relays_connected",
16
+
Help: "number of connected relays, by host",
17
+
}, []string{"host"})
18
+
19
+
RelaySends = promauto.NewCounterVec(prometheus.CounterOpts{
20
+
Namespace: NAMESPACE,
21
+
Name: "relay_sends",
22
+
Help: "number of events sent to a relay, by host",
23
+
}, []string{"host", "kind"})
24
+
25
+
RepoOperations = promauto.NewCounterVec(prometheus.CounterOpts{
26
+
Namespace: NAMESPACE,
27
+
Name: "repo_operations",
28
+
Help: "number of operations made against repos",
29
+
}, []string{"kind"})
30
+
)
-1
oauth/client/manager.go
-1
oauth/client/manager.go
+1
-1
oauth/dpop/jti_cache.go
+1
-1
oauth/dpop/jti_cache.go
···
14
14
}
15
15
16
16
func newJTICache(size int) *jtiCache {
17
-
cache := cache.NewCache[string, bool]().WithTTL(24 * time.Hour).WithLRU().WithTTL(constants.JTITtl)
17
+
cache := cache.NewCache[string, bool]().WithTTL(24 * time.Hour).WithLRU().WithTTL(constants.JTITtl).WithMaxKeys(size)
18
18
return &jtiCache{
19
19
cache: cache,
20
20
mu: sync.Mutex{},
+2
-1
server/handle_account.go
+2
-1
server/handle_account.go
···
12
12
13
13
func (s *Server) handleAccount(e echo.Context) error {
14
14
ctx := e.Request().Context()
15
+
logger := s.logger.With("name", "handleAuth")
15
16
16
17
repo, sess, err := s.getSessionRepoOrErr(e)
17
18
if err != nil {
···
22
23
23
24
var tokens []provider.OauthToken
24
25
if err := s.db.Raw(ctx, "SELECT * FROM oauth_tokens WHERE sub = ? AND created_at < ? ORDER BY created_at ASC", nil, repo.Repo.Did, oldestPossibleSession).Scan(&tokens).Error; err != nil {
25
-
s.logger.Error("couldnt fetch oauth sessions for account", "did", repo.Repo.Did, "error", err)
26
+
logger.Error("couldnt fetch oauth sessions for account", "did", repo.Repo.Did, "error", err)
26
27
sess.AddFlash("Unable to fetch sessions. See server logs for more details.", "error")
27
28
sess.Save(e.Request(), e.Response())
28
29
return e.Render(200, "account.html", map[string]any{
+3
-2
server/handle_account_revoke.go
+3
-2
server/handle_account_revoke.go
···
11
11
12
12
func (s *Server) handleAccountRevoke(e echo.Context) error {
13
13
ctx := e.Request().Context()
14
+
logger := s.logger.With("name", "handleAcocuntRevoke")
14
15
15
16
var req AccountRevokeInput
16
17
if err := e.Bind(&req); err != nil {
17
-
s.logger.Error("could not bind account revoke request", "error", err)
18
+
logger.Error("could not bind account revoke request", "error", err)
18
19
return helpers.ServerError(e, nil)
19
20
}
20
21
···
24
25
}
25
26
26
27
if err := s.db.Exec(ctx, "DELETE FROM oauth_tokens WHERE sub = ? AND token = ?", nil, repo.Repo.Did, req.Token).Error; err != nil {
27
-
s.logger.Error("couldnt delete oauth session for account", "did", repo.Repo.Did, "token", req.Token, "error", err)
28
+
logger.Error("couldnt delete oauth session for account", "did", repo.Repo.Did, "token", req.Token, "error", err)
28
29
sess.AddFlash("Unable to revoke session. See server logs for more details.", "error")
29
30
sess.Save(e.Request(), e.Response())
30
31
return e.Redirect(303, "/account")
+2
-1
server/handle_account_signin.go
+2
-1
server/handle_account_signin.go
···
67
67
68
68
func (s *Server) handleAccountSigninPost(e echo.Context) error {
69
69
ctx := e.Request().Context()
70
+
logger := s.logger.With("name", "handleAccountSigninPost")
70
71
71
72
var req OauthSigninInput
72
73
if err := e.Bind(&req); err != nil {
73
-
s.logger.Error("error binding sign in req", "error", err)
74
+
logger.Error("error binding sign in req", "error", err)
74
75
return helpers.ServerError(e, nil)
75
76
}
76
77
+4
-2
server/handle_identity_get_recommended_did_credentials.go
+4
-2
server/handle_identity_get_recommended_did_credentials.go
···
8
8
)
9
9
10
10
func (s *Server) handleGetRecommendedDidCredentials(e echo.Context) error {
11
+
logger := s.logger.With("name", "handleIdentityGetRecommendedDidCredentials")
12
+
11
13
repo := e.Get("repo").(*models.RepoActor)
12
14
k, err := atcrypto.ParsePrivateBytesK256(repo.SigningKey)
13
15
if err != nil {
14
-
s.logger.Error("error parsing key", "error", err)
16
+
logger.Error("error parsing key", "error", err)
15
17
return helpers.ServerError(e, nil)
16
18
}
17
19
creds, err := s.plcClient.CreateDidCredentials(k, "", repo.Actor.Handle)
18
20
if err != nil {
19
-
s.logger.Error("error crating did credentials", "error", err)
21
+
logger.Error("error crating did credentials", "error", err)
20
22
return helpers.ServerError(e, nil)
21
23
}
22
24
+3
-2
server/handle_identity_request_plc_operation.go
+3
-2
server/handle_identity_request_plc_operation.go
···
11
11
12
12
func (s *Server) handleIdentityRequestPlcOperationSignature(e echo.Context) error {
13
13
ctx := e.Request().Context()
14
+
logger := s.logger.With("name", "handleIdentityRequestPlcOperationSignature")
14
15
15
16
urepo := e.Get("repo").(*models.RepoActor)
16
17
···
18
19
eat := time.Now().Add(10 * time.Minute).UTC()
19
20
20
21
if err := s.db.Exec(ctx, "UPDATE repos SET plc_operation_code = ?, plc_operation_code_expires_at = ? WHERE did = ?", nil, code, eat, urepo.Repo.Did).Error; err != nil {
21
-
s.logger.Error("error updating user", "error", err)
22
+
logger.Error("error updating user", "error", err)
22
23
return helpers.ServerError(e, nil)
23
24
}
24
25
25
26
if err := s.sendPlcTokenReset(urepo.Email, urepo.Handle, code); err != nil {
26
-
s.logger.Error("error sending mail", "error", err)
27
+
logger.Error("error sending mail", "error", err)
27
28
return helpers.ServerError(e, nil)
28
29
}
29
30
+7
-5
server/handle_identity_sign_plc_operation.go
+7
-5
server/handle_identity_sign_plc_operation.go
···
27
27
}
28
28
29
29
func (s *Server) handleSignPlcOperation(e echo.Context) error {
30
+
logger := s.logger.With("name", "handleSignPlcOperation")
31
+
30
32
repo := e.Get("repo").(*models.RepoActor)
31
33
32
34
var req ComAtprotoSignPlcOperationRequest
33
35
if err := e.Bind(&req); err != nil {
34
-
s.logger.Error("error binding", "error", err)
36
+
logger.Error("error binding", "error", err)
35
37
return helpers.ServerError(e, nil)
36
38
}
37
39
···
54
56
ctx := context.WithValue(e.Request().Context(), "skip-cache", true)
55
57
log, err := identity.FetchDidAuditLog(ctx, nil, repo.Repo.Did)
56
58
if err != nil {
57
-
s.logger.Error("error fetching doc", "error", err)
59
+
logger.Error("error fetching doc", "error", err)
58
60
return helpers.ServerError(e, nil)
59
61
}
60
62
···
83
85
84
86
k, err := atcrypto.ParsePrivateBytesK256(repo.SigningKey)
85
87
if err != nil {
86
-
s.logger.Error("error parsing signing key", "error", err)
88
+
logger.Error("error parsing signing key", "error", err)
87
89
return helpers.ServerError(e, nil)
88
90
}
89
91
90
92
if err := s.plcClient.SignOp(k, &op); err != nil {
91
-
s.logger.Error("error signing plc operation", "error", err)
93
+
logger.Error("error signing plc operation", "error", err)
92
94
return helpers.ServerError(e, nil)
93
95
}
94
96
95
97
if err := s.db.Exec(ctx, "UPDATE repos SET plc_operation_code = NULL, plc_operation_code_expires_at = NULL WHERE did = ?", nil, repo.Repo.Did).Error; err != nil {
96
-
s.logger.Error("error updating repo", "error", err)
98
+
logger.Error("error updating repo", "error", err)
97
99
return helpers.ServerError(e, nil)
98
100
}
99
101
+6
-4
server/handle_identity_submit_plc_operation.go
+6
-4
server/handle_identity_submit_plc_operation.go
···
21
21
}
22
22
23
23
func (s *Server) handleSubmitPlcOperation(e echo.Context) error {
24
+
logger := s.logger.With("name", "handleIdentitySubmitPlcOperation")
25
+
24
26
repo := e.Get("repo").(*models.RepoActor)
25
27
26
28
var req ComAtprotoSubmitPlcOperationRequest
27
29
if err := e.Bind(&req); err != nil {
28
-
s.logger.Error("error binding", "error", err)
30
+
logger.Error("error binding", "error", err)
29
31
return helpers.ServerError(e, nil)
30
32
}
31
33
···
40
42
41
43
k, err := atcrypto.ParsePrivateBytesK256(repo.SigningKey)
42
44
if err != nil {
43
-
s.logger.Error("error parsing key", "error", err)
45
+
logger.Error("error parsing key", "error", err)
44
46
return helpers.ServerError(e, nil)
45
47
}
46
48
required, err := s.plcClient.CreateDidCredentials(k, "", repo.Actor.Handle)
47
49
if err != nil {
48
-
s.logger.Error("error crating did credentials", "error", err)
50
+
logger.Error("error crating did credentials", "error", err)
49
51
return helpers.ServerError(e, nil)
50
52
}
51
53
···
72
74
}
73
75
74
76
if err := s.passport.BustDoc(context.TODO(), repo.Repo.Did); err != nil {
75
-
s.logger.Warn("error busting did doc", "error", err)
77
+
logger.Warn("error busting did doc", "error", err)
76
78
}
77
79
78
80
s.evtman.AddEvent(context.TODO(), &events.XRPCStreamEvent{
+7
-5
server/handle_identity_update_handle.go
+7
-5
server/handle_identity_update_handle.go
···
22
22
}
23
23
24
24
func (s *Server) handleIdentityUpdateHandle(e echo.Context) error {
25
+
logger := s.logger.With("name", "handleIdentityUpdateHandle")
26
+
25
27
repo := e.Get("repo").(*models.RepoActor)
26
28
27
29
var req ComAtprotoIdentityUpdateHandleRequest
28
30
if err := e.Bind(&req); err != nil {
29
-
s.logger.Error("error binding", "error", err)
31
+
logger.Error("error binding", "error", err)
30
32
return helpers.ServerError(e, nil)
31
33
}
32
34
···
41
43
if strings.HasPrefix(repo.Repo.Did, "did:plc:") {
42
44
log, err := identity.FetchDidAuditLog(ctx, nil, repo.Repo.Did)
43
45
if err != nil {
44
-
s.logger.Error("error fetching doc", "error", err)
46
+
logger.Error("error fetching doc", "error", err)
45
47
return helpers.ServerError(e, nil)
46
48
}
47
49
···
68
70
69
71
k, err := atcrypto.ParsePrivateBytesK256(repo.SigningKey)
70
72
if err != nil {
71
-
s.logger.Error("error parsing signing key", "error", err)
73
+
logger.Error("error parsing signing key", "error", err)
72
74
return helpers.ServerError(e, nil)
73
75
}
74
76
···
82
84
}
83
85
84
86
if err := s.passport.BustDoc(context.TODO(), repo.Repo.Did); err != nil {
85
-
s.logger.Warn("error busting did doc", "error", err)
87
+
logger.Warn("error busting did doc", "error", err)
86
88
}
87
89
88
90
s.evtman.AddEvent(context.TODO(), &events.XRPCStreamEvent{
···
95
97
})
96
98
97
99
if err := s.db.Exec(ctx, "UPDATE actors SET handle = ? WHERE did = ?", nil, req.Handle, repo.Repo.Did).Error; err != nil {
98
-
s.logger.Error("error updating handle in db", "error", err)
100
+
logger.Error("error updating handle in db", "error", err)
99
101
return helpers.ServerError(e, nil)
100
102
}
101
103
+11
-10
server/handle_import_repo.go
+11
-10
server/handle_import_repo.go
···
19
19
20
20
func (s *Server) handleRepoImportRepo(e echo.Context) error {
21
21
ctx := e.Request().Context()
22
+
logger := s.logger.With("name", "handleImportRepo")
22
23
23
24
urepo := e.Get("repo").(*models.RepoActor)
24
25
25
26
b, err := io.ReadAll(e.Request().Body)
26
27
if err != nil {
27
-
s.logger.Error("could not read bytes in import request", "error", err)
28
+
logger.Error("could not read bytes in import request", "error", err)
28
29
return helpers.ServerError(e, nil)
29
30
}
30
31
···
32
33
33
34
cs, err := car.NewCarReader(bytes.NewReader(b))
34
35
if err != nil {
35
-
s.logger.Error("could not read car in import request", "error", err)
36
+
logger.Error("could not read car in import request", "error", err)
36
37
return helpers.ServerError(e, nil)
37
38
}
38
39
39
40
orderedBlocks := []blocks.Block{}
40
41
currBlock, err := cs.Next()
41
42
if err != nil {
42
-
s.logger.Error("could not get first block from car", "error", err)
43
+
logger.Error("could not get first block from car", "error", err)
43
44
return helpers.ServerError(e, nil)
44
45
}
45
46
currBlockCt := 1
46
47
47
48
for currBlock != nil {
48
-
s.logger.Info("someone is importing their repo", "block", currBlockCt)
49
+
logger.Info("someone is importing their repo", "block", currBlockCt)
49
50
orderedBlocks = append(orderedBlocks, currBlock)
50
51
next, _ := cs.Next()
51
52
currBlock = next
···
55
56
slices.Reverse(orderedBlocks)
56
57
57
58
if err := bs.PutMany(context.TODO(), orderedBlocks); err != nil {
58
-
s.logger.Error("could not insert blocks", "error", err)
59
+
logger.Error("could not insert blocks", "error", err)
59
60
return helpers.ServerError(e, nil)
60
61
}
61
62
62
63
r, err := repo.OpenRepo(context.TODO(), bs, cs.Header.Roots[0])
63
64
if err != nil {
64
-
s.logger.Error("could not open repo", "error", err)
65
+
logger.Error("could not open repo", "error", err)
65
66
return helpers.ServerError(e, nil)
66
67
}
67
68
···
76
77
cidStr := cid.String()
77
78
b, err := bs.Get(context.TODO(), cid)
78
79
if err != nil {
79
-
s.logger.Error("record bytes don't exist in blockstore", "error", err)
80
+
logger.Error("record bytes don't exist in blockstore", "error", err)
80
81
return helpers.ServerError(e, nil)
81
82
}
82
83
···
96
97
return nil
97
98
}); err != nil {
98
99
tx.Rollback()
99
-
s.logger.Error("record bytes don't exist in blockstore", "error", err)
100
+
logger.Error("record bytes don't exist in blockstore", "error", err)
100
101
return helpers.ServerError(e, nil)
101
102
}
102
103
···
104
105
105
106
root, rev, err := r.Commit(context.TODO(), urepo.SignFor)
106
107
if err != nil {
107
-
s.logger.Error("error committing", "error", err)
108
+
logger.Error("error committing", "error", err)
108
109
return helpers.ServerError(e, nil)
109
110
}
110
111
111
112
if err := s.UpdateRepo(context.TODO(), urepo.Repo.Did, root, rev); err != nil {
112
-
s.logger.Error("error updating repo after commit", "error", err)
113
+
logger.Error("error updating repo after commit", "error", err)
113
114
return helpers.ServerError(e, nil)
114
115
}
115
116
+8
-7
server/handle_oauth_par.go
+8
-7
server/handle_oauth_par.go
···
20
20
21
21
func (s *Server) handleOauthPar(e echo.Context) error {
22
22
ctx := e.Request().Context()
23
+
logger := s.logger.With("name", "handleOauthPar")
23
24
24
25
var parRequest provider.ParRequest
25
26
if err := e.Bind(&parRequest); err != nil {
26
-
s.logger.Error("error binding for par request", "error", err)
27
+
logger.Error("error binding for par request", "error", err)
27
28
return helpers.ServerError(e, nil)
28
29
}
29
30
30
31
if err := e.Validate(parRequest); err != nil {
31
-
s.logger.Error("missing parameters for par request", "error", err)
32
+
logger.Error("missing parameters for par request", "error", err)
32
33
return helpers.InputError(e, nil)
33
34
}
34
35
···
45
46
"error": "use_dpop_nonce",
46
47
})
47
48
}
48
-
s.logger.Error("error getting dpop proof", "error", err)
49
+
logger.Error("error getting dpop proof", "error", err)
49
50
return helpers.InputError(e, nil)
50
51
}
51
52
···
55
56
AllowMissingDpopProof: true,
56
57
})
57
58
if err != nil {
58
-
s.logger.Error("error authenticating client", "client_id", parRequest.ClientID, "error", err)
59
+
logger.Error("error authenticating client", "client_id", parRequest.ClientID, "error", err)
59
60
return helpers.InputError(e, to.StringPtr(err.Error()))
60
61
}
61
62
···
66
67
} else {
67
68
if !client.Metadata.DpopBoundAccessTokens {
68
69
msg := "dpop bound access tokens are not enabled for this client"
69
-
s.logger.Error(msg)
70
+
logger.Error(msg)
70
71
return helpers.InputError(e, &msg)
71
72
}
72
73
73
74
if dpopProof.JKT != *parRequest.DpopJkt {
74
75
msg := "supplied dpop jkt does not match header dpop jkt"
75
-
s.logger.Error(msg)
76
+
logger.Error(msg)
76
77
return helpers.InputError(e, &msg)
77
78
}
78
79
}
···
89
90
}
90
91
91
92
if err := s.db.Create(ctx, authRequest, nil).Error; err != nil {
92
-
s.logger.Error("error creating auth request in db", "error", err)
93
+
logger.Error("error creating auth request in db", "error", err)
93
94
return helpers.ServerError(e, nil)
94
95
}
95
96
+9
-8
server/handle_oauth_token.go
+9
-8
server/handle_oauth_token.go
···
39
39
40
40
func (s *Server) handleOauthToken(e echo.Context) error {
41
41
ctx := e.Request().Context()
42
+
logger := s.logger.With("name", "handleOauthToken")
42
43
43
44
var req OauthTokenRequest
44
45
if err := e.Bind(&req); err != nil {
45
-
s.logger.Error("error binding token request", "error", err)
46
+
logger.Error("error binding token request", "error", err)
46
47
return helpers.ServerError(e, nil)
47
48
}
48
49
···
58
59
"error": "use_dpop_nonce",
59
60
})
60
61
}
61
-
s.logger.Error("error getting dpop proof", "error", err)
62
+
logger.Error("error getting dpop proof", "error", err)
62
63
return helpers.InputError(e, nil)
63
64
}
64
65
···
66
67
AllowMissingDpopProof: true,
67
68
})
68
69
if err != nil {
69
-
s.logger.Error("error authenticating client", "client_id", req.ClientID, "error", err)
70
+
logger.Error("error authenticating client", "client_id", req.ClientID, "error", err)
70
71
return helpers.InputError(e, to.StringPtr(err.Error()))
71
72
}
72
73
···
87
88
var authReq provider.OauthAuthorizationRequest
88
89
// get the lil guy and delete him
89
90
if err := s.db.Raw(ctx, "DELETE FROM oauth_authorization_requests WHERE code = ? RETURNING *", nil, *req.Code).Scan(&authReq).Error; err != nil {
90
-
s.logger.Error("error finding authorization request", "error", err)
91
+
logger.Error("error finding authorization request", "error", err)
91
92
return helpers.ServerError(e, nil)
92
93
}
93
94
···
112
113
case "S256":
113
114
inputChal, err := base64.RawURLEncoding.DecodeString(*authReq.Parameters.CodeChallenge)
114
115
if err != nil {
115
-
s.logger.Error("error decoding code challenge", "error", err)
116
+
logger.Error("error decoding code challenge", "error", err)
116
117
return helpers.ServerError(e, nil)
117
118
}
118
119
···
173
174
RefreshToken: refreshToken,
174
175
Ip: authReq.Ip,
175
176
}, nil).Error; err != nil {
176
-
s.logger.Error("error creating token in db", "error", err)
177
+
logger.Error("error creating token in db", "error", err)
177
178
return helpers.ServerError(e, nil)
178
179
}
179
180
···
202
203
203
204
var oauthToken provider.OauthToken
204
205
if err := s.db.Raw(ctx, "SELECT * FROM oauth_tokens WHERE refresh_token = ?", nil, req.RefreshToken).Scan(&oauthToken).Error; err != nil {
205
-
s.logger.Error("error finding oauth token by refresh token", "error", err, "refresh_token", req.RefreshToken)
206
+
logger.Error("error finding oauth token by refresh token", "error", err, "refresh_token", req.RefreshToken)
206
207
return helpers.ServerError(e, nil)
207
208
}
208
209
···
260
261
}
261
262
262
263
if err := s.db.Exec(ctx, "UPDATE oauth_tokens SET token = ?, refresh_token = ?, expires_at = ?, updated_at = ? WHERE refresh_token = ?", nil, accessString, nextRefreshToken, eat, now, *req.RefreshToken).Error; err != nil {
263
-
s.logger.Error("error updating token", "error", err)
264
+
logger.Error("error updating token", "error", err)
264
265
return helpers.ServerError(e, nil)
265
266
}
266
267
+6
-6
server/handle_proxy.go
+6
-6
server/handle_proxy.go
···
47
47
}
48
48
49
49
func (s *Server) handleProxy(e echo.Context) error {
50
-
lgr := s.logger.With("handler", "handleProxy")
50
+
logger := s.logger.With("handler", "handleProxy")
51
51
52
52
repo, isAuthed := e.Get("repo").(*models.RepoActor)
53
53
···
58
58
59
59
endpoint, svcDid, err := s.getAtprotoProxyEndpointFromRequest(e)
60
60
if err != nil {
61
-
lgr.Error("could not get atproto proxy", "error", err)
61
+
logger.Error("could not get atproto proxy", "error", err)
62
62
return helpers.ServerError(e, nil)
63
63
}
64
64
···
90
90
}
91
91
hj, err := json.Marshal(header)
92
92
if err != nil {
93
-
lgr.Error("error marshaling header", "error", err)
93
+
logger.Error("error marshaling header", "error", err)
94
94
return helpers.ServerError(e, nil)
95
95
}
96
96
···
118
118
}
119
119
pj, err := json.Marshal(payload)
120
120
if err != nil {
121
-
lgr.Error("error marashaling payload", "error", err)
121
+
logger.Error("error marashaling payload", "error", err)
122
122
return helpers.ServerError(e, nil)
123
123
}
124
124
···
129
129
130
130
sk, err := secp256k1secec.NewPrivateKey(repo.SigningKey)
131
131
if err != nil {
132
-
lgr.Error("can't load private key", "error", err)
132
+
logger.Error("can't load private key", "error", err)
133
133
return err
134
134
}
135
135
136
136
R, S, _, err := sk.SignRaw(rand.Reader, hash[:])
137
137
if err != nil {
138
-
lgr.Error("error signing", "error", err)
138
+
logger.Error("error signing", "error", err)
139
139
}
140
140
141
141
rBytes := R.Bytes()
+5
-4
server/handle_repo_apply_writes.go
+5
-4
server/handle_repo_apply_writes.go
···
27
27
28
28
func (s *Server) handleApplyWrites(e echo.Context) error {
29
29
ctx := e.Request().Context()
30
+
logger := s.logger.With("name", "handleRepoApplyWrites")
30
31
31
32
var req ComAtprotoRepoApplyWritesInput
32
33
if err := e.Bind(&req); err != nil {
33
-
s.logger.Error("error binding", "error", err)
34
+
logger.Error("error binding", "error", err)
34
35
return helpers.ServerError(e, nil)
35
36
}
36
37
37
38
if err := e.Validate(req); err != nil {
38
-
s.logger.Error("error validating", "error", err)
39
+
logger.Error("error validating", "error", err)
39
40
return helpers.InputError(e, nil)
40
41
}
41
42
42
43
repo := e.Get("repo").(*models.RepoActor)
43
44
44
45
if repo.Repo.Did != req.Repo {
45
-
s.logger.Warn("mismatched repo/auth")
46
+
logger.Warn("mismatched repo/auth")
46
47
return helpers.InputError(e, nil)
47
48
}
48
49
···
58
59
59
60
results, err := s.repoman.applyWrites(ctx, repo.Repo, ops, req.SwapCommit)
60
61
if err != nil {
61
-
s.logger.Error("error applying writes", "error", err)
62
+
logger.Error("error applying writes", "error", err)
62
63
return helpers.ServerError(e, nil)
63
64
}
64
65
+5
-4
server/handle_repo_create_record.go
+5
-4
server/handle_repo_create_record.go
···
18
18
19
19
func (s *Server) handleCreateRecord(e echo.Context) error {
20
20
ctx := e.Request().Context()
21
+
logger := s.logger.With("name", "handleCreateRecord")
21
22
22
23
repo := e.Get("repo").(*models.RepoActor)
23
24
24
25
var req ComAtprotoRepoCreateRecordInput
25
26
if err := e.Bind(&req); err != nil {
26
-
s.logger.Error("error binding", "error", err)
27
+
logger.Error("error binding", "error", err)
27
28
return helpers.ServerError(e, nil)
28
29
}
29
30
30
31
if err := e.Validate(req); err != nil {
31
-
s.logger.Error("error validating", "error", err)
32
+
logger.Error("error validating", "error", err)
32
33
return helpers.InputError(e, nil)
33
34
}
34
35
35
36
if repo.Repo.Did != req.Repo {
36
-
s.logger.Warn("mismatched repo/auth")
37
+
logger.Warn("mismatched repo/auth")
37
38
return helpers.InputError(e, nil)
38
39
}
39
40
···
53
54
},
54
55
}, req.SwapCommit)
55
56
if err != nil {
56
-
s.logger.Error("error applying writes", "error", err)
57
+
logger.Error("error applying writes", "error", err)
57
58
return helpers.ServerError(e, nil)
58
59
}
59
60
+5
-4
server/handle_repo_delete_record.go
+5
-4
server/handle_repo_delete_record.go
···
16
16
17
17
func (s *Server) handleDeleteRecord(e echo.Context) error {
18
18
ctx := e.Request().Context()
19
+
logger := s.logger.With("name", "handleDeleteRecord")
19
20
20
21
repo := e.Get("repo").(*models.RepoActor)
21
22
22
23
var req ComAtprotoRepoDeleteRecordInput
23
24
if err := e.Bind(&req); err != nil {
24
-
s.logger.Error("error binding", "error", err)
25
+
logger.Error("error binding", "error", err)
25
26
return helpers.ServerError(e, nil)
26
27
}
27
28
28
29
if err := e.Validate(req); err != nil {
29
-
s.logger.Error("error validating", "error", err)
30
+
logger.Error("error validating", "error", err)
30
31
return helpers.InputError(e, nil)
31
32
}
32
33
33
34
if repo.Repo.Did != req.Repo {
34
-
s.logger.Warn("mismatched repo/auth")
35
+
logger.Warn("mismatched repo/auth")
35
36
return helpers.InputError(e, nil)
36
37
}
37
38
···
44
45
},
45
46
}, req.SwapCommit)
46
47
if err != nil {
47
-
s.logger.Error("error applying writes", "error", err)
48
+
logger.Error("error applying writes", "error", err)
48
49
return helpers.ServerError(e, nil)
49
50
}
50
51
+4
-3
server/handle_repo_describe_repo.go
+4
-3
server/handle_repo_describe_repo.go
···
21
21
22
22
func (s *Server) handleDescribeRepo(e echo.Context) error {
23
23
ctx := e.Request().Context()
24
+
logger := s.logger.With("name", "handleDescribeRepo")
24
25
25
26
did := e.QueryParam("repo")
26
27
repo, err := s.getRepoActorByDid(ctx, did)
···
29
30
return helpers.InputError(e, to.StringPtr("RepoNotFound"))
30
31
}
31
32
32
-
s.logger.Error("error looking up repo", "error", err)
33
+
logger.Error("error looking up repo", "error", err)
33
34
return helpers.ServerError(e, nil)
34
35
}
35
36
···
37
38
38
39
diddoc, err := s.passport.FetchDoc(e.Request().Context(), repo.Repo.Did)
39
40
if err != nil {
40
-
s.logger.Error("error fetching diddoc", "error", err)
41
+
logger.Error("error fetching diddoc", "error", err)
41
42
return helpers.ServerError(e, nil)
42
43
}
43
44
···
67
68
68
69
var records []models.Record
69
70
if err := s.db.Raw(ctx, "SELECT DISTINCT(nsid) FROM records WHERE did = ?", nil, repo.Repo.Did).Scan(&records).Error; err != nil {
70
-
s.logger.Error("error getting collections", "error", err)
71
+
logger.Error("error getting collections", "error", err)
71
72
return helpers.ServerError(e, nil)
72
73
}
73
74
+2
-1
server/handle_repo_list_missing_blobs.go
+2
-1
server/handle_repo_list_missing_blobs.go
···
23
23
24
24
func (s *Server) handleListMissingBlobs(e echo.Context) error {
25
25
ctx := e.Request().Context()
26
+
logger := s.logger.With("name", "handleListMissingBlos")
26
27
27
28
urepo := e.Get("repo").(*models.RepoActor)
28
29
···
38
39
39
40
var records []models.Record
40
41
if err := s.db.Raw(ctx, "SELECT * FROM records WHERE did = ?", nil, urepo.Repo.Did).Scan(&records).Error; err != nil {
41
-
s.logger.Error("failed to get records for listMissingBlobs", "error", err)
42
+
logger.Error("failed to get records for listMissingBlobs", "error", err)
42
43
return helpers.ServerError(e, nil)
43
44
}
44
45
+3
-2
server/handle_repo_list_records.go
+3
-2
server/handle_repo_list_records.go
···
47
47
48
48
func (s *Server) handleListRecords(e echo.Context) error {
49
49
ctx := e.Request().Context()
50
+
logger := s.logger.With("name", "handleListRecords")
50
51
51
52
var req ComAtprotoRepoListRecordsRequest
52
53
if err := e.Bind(&req); err != nil {
53
-
s.logger.Error("could not bind list records request", "error", err)
54
+
logger.Error("could not bind list records request", "error", err)
54
55
return helpers.ServerError(e, nil)
55
56
}
56
57
···
96
97
97
98
var records []models.Record
98
99
if err := s.db.Raw(ctx, "SELECT * FROM records WHERE did = ? AND nsid = ? "+cursorquery+" ORDER BY created_at "+sort+" limit ?", nil, params...).Scan(&records).Error; err != nil {
99
-
s.logger.Error("error getting records", "error", err)
100
+
logger.Error("error getting records", "error", err)
100
101
return helpers.ServerError(e, nil)
101
102
}
102
103
+5
-4
server/handle_repo_put_record.go
+5
-4
server/handle_repo_put_record.go
···
18
18
19
19
func (s *Server) handlePutRecord(e echo.Context) error {
20
20
ctx := e.Request().Context()
21
+
logger := s.logger.With("name", "handlePutRecord")
21
22
22
23
repo := e.Get("repo").(*models.RepoActor)
23
24
24
25
var req ComAtprotoRepoPutRecordInput
25
26
if err := e.Bind(&req); err != nil {
26
-
s.logger.Error("error binding", "error", err)
27
+
logger.Error("error binding", "error", err)
27
28
return helpers.ServerError(e, nil)
28
29
}
29
30
30
31
if err := e.Validate(req); err != nil {
31
-
s.logger.Error("error validating", "error", err)
32
+
logger.Error("error validating", "error", err)
32
33
return helpers.InputError(e, nil)
33
34
}
34
35
35
36
if repo.Repo.Did != req.Repo {
36
-
s.logger.Warn("mismatched repo/auth")
37
+
logger.Warn("mismatched repo/auth")
37
38
return helpers.InputError(e, nil)
38
39
}
39
40
···
53
54
},
54
55
}, req.SwapCommit)
55
56
if err != nil {
56
-
s.logger.Error("error applying writes", "error", err)
57
+
logger.Error("error applying writes", "error", err)
57
58
return helpers.ServerError(e, nil)
58
59
}
59
60
+8
-7
server/handle_repo_upload_blob.go
+8
-7
server/handle_repo_upload_blob.go
···
33
33
34
34
func (s *Server) handleRepoUploadBlob(e echo.Context) error {
35
35
ctx := e.Request().Context()
36
+
logger := s.logger.With("name", "handleRepoUploadBlob")
36
37
37
38
urepo := e.Get("repo").(*models.RepoActor)
38
39
···
54
55
}
55
56
56
57
if err := s.db.Create(ctx, &blob, nil).Error; err != nil {
57
-
s.logger.Error("error creating new blob in db", "error", err)
58
+
logger.Error("error creating new blob in db", "error", err)
58
59
return helpers.ServerError(e, nil)
59
60
}
60
61
···
71
72
break
72
73
}
73
74
} else if err != nil && err != io.ErrUnexpectedEOF {
74
-
s.logger.Error("error reading blob", "error", err)
75
+
logger.Error("error reading blob", "error", err)
75
76
return helpers.ServerError(e, nil)
76
77
}
77
78
···
87
88
}
88
89
89
90
if err := s.db.Create(ctx, &blobPart, nil).Error; err != nil {
90
-
s.logger.Error("error adding blob part to db", "error", err)
91
+
logger.Error("error adding blob part to db", "error", err)
91
92
return helpers.ServerError(e, nil)
92
93
}
93
94
}
···
100
101
101
102
c, err := cid.NewPrefixV1(cid.Raw, multihash.SHA2_256).Sum(fulldata.Bytes())
102
103
if err != nil {
103
-
s.logger.Error("error creating cid prefix", "error", err)
104
+
logger.Error("error creating cid prefix", "error", err)
104
105
return helpers.ServerError(e, nil)
105
106
}
106
107
···
117
118
118
119
sess, err := session.NewSession(config)
119
120
if err != nil {
120
-
s.logger.Error("error creating aws session", "error", err)
121
+
logger.Error("error creating aws session", "error", err)
121
122
return helpers.ServerError(e, nil)
122
123
}
123
124
···
128
129
Key: aws.String(fmt.Sprintf("blobs/%s/%s", urepo.Repo.Did, c.String())),
129
130
Body: bytes.NewReader(fulldata.Bytes()),
130
131
}); err != nil {
131
-
s.logger.Error("error uploading blob to s3", "error", err)
132
+
logger.Error("error uploading blob to s3", "error", err)
132
133
return helpers.ServerError(e, nil)
133
134
}
134
135
}
135
136
136
137
if err := s.db.Exec(ctx, "UPDATE blobs SET cid = ? WHERE id = ?", nil, c.Bytes(), blob.ID).Error; err != nil {
137
138
// there should probably be somme handling here if this fails...
138
-
s.logger.Error("error updating blob", "error", err)
139
+
logger.Error("error updating blob", "error", err)
139
140
return helpers.ServerError(e, nil)
140
141
}
141
142
+3
-2
server/handle_server_activate_account.go
+3
-2
server/handle_server_activate_account.go
···
19
19
20
20
func (s *Server) handleServerActivateAccount(e echo.Context) error {
21
21
ctx := e.Request().Context()
22
+
logger := s.logger.With("name", "handleServerActivateAccount")
22
23
23
24
var req ComAtprotoServerDeactivateAccountRequest
24
25
if err := e.Bind(&req); err != nil {
25
-
s.logger.Error("error binding", "error", err)
26
+
logger.Error("error binding", "error", err)
26
27
return helpers.ServerError(e, nil)
27
28
}
28
29
29
30
urepo := e.Get("repo").(*models.RepoActor)
30
31
31
32
if err := s.db.Exec(ctx, "UPDATE repos SET deactivated = ? WHERE did = ?", nil, false, urepo.Repo.Did).Error; err != nil {
32
-
s.logger.Error("error updating account status to deactivated", "error", err)
33
+
logger.Error("error updating account status to deactivated", "error", err)
33
34
return helpers.ServerError(e, nil)
34
35
}
35
36
+5
-4
server/handle_server_check_account_status.go
+5
-4
server/handle_server_check_account_status.go
···
21
21
22
22
func (s *Server) handleServerCheckAccountStatus(e echo.Context) error {
23
23
ctx := e.Request().Context()
24
+
logger := s.logger.With("name", "handleServerCheckAccountStatus")
24
25
25
26
urepo := e.Get("repo").(*models.RepoActor)
26
27
···
33
34
34
35
rootcid, err := cid.Cast(urepo.Root)
35
36
if err != nil {
36
-
s.logger.Error("error casting cid", "error", err)
37
+
logger.Error("error casting cid", "error", err)
37
38
return helpers.ServerError(e, nil)
38
39
}
39
40
resp.RepoCommit = rootcid.String()
···
44
45
45
46
var blockCtResp CountResp
46
47
if err := s.db.Raw(ctx, "SELECT COUNT(*) AS ct FROM blocks WHERE did = ?", nil, urepo.Repo.Did).Scan(&blockCtResp).Error; err != nil {
47
-
s.logger.Error("error getting block count", "error", err)
48
+
logger.Error("error getting block count", "error", err)
48
49
return helpers.ServerError(e, nil)
49
50
}
50
51
resp.RepoBlocks = blockCtResp.Ct
51
52
52
53
var recCtResp CountResp
53
54
if err := s.db.Raw(ctx, "SELECT COUNT(*) AS ct FROM records WHERE did = ?", nil, urepo.Repo.Did).Scan(&recCtResp).Error; err != nil {
54
-
s.logger.Error("error getting record count", "error", err)
55
+
logger.Error("error getting record count", "error", err)
55
56
return helpers.ServerError(e, nil)
56
57
}
57
58
resp.IndexedRecords = recCtResp.Ct
58
59
59
60
var blobCtResp CountResp
60
61
if err := s.db.Raw(ctx, "SELECT COUNT(*) AS ct FROM blobs WHERE did = ?", nil, urepo.Repo.Did).Scan(&blobCtResp).Error; err != nil {
61
-
s.logger.Error("error getting record count", "error", err)
62
+
logger.Error("error getting record count", "error", err)
62
63
return helpers.ServerError(e, nil)
63
64
}
64
65
resp.ExpectedBlobs = blobCtResp.Ct
+3
-2
server/handle_server_confirm_email.go
+3
-2
server/handle_server_confirm_email.go
···
16
16
17
17
func (s *Server) handleServerConfirmEmail(e echo.Context) error {
18
18
ctx := e.Request().Context()
19
+
logger := s.logger.With("name", "handleServerConfirmEmail")
19
20
20
21
urepo := e.Get("repo").(*models.RepoActor)
21
22
22
23
var req ComAtprotoServerConfirmEmailRequest
23
24
if err := e.Bind(&req); err != nil {
24
-
s.logger.Error("error binding", "error", err)
25
+
logger.Error("error binding", "error", err)
25
26
return helpers.ServerError(e, nil)
26
27
}
27
28
···
44
45
now := time.Now().UTC()
45
46
46
47
if err := s.db.Exec(ctx, "UPDATE repos SET email_verification_code = NULL, email_verification_code_expires_at = NULL, email_confirmed_at = ? WHERE did = ?", nil, now, urepo.Repo.Did).Error; err != nil {
47
-
s.logger.Error("error updating user", "error", err)
48
+
logger.Error("error updating user", "error", err)
48
49
return helpers.ServerError(e, nil)
49
50
}
50
51
+23
-22
server/handle_server_create_account.go
+23
-22
server/handle_server_create_account.go
···
37
37
38
38
func (s *Server) handleCreateAccount(e echo.Context) error {
39
39
ctx := e.Request().Context()
40
+
logger := s.logger.With("name", "handleServerCreateAccount")
40
41
41
42
var request ComAtprotoServerCreateAccountRequest
42
43
43
44
if err := e.Bind(&request); err != nil {
44
-
s.logger.Error("error receiving request", "endpoint", "com.atproto.server.createAccount", "error", err)
45
+
logger.Error("error receiving request", "endpoint", "com.atproto.server.createAccount", "error", err)
45
46
return helpers.ServerError(e, nil)
46
47
}
47
48
48
49
request.Handle = strings.ToLower(request.Handle)
49
50
50
51
if err := e.Validate(request); err != nil {
51
-
s.logger.Error("error validating request", "endpoint", "com.atproto.server.createAccount", "error", err)
52
+
logger.Error("error validating request", "endpoint", "com.atproto.server.createAccount", "error", err)
52
53
53
54
var verr ValidationError
54
55
if errors.As(err, &verr) {
···
82
83
authDid, err := s.validateServiceAuth(e.Request().Context(), token, "com.atproto.server.createAccount")
83
84
84
85
if err != nil {
85
-
s.logger.Warn("error validating authorization token", "endpoint", "com.atproto.server.createAccount", "error", err)
86
+
logger.Warn("error validating authorization token", "endpoint", "com.atproto.server.createAccount", "error", err)
86
87
return helpers.UnauthorizedError(e, to.StringPtr("invalid authorization token"))
87
88
}
88
89
···
94
95
// see if the handle is already taken
95
96
actor, err := s.getActorByHandle(ctx, request.Handle)
96
97
if err != nil && err != gorm.ErrRecordNotFound {
97
-
s.logger.Error("error looking up handle in db", "endpoint", "com.atproto.server.createAccount", "error", err)
98
+
logger.Error("error looking up handle in db", "endpoint", "com.atproto.server.createAccount", "error", err)
98
99
return helpers.ServerError(e, nil)
99
100
}
100
101
if err == nil && actor.Did != signupDid {
···
115
116
if err == gorm.ErrRecordNotFound {
116
117
return helpers.InputError(e, to.StringPtr("InvalidInviteCode"))
117
118
}
118
-
s.logger.Error("error getting invite code from db", "error", err)
119
+
logger.Error("error getting invite code from db", "error", err)
119
120
return helpers.ServerError(e, nil)
120
121
}
121
122
···
127
128
// see if the email is already taken
128
129
existingRepo, err := s.getRepoByEmail(ctx, request.Email)
129
130
if err != nil && err != gorm.ErrRecordNotFound {
130
-
s.logger.Error("error looking up email in db", "endpoint", "com.atproto.server.createAccount", "error", err)
131
+
logger.Error("error looking up email in db", "endpoint", "com.atproto.server.createAccount", "error", err)
131
132
return helpers.ServerError(e, nil)
132
133
}
133
134
if err == nil && existingRepo.Did != signupDid {
···
141
142
if signupDid != "" {
142
143
reservedKey, err := s.getReservedKey(ctx, signupDid)
143
144
if err != nil {
144
-
s.logger.Error("error looking up reserved key", "error", err)
145
+
logger.Error("error looking up reserved key", "error", err)
145
146
}
146
147
if reservedKey != nil {
147
148
k, err = atcrypto.ParsePrivateBytesK256(reservedKey.PrivateKey)
148
149
if err != nil {
149
-
s.logger.Error("error parsing reserved key", "error", err)
150
+
logger.Error("error parsing reserved key", "error", err)
150
151
k = nil
151
152
} else {
152
153
defer func() {
153
154
if delErr := s.deleteReservedKey(ctx, reservedKey.KeyDid, reservedKey.Did); delErr != nil {
154
-
s.logger.Error("error deleting reserved key", "error", delErr)
155
+
logger.Error("error deleting reserved key", "error", delErr)
155
156
}
156
157
}()
157
158
}
···
161
162
if k == nil {
162
163
k, err = atcrypto.GeneratePrivateKeyK256()
163
164
if err != nil {
164
-
s.logger.Error("error creating signing key", "endpoint", "com.atproto.server.createAccount", "error", err)
165
+
logger.Error("error creating signing key", "endpoint", "com.atproto.server.createAccount", "error", err)
165
166
return helpers.ServerError(e, nil)
166
167
}
167
168
}
···
169
170
if signupDid == "" {
170
171
did, op, err := s.plcClient.CreateDID(k, "", request.Handle)
171
172
if err != nil {
172
-
s.logger.Error("error creating operation", "endpoint", "com.atproto.server.createAccount", "error", err)
173
+
logger.Error("error creating operation", "endpoint", "com.atproto.server.createAccount", "error", err)
173
174
return helpers.ServerError(e, nil)
174
175
}
175
176
176
177
if err := s.plcClient.SendOperation(e.Request().Context(), did, op); err != nil {
177
-
s.logger.Error("error sending plc op", "endpoint", "com.atproto.server.createAccount", "error", err)
178
+
logger.Error("error sending plc op", "endpoint", "com.atproto.server.createAccount", "error", err)
178
179
return helpers.ServerError(e, nil)
179
180
}
180
181
signupDid = did
···
182
183
183
184
hashed, err := bcrypt.GenerateFromPassword([]byte(request.Password), 10)
184
185
if err != nil {
185
-
s.logger.Error("error hashing password", "error", err)
186
+
logger.Error("error hashing password", "error", err)
186
187
return helpers.ServerError(e, nil)
187
188
}
188
189
···
202
203
}
203
204
204
205
if err := s.db.Create(ctx, &urepo, nil).Error; err != nil {
205
-
s.logger.Error("error inserting new repo", "error", err)
206
+
logger.Error("error inserting new repo", "error", err)
206
207
return helpers.ServerError(e, nil)
207
208
}
208
209
209
210
if err := s.db.Create(ctx, &actor, nil).Error; err != nil {
210
-
s.logger.Error("error inserting new actor", "error", err)
211
+
logger.Error("error inserting new actor", "error", err)
211
212
return helpers.ServerError(e, nil)
212
213
}
213
214
} else {
214
215
if err := s.db.Save(ctx, &actor, nil).Error; err != nil {
215
-
s.logger.Error("error inserting new actor", "error", err)
216
+
logger.Error("error inserting new actor", "error", err)
216
217
return helpers.ServerError(e, nil)
217
218
}
218
219
}
···
223
224
224
225
root, rev, err := r.Commit(context.TODO(), urepo.SignFor)
225
226
if err != nil {
226
-
s.logger.Error("error committing", "error", err)
227
+
logger.Error("error committing", "error", err)
227
228
return helpers.ServerError(e, nil)
228
229
}
229
230
230
231
if err := s.UpdateRepo(context.TODO(), urepo.Did, root, rev); err != nil {
231
-
s.logger.Error("error updating repo after commit", "error", err)
232
+
logger.Error("error updating repo after commit", "error", err)
232
233
return helpers.ServerError(e, nil)
233
234
}
234
235
···
244
245
245
246
if s.config.RequireInvite {
246
247
if err := s.db.Raw(ctx, "UPDATE invite_codes SET remaining_use_count = remaining_use_count - 1 WHERE code = ?", nil, request.InviteCode).Scan(&ic).Error; err != nil {
247
-
s.logger.Error("error decrementing use count", "error", err)
248
+
logger.Error("error decrementing use count", "error", err)
248
249
return helpers.ServerError(e, nil)
249
250
}
250
251
}
251
252
252
253
sess, err := s.createSession(ctx, &urepo)
253
254
if err != nil {
254
-
s.logger.Error("error creating new session", "error", err)
255
+
logger.Error("error creating new session", "error", err)
255
256
return helpers.ServerError(e, nil)
256
257
}
257
258
258
259
go func() {
259
260
if err := s.sendEmailVerification(urepo.Email, actor.Handle, *urepo.EmailVerificationCode); err != nil {
260
-
s.logger.Error("error sending email verification email", "error", err)
261
+
logger.Error("error sending email verification email", "error", err)
261
262
}
262
263
if err := s.sendWelcomeMail(urepo.Email, actor.Handle); err != nil {
263
-
s.logger.Error("error sending welcome email", "error", err)
264
+
logger.Error("error sending welcome email", "error", err)
264
265
}
265
266
}()
266
267
+4
-3
server/handle_server_create_invite_code.go
+4
-3
server/handle_server_create_invite_code.go
···
18
18
19
19
func (s *Server) handleCreateInviteCode(e echo.Context) error {
20
20
ctx := e.Request().Context()
21
+
logger := s.logger.With("name", "handleServerCreateInviteCode")
21
22
22
23
var req ComAtprotoServerCreateInviteCodeRequest
23
24
if err := e.Bind(&req); err != nil {
24
-
s.logger.Error("error binding", "error", err)
25
+
logger.Error("error binding", "error", err)
25
26
return helpers.ServerError(e, nil)
26
27
}
27
28
28
29
if err := e.Validate(req); err != nil {
29
-
s.logger.Error("error validating", "error", err)
30
+
logger.Error("error validating", "error", err)
30
31
return helpers.InputError(e, nil)
31
32
}
32
33
···
44
45
Did: acc,
45
46
RemainingUseCount: req.UseCount,
46
47
}, nil).Error; err != nil {
47
-
s.logger.Error("error creating invite code", "error", err)
48
+
logger.Error("error creating invite code", "error", err)
48
49
return helpers.ServerError(e, nil)
49
50
}
50
51
+4
-3
server/handle_server_create_invite_codes.go
+4
-3
server/handle_server_create_invite_codes.go
···
23
23
24
24
func (s *Server) handleCreateInviteCodes(e echo.Context) error {
25
25
ctx := e.Request().Context()
26
+
logger := s.logger.With("name", "handleServerCreateInviteCodes")
26
27
27
28
var req ComAtprotoServerCreateInviteCodesRequest
28
29
if err := e.Bind(&req); err != nil {
29
-
s.logger.Error("error binding", "error", err)
30
+
logger.Error("error binding", "error", err)
30
31
return helpers.ServerError(e, nil)
31
32
}
32
33
33
34
if err := e.Validate(req); err != nil {
34
-
s.logger.Error("error validating", "error", err)
35
+
logger.Error("error validating", "error", err)
35
36
return helpers.InputError(e, nil)
36
37
}
37
38
···
57
58
Did: did,
58
59
RemainingUseCount: req.UseCount,
59
60
}, nil).Error; err != nil {
60
-
s.logger.Error("error creating invite code", "error", err)
61
+
logger.Error("error creating invite code", "error", err)
61
62
return helpers.ServerError(e, nil)
62
63
}
63
64
}
+5
-4
server/handle_server_create_session.go
+5
-4
server/handle_server_create_session.go
···
36
36
37
37
func (s *Server) handleCreateSession(e echo.Context) error {
38
38
ctx := e.Request().Context()
39
+
logger := s.logger.With("name", "handleServerCreateSession")
39
40
40
41
var req ComAtprotoServerCreateSessionRequest
41
42
if err := e.Bind(&req); err != nil {
42
-
s.logger.Error("error binding request", "endpoint", "com.atproto.server.serverCreateSession", "error", err)
43
+
logger.Error("error binding request", "endpoint", "com.atproto.server.serverCreateSession", "error", err)
43
44
return helpers.ServerError(e, nil)
44
45
}
45
46
···
82
83
return helpers.InputError(e, to.StringPtr("InvalidRequest"))
83
84
}
84
85
85
-
s.logger.Error("erorr looking up repo", "endpoint", "com.atproto.server.createSession", "error", err)
86
+
logger.Error("erorr looking up repo", "endpoint", "com.atproto.server.createSession", "error", err)
86
87
return helpers.ServerError(e, nil)
87
88
}
88
89
89
90
if err := bcrypt.CompareHashAndPassword([]byte(repo.Password), []byte(req.Password)); err != nil {
90
91
if err != bcrypt.ErrMismatchedHashAndPassword {
91
-
s.logger.Error("erorr comparing hash and password", "error", err)
92
+
logger.Error("erorr comparing hash and password", "error", err)
92
93
}
93
94
return helpers.InputError(e, to.StringPtr("InvalidRequest"))
94
95
}
···
127
128
128
129
sess, err := s.createSession(ctx, &repo.Repo)
129
130
if err != nil {
130
-
s.logger.Error("error creating session", "error", err)
131
+
logger.Error("error creating session", "error", err)
131
132
return helpers.ServerError(e, nil)
132
133
}
133
134
+3
-2
server/handle_server_deactivate_account.go
+3
-2
server/handle_server_deactivate_account.go
···
20
20
21
21
func (s *Server) handleServerDeactivateAccount(e echo.Context) error {
22
22
ctx := e.Request().Context()
23
+
logger := s.logger.With("name", "handleServerDeactivateAccount")
23
24
24
25
var req ComAtprotoServerDeactivateAccountRequest
25
26
if err := e.Bind(&req); err != nil {
26
-
s.logger.Error("error binding", "error", err)
27
+
logger.Error("error binding", "error", err)
27
28
return helpers.ServerError(e, nil)
28
29
}
29
30
30
31
urepo := e.Get("repo").(*models.RepoActor)
31
32
32
33
if err := s.db.Exec(ctx, "UPDATE repos SET deactivated = ? WHERE did = ?", nil, true, urepo.Repo.Did).Error; err != nil {
33
-
s.logger.Error("error updating account status to deactivated", "error", err)
34
+
logger.Error("error updating account status to deactivated", "error", err)
34
35
return helpers.ServerError(e, nil)
35
36
}
36
37
+30
-27
server/handle_server_delete_account.go
+30
-27
server/handle_server_delete_account.go
···
21
21
22
22
func (s *Server) handleServerDeleteAccount(e echo.Context) error {
23
23
ctx := e.Request().Context()
24
+
logger := s.logger.With("name", "handleServerDeleteAccount")
24
25
25
26
var req ComAtprotoServerDeleteAccountRequest
26
27
if err := e.Bind(&req); err != nil {
27
-
s.logger.Error("error binding", "error", err)
28
+
logger.Error("error binding", "error", err)
28
29
return helpers.ServerError(e, nil)
29
30
}
30
31
31
32
if err := e.Validate(&req); err != nil {
32
-
s.logger.Error("error validating", "error", err)
33
+
logger.Error("error validating", "error", err)
33
34
return helpers.ServerError(e, nil)
34
35
}
35
36
36
37
urepo, err := s.getRepoActorByDid(ctx, req.Did)
37
38
if err != nil {
38
-
s.logger.Error("error getting repo", "error", err)
39
+
logger.Error("error getting repo", "error", err)
39
40
return echo.NewHTTPError(400, "account not found")
40
41
}
41
42
42
43
if err := bcrypt.CompareHashAndPassword([]byte(urepo.Repo.Password), []byte(req.Password)); err != nil {
43
-
s.logger.Error("password mismatch", "error", err)
44
+
logger.Error("password mismatch", "error", err)
44
45
return echo.NewHTTPError(401, "Invalid did or password")
45
46
}
46
47
47
48
if urepo.Repo.AccountDeleteCode == nil || urepo.Repo.AccountDeleteCodeExpiresAt == nil {
48
-
s.logger.Error("no deletion token found for account")
49
+
logger.Error("no deletion token found for account")
49
50
return echo.NewHTTPError(400, map[string]interface{}{
50
51
"error": "InvalidToken",
51
52
"message": "Token is invalid",
···
53
54
}
54
55
55
56
if *urepo.Repo.AccountDeleteCode != req.Token {
56
-
s.logger.Error("deletion token mismatch")
57
+
logger.Error("deletion token mismatch")
57
58
return echo.NewHTTPError(400, map[string]interface{}{
58
59
"error": "InvalidToken",
59
60
"message": "Token is invalid",
···
61
62
}
62
63
63
64
if time.Now().UTC().After(*urepo.Repo.AccountDeleteCodeExpiresAt) {
64
-
s.logger.Error("deletion token expired")
65
+
logger.Error("deletion token expired")
65
66
return echo.NewHTTPError(400, map[string]interface{}{
66
67
"error": "ExpiredToken",
67
68
"message": "Token is expired",
···
70
71
71
72
tx := s.db.BeginDangerously(ctx)
72
73
if tx.Error != nil {
73
-
s.logger.Error("error starting transaction", "error", tx.Error)
74
+
logger.Error("error starting transaction", "error", tx.Error)
74
75
return helpers.ServerError(e, nil)
75
76
}
76
77
78
+
status := "error"
79
+
func() {
80
+
if status == "error" {
81
+
if err := tx.Rollback().Error; err != nil {
82
+
logger.Error("error rolling back after delete failure", "err", err)
83
+
}
84
+
}
85
+
}()
86
+
77
87
if err := tx.Exec("DELETE FROM blocks WHERE did = ?", nil, req.Did).Error; err != nil {
78
-
tx.Rollback()
79
-
s.logger.Error("error deleting blocks", "error", err)
88
+
logger.Error("error deleting blocks", "error", err)
80
89
return helpers.ServerError(e, nil)
81
90
}
82
91
83
92
if err := tx.Exec("DELETE FROM records WHERE did = ?", nil, req.Did).Error; err != nil {
84
-
tx.Rollback()
85
-
s.logger.Error("error deleting records", "error", err)
93
+
logger.Error("error deleting records", "error", err)
86
94
return helpers.ServerError(e, nil)
87
95
}
88
96
89
97
if err := tx.Exec("DELETE FROM blobs WHERE did = ?", nil, req.Did).Error; err != nil {
90
-
tx.Rollback()
91
-
s.logger.Error("error deleting blobs", "error", err)
98
+
logger.Error("error deleting blobs", "error", err)
92
99
return helpers.ServerError(e, nil)
93
100
}
94
101
95
102
if err := tx.Exec("DELETE FROM tokens WHERE did = ?", nil, req.Did).Error; err != nil {
96
-
tx.Rollback()
97
-
s.logger.Error("error deleting tokens", "error", err)
103
+
logger.Error("error deleting tokens", "error", err)
98
104
return helpers.ServerError(e, nil)
99
105
}
100
106
101
107
if err := tx.Exec("DELETE FROM refresh_tokens WHERE did = ?", nil, req.Did).Error; err != nil {
102
-
tx.Rollback()
103
-
s.logger.Error("error deleting refresh tokens", "error", err)
108
+
logger.Error("error deleting refresh tokens", "error", err)
104
109
return helpers.ServerError(e, nil)
105
110
}
106
111
107
112
if err := tx.Exec("DELETE FROM reserved_keys WHERE did = ?", nil, req.Did).Error; err != nil {
108
-
tx.Rollback()
109
-
s.logger.Error("error deleting reserved keys", "error", err)
113
+
logger.Error("error deleting reserved keys", "error", err)
110
114
return helpers.ServerError(e, nil)
111
115
}
112
116
113
117
if err := tx.Exec("DELETE FROM invite_codes WHERE did = ?", nil, req.Did).Error; err != nil {
114
-
tx.Rollback()
115
-
s.logger.Error("error deleting invite codes", "error", err)
118
+
logger.Error("error deleting invite codes", "error", err)
116
119
return helpers.ServerError(e, nil)
117
120
}
118
121
119
122
if err := tx.Exec("DELETE FROM actors WHERE did = ?", nil, req.Did).Error; err != nil {
120
-
tx.Rollback()
121
-
s.logger.Error("error deleting actor", "error", err)
123
+
logger.Error("error deleting actor", "error", err)
122
124
return helpers.ServerError(e, nil)
123
125
}
124
126
125
127
if err := tx.Exec("DELETE FROM repos WHERE did = ?", nil, req.Did).Error; err != nil {
126
-
tx.Rollback()
127
-
s.logger.Error("error deleting repo", "error", err)
128
+
logger.Error("error deleting repo", "error", err)
128
129
return helpers.ServerError(e, nil)
129
130
}
130
131
132
+
status = "ok"
133
+
131
134
if err := tx.Commit().Error; err != nil {
132
-
s.logger.Error("error committing transaction", "error", err)
135
+
logger.Error("error committing transaction", "error", err)
133
136
return helpers.ServerError(e, nil)
134
137
}
135
138
+7
-5
server/handle_server_get_service_auth.go
+7
-5
server/handle_server_get_service_auth.go
···
25
25
}
26
26
27
27
func (s *Server) handleServerGetServiceAuth(e echo.Context) error {
28
+
logger := s.logger.With("name", "handleServerGetServiceAuth")
29
+
28
30
var req ServerGetServiceAuthRequest
29
31
if err := e.Bind(&req); err != nil {
30
-
s.logger.Error("could not bind service auth request", "error", err)
32
+
logger.Error("could not bind service auth request", "error", err)
31
33
return helpers.ServerError(e, nil)
32
34
}
33
35
···
64
66
}
65
67
hj, err := json.Marshal(header)
66
68
if err != nil {
67
-
s.logger.Error("error marshaling header", "error", err)
69
+
logger.Error("error marshaling header", "error", err)
68
70
return helpers.ServerError(e, nil)
69
71
}
70
72
···
82
84
}
83
85
pj, err := json.Marshal(payload)
84
86
if err != nil {
85
-
s.logger.Error("error marashaling payload", "error", err)
87
+
logger.Error("error marashaling payload", "error", err)
86
88
return helpers.ServerError(e, nil)
87
89
}
88
90
···
93
95
94
96
sk, err := secp256k1secec.NewPrivateKey(repo.SigningKey)
95
97
if err != nil {
96
-
s.logger.Error("can't load private key", "error", err)
98
+
logger.Error("can't load private key", "error", err)
97
99
return err
98
100
}
99
101
100
102
R, S, _, err := sk.SignRaw(rand.Reader, hash[:])
101
103
if err != nil {
102
-
s.logger.Error("error signing", "error", err)
104
+
logger.Error("error signing", "error", err)
103
105
return helpers.ServerError(e, nil)
104
106
}
105
107
+4
-3
server/handle_server_refresh_session.go
+4
-3
server/handle_server_refresh_session.go
···
17
17
18
18
func (s *Server) handleRefreshSession(e echo.Context) error {
19
19
ctx := e.Request().Context()
20
+
logger := s.logger.With("name", "handleServerRefreshSession")
20
21
21
22
token := e.Get("token").(string)
22
23
repo := e.Get("repo").(*models.RepoActor)
23
24
24
25
if err := s.db.Exec(ctx, "DELETE FROM refresh_tokens WHERE token = ?", nil, token).Error; err != nil {
25
-
s.logger.Error("error getting refresh token from db", "error", err)
26
+
logger.Error("error getting refresh token from db", "error", err)
26
27
return helpers.ServerError(e, nil)
27
28
}
28
29
29
30
if err := s.db.Exec(ctx, "DELETE FROM tokens WHERE refresh_token = ?", nil, token).Error; err != nil {
30
-
s.logger.Error("error deleting access token from db", "error", err)
31
+
logger.Error("error deleting access token from db", "error", err)
31
32
return helpers.ServerError(e, nil)
32
33
}
33
34
34
35
sess, err := s.createSession(ctx, &repo.Repo)
35
36
if err != nil {
36
-
s.logger.Error("error creating new session for refresh", "error", err)
37
+
logger.Error("error creating new session for refresh", "error", err)
37
38
return helpers.ServerError(e, nil)
38
39
}
39
40
+3
-2
server/handle_server_request_account_delete.go
+3
-2
server/handle_server_request_account_delete.go
···
11
11
12
12
func (s *Server) handleServerRequestAccountDelete(e echo.Context) error {
13
13
ctx := e.Request().Context()
14
+
logger := s.logger.With("name", "handleServerRequestAccountDelete")
14
15
15
16
urepo := e.Get("repo").(*models.RepoActor)
16
17
···
18
19
expiresAt := time.Now().UTC().Add(15 * time.Minute)
19
20
20
21
if err := s.db.Exec(ctx, "UPDATE repos SET account_delete_code = ?, account_delete_code_expires_at = ? WHERE did = ?", nil, token, expiresAt, urepo.Repo.Did).Error; err != nil {
21
-
s.logger.Error("error setting deletion token", "error", err)
22
+
logger.Error("error setting deletion token", "error", err)
22
23
return helpers.ServerError(e, nil)
23
24
}
24
25
25
26
if urepo.Email != "" {
26
27
if err := s.sendAccountDeleteEmail(urepo.Email, urepo.Actor.Handle, token); err != nil {
27
-
s.logger.Error("error sending account deletion email", "error", err)
28
+
logger.Error("error sending account deletion email", "error", err)
28
29
}
29
30
}
30
31
+3
-2
server/handle_server_request_email_confirmation.go
+3
-2
server/handle_server_request_email_confirmation.go
···
12
12
13
13
func (s *Server) handleServerRequestEmailConfirmation(e echo.Context) error {
14
14
ctx := e.Request().Context()
15
+
logger := s.logger.With("name", "handleServerRequestEmailConfirm")
15
16
16
17
urepo := e.Get("repo").(*models.RepoActor)
17
18
···
23
24
eat := time.Now().Add(10 * time.Minute).UTC()
24
25
25
26
if err := s.db.Exec(ctx, "UPDATE repos SET email_verification_code = ?, email_verification_code_expires_at = ? WHERE did = ?", nil, code, eat, urepo.Repo.Did).Error; err != nil {
26
-
s.logger.Error("error updating user", "error", err)
27
+
logger.Error("error updating user", "error", err)
27
28
return helpers.ServerError(e, nil)
28
29
}
29
30
30
31
if err := s.sendEmailVerification(urepo.Email, urepo.Handle, code); err != nil {
31
-
s.logger.Error("error sending mail", "error", err)
32
+
logger.Error("error sending mail", "error", err)
32
33
return helpers.ServerError(e, nil)
33
34
}
34
35
+3
-2
server/handle_server_request_email_update.go
+3
-2
server/handle_server_request_email_update.go
···
15
15
16
16
func (s *Server) handleServerRequestEmailUpdate(e echo.Context) error {
17
17
ctx := e.Request().Context()
18
+
logger := s.logger.With("name", "handleServerRequestEmailUpdate")
18
19
19
20
urepo := e.Get("repo").(*models.RepoActor)
20
21
···
23
24
eat := time.Now().Add(10 * time.Minute).UTC()
24
25
25
26
if err := s.db.Exec(ctx, "UPDATE repos SET email_update_code = ?, email_update_code_expires_at = ? WHERE did = ?", nil, code, eat, urepo.Repo.Did).Error; err != nil {
26
-
s.logger.Error("error updating repo", "error", err)
27
+
logger.Error("error updating repo", "error", err)
27
28
return helpers.ServerError(e, nil)
28
29
}
29
30
30
31
if err := s.sendEmailUpdate(urepo.Email, urepo.Handle, code); err != nil {
31
-
s.logger.Error("error sending email", "error", err)
32
+
logger.Error("error sending email", "error", err)
32
33
return helpers.ServerError(e, nil)
33
34
}
34
35
}
+3
-2
server/handle_server_request_password_reset.go
+3
-2
server/handle_server_request_password_reset.go
···
15
15
16
16
func (s *Server) handleServerRequestPasswordReset(e echo.Context) error {
17
17
ctx := e.Request().Context()
18
+
logger := s.logger.With("name", "handleServerRequestPasswordReset")
18
19
19
20
urepo, ok := e.Get("repo").(*models.RepoActor)
20
21
if !ok {
···
39
40
eat := time.Now().Add(10 * time.Minute).UTC()
40
41
41
42
if err := s.db.Exec(ctx, "UPDATE repos SET password_reset_code = ?, password_reset_code_expires_at = ? WHERE did = ?", nil, code, eat, urepo.Repo.Did).Error; err != nil {
42
-
s.logger.Error("error updating repo", "error", err)
43
+
logger.Error("error updating repo", "error", err)
43
44
return helpers.ServerError(e, nil)
44
45
}
45
46
46
47
if err := s.sendPasswordReset(urepo.Email, urepo.Handle, code); err != nil {
47
-
s.logger.Error("error sending email", "error", err)
48
+
logger.Error("error sending email", "error", err)
48
49
return helpers.ServerError(e, nil)
49
50
}
50
51
+6
-5
server/handle_server_reserve_signing_key.go
+6
-5
server/handle_server_reserve_signing_key.go
···
20
20
21
21
func (s *Server) handleServerReserveSigningKey(e echo.Context) error {
22
22
ctx := e.Request().Context()
23
+
logger := s.logger.With("name", "handleServerReserveSigningKey")
23
24
24
25
var req ServerReserveSigningKeyRequest
25
26
if err := e.Bind(&req); err != nil {
26
-
s.logger.Error("could not bind reserve signing key request", "error", err)
27
+
logger.Error("could not bind reserve signing key request", "error", err)
27
28
return helpers.ServerError(e, nil)
28
29
}
29
30
···
38
39
39
40
k, err := atcrypto.GeneratePrivateKeyK256()
40
41
if err != nil {
41
-
s.logger.Error("error creating signing key", "endpoint", "com.atproto.server.reserveSigningKey", "error", err)
42
+
logger.Error("error creating signing key", "endpoint", "com.atproto.server.reserveSigningKey", "error", err)
42
43
return helpers.ServerError(e, nil)
43
44
}
44
45
45
46
pubKey, err := k.PublicKey()
46
47
if err != nil {
47
-
s.logger.Error("error getting public key", "endpoint", "com.atproto.server.reserveSigningKey", "error", err)
48
+
logger.Error("error getting public key", "endpoint", "com.atproto.server.reserveSigningKey", "error", err)
48
49
return helpers.ServerError(e, nil)
49
50
}
50
51
···
58
59
}
59
60
60
61
if err := s.db.Create(ctx, &reservedKey, nil).Error; err != nil {
61
-
s.logger.Error("error storing reserved key", "endpoint", "com.atproto.server.reserveSigningKey", "error", err)
62
+
logger.Error("error storing reserved key", "endpoint", "com.atproto.server.reserveSigningKey", "error", err)
62
63
return helpers.ServerError(e, nil)
63
64
}
64
65
65
-
s.logger.Info("reserved signing key", "keyDid", keyDid, "forDid", req.Did)
66
+
logger.Info("reserved signing key", "keyDid", keyDid, "forDid", req.Did)
66
67
67
68
return e.JSON(200, ServerReserveSigningKeyResponse{
68
69
SigningKey: keyDid,
+4
-3
server/handle_server_reset_password.go
+4
-3
server/handle_server_reset_password.go
···
17
17
18
18
func (s *Server) handleServerResetPassword(e echo.Context) error {
19
19
ctx := e.Request().Context()
20
+
logger := s.logger.With("name", "handleServerResetPassword")
20
21
21
22
urepo := e.Get("repo").(*models.RepoActor)
22
23
23
24
var req ComAtprotoServerResetPasswordRequest
24
25
if err := e.Bind(&req); err != nil {
25
-
s.logger.Error("error binding", "error", err)
26
+
logger.Error("error binding", "error", err)
26
27
return helpers.ServerError(e, nil)
27
28
}
28
29
···
44
45
45
46
hash, err := bcrypt.GenerateFromPassword([]byte(req.Password), 10)
46
47
if err != nil {
47
-
s.logger.Error("error creating hash", "error", err)
48
+
logger.Error("error creating hash", "error", err)
48
49
return helpers.ServerError(e, nil)
49
50
}
50
51
51
52
if err := s.db.Exec(ctx, "UPDATE repos SET password_reset_code = NULL, password_reset_code_expires_at = NULL, password = ? WHERE did = ?", nil, hash, urepo.Repo.Did).Error; err != nil {
52
-
s.logger.Error("error updating repo", "error", err)
53
+
logger.Error("error updating repo", "error", err)
53
54
return helpers.ServerError(e, nil)
54
55
}
55
56
+3
-1
server/handle_server_resolve_handle.go
+3
-1
server/handle_server_resolve_handle.go
···
10
10
)
11
11
12
12
func (s *Server) handleResolveHandle(e echo.Context) error {
13
+
logger := s.logger.With("name", "handleServerResolveHandle")
14
+
13
15
type Resp struct {
14
16
Did string `json:"did"`
15
17
}
···
28
30
ctx := context.WithValue(e.Request().Context(), "skip-cache", true)
29
31
did, err := s.passport.ResolveHandle(ctx, parsed.String())
30
32
if err != nil {
31
-
s.logger.Error("error resolving handle", "error", err)
33
+
logger.Error("error resolving handle", "error", err)
32
34
return helpers.ServerError(e, nil)
33
35
}
34
36
+3
-2
server/handle_server_update_email.go
+3
-2
server/handle_server_update_email.go
···
16
16
17
17
func (s *Server) handleServerUpdateEmail(e echo.Context) error {
18
18
ctx := e.Request().Context()
19
+
logger := s.logger.With("name", "handleServerUpdateEmail")
19
20
20
21
urepo := e.Get("repo").(*models.RepoActor)
21
22
22
23
var req ComAtprotoServerUpdateEmailRequest
23
24
if err := e.Bind(&req); err != nil {
24
-
s.logger.Error("error binding", "error", err)
25
+
logger.Error("error binding", "error", err)
25
26
return helpers.ServerError(e, nil)
26
27
}
27
28
···
64
65
query += " WHERE did = ?"
65
66
66
67
if err := s.db.Exec(ctx, query, nil, twoFactorType, req.Email, urepo.Repo.Did).Error; err != nil {
67
-
s.logger.Error("error updating repo", "error", err)
68
+
logger.Error("error updating repo", "error", err)
68
69
return helpers.ServerError(e, nil)
69
70
}
70
71
+9
-8
server/handle_sync_get_blob.go
+9
-8
server/handle_sync_get_blob.go
···
18
18
19
19
func (s *Server) handleSyncGetBlob(e echo.Context) error {
20
20
ctx := e.Request().Context()
21
+
logger := s.logger.With("name", "handleSyncGetBlob")
21
22
22
23
did := e.QueryParam("did")
23
24
if did == "" {
···
36
37
37
38
urepo, err := s.getRepoActorByDid(ctx, did)
38
39
if err != nil {
39
-
s.logger.Error("could not find user for requested blob", "error", err)
40
+
logger.Error("could not find user for requested blob", "error", err)
40
41
return helpers.InputError(e, nil)
41
42
}
42
43
···
49
50
50
51
var blob models.Blob
51
52
if err := s.db.Raw(ctx, "SELECT * FROM blobs WHERE did = ? AND cid = ?", nil, did, c.Bytes()).Scan(&blob).Error; err != nil {
52
-
s.logger.Error("error looking up blob", "error", err)
53
+
logger.Error("error looking up blob", "error", err)
53
54
return helpers.ServerError(e, nil)
54
55
}
55
56
···
58
59
if blob.Storage == "sqlite" {
59
60
var parts []models.BlobPart
60
61
if err := s.db.Raw(ctx, "SELECT * FROM blob_parts WHERE blob_id = ? ORDER BY idx", nil, blob.ID).Scan(&parts).Error; err != nil {
61
-
s.logger.Error("error getting blob parts", "error", err)
62
+
logger.Error("error getting blob parts", "error", err)
62
63
return helpers.ServerError(e, nil)
63
64
}
64
65
···
68
69
}
69
70
} else if blob.Storage == "s3" {
70
71
if !(s.s3Config != nil && s.s3Config.BlobstoreEnabled) {
71
-
s.logger.Error("s3 storage disabled")
72
+
logger.Error("s3 storage disabled")
72
73
return helpers.ServerError(e, nil)
73
74
}
74
75
···
91
92
92
93
sess, err := session.NewSession(config)
93
94
if err != nil {
94
-
s.logger.Error("error creating aws session", "error", err)
95
+
logger.Error("error creating aws session", "error", err)
95
96
return helpers.ServerError(e, nil)
96
97
}
97
98
···
100
101
Bucket: aws.String(s.s3Config.Bucket),
101
102
Key: aws.String(blobKey),
102
103
}); err != nil {
103
-
s.logger.Error("error getting blob from s3", "error", err)
104
+
logger.Error("error getting blob from s3", "error", err)
104
105
return helpers.ServerError(e, nil)
105
106
} else {
106
107
read := 0
···
114
115
break
115
116
}
116
117
} else if err != nil && err != io.ErrUnexpectedEOF {
117
-
s.logger.Error("error reading blob", "error", err)
118
+
logger.Error("error reading blob", "error", err)
118
119
return helpers.ServerError(e, nil)
119
120
}
120
121
···
125
126
}
126
127
}
127
128
} else {
128
-
s.logger.Error("unknown storage", "storage", blob.Storage)
129
+
logger.Error("unknown storage", "storage", blob.Storage)
129
130
return helpers.ServerError(e, nil)
130
131
}
131
132
+2
-1
server/handle_sync_get_blocks.go
+2
-1
server/handle_sync_get_blocks.go
···
18
18
19
19
func (s *Server) handleGetBlocks(e echo.Context) error {
20
20
ctx := e.Request().Context()
21
+
logger := s.logger.With("name", "handleSyncGetBlocks")
21
22
22
23
var req ComAtprotoSyncGetBlocksRequest
23
24
if err := e.Bind(&req); err != nil {
···
52
53
})
53
54
54
55
if _, err := carstore.LdWrite(buf, hb); err != nil {
55
-
s.logger.Error("error writing to car", "error", err)
56
+
logger.Error("error writing to car", "error", err)
56
57
return helpers.ServerError(e, nil)
57
58
}
58
59
+4
-3
server/handle_sync_get_record.go
+4
-3
server/handle_sync_get_record.go
···
14
14
15
15
func (s *Server) handleSyncGetRecord(e echo.Context) error {
16
16
ctx := e.Request().Context()
17
+
logger := s.logger.With("name", "handleSyncGetRecord")
17
18
18
19
did := e.QueryParam("did")
19
20
collection := e.QueryParam("collection")
···
21
22
22
23
var urepo models.Repo
23
24
if err := s.db.Raw(ctx, "SELECT * FROM repos WHERE did = ?", nil, did).Scan(&urepo).Error; err != nil {
24
-
s.logger.Error("error getting repo", "error", err)
25
+
logger.Error("error getting repo", "error", err)
25
26
return helpers.ServerError(e, nil)
26
27
}
27
28
···
38
39
})
39
40
40
41
if _, err := carstore.LdWrite(buf, hb); err != nil {
41
-
s.logger.Error("error writing to car", "error", err)
42
+
logger.Error("error writing to car", "error", err)
42
43
return helpers.ServerError(e, nil)
43
44
}
44
45
45
46
for _, blk := range blocks {
46
47
if _, err := carstore.LdWrite(buf, blk.Cid().Bytes(), blk.RawData()); err != nil {
47
-
s.logger.Error("error writing to car", "error", err)
48
+
logger.Error("error writing to car", "error", err)
48
49
return helpers.ServerError(e, nil)
49
50
}
50
51
}
+2
-1
server/handle_sync_get_repo.go
+2
-1
server/handle_sync_get_repo.go
···
14
14
15
15
func (s *Server) handleSyncGetRepo(e echo.Context) error {
16
16
ctx := e.Request().Context()
17
+
logger := s.logger.With("name", "handleSyncGetRepo")
17
18
18
19
did := e.QueryParam("did")
19
20
if did == "" {
···
38
39
buf := new(bytes.Buffer)
39
40
40
41
if _, err := carstore.LdWrite(buf, hb); err != nil {
41
-
s.logger.Error("error writing to car", "error", err)
42
+
logger.Error("error writing to car", "error", err)
42
43
return helpers.ServerError(e, nil)
43
44
}
44
45
+4
-3
server/handle_sync_list_blobs.go
+4
-3
server/handle_sync_list_blobs.go
···
15
15
16
16
func (s *Server) handleSyncListBlobs(e echo.Context) error {
17
17
ctx := e.Request().Context()
18
+
logger := s.logger.With("name", "handleSyncListBlobs")
18
19
19
20
did := e.QueryParam("did")
20
21
if did == "" {
···
39
40
40
41
urepo, err := s.getRepoActorByDid(ctx, did)
41
42
if err != nil {
42
-
s.logger.Error("could not find user for requested blobs", "error", err)
43
+
logger.Error("could not find user for requested blobs", "error", err)
43
44
return helpers.InputError(e, nil)
44
45
}
45
46
···
52
53
53
54
var blobs []models.Blob
54
55
if err := s.db.Raw(ctx, "SELECT * FROM blobs WHERE did = ? "+cursorquery+" ORDER BY created_at DESC LIMIT ?", nil, params...).Scan(&blobs).Error; err != nil {
55
-
s.logger.Error("error getting records", "error", err)
56
+
logger.Error("error getting records", "error", err)
56
57
return helpers.ServerError(e, nil)
57
58
}
58
59
···
60
61
for _, b := range blobs {
61
62
c, err := cid.Cast(b.Cid)
62
63
if err != nil {
63
-
s.logger.Error("error casting cid", "error", err)
64
+
logger.Error("error casting cid", "error", err)
64
65
return helpers.ServerError(e, nil)
65
66
}
66
67
cstrs = append(cstrs, c.String())
+54
-42
server/handle_sync_subscribe_repos.go
+54
-42
server/handle_sync_subscribe_repos.go
···
7
7
"github.com/bluesky-social/indigo/events"
8
8
"github.com/bluesky-social/indigo/lex/util"
9
9
"github.com/btcsuite/websocket"
10
+
"github.com/haileyok/cocoon/metrics"
10
11
"github.com/labstack/echo/v4"
11
12
)
12
13
···
24
25
logger = logger.With("ident", ident)
25
26
logger.Info("new connection established")
26
27
28
+
metrics.RelaysConnected.WithLabelValues(ident).Inc()
29
+
defer func() {
30
+
metrics.RelaysConnected.WithLabelValues(ident).Dec()
31
+
}()
32
+
27
33
evts, cancel, err := s.evtman.Subscribe(ctx, ident, func(evt *events.XRPCStreamEvent) bool {
28
34
return true
29
35
}, nil)
···
34
40
35
41
header := events.EventHeader{Op: events.EvtKindMessage}
36
42
for evt := range evts {
37
-
wc, err := conn.NextWriter(websocket.BinaryMessage)
38
-
if err != nil {
39
-
logger.Error("error writing message to relay", "err", err)
40
-
break
41
-
}
43
+
func() {
44
+
defer func() {
45
+
metrics.RelaySends.WithLabelValues(ident, header.MsgType).Inc()
46
+
}()
42
47
43
-
if ctx.Err() != nil {
44
-
logger.Error("context error", "err", err)
45
-
break
46
-
}
48
+
wc, err := conn.NextWriter(websocket.BinaryMessage)
49
+
if err != nil {
50
+
logger.Error("error writing message to relay", "err", err)
51
+
return
52
+
}
47
53
48
-
var obj util.CBOR
49
-
switch {
50
-
case evt.Error != nil:
51
-
header.Op = events.EvtKindErrorFrame
52
-
obj = evt.Error
53
-
case evt.RepoCommit != nil:
54
-
header.MsgType = "#commit"
55
-
obj = evt.RepoCommit
56
-
case evt.RepoIdentity != nil:
57
-
header.MsgType = "#identity"
58
-
obj = evt.RepoIdentity
59
-
case evt.RepoAccount != nil:
60
-
header.MsgType = "#account"
61
-
obj = evt.RepoAccount
62
-
case evt.RepoInfo != nil:
63
-
header.MsgType = "#info"
64
-
obj = evt.RepoInfo
65
-
default:
66
-
logger.Warn("unrecognized event kind")
67
-
return nil
68
-
}
54
+
if ctx.Err() != nil {
55
+
logger.Error("context error", "err", err)
56
+
return
57
+
}
69
58
70
-
if err := header.MarshalCBOR(wc); err != nil {
71
-
logger.Error("failed to write header to relay", "err", err)
72
-
break
73
-
}
59
+
var obj util.CBOR
60
+
switch {
61
+
case evt.Error != nil:
62
+
header.Op = events.EvtKindErrorFrame
63
+
obj = evt.Error
64
+
case evt.RepoCommit != nil:
65
+
header.MsgType = "#commit"
66
+
obj = evt.RepoCommit
67
+
case evt.RepoIdentity != nil:
68
+
header.MsgType = "#identity"
69
+
obj = evt.RepoIdentity
70
+
case evt.RepoAccount != nil:
71
+
header.MsgType = "#account"
72
+
obj = evt.RepoAccount
73
+
case evt.RepoInfo != nil:
74
+
header.MsgType = "#info"
75
+
obj = evt.RepoInfo
76
+
default:
77
+
logger.Warn("unrecognized event kind")
78
+
return
79
+
}
74
80
75
-
if err := obj.MarshalCBOR(wc); err != nil {
76
-
logger.Error("failed to write event to relay", "err", err)
77
-
break
78
-
}
81
+
if err := header.MarshalCBOR(wc); err != nil {
82
+
logger.Error("failed to write header to relay", "err", err)
83
+
return
84
+
}
79
85
80
-
if err := wc.Close(); err != nil {
81
-
logger.Error("failed to flush-close our event write", "err", err)
82
-
break
83
-
}
86
+
if err := obj.MarshalCBOR(wc); err != nil {
87
+
logger.Error("failed to write event to relay", "err", err)
88
+
return
89
+
}
90
+
91
+
if err := wc.Close(); err != nil {
92
+
logger.Error("failed to flush-close our event write", "err", err)
93
+
return
94
+
}
95
+
}()
84
96
}
85
97
86
98
// we should tell the relay to request a new crawl at this point if we got disconnected
+2
-1
server/handle_well_known.go
+2
-1
server/handle_well_known.go
···
68
68
69
69
func (s *Server) handleAtprotoDid(e echo.Context) error {
70
70
ctx := e.Request().Context()
71
+
logger := s.logger.With("name", "handleAtprotoDid")
71
72
72
73
host := e.Request().Host
73
74
if host == "" {
···
91
92
if err == gorm.ErrRecordNotFound {
92
93
return e.NoContent(404)
93
94
}
94
-
s.logger.Error("error looking up actor by handle", "error", err)
95
+
logger.Error("error looking up actor by handle", "error", err)
95
96
return helpers.ServerError(e, nil)
96
97
}
97
98
+33
-16
server/middleware.go
+33
-16
server/middleware.go
···
38
38
func (s *Server) handleLegacySessionMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
39
39
return func(e echo.Context) error {
40
40
ctx := e.Request().Context()
41
+
logger := s.logger.With("name", "handleLegacySessionMiddleware")
41
42
42
43
authheader := e.Request().Header.Get("authorization")
43
44
if authheader == "" {
···
69
70
if hasLxm {
70
71
pts := strings.Split(e.Request().URL.String(), "/")
71
72
if lxm != pts[len(pts)-1] {
72
-
s.logger.Error("service auth lxm incorrect", "lxm", lxm, "expected", pts[len(pts)-1], "error", err)
73
+
logger.Error("service auth lxm incorrect", "lxm", lxm, "expected", pts[len(pts)-1], "error", err)
73
74
return helpers.InputError(e, nil)
74
75
}
75
76
76
77
maybeDid, ok := claims["iss"].(string)
77
78
if !ok {
78
-
s.logger.Error("no iss in service auth token", "error", err)
79
+
logger.Error("no iss in service auth token", "error", err)
79
80
return helpers.InputError(e, nil)
80
81
}
81
82
did = maybeDid
82
83
83
84
maybeRepo, err := s.getRepoActorByDid(ctx, did)
84
85
if err != nil {
85
-
s.logger.Error("error fetching repo", "error", err)
86
+
logger.Error("error fetching repo", "error", err)
86
87
return helpers.ServerError(e, nil)
87
88
}
88
89
repo = maybeRepo
···
96
97
return s.privateKey.Public(), nil
97
98
})
98
99
if err != nil {
99
-
s.logger.Error("error parsing jwt", "error", err)
100
+
logger.Error("error parsing jwt", "error", err)
100
101
return helpers.ExpiredTokenError(e)
101
102
}
102
103
···
109
110
hash := sha256.Sum256([]byte(signingInput))
110
111
sigBytes, err := base64.RawURLEncoding.DecodeString(kpts[2])
111
112
if err != nil {
112
-
s.logger.Error("error decoding signature bytes", "error", err)
113
+
logger.Error("error decoding signature bytes", "error", err)
113
114
return helpers.ServerError(e, nil)
114
115
}
115
116
116
117
if len(sigBytes) != 64 {
117
-
s.logger.Error("incorrect sigbytes length", "length", len(sigBytes))
118
+
logger.Error("incorrect sigbytes length", "length", len(sigBytes))
118
119
return helpers.ServerError(e, nil)
119
120
}
120
121
···
123
124
rr, _ := secp256k1.NewScalarFromBytes((*[32]byte)(rBytes))
124
125
ss, _ := secp256k1.NewScalarFromBytes((*[32]byte)(sBytes))
125
126
127
+
if repo == nil {
128
+
sub, ok := claims["sub"].(string)
129
+
if !ok {
130
+
s.logger.Error("no sub claim in ES256K token and repo not set")
131
+
return helpers.InvalidTokenError(e)
132
+
}
133
+
maybeRepo, err := s.getRepoActorByDid(ctx, sub)
134
+
if err != nil {
135
+
s.logger.Error("error fetching repo for ES256K verification", "error", err)
136
+
return helpers.ServerError(e, nil)
137
+
}
138
+
repo = maybeRepo
139
+
did = sub
140
+
}
141
+
126
142
sk, err := secp256k1secec.NewPrivateKey(repo.SigningKey)
127
143
if err != nil {
128
-
s.logger.Error("can't load private key", "error", err)
144
+
logger.Error("can't load private key", "error", err)
129
145
return err
130
146
}
131
147
132
148
pubKey, ok := sk.Public().(*secp256k1secec.PublicKey)
133
149
if !ok {
134
-
s.logger.Error("error getting public key from sk")
150
+
logger.Error("error getting public key from sk")
135
151
return helpers.ServerError(e, nil)
136
152
}
137
153
138
154
verified := pubKey.VerifyRaw(hash[:], rr, ss)
139
155
if !verified {
140
-
s.logger.Error("error verifying", "error", err)
156
+
logger.Error("error verifying", "error", err)
141
157
return helpers.ServerError(e, nil)
142
158
}
143
159
}
···
166
182
return helpers.InvalidTokenError(e)
167
183
}
168
184
169
-
s.logger.Error("error getting token from db", "error", err)
185
+
logger.Error("error getting token from db", "error", err)
170
186
return helpers.ServerError(e, nil)
171
187
}
172
188
···
177
193
178
194
exp, ok := claims["exp"].(float64)
179
195
if !ok {
180
-
s.logger.Error("error getting iat from token")
196
+
logger.Error("error getting iat from token")
181
197
return helpers.ServerError(e, nil)
182
198
}
183
199
···
188
204
if repo == nil {
189
205
maybeRepo, err := s.getRepoActorByDid(ctx, claims["sub"].(string))
190
206
if err != nil {
191
-
s.logger.Error("error fetching repo", "error", err)
207
+
logger.Error("error fetching repo", "error", err)
192
208
return helpers.ServerError(e, nil)
193
209
}
194
210
repo = maybeRepo
···
210
226
func (s *Server) handleOauthSessionMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
211
227
return func(e echo.Context) error {
212
228
ctx := e.Request().Context()
229
+
logger := s.logger.With("name", "handleOauthSessionMiddleware")
213
230
214
231
authheader := e.Request().Header.Get("authorization")
215
232
if authheader == "" {
···
242
259
"error": "use_dpop_nonce",
243
260
})
244
261
}
245
-
s.logger.Error("invalid dpop proof", "error", err)
262
+
logger.Error("invalid dpop proof", "error", err)
246
263
return helpers.InputError(e, nil)
247
264
}
248
265
249
266
var oauthToken provider.OauthToken
250
267
if err := s.db.Raw(ctx, "SELECT * FROM oauth_tokens WHERE token = ?", nil, accessToken).Scan(&oauthToken).Error; err != nil {
251
-
s.logger.Error("error finding access token in db", "error", err)
268
+
logger.Error("error finding access token in db", "error", err)
252
269
return helpers.InputError(e, nil)
253
270
}
254
271
···
257
274
}
258
275
259
276
if *oauthToken.Parameters.DpopJkt != proof.JKT {
260
-
s.logger.Error("jkt mismatch", "token", oauthToken.Parameters.DpopJkt, "proof", proof.JKT)
277
+
logger.Error("jkt mismatch", "token", oauthToken.Parameters.DpopJkt, "proof", proof.JKT)
261
278
return helpers.InputError(e, to.StringPtr("dpop jkt mismatch"))
262
279
}
263
280
···
272
289
273
290
repo, err := s.getRepoActorByDid(ctx, oauthToken.Sub)
274
291
if err != nil {
275
-
s.logger.Error("could not find actor in db", "error", err)
292
+
logger.Error("could not find actor in db", "error", err)
276
293
return helpers.ServerError(e, nil)
277
294
}
278
295
+7
server/repo.go
+7
server/repo.go
···
17
17
lexutil "github.com/bluesky-social/indigo/lex/util"
18
18
"github.com/bluesky-social/indigo/repo"
19
19
"github.com/haileyok/cocoon/internal/db"
20
+
"github.com/haileyok/cocoon/metrics"
20
21
"github.com/haileyok/cocoon/models"
21
22
"github.com/haileyok/cocoon/recording_blockstore"
22
23
blocks "github.com/ipfs/go-block-format"
···
249
250
newroot, rev, err := r.Commit(ctx, urepo.SignFor)
250
251
if err != nil {
251
252
return nil, err
253
+
}
254
+
255
+
for _, result := range results {
256
+
if result.Type != nil {
257
+
metrics.RepoOperations.WithLabelValues(*result.Type).Inc()
258
+
}
252
259
}
253
260
254
261
// create a buffer for dumping our new cbor into
+38
-27
server/server.go
+38
-27
server/server.go
···
39
39
"github.com/haileyok/cocoon/oauth/provider"
40
40
"github.com/haileyok/cocoon/plc"
41
41
"github.com/ipfs/go-cid"
42
+
"github.com/labstack/echo-contrib/echoprometheus"
42
43
echo_session "github.com/labstack/echo-contrib/session"
43
44
"github.com/labstack/echo/v4"
44
45
"github.com/labstack/echo/v4/middleware"
···
89
90
}
90
91
91
92
type Args struct {
93
+
Logger *slog.Logger
94
+
92
95
Addr string
93
96
DbName string
94
97
DbType string
95
98
DatabaseURL string
96
-
Logger *slog.Logger
97
99
Version string
98
100
Did string
99
101
Hostname string
···
209
211
}
210
212
211
213
func New(args *Args) (*Server, error) {
214
+
if args.Logger == nil {
215
+
args.Logger = slog.Default()
216
+
}
217
+
218
+
logger := args.Logger.With("name", "New")
219
+
212
220
if args.Addr == "" {
213
221
return nil, fmt.Errorf("addr must be set")
214
222
}
···
237
245
return nil, fmt.Errorf("admin password must be set")
238
246
}
239
247
240
-
if args.Logger == nil {
241
-
args.Logger = slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{}))
242
-
}
243
-
244
248
if args.SessionSecret == "" {
245
249
panic("SESSION SECRET WAS NOT SET. THIS IS REQUIRED. ")
246
250
}
···
248
252
e := echo.New()
249
253
250
254
e.Pre(middleware.RemoveTrailingSlash())
251
-
e.Pre(slogecho.New(args.Logger))
255
+
e.Pre(slogecho.New(args.Logger.With("component", "slogecho")))
252
256
e.Use(echo_session.Middleware(sessions.NewCookieStore([]byte(args.SessionSecret))))
257
+
e.Use(echoprometheus.NewMiddleware("cocoon"))
253
258
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
254
259
AllowOrigins: []string{"*"},
255
260
AllowHeaders: []string{"*"},
···
311
316
if err != nil {
312
317
return nil, fmt.Errorf("failed to connect to postgres: %w", err)
313
318
}
314
-
args.Logger.Info("connected to PostgreSQL database")
319
+
logger.Info("connected to PostgreSQL database")
315
320
default:
316
321
gdb, err = gorm.Open(sqlite.Open(args.DbName), &gorm.Config{})
317
322
if err != nil {
318
323
return nil, fmt.Errorf("failed to open sqlite database: %w", err)
319
324
}
320
-
args.Logger.Info("connected to SQLite database", "path", args.DbName)
325
+
logger.Info("connected to SQLite database", "path", args.DbName)
321
326
}
322
327
dbw := db.NewDB(gdb)
323
328
···
360
365
var nonceSecret []byte
361
366
maybeSecret, err := os.ReadFile("nonce.secret")
362
367
if err != nil && !os.IsNotExist(err) {
363
-
args.Logger.Error("error attempting to read nonce secret", "error", err)
368
+
logger.Error("error attempting to read nonce secret", "error", err)
364
369
} else {
365
370
nonceSecret = maybeSecret
366
371
}
···
398
403
Hostname: args.Hostname,
399
404
ClientManagerArgs: client.ManagerArgs{
400
405
Cli: oauthCli,
401
-
Logger: args.Logger,
406
+
Logger: args.Logger.With("component", "oauth-client-manager"),
402
407
},
403
408
DpopManagerArgs: dpop.ManagerArgs{
404
409
NonceSecret: nonceSecret,
405
410
NonceRotationInterval: constants.NonceMaxRotationInterval / 3,
406
411
OnNonceSecretCreated: func(newNonce []byte) {
407
412
if err := os.WriteFile("nonce.secret", newNonce, 0644); err != nil {
408
-
args.Logger.Error("error writing new nonce secret", "error", err)
413
+
logger.Error("error writing new nonce secret", "error", err)
409
414
}
410
415
},
411
-
Logger: args.Logger,
416
+
Logger: args.Logger.With("component", "dpop-manager"),
412
417
Hostname: args.Hostname,
413
418
},
414
419
}),
···
535
540
}
536
541
537
542
func (s *Server) Serve(ctx context.Context) error {
543
+
logger := s.logger.With("name", "Serve")
544
+
538
545
s.addRoutes()
539
546
540
-
s.logger.Info("migrating...")
547
+
logger.Info("migrating...")
541
548
542
549
s.db.AutoMigrate(
543
550
&models.Actor{},
···
554
561
&provider.OauthAuthorizationRequest{},
555
562
)
556
563
557
-
s.logger.Info("starting cocoon")
564
+
logger.Info("starting cocoon")
558
565
559
566
go func() {
560
567
if err := s.httpd.ListenAndServe(); err != nil {
···
566
573
567
574
go func() {
568
575
if err := s.requestCrawl(ctx); err != nil {
569
-
s.logger.Error("error requesting crawls", "err", err)
576
+
logger.Error("error requesting crawls", "err", err)
570
577
}
571
578
}()
572
579
···
584
591
585
592
logger.Info("requesting crawl with configured relays")
586
593
587
-
if time.Now().Sub(s.lastRequestCrawl) <= 1*time.Minute {
594
+
if time.Since(s.lastRequestCrawl) <= 1*time.Minute {
588
595
return fmt.Errorf("a crawl request has already been made within the last minute")
589
596
}
590
597
···
607
614
}
608
615
609
616
func (s *Server) doBackup() {
617
+
logger := s.logger.With("name", "doBackup")
618
+
610
619
if s.dbType == "postgres" {
611
-
s.logger.Info("skipping S3 backup - PostgreSQL backups should be handled externally (pg_dump, managed database backups, etc.)")
620
+
logger.Info("skipping S3 backup - PostgreSQL backups should be handled externally (pg_dump, managed database backups, etc.)")
612
621
return
613
622
}
614
623
615
624
start := time.Now()
616
625
617
-
s.logger.Info("beginning backup to s3...")
626
+
logger.Info("beginning backup to s3...")
618
627
619
628
var buf bytes.Buffer
620
629
if err := func() error {
621
-
s.logger.Info("reading database bytes...")
630
+
logger.Info("reading database bytes...")
622
631
s.db.Lock()
623
632
defer s.db.Unlock()
624
633
···
634
643
635
644
return nil
636
645
}(); err != nil {
637
-
s.logger.Error("error backing up database", "error", err)
646
+
logger.Error("error backing up database", "error", err)
638
647
return
639
648
}
640
649
641
650
if err := func() error {
642
-
s.logger.Info("sending to s3...")
651
+
logger.Info("sending to s3...")
643
652
644
653
currTime := time.Now().Format("2006-01-02_15-04-05")
645
654
key := "cocoon-backup-" + currTime + ".db"
···
669
678
return fmt.Errorf("error uploading file to s3: %w", err)
670
679
}
671
680
672
-
s.logger.Info("finished uploading backup to s3", "key", key, "duration", time.Now().Sub(start).Seconds())
681
+
logger.Info("finished uploading backup to s3", "key", key, "duration", time.Now().Sub(start).Seconds())
673
682
674
683
return nil
675
684
}(); err != nil {
676
-
s.logger.Error("error uploading database backup", "error", err)
685
+
logger.Error("error uploading database backup", "error", err)
677
686
return
678
687
}
679
688
···
681
690
}
682
691
683
692
func (s *Server) backupRoutine() {
693
+
logger := s.logger.With("name", "backupRoutine")
694
+
684
695
if s.s3Config == nil || !s.s3Config.BackupsEnabled {
685
696
return
686
697
}
687
698
688
699
if s.s3Config.Region == "" {
689
-
s.logger.Warn("no s3 region configured but backups are enabled. backups will not run.")
700
+
logger.Warn("no s3 region configured but backups are enabled. backups will not run.")
690
701
return
691
702
}
692
703
693
704
if s.s3Config.Bucket == "" {
694
-
s.logger.Warn("no s3 bucket configured but backups are enabled. backups will not run.")
705
+
logger.Warn("no s3 bucket configured but backups are enabled. backups will not run.")
695
706
return
696
707
}
697
708
698
709
if s.s3Config.AccessKey == "" {
699
-
s.logger.Warn("no s3 access key configured but backups are enabled. backups will not run.")
710
+
logger.Warn("no s3 access key configured but backups are enabled. backups will not run.")
700
711
return
701
712
}
702
713
703
714
if s.s3Config.SecretKey == "" {
704
-
s.logger.Warn("no s3 secret key configured but backups are enabled. backups will not run.")
715
+
logger.Warn("no s3 secret key configured but backups are enabled. backups will not run.")
705
716
return
706
717
}
707
718
+1
-1
test.go
+1
-1
test.go
···
32
32
33
33
u.Path = "xrpc/com.atproto.sync.subscribeRepos"
34
34
conn, _, err := dialer.Dial(u.String(), http.Header{
35
-
"User-Agent": []string{fmt.Sprintf("hot-topic/0.0.0")},
35
+
"User-Agent": []string{"cocoon-test/0.0.0"},
36
36
})
37
37
if err != nil {
38
38
return fmt.Errorf("subscribing to firehose failed (dialing): %w", err)