forked from tangled.org/core
this repo has no description

add delete-key feature

Changed files
+116 -20
appview
db
pages
templates
state
+23
appview/db/db.go
··· 140 return nil 141 }) 142 143 return &DB{db}, nil 144 } 145
··· 140 return nil 141 }) 142 143 + runMigration(db, "add-rkey-to-pubkeys", func(tx *sql.Tx) error { 144 + // add unconstrained column 145 + _, err := tx.Exec(` 146 + alter table public_keys 147 + add column rkey text; 148 + `) 149 + if err != nil { 150 + return err 151 + } 152 + 153 + // backfill 154 + _, err = tx.Exec(` 155 + update public_keys 156 + set rkey = '' 157 + where rkey is null; 158 + `) 159 + if err != nil { 160 + return err 161 + } 162 + 163 + return nil 164 + }) 165 + 166 return &DB{db}, nil 167 } 168
+15 -10
appview/db/pubkeys.go
··· 5 "time" 6 ) 7 8 - func AddPublicKey(e Execer, did, name, key string) error { 9 - query := `insert or ignore into public_keys (did, name, key) values (?, ?, ?)` 10 - _, err := e.Exec(query, did, name, key) 11 return err 12 } 13 14 - func RemovePublicKey(e Execer, did string) error { 15 - query := `delete from public_keys where did = ?` 16 - _, err := e.Exec(query, did) 17 return err 18 } 19 ··· 21 Did string `json:"did"` 22 Key string `json:"key"` 23 Name string `json:"name"` 24 Created *time.Time 25 } 26 ··· 38 func GetAllPublicKeys(e Execer) ([]PublicKey, error) { 39 var keys []PublicKey 40 41 - rows, err := e.Query(`select key, name, did, created from public_keys`) 42 if err != nil { 43 return nil, err 44 } ··· 47 for rows.Next() { 48 var publicKey PublicKey 49 var createdAt string 50 - if err := rows.Scan(&publicKey.Key, &publicKey.Name, &publicKey.Did, &createdAt); err != nil { 51 return nil, err 52 } 53 createdAtTime, _ := time.Parse(time.RFC3339, createdAt) ··· 65 func GetPublicKeys(e Execer, did string) ([]PublicKey, error) { 66 var keys []PublicKey 67 68 - rows, err := e.Query(`select did, key, name, created from public_keys where did = ?`, did) 69 if err != nil { 70 return nil, err 71 } ··· 74 for rows.Next() { 75 var publicKey PublicKey 76 var createdAt string 77 - if err := rows.Scan(&publicKey.Did, &publicKey.Key, &publicKey.Name, &createdAt); err != nil { 78 return nil, err 79 } 80 createdAtTime, _ := time.Parse(time.RFC3339, createdAt)
··· 5 "time" 6 ) 7 8 + func AddPublicKey(e Execer, did, name, key, rkey string) error { 9 + _, err := e.Exec( 10 + `insert or ignore into public_keys (did, name, key, rkey) 11 + values (?, ?, ?, ?)`, 12 + did, name, key, rkey) 13 return err 14 } 15 16 + func RemovePublicKey(e Execer, did, name, key string) error { 17 + _, err := e.Exec(` 18 + delete from public_keys 19 + where did = ? and name = ? and key = ?`, 20 + did, name, key) 21 return err 22 } 23 ··· 25 Did string `json:"did"` 26 Key string `json:"key"` 27 Name string `json:"name"` 28 + Rkey string `json:"rkey"` 29 Created *time.Time 30 } 31 ··· 43 func GetAllPublicKeys(e Execer) ([]PublicKey, error) { 44 var keys []PublicKey 45 46 + rows, err := e.Query(`select key, name, did, rkey, created from public_keys`) 47 if err != nil { 48 return nil, err 49 } ··· 52 for rows.Next() { 53 var publicKey PublicKey 54 var createdAt string 55 + if err := rows.Scan(&publicKey.Key, &publicKey.Name, &publicKey.Did, &publicKey.Rkey, &createdAt); err != nil { 56 return nil, err 57 } 58 createdAtTime, _ := time.Parse(time.RFC3339, createdAt) ··· 70 func GetPublicKeys(e Execer, did string) ([]PublicKey, error) { 71 var keys []PublicKey 72 73 + rows, err := e.Query(`select did, key, name, rkey, created from public_keys where did = ?`, did) 74 if err != nil { 75 return nil, err 76 } ··· 79 for rows.Next() { 80 var publicKey PublicKey 81 var createdAt string 82 + if err := rows.Scan(&publicKey.Did, &publicKey.Key, &publicKey.Name, &publicKey.Rkey, &createdAt); err != nil { 83 return nil, err 84 } 85 createdAtTime, _ := time.Parse(time.RFC3339, createdAt)
+2 -2
appview/pages/templates/repo/issues/issue.html
··· 5 6 {{ define "repoContent" }} 7 <header> 8 - <p class="text-2xl font-bold"> 9 {{ .Issue.Title }} 10 <span class="text-gray-500">#{{ .Issue.IssueId }}</span> 11 </p> ··· 18 {{ $icon = "circle-dot" }} 19 {{ end }} 20 21 - <section> 22 <div class="inline-flex items-center gap-2"> 23 <div id="state" 24 class="inline-flex items-center rounded px-3 py-1 {{ $bgColor }} text-sm">
··· 5 6 {{ define "repoContent" }} 7 <header> 8 + <p class="text-2xl"> 9 {{ .Issue.Title }} 10 <span class="text-gray-500">#{{ .Issue.IssueId }}</span> 11 </p> ··· 18 {{ $icon = "circle-dot" }} 19 {{ end }} 20 21 + <section class="mt-2"> 22 <div class="inline-flex items-center gap-2"> 23 <div id="state" 24 class="inline-flex items-center rounded px-3 py-1 {{ $bgColor }} text-sm">
+15 -6
appview/pages/templates/settings.html
··· 32 <section class="rounded bg-white drop-shadow-sm px-6 py-4 mb-6 w-full lg:w-fit"> 33 <div id="key-list" class="flex flex-col gap-6 mb-8"> 34 {{ range .PubKeys }} 35 - <div> 36 - <div class="inline-flex items-center gap-4"> 37 - <i class="w-3 h-3" data-lucide="key"></i> 38 - <p class="font-bold">{{ .Name }} </p> 39 - <p class="text-sm text-gray-500">added {{ .Created | timeFmt }}</p> 40 </div> 41 - <code class="block text-sm break-all text-gray-500">{{ .Key }}</code> 42 </div> 43 {{ end }} 44 </div>
··· 32 <section class="rounded bg-white drop-shadow-sm px-6 py-4 mb-6 w-full lg:w-fit"> 33 <div id="key-list" class="flex flex-col gap-6 mb-8"> 34 {{ range .PubKeys }} 35 + <div class="flex justify-between items-center gap-4"> 36 + <div> 37 + <div class="inline-flex items-center gap-4"> 38 + <i class="w-3 h-3" data-lucide="key"></i> 39 + <p class="font-bold">{{ .Name }}</p> 40 + <p class="text-sm text-gray-500">added {{ .Created | timeFmt }}</p> 41 + </div> 42 + <code class="block break-all text-sm break-all text-gray-500">{{ .Key }}</code> 43 </div> 44 + <button 45 + class="btn text-red-500 hover:text-red-700" 46 + title="Delete key" 47 + hx-delete="/settings/keys?name={{urlquery .Name}}&rkey={{urlquery .Rkey}}&key={{urlquery .Key}}" 48 + hx-confirm="Are you sure you wish to delete the key '{{ .Name }}'?"> 49 + <i class="w-5 h-5" data-lucide="trash-2"></i> 50 + </button> 51 </div> 52 {{ end }} 53 </div>
+60 -2
appview/state/settings.go
··· 48 return 49 } 50 51 - if err := db.AddPublicKey(s.db, did, name, key); err != nil { 52 log.Printf("adding public key: %s", err) 53 s.pages.Notice(w, "settings-keys", "Failed to add public key.") 54 return ··· 58 resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ 59 Collection: tangled.PublicKeyNSID, 60 Repo: did, 61 - Rkey: s.TID(), 62 Record: &lexutil.LexiconTypeDecoder{ 63 Val: &tangled.PublicKey{ 64 Created: time.Now().Format(time.RFC3339), ··· 74 } 75 76 log.Println("created atproto record: ", resp.Uri) 77 s.pages.HxLocation(w, "/settings") 78 return 79 }
··· 48 return 49 } 50 51 + rkey := s.TID() 52 + 53 + tx, err := s.db.Begin() 54 + if err != nil { 55 + log.Printf("failed to start tx; adding public key: %s", err) 56 + s.pages.Notice(w, "settings-keys", "Unable to add public key at this moment, try again later.") 57 + return 58 + } 59 + defer tx.Rollback() 60 + 61 + if err := db.AddPublicKey(tx, did, name, key, rkey); err != nil { 62 log.Printf("adding public key: %s", err) 63 s.pages.Notice(w, "settings-keys", "Failed to add public key.") 64 return ··· 68 resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ 69 Collection: tangled.PublicKeyNSID, 70 Repo: did, 71 + Rkey: rkey, 72 Record: &lexutil.LexiconTypeDecoder{ 73 Val: &tangled.PublicKey{ 74 Created: time.Now().Format(time.RFC3339), ··· 84 } 85 86 log.Println("created atproto record: ", resp.Uri) 87 + 88 + err = tx.Commit() 89 + if err != nil { 90 + log.Printf("failed to commit tx; adding public key: %s", err) 91 + s.pages.Notice(w, "settings-keys", "Unable to add public key at this moment, try again later.") 92 + return 93 + } 94 + 95 + s.pages.HxLocation(w, "/settings") 96 + return 97 + 98 + case http.MethodDelete: 99 + did := s.auth.GetDid(r) 100 + q := r.URL.Query() 101 + 102 + name := q.Get("name") 103 + rkey := q.Get("rkey") 104 + key := q.Get("key") 105 + 106 + log.Println(name) 107 + log.Println(rkey) 108 + log.Println(key) 109 + 110 + client, _ := s.auth.AuthorizedClient(r) 111 + 112 + if err := db.RemovePublicKey(s.db, did, name, key); err != nil { 113 + log.Printf("removing public key: %s", err) 114 + s.pages.Notice(w, "settings-keys", "Failed to remove public key.") 115 + return 116 + } 117 + 118 + if rkey != "" { 119 + // remove from pds too 120 + _, err := comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{ 121 + Collection: tangled.PublicKeyNSID, 122 + Repo: did, 123 + Rkey: rkey, 124 + }) 125 + 126 + // invalid record 127 + if err != nil { 128 + log.Printf("failed to delete record from PDS: %s", err) 129 + s.pages.Notice(w, "settings-keys", "Failed to remove key from PDS.") 130 + return 131 + } 132 + } 133 + log.Println("deleted successfully") 134 + 135 s.pages.HxLocation(w, "/settings") 136 return 137 }
+1
appview/state/state.go
··· 965 r.Use(AuthMiddleware(s)) 966 r.Get("/", s.Settings) 967 r.Put("/keys", s.SettingsKeys) 968 }) 969 970 r.Get("/keys/{user}", s.Keys)
··· 965 r.Use(AuthMiddleware(s)) 966 r.Get("/", s.Settings) 967 r.Put("/keys", s.SettingsKeys) 968 + r.Delete("/keys", s.SettingsKeys) 969 }) 970 971 r.Get("/keys/{user}", s.Keys)