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.
|
f09ef39e
Keenan Nemetz
15d ago
|
1 | {{define "account"}} |
| 2 | {{template "header" .}} | |
|
074ae160
Keenan Nemetz
14d ago
|
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> | |
|
f09ef39e
Keenan Nemetz
15d ago
|
9 | |
|
796ac8c0
Keenan Nemetz
11d ago
|
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> | |
|
b42d384d
Keenan Nemetz
1d ago
|
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> | |
|
97b3b022
Keenan Nemetz
1d ago
|
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> | |
|
b42d384d
Keenan Nemetz
1d ago
|
31 | {{range .InstanceThemes}}<option value="{{.ID}}">{{.Name}}</option>{{end}} |
|
796ac8c0
Keenan Nemetz
11d ago
|
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 | ||
|
f09ef39e
Keenan Nemetz
15d ago
|
44 | <h2>SSH keys</h2> |
| 45 | {{if .Account.Keys}} | |
|
796ac8c0
Keenan Nemetz
11d ago
|
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> | |
|
ed03b3d1
Keenan Nemetz
4h ago
|
56 | <form method="post" action="/-/account/keys/remove"> |
|
796ac8c0
Keenan Nemetz
11d ago
|
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> | |
|
f09ef39e
Keenan Nemetz
15d ago
|
67 | {{else}} |
|
c7b9094f
Keenan Nemetz
1d ago
|
68 | <div class="empty-state"><p>No SSH keys yet.</p></div> |
|
f09ef39e
Keenan Nemetz
15d ago
|
69 | {{end}} |
|
ed03b3d1
Keenan Nemetz
4h ago
|
70 | <form method="post" action="/-/account/keys" class="form-block"> |
|
f09ef39e
Keenan Nemetz
15d ago
|
71 | <input type="hidden" name="csrf" value="{{.CSRF}}"> |
|
796ac8c0
Keenan Nemetz
11d ago
|
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> | |
|
f09ef39e
Keenan Nemetz
15d ago
|
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}} | |
|
796ac8c0
Keenan Nemetz
11d ago
|
81 | <div class="panel"> |
| 82 | <table> | |
|
7d7718fa
Keenan Nemetz
2h ago
|
83 | <thead><tr><th>Credential</th><th>Label</th><th>Created</th><th>Last used</th><th></th></tr></thead> |
|
796ac8c0
Keenan Nemetz
11d ago
|
84 | <tbody> |
| 85 | {{range .Credentials}} | |
| 86 | <tr> | |
| 87 | <td class="sha">{{credid .ID}}</td> | |
|
7d7718fa
Keenan Nemetz
2h ago
|
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> | |
|
796ac8c0
Keenan Nemetz
11d ago
|
96 | <td class="muted">{{since .Created.Unix}}</td> |
| 97 | <td class="muted">{{if .LastUsed.IsZero}}never{{else}}{{since .LastUsed.Unix}}{{end}}</td> | |
|
7d7718fa
Keenan Nemetz
2h ago
|
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> | |
|
796ac8c0
Keenan Nemetz
11d ago
|
105 | </tr> |
| 106 | {{end}} | |
| 107 | </tbody> | |
| 108 | </table> | |
| 109 | </div> | |
|
7d7718fa
Keenan Nemetz
2h ago
|
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> |
|
f09ef39e
Keenan Nemetz
15d ago
|
111 | {{else}} |
|
c7b9094f
Keenan Nemetz
1d ago
|
112 | <div class="empty-state"><p>No passkeys yet.</p></div> |
|
f09ef39e
Keenan Nemetz
15d ago
|
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}} | |
|
796ac8c0
Keenan Nemetz
11d ago
|
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> | |
|
f09ef39e
Keenan Nemetz
15d ago
|
145 | {{else}} |
|
c7b9094f
Keenan Nemetz
1d ago
|
146 | <div class="empty-state"><p>No sessions.</p></div> |
|
f09ef39e
Keenan Nemetz
15d ago
|
147 | {{end}} |
| 148 | {{template "footer" .}} | |
| 149 | {{end}} |