A fork of the Cocoon PDS but being made more distributed.
11

Configure Feed

Select the types of activity you want to include in your feed.

add additional admin helpers

Hailey (Mar 29, 2025, 3:46 PM -0700) 9eeb0dcc 4e999a24

+107 -1
+92
cmd/admin/main.go
··· 10 10 "time" 11 11 12 12 "github.com/bluesky-social/indigo/atproto/crypto" 13 + "github.com/bluesky-social/indigo/atproto/syntax" 14 + "github.com/haileyok/cocoon/internal/helpers" 13 15 "github.com/lestrrat-go/jwx/v2/jwk" 14 16 "github.com/urfave/cli/v2" 17 + "golang.org/x/crypto/bcrypt" 18 + "gorm.io/driver/sqlite" 19 + "gorm.io/gorm" 15 20 ) 16 21 17 22 func main() { ··· 20 25 Commands: cli.Commands{ 21 26 runCreateRotationKey, 22 27 runCreatePrivateJwk, 28 + runCreateInviteCode, 29 + runResetPassword, 23 30 }, 24 31 ErrWriter: os.Stdout, 25 32 } ··· 92 99 return nil 93 100 }, 94 101 } 102 + 103 + var runCreateInviteCode = &cli.Command{ 104 + Name: "create-invite-code", 105 + Usage: "creates an invite code", 106 + Flags: []cli.Flag{ 107 + &cli.StringFlag{ 108 + Name: "for", 109 + Usage: "optional did to assign the invite code to", 110 + }, 111 + &cli.IntFlag{ 112 + Name: "uses", 113 + Usage: "number of times the invite code can be used", 114 + Value: 1, 115 + }, 116 + }, 117 + Action: func(cmd *cli.Context) error { 118 + db, err := newDb() 119 + if err != nil { 120 + return err 121 + } 122 + 123 + forDid := "did:plc:123" 124 + if cmd.String("for") != "" { 125 + did, err := syntax.ParseDID(cmd.String("for")) 126 + if err != nil { 127 + return err 128 + } 129 + 130 + forDid = did.String() 131 + } 132 + 133 + uses := cmd.Int("uses") 134 + 135 + code := fmt.Sprintf("%s-%s", helpers.RandomVarchar(8), helpers.RandomVarchar(8)) 136 + 137 + if err := db.Exec("INSERT INTO invite_codes (did, code, remaining_use_count) VALUES (?, ?, ?)", forDid, code, uses).Error; err != nil { 138 + return err 139 + } 140 + 141 + fmt.Printf("New invite code created with %d uses: %s\n", uses, code) 142 + 143 + return nil 144 + }, 145 + } 146 + 147 + var runResetPassword = &cli.Command{ 148 + Name: "reset-password", 149 + Usage: "resets a password", 150 + Flags: []cli.Flag{ 151 + &cli.StringFlag{ 152 + Name: "did", 153 + Usage: "did of the user who's password you want to reset", 154 + }, 155 + }, 156 + Action: func(cmd *cli.Context) error { 157 + db, err := newDb() 158 + if err != nil { 159 + return err 160 + } 161 + 162 + didStr := cmd.String("did") 163 + did, err := syntax.ParseDID(didStr) 164 + if err != nil { 165 + return err 166 + } 167 + 168 + newPass := fmt.Sprintf("%s-%s", helpers.RandomVarchar(12), helpers.RandomVarchar(12)) 169 + hashed, err := bcrypt.GenerateFromPassword([]byte(newPass), 10) 170 + if err != nil { 171 + return err 172 + } 173 + 174 + if err := db.Exec("UPDATE repos SET password = ? WHERE did = ?", hashed, did.String()).Error; err != nil { 175 + return err 176 + } 177 + 178 + fmt.Printf("Password for %s has been reset to: %s", did.String(), newPass) 179 + 180 + return nil 181 + }, 182 + } 183 + 184 + func newDb() (*gorm.DB, error) { 185 + return gorm.Open(sqlite.Open("cocoon.db"), &gorm.Config{}) 186 + }
+15 -1
internal/helpers/helpers.go
··· 1 1 package helpers 2 2 3 - import "github.com/labstack/echo/v4" 3 + import ( 4 + "math/rand" 5 + 6 + "github.com/labstack/echo/v4" 7 + ) 8 + 9 + var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890") 4 10 5 11 func InputError(e echo.Context, custom *string) error { 6 12 msg := "InvalidRequest" ··· 23 29 "error": msg, 24 30 }) 25 31 } 32 + 33 + func RandomVarchar(length int) string { 34 + b := make([]rune, length) 35 + for i := range b { 36 + b[i] = letters[rand.Intn(len(letters))] 37 + } 38 + return string(b) 39 + }