···1+MIT License
2+3+Copyright (c) 2025 me@haileyok.com
4+5+Permission is hereby granted, free of charge, to any person obtaining a copy
6+of this software and associated documentation files (the "Software"), to deal
7+in the Software without restriction, including without limitation the rights
8+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+copies of the Software, and to permit persons to whom the Software is
10+furnished to do so, subject to the following conditions:
11+12+The above copyright notice and this permission notice shall be included in all
13+copies or substantial portions of the Software.
14+15+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+SOFTWARE.
···71- [ ] com.atproto.moderation.createReport
72- [x] app.bsky.actor.getPreferences
73- [x] app.bsky.actor.putPreferences
74+75+76+## License
77+78+This project is licensed under MIT license. `server/static/pico.css` is also licensed under MIT license, available at [https://github.com/picocss/pico/](https://github.com/picocss/pico/).
···1package helpers
23import (
0004 "math/rand"
056 "github.com/labstack/echo/v4"
07)
89// This will confirm to the regex in the application if 5 chars are used for each side of the -
···39 }
40 return string(b)
41}
000000000000000000000000000000000000000000
···1package helpers
23import (
4+ crand "crypto/rand"
5+ "encoding/hex"
6+ "errors"
7 "math/rand"
8+ "net/url"
910 "github.com/labstack/echo/v4"
11+ "github.com/lestrrat-go/jwx/v2/jwk"
12)
1314// This will confirm to the regex in the application if 5 chars are used for each side of the -
···44 }
45 return string(b)
46}
47+48+func RandomHex(n int) (string, error) {
49+ bytes := make([]byte, n)
50+ if _, err := crand.Read(bytes); err != nil {
51+ return "", err
52+ }
53+ return hex.EncodeToString(bytes), nil
54+}
55+56+func RandomBytes(n int) []byte {
57+ bs := make([]byte, n)
58+ crand.Read(bs)
59+ return bs
60+}
61+62+func ParseJWKFromBytes(b []byte) (jwk.Key, error) {
63+ return jwk.ParseKey(b)
64+}
65+66+func OauthParseHtu(htu string) (string, error) {
67+ u, err := url.Parse(htu)
68+ if err != nil {
69+ return "", errors.New("`htu` is not a valid URL")
70+ }
71+72+ if u.User != nil {
73+ _, containsPass := u.User.Password()
74+ if u.User.Username() != "" || containsPass {
75+ return "", errors.New("`htu` must not contain credentials")
76+ }
77+ }
78+79+ if u.Scheme != "http" && u.Scheme != "https" {
80+ return "", errors.New("`htu` must be http or https")
81+ }
82+83+ return OauthNormalizeHtu(u), nil
84+}
85+86+func OauthNormalizeHtu(u *url.URL) string {
87+ return u.Scheme + "://" + u.Host + u.RawPath
88+}