An experimental IndieWeb site built in Go.
1package pages
2
3import (
4 "go.hacdias.com/indielib/indieauth"
5 "strings"
6)
7
8templ Auth(req *indieauth.AuthenticationRequest, app *indieauth.ApplicationMetadata, nonceId string, nonce string) {
9 <main class="mx-auto max-w-screen-sm">
10 <p class="text-sm font-thin italic">authorize access to</p>
11 <h1 class="mb-8 text-3xl font-extrabold">puregarlic dot space</h1>
12 <div class="pt-6 border border-highlightMed rounded bg-surface">
13 if app != nil {
14 <div class="px-6 flex gap-6 items-center">
15 if len(app.Logo) > 0 {
16 <img class="max-w-12" src={ app.Logo }/>
17 }
18 <div>
19 <h2 class="font-bold text-lg">{ app.Name }</h2>
20 if len(app.Author) > 0 {
21 <p class="text-sm font-light">by { app.Author }</p>
22 }
23 </div>
24 </div>
25 } else {
26 <h2 class="px-6 font-bold text-subtle">unidentified client</h2>
27 }
28 <div class="mt-6 grid md:grid-cols-[max-content_1fr] *:border-highlightMed">
29 <h3 class="px-6 pt-4 pb-2 md:py-4 border-t bg-overlay md:border-r text-subtle font-bold">Client ID</h3>
30 <p class="px-6 pb-4 pt-1 md:py-4 md:border-t bg-overlay min-w-0 overflow-x-scroll">{ req.ClientID }</p>
31 <h3 class="px-6 pt-4 pb-2 md:py-4 border-t md:border-b md:border-r text-subtle font-bold">Redirect URL</h3>
32 <p class="px-6 pb-4 pt-1 md:py-4 md:border-y min-w-0 overflow-x-scroll">{ req.RedirectURI }</p>
33 <h3 class="px-6 pt-4 pb-2 md:py-4 border-t bg-overlay md:border-r text-subtle font-bold">Scopes</h3>
34 <ul class="px-6 pb-4 pt-1 md:py-4 bg-overlay flex flex-wrap gap-3">
35 for _, scope := range req.Scopes {
36 <li class="px-2 py-1 text-sm bg-pine rounded">{ scope }</li>
37 }
38 </ul>
39 </div>
40 </div>
41 <form method="post" action="/authorization/accept">
42 <input type="hidden" name="response_type" value="code"/>
43 <input type="hidden" name="scope" value={ strings.Join(req.Scopes, " ") }/>
44 <input type="hidden" name="redirect_uri" value={ req.RedirectURI }/>
45 <input type="hidden" name="client_id" value={ req.ClientID }/>
46 <input type="hidden" name="state" value={ req.State }/>
47 <input type="hidden" name="code_challenge" value={ req.CodeChallenge }/>
48 <input type="hidden" name="code_challenge_method" value={ req.CodeChallengeMethod }/>
49 // CSRF protections
50 <input type="hidden" name="nonce_id" value={ nonceId }/>
51 <input type="hidden" name="nonce" value={ nonce }/>
52 <button
53 class="mt-8 px-3 py-2 flex items-center justify-center gap-2 bg-surface border border-highlightMed text-sm font-bold transition rounded hover:bg-foam hover:text-surface"
54 id="submit"
55 >
56 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" class="size-4">
57 <path fill-rule="evenodd" d="M8 15A7 7 0 1 0 8 1a7 7 0 0 0 0 14Zm3.844-8.791a.75.75 0 0 0-1.188-.918l-3.7 4.79-1.649-1.833a.75.75 0 1 0-1.114 1.004l2.25 2.5a.75.75 0 0 0 1.15-.043l4.25-5.5Z" clip-rule="evenodd"></path>
58 </svg>
59 Authorize
60 </button>
61 </form>
62 </main>
63}