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/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

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

Blame · server/web/templates/admin_users.html

Line attribution on main · 166 line(s)

43e681d8
Keenan Nemetz
4d ago
1 {{define "accounts_body"}}
395554f4
Keenan Nemetz
15d ago
2 {{if .Error}}<div class="flash bad">{{.Error}}</div>{{end}}
3
ed03b3d1
Keenan Nemetz
6h ago
4 <p class="muted">To change a role, inspect keys or sessions, or retire an account, open it from the <a href="/-/u">users directory</a>.</p>
9579c1f9
Keenan Nemetz
14d ago
5
8c72543b
Keenan Nemetz
5d ago
6 <h2>Invite a person</h2>
7 <p class="muted">Send them a one-time link: they choose a passkey, then can add an SSH key.</p>
ed03b3d1
Keenan Nemetz
6h ago
8 <form method="post" action="/-/users" class="form-block">
9579c1f9
Keenan Nemetz
14d ago
9 <input type="hidden" name="csrf" value="{{.CSRF}}">
10 <div class="card form-card">
11 <label>Account name
12 <input type="text" name="name" required maxlength="63" autocomplete="off" placeholder="lowercase-name">
13 </label>
5b814e99
Keenan Nemetz
14d ago
14 {{template "role-picker" (rolePicker "role" "none" "Instance role" "Instance roles apply to public repositories; admin applies everywhere." "instance" false)}}
9579c1f9
Keenan Nemetz
14d ago
15 </div>
ab326d3a
Keenan Nemetz
14d ago
16 <div class="form-actions"><button type="submit">{{icon "user"}}Create account</button></div>
9579c1f9
Keenan Nemetz
14d ago
17 </form>
8c72543b
Keenan Nemetz
5d ago
18
19 <h2>Create a bot account</h2>
20 <p class="muted">For a runner or another automation. It acts with the SSH key you paste here and cannot sign in to the browser or become an instance admin.</p>
ed03b3d1
Keenan Nemetz
6h ago
21 <form method="post" action="/-/users/bots" class="form-block">
8c72543b
Keenan Nemetz
5d ago
22 <input type="hidden" name="csrf" value="{{.CSRF}}">
23 <div class="card form-card">
24 <label>Account name
25 <input type="text" name="name" required maxlength="63" autocomplete="off" placeholder="lowercase-name">
26 </label>
27 <label for="bot-public-key">SSH public key</label>
28 <textarea id="bot-public-key" name="key" rows="3" placeholder="ssh-ed25519 AAAA... you@example.com" required></textarea>
29 {{template "role-picker" (rolePicker "role" "none" "Instance role" "Instance roles apply to public repositories. A bot cannot be an instance admin." "bot" false)}}
30 </div>
31 <div class="form-actions"><button type="submit">{{icon "terminal"}}Create bot</button></div>
32 </form>
395554f4
Keenan Nemetz
15d ago
33 {{end}}
34
35 {{define "admin_user"}}
36 {{template "header" .}}
9579c1f9
Keenan Nemetz
14d ago
37 <div class="page-head">
395554f4
Keenan Nemetz
15d ago
38 <div class="page-head-main">
8c72543b
Keenan Nemetz
5d ago
39 <h1>{{.Account.Name}}{{if .Account.Bot}} <span class="state">bot</span>{{end}}</h1>
395554f4
Keenan Nemetz
15d ago
40 <p class="page-sub">
62576fa8
Keenan Nemetz
14d ago
41 <span class="state {{.Account.Status}}">{{.Account.Status}}</span>
5b814e99
Keenan Nemetz
14d ago
42 · instance role {{.Account.Role}}
395554f4
Keenan Nemetz
15d ago
43 · created {{since .Account.Created.Unix}}
44 </p>
45 </div>
8c72543b
Keenan Nemetz
5d ago
46 {{if not .Account.Bot}}
9579c1f9
Keenan Nemetz
14d ago
47 <div class="page-head-actions">
ed03b3d1
Keenan Nemetz
6h ago
48 <form class="inline" method="post" action="/-/users/{{.Account.Name}}/invite">
395554f4
Keenan Nemetz
15d ago
49 <input type="hidden" name="csrf" value="{{.CSRF}}">
50 <button type="submit" class="secondary">{{icon "external-link"}}New enrollment link</button>
51 </form>
52 </div>
8c72543b
Keenan Nemetz
5d ago
53 {{end}}
395554f4
Keenan Nemetz
15d ago
54 </div>
55
9579c1f9
Keenan Nemetz
14d ago
56 {{if .Error}}<div class="flash bad">{{.Error}}</div>{{end}}
57
5b814e99
Keenan Nemetz
14d ago
58 <h2>Instance role</h2>
59 {{$role := .Account.Role.String}}
ed03b3d1
Keenan Nemetz
6h ago
60 <form method="post" action="/-/users/{{.Account.Name}}/role" class="form-block">
5b814e99
Keenan Nemetz
14d ago
61 <input type="hidden" name="csrf" value="{{.CSRF}}">
62 <div class="card form-card">
8c72543b
Keenan Nemetz
5d ago
63 {{template "role-picker" (rolePicker "role" $role (printf "Role for %s" .Account.Name) .RoleHelp .RoleScope false)}}
5b814e99
Keenan Nemetz
14d ago
64 </div>
65 <div class="form-actions">
66 <button type="submit">{{icon "check"}}Save role</button>
67 </div>
68 </form>
69
395554f4
Keenan Nemetz
15d ago
70 <h2>SSH keys</h2>
71 {{if .Account.Keys}}
72 <div class="panel">
73 <table>
74 <thead><tr><th>Fingerprint</th><th>Type</th><th>Comment</th><th></th></tr></thead>
75 <tbody>
76 {{range .Account.Keys}}
77 <tr>
78 <td><code>{{.Fingerprint}}</code></td>
79 <td>{{.Type}}</td>
80 <td class="muted">{{.Comment}}</td>
81 <td>
ed03b3d1
Keenan Nemetz
6h ago
82 <form class="inline" method="post" action="/-/users/{{$.Account.Name}}/keys/remove">
395554f4
Keenan Nemetz
15d ago
83 <input type="hidden" name="csrf" value="{{$.CSRF}}">
84 <input type="hidden" name="fingerprint" value="{{.Fingerprint}}">
85 <button type="submit" class="danger">Remove</button>
86 </form>
87 </td>
88 </tr>
89 {{end}}
90 </tbody>
91 </table>
92 </div>
8c72543b
Keenan Nemetz
5d ago
93 {{else if .Account.Bot}}
c7b9094f
Keenan Nemetz
1d ago
94 <div class="empty-state"><p>No SSH keys. This bot cannot act until a key is added.</p></div>
395554f4
Keenan Nemetz
15d ago
95 {{else}}
c7b9094f
Keenan Nemetz
1d ago
96 <div class="empty-state"><p>No SSH keys. This account can sign in with a passkey only.</p></div>
395554f4
Keenan Nemetz
15d ago
97 {{end}}
98
9579c1f9
Keenan Nemetz
14d ago
99 <div class="with-more">
100 <h2>Sessions</h2>
101 {{if .Sessions}}
ed03b3d1
Keenan Nemetz
6h ago
102 <form class="inline" method="post" action="/-/users/{{.Account.Name}}/sessions/revoke">
9579c1f9
Keenan Nemetz
14d ago
103 <input type="hidden" name="csrf" value="{{.CSRF}}">
104 <button type="submit" class="link">Revoke all sessions</button>
105 </form>
106 {{end}}
107 </div>
395554f4
Keenan Nemetz
15d ago
108 {{if .Sessions}}
109 <div class="panel">
110 <table>
111 <thead><tr><th>Created</th><th>Last seen</th><th>Expires</th><th>User agent</th></tr></thead>
112 <tbody>
113 {{range .Sessions}}
114 <tr>
115 <td class="nowrap">{{since .Created.Unix}}</td>
116 <td class="nowrap">{{since .LastSeen.Unix}}</td>
117 <td class="nowrap">{{.Expires.UTC.Format "2006-01-02 15:04"}}</td>
118 <td class="muted">{{.UserAgent}}</td>
119 </tr>
120 {{end}}
121 </tbody>
122 </table>
123 </div>
124 {{else}}
c7b9094f
Keenan Nemetz
1d ago
125 <div class="empty-state"><p>No browser sessions.</p></div>
395554f4
Keenan Nemetz
15d ago
126 {{end}}
127
128 <h2>Danger zone</h2>
ed03b3d1
Keenan Nemetz
6h ago
129 <form method="post" action="/-/users/{{.Account.Name}}/retire" class="form-block">
9579c1f9
Keenan Nemetz
14d ago
130 <input type="hidden" name="csrf" value="{{.CSRF}}">
131 <div class="card form-card danger-zone">
395554f4
Keenan Nemetz
15d ago
132 <h3>Retire account</h3>
133 <p class="muted">Disables the account, ends its sessions, and closes any enrollment links. The name is never reissued.</p>
134 <label>Type <code>{{.Account.Name}}</code> to confirm
135 <input type="text" name="confirm" required autocomplete="off">
136 </label>
9579c1f9
Keenan Nemetz
14d ago
137 </div>
138 <div class="form-actions"><button type="submit" class="danger">{{icon "circle-x"}}Retire account</button></div>
139 </form>
395554f4
Keenan Nemetz
15d ago
140 {{template "footer" .}}
141 {{end}}
142
143 {{define "admin_invite"}}
144 {{template "header" .}}
9579c1f9
Keenan Nemetz
14d ago
145 <div class="page-head">
395554f4
Keenan Nemetz
15d ago
146 <div class="page-head-main">
147 <h1>Enrollment link</h1>
62576fa8
Keenan Nemetz
14d ago
148 <p class="page-sub">For <strong>{{.Account.Name}}</strong> · expires {{.Expires.UTC.Format "2006-01-02 15:04 UTC"}}</p>
395554f4
Keenan Nemetz
15d ago
149 </div>
150 </div>
151
152 {{if not .BrowserLogin}}
ab326d3a
Keenan Nemetz
14d ago
153 <div class="flash bad">Browser sign-in is disabled on this instance, so this link cannot be used until public_url is set to an HTTPS URL.</div>
395554f4
Keenan Nemetz
15d ago
154 {{end}}
155
156 <div class="card">
157 <p>Send this link to the account holder. It is shown once, and any earlier unused link for this account has been superseded.</p>
158 <p><code>{{.Link}}</code></p>
159 <p><button type="button" class="secondary" data-copy="{{.Link}}">{{icon "copy"}}Copy link</button></p>
160 </div>
161
162 <div class="form-actions">
ed03b3d1
Keenan Nemetz
6h ago
163 <a class="button secondary" href="/-/users/{{.Account.Name}}">{{icon "user"}}Back to account</a>
395554f4
Keenan Nemetz
15d ago
164 </div>
165 {{template "footer" .}}
166 {{end}}