Weighs the soul of incoming HTTP requests to stop AI crawlers
1package web
2
3import (
4 "fmt"
5 "github.com/TecharoHQ/anubis"
6 "github.com/TecharoHQ/anubis/lib/localization"
7 "github.com/TecharoHQ/anubis/lib/policy/config"
8 "github.com/TecharoHQ/anubis/xess"
9)
10
11templ base(title string, body templ.Component, impressum *config.Impressum, challenge any, ogTags map[string]string, localizer *localization.SimpleLocalizer) {
12 <!DOCTYPE html>
13 <html lang="en">
14 <head>
15 <title>{ title }</title>
16 <link rel="stylesheet" href={ anubis.BasePrefix + xess.URL }/>
17 <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
18 <meta name="robots" content="noindex,nofollow"/>
19 for key, value := range ogTags {
20 <meta property={ key } content={ value }/>
21 }
22 <style>
23 body,
24 html {
25 height: 100%;
26 display: flex;
27 justify-content: center;
28 align-items: center;
29 margin-left: auto;
30 margin-right: auto;
31 }
32
33 .centered-div {
34 text-align: center;
35 }
36
37 #status {
38 font-variant-numeric: tabular-nums;
39 }
40
41 #progress {
42 display: none;
43 width: 90%;
44 width: min(20rem, 90%);
45 height: 2rem;
46 border-radius: 1rem;
47 overflow: hidden;
48 margin: 1rem 0 2rem;
49 outline-offset: 2px;
50 outline: #b16286 solid 4px;
51 }
52
53 .bar-inner {
54 background-color: #b16286;
55 height: 100%;
56 width: 0;
57 transition: width 0.25s ease-in;
58 }
59 </style>
60 @templ.JSONScript("anubis_version", anubis.Version)
61 if challenge != nil {
62 @templ.JSONScript("anubis_challenge", challenge)
63 }
64 @templ.JSONScript("anubis_base_prefix", anubis.BasePrefix)
65 </head>
66 <body id="top">
67 <main>
68 <center>
69 <h1 id="title" class=".centered-div">{ title }</h1>
70 </center>
71 @body
72 <footer>
73 <center>
74 <p>
75 { localizer.T("protected_by") } <a href="https://github.com/TecharoHQ/anubis">Anubis</a> from <a
76 href="https://techaro.lol"
77>Techaro</a>. { localizer.T("made_with") }.
78 </p>
79 <p>{ localizer.T("mascot_design") } <a href="https://bsky.app/profile/celphase.bsky.social">{ localizer.T("celphase") }</a>.</p>
80 if impressum != nil {
81 <p>
82 @templ.Raw(impressum.Footer)
83 -- <a href={ templ.SafeURL(fmt.Sprintf("%simprint", anubis.APIPrefix)) }>Imprint</a>
84 </p>
85 }
86 </center>
87 </footer>
88 </main>
89 </body>
90 </html>
91}
92
93templ index(localizer *localization.SimpleLocalizer) {
94 <div class="centered-div">
95 <img id="image" style="width:100%;max-width:256px;" src={ anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=" + anubis.Version }/>
96 <img style="display:none;" style="width:100%;max-width:256px;" src={ anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/happy.webp?cacheBuster=" + anubis.Version }/>
97 <p id="status">{ localizer.T("loading") }</p>
98 <script async type="module" src={ anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/js/main.mjs?cacheBuster=" + anubis.Version }></script>
99 <div id="progress" role="progressbar" aria-labelledby="status">
100 <div class="bar-inner"></div>
101 </div>
102 <details>
103 <summary>{ localizer.T("why_am_i_seeing") }</summary>
104 <p>
105 { localizer.T("ai_companies_explanation") }
106 </p>
107 <p>
108 { localizer.T("anubis_compromise") }
109 </p>
110 <p>
111 { localizer.T("hack_purpose") }
112 </p>
113 <p>
114 { localizer.T("jshelter_note") }
115 </p>
116 <p>{ localizer.T("version_info") } <code>{ anubis.Version }</code>.</p>
117 </details>
118 <noscript>
119 <p>
120 { localizer.T("javascript_required") }
121 </p>
122 </noscript>
123 <div id="testarea"></div>
124 </div>
125}
126
127templ errorPage(message string, mail string, localizer *localization.SimpleLocalizer) {
128 <div class="centered-div">
129 <img id="image" alt="Sad Anubis" style="width:100%;max-width:256px;" src={ anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/reject.webp?cacheBuster=" + anubis.Version }/>
130 <p>{ message }.</p>
131 <button onClick="window.location.reload();">{ localizer.T("try_again") }</button>
132 if mail != "" {
133 <p>
134 <a href="/">{ localizer.T("go_home") }</a> { localizer.T("contact_webmaster") }
135 <a href={ "mailto:" + templ.SafeURL(mail) }>
136 { mail }
137 </a>
138 </p>
139 } else {
140 <p><a href="/">{ localizer.T("go_home") }</a></p>
141 }
142 </div>
143}
144
145templ StaticHappy(localizer *localization.SimpleLocalizer) {
146 <div class="centered-div">
147 <img
148 style="display:none;"
149 style="width:100%;max-width:256px;"
150 src={ "/.within.website/x/cmd/anubis/static/img/happy.webp?cacheBuster=" +
151 anubis.Version }
152 />
153 <p>{ localizer.T("static_check_endpoint") }</p>
154 </div>
155}
156
157templ bench(localizer *localization.SimpleLocalizer) {
158 <div style="height:20rem;display:flex">
159 <table style="margin-top:1rem;display:grid;grid-template:auto 1fr/auto auto;gap:0 0.5rem">
160 <thead
161 style="border-bottom:1px solid black;padding:0.25rem 0;display:grid;grid-template:1fr/subgrid;grid-column:1/-1"
162 >
163 <tr id="table-header" style="display:contents">
164 <th style="width:4.5rem">{ localizer.T("time") }</th>
165 <th style="width:4rem">{ localizer.T("iters") }</th>
166 </tr>
167 <tr id="table-header-compare" style="display:none">
168 <th style="width:4.5rem">{ localizer.T("time_a") }</th>
169 <th style="width:4rem">{ localizer.T("iters_a") }</th>
170 <th style="width:4.5rem">{ localizer.T("time_b") }</th>
171 <th style="width:4rem">{ localizer.T("iters_b") }</th>
172 </tr>
173 </thead>
174 <tbody
175 id="results"
176 style="padding-top:0.25rem;display:grid;grid-template-columns:subgrid;grid-auto-rows:min-content;grid-column:1/-1;row-gap:0.25rem;overflow-y:auto;font-variant-numeric:tabular-nums"
177 ></tbody>
178 </table>
179 <div class="centered-div">
180 <img id="image" style="width:100%;max-width:256px;" src={ anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/img/pensive.webp?cacheBuster=" + anubis.Version }/>
181 <p id="status" style="max-width:256px">{ localizer.T("loading") }</p>
182 <script async type="module" src={ anubis.BasePrefix + "/.within.website/x/cmd/anubis/static/js/bench.mjs?cacheBuster=" + anubis.Version }></script>
183 <div id="sparkline"></div>
184 <noscript>
185 <p>{ localizer.T("benchmark_requires_js") }</p>
186 </noscript>
187 </div>
188 </div>
189 <form id="controls" style="position:fixed;top:0.5rem;right:0.5rem">
190 <div style="display:flex;justify-content:end">
191 <label for="difficulty-input" style="margin-right:0.5rem">{ localizer.T("difficulty") }</label>
192 <input id="difficulty-input" type="number" name="difficulty" style="width:3rem"/>
193 </div>
194 <div style="margin-top:0.25rem;display:flex;justify-content:end">
195 <label for="algorithm-select" style="margin-right:0.5rem">{ localizer.T("algorithm") }</label>
196 <select id="algorithm-select" name="algorithm"></select>
197 </div>
198 <div style="margin-top:0.25rem;display:flex;justify-content:end">
199 <label for="compare-select" style="margin-right:0.5rem">{ localizer.T("compare") }</label>
200 <select id="compare-select" name="compare">
201 <option value="NONE">-</option>
202 </select>
203 </div>
204 </form>
205}