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
···
return nil
})
+
runMigration(db, "add-rkey-to-pubkeys", func(tx *sql.Tx) error {
+
// add unconstrained column
+
_, err := tx.Exec(`
+
alter table public_keys
+
add column rkey text;
+
`)
+
if err != nil {
+
return err
+
}
+
+
// backfill
+
_, err = tx.Exec(`
+
update public_keys
+
set rkey = ''
+
where rkey is null;
+
`)
+
if err != nil {
+
return err
+
}
+
+
return nil
+
})
+
return &DB{db}, nil
}
+15 -10
appview/db/pubkeys.go
···
"time"
)
-
func AddPublicKey(e Execer, did, name, key string) error {
-
query := `insert or ignore into public_keys (did, name, key) values (?, ?, ?)`
-
_, err := e.Exec(query, did, name, key)
+
func AddPublicKey(e Execer, did, name, key, rkey string) error {
+
_, err := e.Exec(
+
`insert or ignore into public_keys (did, name, key, rkey)
+
values (?, ?, ?, ?)`,
+
did, name, key, rkey)
return err
}
-
func RemovePublicKey(e Execer, did string) error {
-
query := `delete from public_keys where did = ?`
-
_, err := e.Exec(query, did)
+
func RemovePublicKey(e Execer, did, name, key string) error {
+
_, err := e.Exec(`
+
delete from public_keys
+
where did = ? and name = ? and key = ?`,
+
did, name, key)
return err
}
···
Did string `json:"did"`
Key string `json:"key"`
Name string `json:"name"`
+
Rkey string `json:"rkey"`
Created *time.Time
}
···
func GetAllPublicKeys(e Execer) ([]PublicKey, error) {
var keys []PublicKey
-
rows, err := e.Query(`select key, name, did, created from public_keys`)
+
rows, err := e.Query(`select key, name, did, rkey, created from public_keys`)
if err != nil {
return nil, err
}
···
for rows.Next() {
var publicKey PublicKey
var createdAt string
-
if err := rows.Scan(&publicKey.Key, &publicKey.Name, &publicKey.Did, &createdAt); err != nil {
+
if err := rows.Scan(&publicKey.Key, &publicKey.Name, &publicKey.Did, &publicKey.Rkey, &createdAt); err != nil {
return nil, err
}
createdAtTime, _ := time.Parse(time.RFC3339, createdAt)
···
func GetPublicKeys(e Execer, did string) ([]PublicKey, error) {
var keys []PublicKey
-
rows, err := e.Query(`select did, key, name, created from public_keys where did = ?`, did)
+
rows, err := e.Query(`select did, key, name, rkey, created from public_keys where did = ?`, did)
if err != nil {
return nil, err
}
···
for rows.Next() {
var publicKey PublicKey
var createdAt string
-
if err := rows.Scan(&publicKey.Did, &publicKey.Key, &publicKey.Name, &createdAt); err != nil {
+
if err := rows.Scan(&publicKey.Did, &publicKey.Key, &publicKey.Name, &publicKey.Rkey, &createdAt); err != nil {
return nil, err
}
createdAtTime, _ := time.Parse(time.RFC3339, createdAt)
+2 -2
appview/pages/templates/repo/issues/issue.html
···
{{ define "repoContent" }}
<header>
-
<p class="text-2xl font-bold">
+
<p class="text-2xl">
{{ .Issue.Title }}
<span class="text-gray-500">#{{ .Issue.IssueId }}</span>
</p>
···
{{ $icon = "circle-dot" }}
{{ end }}
-
<section>
+
<section class="mt-2">
<div class="inline-flex items-center gap-2">
<div id="state"
class="inline-flex items-center rounded px-3 py-1 {{ $bgColor }} text-sm">
+15 -6
appview/pages/templates/settings.html
···
<section class="rounded bg-white drop-shadow-sm px-6 py-4 mb-6 w-full lg:w-fit">
<div id="key-list" class="flex flex-col gap-6 mb-8">
{{ range .PubKeys }}
-
<div>
-
<div class="inline-flex items-center gap-4">
-
<i class="w-3 h-3" data-lucide="key"></i>
-
<p class="font-bold">{{ .Name }} </p>
-
<p class="text-sm text-gray-500">added {{ .Created | timeFmt }}</p>
+
<div class="flex justify-between items-center gap-4">
+
<div>
+
<div class="inline-flex items-center gap-4">
+
<i class="w-3 h-3" data-lucide="key"></i>
+
<p class="font-bold">{{ .Name }}</p>
+
<p class="text-sm text-gray-500">added {{ .Created | timeFmt }}</p>
+
</div>
+
<code class="block break-all text-sm break-all text-gray-500">{{ .Key }}</code>
</div>
-
<code class="block text-sm break-all text-gray-500">{{ .Key }}</code>
+
<button
+
class="btn text-red-500 hover:text-red-700"
+
title="Delete key"
+
hx-delete="/settings/keys?name={{urlquery .Name}}&rkey={{urlquery .Rkey}}&key={{urlquery .Key}}"
+
hx-confirm="Are you sure you wish to delete the key '{{ .Name }}'?">
+
<i class="w-5 h-5" data-lucide="trash-2"></i>
+
</button>
</div>
{{ end }}
</div>
+60 -2
appview/state/settings.go
···
return
}
-
if err := db.AddPublicKey(s.db, did, name, key); err != nil {
+
rkey := s.TID()
+
+
tx, err := s.db.Begin()
+
if err != nil {
+
log.Printf("failed to start tx; adding public key: %s", err)
+
s.pages.Notice(w, "settings-keys", "Unable to add public key at this moment, try again later.")
+
return
+
}
+
defer tx.Rollback()
+
+
if err := db.AddPublicKey(tx, did, name, key, rkey); err != nil {
log.Printf("adding public key: %s", err)
s.pages.Notice(w, "settings-keys", "Failed to add public key.")
return
···
resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
Collection: tangled.PublicKeyNSID,
Repo: did,
-
Rkey: s.TID(),
+
Rkey: rkey,
Record: &lexutil.LexiconTypeDecoder{
Val: &tangled.PublicKey{
Created: time.Now().Format(time.RFC3339),
···
}
log.Println("created atproto record: ", resp.Uri)
+
+
err = tx.Commit()
+
if err != nil {
+
log.Printf("failed to commit tx; adding public key: %s", err)
+
s.pages.Notice(w, "settings-keys", "Unable to add public key at this moment, try again later.")
+
return
+
}
+
+
s.pages.HxLocation(w, "/settings")
+
return
+
+
case http.MethodDelete:
+
did := s.auth.GetDid(r)
+
q := r.URL.Query()
+
+
name := q.Get("name")
+
rkey := q.Get("rkey")
+
key := q.Get("key")
+
+
log.Println(name)
+
log.Println(rkey)
+
log.Println(key)
+
+
client, _ := s.auth.AuthorizedClient(r)
+
+
if err := db.RemovePublicKey(s.db, did, name, key); err != nil {
+
log.Printf("removing public key: %s", err)
+
s.pages.Notice(w, "settings-keys", "Failed to remove public key.")
+
return
+
}
+
+
if rkey != "" {
+
// remove from pds too
+
_, err := comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
+
Collection: tangled.PublicKeyNSID,
+
Repo: did,
+
Rkey: rkey,
+
})
+
+
// invalid record
+
if err != nil {
+
log.Printf("failed to delete record from PDS: %s", err)
+
s.pages.Notice(w, "settings-keys", "Failed to remove key from PDS.")
+
return
+
}
+
}
+
log.Println("deleted successfully")
+
s.pages.HxLocation(w, "/settings")
return
}
+1
appview/state/state.go
···
r.Use(AuthMiddleware(s))
r.Get("/", s.Settings)
r.Put("/keys", s.SettingsKeys)
+
r.Delete("/keys", s.SettingsKeys)
})
r.Get("/keys/{user}", s.Keys)