+6
-2
Makefile
+6
-2
Makefile
···
13
13
&& go run golang.org/x/tools/cmd/goimports@latest -w $$(find ./api/teal -type f) \
14
14
&& go run ./util/gencbor/gencbor.go \
15
15
&& $(MAKE) lexgen \
16
-
&& find . | grep bak$$ | xargs rm
16
+
&& find . | grep bak$$ | xargs rm
17
17
18
18
.PHONY: lexgen
19
19
lexgen:
···
24
24
go run github.com/bluesky-social/indigo/cmd/lexgen \
25
25
--build-file ./lexcfg.json \
26
26
../atproto/lexicons \
27
-
./lexicons/teal \
27
+
./lexicons/teal
28
+
29
+
.PHONY: jwtgen
30
+
jwtgen:
31
+
go run github.com/haileyok/atproto-oauth-golang/cmd/helper generate-jwks
+2
-10
cmd/main.go
+2
-10
cmd/main.go
···
18
18
"github.com/teal-fm/piper/service/musicbrainz"
19
19
"github.com/teal-fm/piper/service/spotify"
20
20
"github.com/teal-fm/piper/session"
21
-
"github.com/teal-fm/piper/util/jwtgen"
22
21
)
23
22
24
23
type application struct {
···
56
55
// --- Service Initializations ---
57
56
jwksBytes, err := os.ReadFile("./jwks.json")
58
57
if err != nil {
59
-
// fuck Makefiles
60
-
if err := jwtgen.WriteJwksToDisk(""); err != nil {
61
-
log.Fatalf("Error reading JWK file: %v", err)
62
-
}
63
-
// works for now
64
-
jwksBytes, err = os.ReadFile("./jwks.json")
65
-
if err != nil {
66
-
log.Fatalf("Error reading JWK file: %v", err)
67
-
}
58
+
// run `make jwtgen`
59
+
log.Fatalf("Error reading JWK file: %v", err)
68
60
}
69
61
jwks, err := atproto.LoadJwks(jwksBytes)
70
62
if err != nil {
+4
go.mod
+4
go.mod
···
26
26
github.com/bep/golibsass v1.2.0 // indirect
27
27
github.com/carlmjohnson/versioninfo v0.22.5 // indirect
28
28
github.com/cli/safeexec v1.0.1 // indirect
29
+
github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
29
30
github.com/creack/pty v1.1.23 // indirect
30
31
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
31
32
github.com/fatih/color v1.17.0 // indirect
···
74
75
github.com/pelletier/go-toml v1.9.5 // indirect
75
76
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
76
77
github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f // indirect
78
+
github.com/russross/blackfriday/v2 v2.1.0 // indirect
77
79
github.com/sagikazarmark/locafero v0.7.0 // indirect
78
80
github.com/segmentio/asm v1.2.0 // indirect
79
81
github.com/sourcegraph/conc v0.3.0 // indirect
···
83
85
github.com/spf13/pflag v1.0.6 // indirect
84
86
github.com/subosito/gotenv v1.6.0 // indirect
85
87
github.com/tdewolff/parse/v2 v2.7.15 // indirect
88
+
github.com/urfave/cli/v2 v2.27.5 // indirect
89
+
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
86
90
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
87
91
go.opentelemetry.io/otel v1.29.0 // indirect
88
92
go.opentelemetry.io/otel/metric v1.29.0 // indirect
+9
go.sum
+9
go.sum
···
51
51
github.com/cli/safeexec v1.0.1/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q=
52
52
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
53
53
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
54
+
github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
55
+
github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
54
56
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
55
57
github.com/creack/pty v1.1.23 h1:4M6+isWdcStXEf15G/RbrMPOQj1dZ7HPZCGwE4kOeP0=
56
58
github.com/creack/pty v1.1.23/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE=
···
303
305
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
304
306
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
305
307
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
308
+
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
309
+
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
306
310
github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo=
307
311
github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k=
308
312
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
···
348
352
github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8=
349
353
github.com/tetratelabs/wazero v1.8.0 h1:iEKu0d4c2Pd+QSRieYbnQC9yiFlMS9D+Jr0LsRmcF4g=
350
354
github.com/tetratelabs/wazero v1.8.0/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs=
355
+
github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk=
351
356
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
357
+
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
358
+
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
352
359
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ=
353
360
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
354
361
github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0=
355
362
github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ=
356
363
github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e h1:28X54ciEwwUxyHn9yrZfl5ojgF4CBNLWX7LR0rvBkf4=
357
364
github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so=
365
+
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
366
+
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
358
367
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
359
368
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
360
369
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-120
util/jwtgen/jwtgen.go
-120
util/jwtgen/jwtgen.go
···
1
-
// bless up @haileyok
2
-
// https://github.com/haileyok/atproto-oauth-golang/blob/main/helpers/generic.go
3
-
4
-
package jwtgen
5
-
6
-
import (
7
-
"crypto/ecdsa"
8
-
"crypto/elliptic"
9
-
"crypto/rand"
10
-
"encoding/json"
11
-
"fmt"
12
-
"net/url"
13
-
"os"
14
-
"time"
15
-
16
-
"github.com/lestrrat-go/jwx/v2/jwk"
17
-
)
18
-
19
-
func WriteJwksToDisk(inputPrefix string) error {
20
-
var prefix *string
21
-
if inputPrefix != "" {
22
-
prefix = &inputPrefix
23
-
}
24
-
key, err := GenerateKey(prefix)
25
-
if err != nil {
26
-
return fmt.Errorf("error generating key: %v\n", err)
27
-
}
28
-
29
-
b, err := json.Marshal(key)
30
-
if err != nil {
31
-
return fmt.Errorf("error marshaling key: %v\n", err)
32
-
}
33
-
34
-
if err := os.WriteFile("./jwks.json", b, 0644); err != nil {
35
-
return fmt.Errorf("error writing jwk to disk: %v\n", err)
36
-
}
37
-
38
-
return nil
39
-
}
40
-
41
-
func GenerateKey(kidPrefix *string) (jwk.Key, error) {
42
-
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
43
-
if err != nil {
44
-
return nil, err
45
-
}
46
-
47
-
key, err := jwk.FromRaw(privKey)
48
-
if err != nil {
49
-
return nil, err
50
-
}
51
-
52
-
var kid string
53
-
if kidPrefix != nil {
54
-
kid = fmt.Sprintf("%s-%d", *kidPrefix, time.Now().Unix())
55
-
} else {
56
-
kid = fmt.Sprintf("%d", time.Now().Unix())
57
-
}
58
-
59
-
if err := key.Set(jwk.KeyIDKey, kid); err != nil {
60
-
return nil, err
61
-
}
62
-
return key, nil
63
-
}
64
-
65
-
func IsUrlSafeAndParsed(rawString string) (*url.URL, error) {
66
-
u, err := url.Parse(rawString)
67
-
if err != nil {
68
-
return nil, err
69
-
}
70
-
71
-
if u.Scheme != "https" {
72
-
return nil, fmt.Errorf("input url is not https")
73
-
}
74
-
75
-
if u.Hostname() == "" {
76
-
return nil, fmt.Errorf("url hostname was empty")
77
-
}
78
-
79
-
if u.User != nil {
80
-
return nil, fmt.Errorf("url user was not empty")
81
-
}
82
-
83
-
if u.Port() != "" {
84
-
return nil, fmt.Errorf("url port was not empty")
85
-
}
86
-
87
-
return u, nil
88
-
}
89
-
90
-
func GetPrivateKey(key jwk.Key) (*ecdsa.PrivateKey, error) {
91
-
var pkey ecdsa.PrivateKey
92
-
if err := key.Raw(&pkey); err != nil {
93
-
return nil, err
94
-
}
95
-
96
-
return &pkey, nil
97
-
}
98
-
99
-
func GetPublicKey(key jwk.Key) (*ecdsa.PublicKey, error) {
100
-
var pkey ecdsa.PublicKey
101
-
if err := key.Raw(&pkey); err != nil {
102
-
return nil, err
103
-
}
104
-
105
-
return &pkey, nil
106
-
}
107
-
108
-
type JwksResponseObject struct {
109
-
Keys []jwk.Key `json:"keys"`
110
-
}
111
-
112
-
func CreateJwksResponseObject(key jwk.Key) *JwksResponseObject {
113
-
return &JwksResponseObject{
114
-
Keys: []jwk.Key{key},
115
-
}
116
-
}
117
-
118
-
func ParseJWKFromBytes(bytes []byte) (jwk.Key, error) {
119
-
return jwk.ParseKey(bytes)
120
-
}