Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Code

392 commit(s) on main

Merge change request 01M70WES5ZZDJ6RP226WB11BBZ: Let people rename and remove their own passkeys keenan · 1h ago 4b8c9e1d
history blame raw 5.7 KiB
1{{define "account"}}
2{{template "header" .}}
3<div class="page-head">
4 <div class="page-head-main">
5 <h1>Account</h1>
6 <p class="page-sub"><strong>{{.Account.Name}}</strong> · your account name is permanent</p>
7 </div>
8</div>
9
10<h2>Appearance</h2>
11<div class="card form-card">
12 <label>Theme
13 <select data-theme-select aria-label="Theme">
14 <option value="system" selected>System</option>
15 <option value="everforest-dark-hard">Everforest Dark · Hard</option>
16 <option value="everforest-dark-medium">Everforest Dark · Medium</option>
17 <option value="everforest-dark-soft">Everforest Dark · Soft</option>
18 <option value="everforest-light-hard">Everforest Light · Hard</option>
19 <option value="everforest-light-medium">Everforest Light · Medium</option>
20 <option value="everforest-light-soft">Everforest Light · Soft</option>
21 <option value="catppuccin-mocha">Catppuccin Mocha</option>
22 <option value="catppuccin-latte">Catppuccin Latte</option>
23 <option value="nord">Nord</option>
24 <option value="solarized-light">Solarized Light</option>
25 <option value="rose-pine-moon">Rosé Pine Moon</option>
26 <option value="rose-pine-dawn">Rosé Pine Dawn</option>
27 <option value="kanagawa-wave">Kanagawa Wave</option>
28 <option value="dracula">Dracula</option>
29 <option value="tokyo-night">Tokyo Night</option>
30 <option value="ayu-light">Ayu Light</option>
31 {{range .InstanceThemes}}<option value="{{.ID}}">{{.Name}}</option>{{end}}
32 </select>
33 </label>
34 <label>Text size
35 <select data-font-scale-select aria-label="Text size">
36 <option value="small">Small · 90%</option>
37 <option value="medium" selected>Medium · 100%</option>
38 <option value="large">Large · 110%</option>
39 </select>
40 </label>
41 <p class="muted">Both are stored in this browser, not on your account. System follows your operating system and uses the medium contrast. Text size scales labels, prose, and code.</p>
42</div>
43
44<h2>SSH keys</h2>
45{{if .Account.Keys}}
46<div class="panel">
47 <table>
48 <thead><tr><th>Fingerprint</th><th>Type</th><th>Comment</th><th></th></tr></thead>
49 <tbody>
50 {{range .Account.Keys}}
51 <tr>
52 <td class="sha">{{.Fingerprint}}</td>
53 <td class="muted">{{.Type}}</td>
54 <td class="muted">{{.Comment}}</td>
55 <td>
56 <form method="post" action="/-/account/keys/remove">
57 <input type="hidden" name="csrf" value="{{$.CSRF}}">
58 <input type="hidden" name="fingerprint" value="{{.Fingerprint}}">
59 <button class="link" type="submit">remove</button>
60 </form>
61 </td>
62 </tr>
63 {{end}}
64 </tbody>
65 </table>
66</div>
67{{else}}
68<div class="empty-state"><p>No SSH keys yet.</p></div>
69{{end}}
70<form method="post" action="/-/account/keys" class="form-block">
71 <input type="hidden" name="csrf" value="{{.CSRF}}">
72 <label for="public-key">Add public key</label>
73 <div class="card form-card key-card">
74 <textarea id="public-key" name="key" rows="3" placeholder="ssh-ed25519 AAAA... you@example.com" required></textarea>
75 </div>
76 <div class="form-actions"><button type="submit">{{icon "plus"}}Add SSH key</button></div>
77</form>
78
79<h2>Passkeys</h2>
80{{if .Credentials}}
81<div class="panel">
82 <table>
83 <thead><tr><th>Credential</th><th>Label</th><th>Created</th><th>Last used</th><th></th></tr></thead>
84 <tbody>
85 {{range .Credentials}}
86 <tr>
87 <td class="sha">{{credid .ID}}</td>
88 <td>
89 <form method="post" action="/-/account/passkeys/rename" class="inline">
90 <input type="hidden" name="csrf" value="{{$.CSRF}}">
91 <input type="hidden" name="credential" value="{{credid .ID}}">
92 <input type="text" name="label" value="{{.Label}}" maxlength="128" placeholder="passkey" aria-label="Passkey label">
93 <button class="link" type="submit">rename</button>
94 </form>
95 </td>
96 <td class="muted">{{since .Created.Unix}}</td>
97 <td class="muted">{{if .LastUsed.IsZero}}never{{else}}{{since .LastUsed.Unix}}{{end}}</td>
98 <td>
99 <form method="post" action="/-/account/passkeys/remove" data-confirm="Remove this passkey? Sessions that signed in with it end now.">
100 <input type="hidden" name="csrf" value="{{$.CSRF}}">
101 <input type="hidden" name="credential" value="{{credid .ID}}">
102 <button class="link" type="submit">remove</button>
103 </form>
104 </td>
105 </tr>
106 {{end}}
107 </tbody>
108 </table>
109</div>
110<p class="muted">A label is only what you call a passkey; renaming one does not change what it can do. Removing one ends the sessions that signed in with it. Your last passkey cannot be removed while it is your only way into your account: register another passkey or add an SSH key first.</p>
111{{else}}
112<div class="empty-state"><p>No passkeys yet.</p></div>
113{{end}}
114
115{{if .Enabled}}
116<h2>Add a passkey</h2>
117<form data-auth="passkey" class="form-block">
118 <div class="card form-card">
119 <label>Label <input type="text" name="label" placeholder="laptop, phone, security key"></label>
120 <p class="error" data-auth-error></p>
121 </div>
122 <div class="form-actions"><button type="submit">{{icon "plus"}}Register this device</button></div>
123</form>
124{{else}}
125<p class="muted">{{.Reason}}</p>
126{{end}}
127
128<h2>Sessions</h2>
129{{if .Sessions}}
130<div class="panel">
131 <table>
132 <thead><tr><th>Created</th><th>Last seen</th><th>Expires</th><th>Client</th></tr></thead>
133 <tbody>
134 {{range .Sessions}}
135 <tr>
136 <td class="muted">{{since .Created.Unix}}</td>
137 <td class="muted">{{since .LastSeen.Unix}}</td>
138 <td class="muted">{{.Expires.Format "2006-01-02 15:04"}}</td>
139 <td class="muted">{{.UserAgent}}</td>
140 </tr>
141 {{end}}
142 </tbody>
143 </table>
144</div>
145{{else}}
146<div class="empty-state"><p>No sessions.</p></div>
147{{end}}
148{{template "footer" .}}
149{{end}}
150