diff options
| author | Lena <lena@omega> | 2026-08-01 00:00:00 +0000 |
|---|---|---|
| committer | Lena <lena@omega> | 2026-08-01 00:00:00 +0000 |
| commit | bb6bc2387d58c737dbf92e73f8544bf39319dbd8 (patch) | |
| tree | 6d5eaf5dac213074cd832da50f64260fce728fed /templates/settings.html | |
| download | git-forge-bb6bc2387d58c737dbf92e73f8544bf39319dbd8.tar.gz | |
A small self-hosted git forge: HTTP push and pull, cgit browsing,
local and OIDC accounts, TOTP, scoped push tokens, per-repo
permissions, issues, a wiki, and outbound mail.
It does not reimplement git. git-http-backend and cgit run as CGI
behind its own listener, which authorises every request before
exec'ing either. One binary, one data directory, one listener: no
database, no JavaScript, and state is JSON in a git repo with a
working tree.
Diffstat (limited to 'templates/settings.html')
| -rw-r--r-- | templates/settings.html | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/templates/settings.html b/templates/settings.html new file mode 100644 index 0000000..8b2f0f1 --- /dev/null +++ b/templates/settings.html @@ -0,0 +1,126 @@ +{{define "title"}}Settings - {{.Site}}{{end}} +{{define "main"}} +<h2>Account</h2> +<p> +Signed in as {{template "who" .User}}{{if .Admin}}, a global admin{{end}}. +</p> + +<h3>Email and notifications</h3> +{{if .MailOff}} +<p class="dim"> +Mail is turned off on this instance, so nothing is sent. The address below is +still what commits made through the web are attributed to. +</p> +{{else}} +<p class="dim"> +An address receives nothing until a link sent to it has been followed. Notices +about your own account ignore the toggle below, because they are security facts +rather than activity. +</p> +{{end}} +<form method="post" action="/settings/email"> +<input type="hidden" name="csrf" value="{{.CSRF}}"> +<p> +<label for="email">Email address</label> +<input id="email" name="email" type="email" value="{{.Data.Email}}"> +{{if .Data.Email}}{{if not .Data.EmailConfirmed}}<span class="dim">unconfirmed</span>{{end}}{{end}} +</p> +<p> +<label for="notify"> +<input id="notify" name="notify" type="checkbox" value="yes" {{if .Data.Notify}}checked{{end}}> +Send me issue and repository notifications +</label> +</p> +<p><button type="submit">Save</button></p> +</form> + +{{if .Data.Local}} +<h3>Change password</h3> +<form method="post" action="/settings/password"> +<input type="hidden" name="csrf" value="{{.CSRF}}"> +<p> +<label for="current">Current password</label> +<input id="current" name="current" type="password" autocomplete="current-password" required> +</p> +<p> +<label for="new">New password</label> +<input id="new" name="new" type="password" autocomplete="new-password" required> +</p> +<p> +<label for="again">New password again</label> +<input id="again" name="again" type="password" autocomplete="new-password" required> +</p> +<p><button type="submit">Change password</button></p> +</form> +{{else}} +<h3>Password</h3> +<p>This account signs in through an external provider, so there is no password here.</p> +{{end}} + +<h3>Push tokens</h3> +<p class="dim"> +Git over HTTP takes a token, never your password. A token is scoped to one +repository and carries the access you already have there: clone if you can read +it, push if you can write it, the wiki if you may edit it. It carries no second +factor, and it can be revoked on its own without touching anything else. +</p> +<pre>git clone {{.Base}}/section/repo.git +Username: {{.User}} +Password: the token</pre> +{{with .Data.Secret}} +<div class="notice">Token for {{$.User}}, shown once:</div> +<pre id="token">{{.}}</pre> +{{end}} +<table summary="push tokens" class="list nowrap"> +<tr class="nohover"> +<th class="left">Id</th><th class="left">Repository</th> +<th class="left">Made</th><th class="left">Last used</th><th class="left"></th> +</tr> +{{range .Data.Tokens}} +<tr> +<td>{{.ID}}</td> +<td><a href="/{{.Repo}}/">{{.Repo}}</a></td> +<td class="dim">{{if .Created}}{{.Created}}{{else}}unknown{{end}}</td> +<td class="dim">{{if .Used}}{{.Used}}{{else}}never{{end}}</td> +<td> +<form method="post" action="/settings/tokens/revoke"> +<input type="hidden" name="csrf" value="{{$.CSRF}}"> +<input type="hidden" name="id" value="{{.ID}}"> +<button type="submit">revoke</button> +</form> +</td> +</tr> +{{else}} +<tr><td colspan="5" class="dim">None. Mint one below to push over HTTP.</td></tr> +{{end}} +</table> +<p class="dim"> +Dates are days, not times: a write on every request git makes would be a write +on every request git makes. A token that has never been used, or was last used +a long time ago, is one worth revoking. +</p> +<form method="post" action="/settings/tokens"> +<input type="hidden" name="csrf" value="{{.CSRF}}"> +<p> +<label for="repo">Repository you can reach</label> +<input id="repo" name="repo" placeholder="section/repo" autocapitalize="none" required> +</p> +<p><button type="submit">Mint a token</button></p> +</form> + +<h3>Authenticator</h3> +<p> +<a href="/settings/totp">Second factor</a>. An account with the global admin +flag has to have one before it can administer anything. +</p> + +<h3>Sessions</h3> +<p> +Signing out everywhere invalidates every session cookie ever issued for this +account, including this browser's. +</p> +<form method="post" action="/settings/sessions"> +<input type="hidden" name="csrf" value="{{.CSRF}}"> +<p><button type="submit">Sign out everywhere</button></p> +</form> +{{end}} |