···
12
+
"github.com/bluesky-social/indigo/atproto/crypto"
13
+
"github.com/bluesky-social/indigo/atproto/syntax"
14
+
"github.com/haileyok/cocoon/internal/helpers"
"github.com/haileyok/cocoon/server"
_ "github.com/joho/godotenv/autoload"
17
+
"github.com/lestrrat-go/jwx/v2/jwk"
"github.com/urfave/cli/v2"
19
+
"golang.org/x/crypto/bcrypt"
20
+
"gorm.io/driver/sqlite"
···
Commands: []*cli.Command{
137
+
runCreateRotationKey,
138
+
runCreatePrivateJwk,
139
+
runCreateInviteCode,
···
135
-
var run = &cli.Command{
151
+
var runServe = &cli.Command{
Usage: "Start the cocoon PDS",
···
197
+
var runCreateRotationKey = &cli.Command{
198
+
Name: "create-rotation-key",
199
+
Usage: "creates a rotation key for your pds",
204
+
Usage: "output file for your rotation key",
207
+
Action: func(cmd *cli.Context) error {
208
+
key, err := crypto.GeneratePrivateKeyK256()
213
+
bytes := key.Bytes()
215
+
if err := os.WriteFile(cmd.String("out"), bytes, 0644); err != nil {
223
+
var runCreatePrivateJwk = &cli.Command{
224
+
Name: "create-private-jwk",
225
+
Usage: "creates a private jwk for your pds",
230
+
Usage: "output file for your jwk",
233
+
Action: func(cmd *cli.Context) error {
234
+
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
239
+
key, err := jwk.FromRaw(privKey)
244
+
kid := fmt.Sprintf("%d", time.Now().Unix())
246
+
if err := key.Set(jwk.KeyIDKey, kid); err != nil {
250
+
b, err := json.Marshal(key)
255
+
if err := os.WriteFile(cmd.String("out"), b, 0644); err != nil {
263
+
var runCreateInviteCode = &cli.Command{
264
+
Name: "create-invite-code",
265
+
Usage: "creates an invite code",
269
+
Usage: "optional did to assign the invite code to",
273
+
Usage: "number of times the invite code can be used",
277
+
Action: func(cmd *cli.Context) error {
283
+
forDid := "did:plc:123"
284
+
if cmd.String("for") != "" {
285
+
did, err := syntax.ParseDID(cmd.String("for"))
290
+
forDid = did.String()
293
+
uses := cmd.Int("uses")
295
+
code := fmt.Sprintf("%s-%s", helpers.RandomVarchar(8), helpers.RandomVarchar(8))
297
+
if err := db.Exec("INSERT INTO invite_codes (did, code, remaining_use_count) VALUES (?, ?, ?)", forDid, code, uses).Error; err != nil {
301
+
fmt.Printf("New invite code created with %d uses: %s\n", uses, code)
307
+
var runResetPassword = &cli.Command{
308
+
Name: "reset-password",
309
+
Usage: "resets a password",
313
+
Usage: "did of the user who's password you want to reset",
316
+
Action: func(cmd *cli.Context) error {
322
+
didStr := cmd.String("did")
323
+
did, err := syntax.ParseDID(didStr)
328
+
newPass := fmt.Sprintf("%s-%s", helpers.RandomVarchar(12), helpers.RandomVarchar(12))
329
+
hashed, err := bcrypt.GenerateFromPassword([]byte(newPass), 10)
334
+
if err := db.Exec("UPDATE repos SET password = ? WHERE did = ?", hashed, did.String()).Error; err != nil {
338
+
fmt.Printf("Password for %s has been reset to: %s", did.String(), newPass)
344
+
func newDb() (*gorm.DB, error) {
345
+
return gorm.Open(sqlite.Open("cocoon.db"), &gorm.Config{})