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.

Build out the forge web UI

f09ef39efe44de693748053a7b596ef328fcf06b · Keenan Nemetz · 15d ago · parent 70b70264

Build out the forge web UI

Turn the web surface into a compact, server-rendered forge with HTMX as the
progressive dynamic layer.

- Split templates and assets into embedded files; add a tokenised dark theme,
  Lucide icons, and vendored HTMX.
- Add the repository Overview page and a separate chronological Activity feed
  with type filters and HTMX fragment updates.
- Finish the issue and change workflows: create pages, comments, close/reopen,
  labels and assignees, approval, discussion, line-anchored review comments,
  and HTMX list filters.
- Add syntax-highlighted blobs, contributor/statistics derivation, branch-aware
  code browsing, and a repository Runs list.
- Add a loopback-only development login for local write testing, with explicit
  configuration and listener checks.
- Extend tests for the new pages, fragments, labels, assignees, anchors, and
  development login.

server/web/templates/auth.html +81

@@ -0,0 +1,81 @@
1 {{define "login"}}
2 {{template "header" .}}
3 {{if not .Enabled}}
4 <div class="auth">
5 <div class="card">
6 <h1>Log in</h1>
7 <p class="muted">{{.Reason}}</p>
8 </div>
9 </div>
10 {{else}}
11 <form class="auth" data-auth="login" data-next="{{.Next}}">
12 <div class="card form-card">
13 <h1>Log in</h1>
14 <label>Account name
15 <input type="text" name="username" autocomplete="username webauthn" required autofocus>
16 </label>
17 <p class="error" data-auth-error></p>
18 {{if .Registration}}
19 <p class="muted">No account yet? <a href="/register">Create one</a>.</p>
20 {{else}}
21 <p class="muted">No account yet? Ask an administrator for a one-time enrollment link.</p>
22 {{end}}
23 </div>
24 <div class="form-actions"><button type="submit">Use a passkey</button></div>
25 </form>
26 {{end}}
27 {{template "footer" .}}
28 {{end}}
29
30 {{define "register"}}
31 {{template "header" .}}
32 <form class="auth" data-auth="register">
33 <div class="card form-card">
34 <h1>Create an account</h1>
35 <p class="muted">Pick a name and register a passkey. You can add an SSH key after signing in.</p>
36 <label>Account name
37 <input type="text" name="username" pattern="[a-z0-9][a-z0-9_-]{1,31}" maxlength="32" autocomplete="username webauthn" required autofocus>
38 </label>
39 <label>Display name <span class="muted">(optional, shown to other people)</span>
40 <input type="text" name="display" maxlength="64" autocomplete="name">
41 </label>
42 <p class="error" data-auth-error></p>
43 <p class="muted">Names are 2–32 characters: lowercase letters, digits, <code>-</code> and <code>_</code>.
44 The account name is permanent — it is the folder your branches live under and cannot be
45 changed later. The display name is a label and can be changed any time.</p>
46 </div>
47 <div class="form-actions"><button type="submit">Create account and passkey</button></div>
48 </form>
49 {{template "footer" .}}
50 {{end}}
51
52 {{define "invite"}}
53 {{template "header" .}}
54 {{if and .Account .Enabled .Token}}
55 <form class="auth" data-auth="invite" data-token="{{.Token}}">
56 <div class="card form-card">
57 <h1>Join {{.Account.Name}}</h1>
58 <p class="muted">Register this device as a passkey for <strong>{{.Account.Name}}</strong>. The link works once.</p>
59 <p class="error" data-auth-error></p>
60 </div>
61 <div class="form-actions"><button type="submit">Create a passkey</button></div>
62 </form>
63 {{else}}
64 <div class="auth">
65 <div class="card">
66 {{if .Account}}
67 <h1>Join {{.Account.Name}}</h1>
68 {{if not .Enabled}}
69 <p class="muted">{{.Reason}}</p>
70 {{else}}
71 <p class="error">This enrollment link is no longer valid.</p>
72 {{end}}
73 {{else}}
74 <h1>Enrollment link</h1>
75 <p class="error">This enrollment link is invalid or has expired. Ask an administrator for a new one.</p>
76 {{end}}
77 </div>
78 </div>
79 {{end}}
80 {{template "footer" .}}
81 {{end}}