<feed xmlns='http://www.w3.org/2005/Atom'>
<title>webao/public/client.html, branch master</title>
<subtitle>WebAO fork</subtitle>
<link rel='alternate' type='text/html' href='https://git.sof.beauty/webao/'/>
<entry>
<title>Add passkey authentication (WebAuthn)</title>
<updated>2026-04-18T16:52:23+00:00</updated>
<author>
<name>Osmium Sorcerer</name>
<email>os@sof.beauty</email>
</author>
<published>2026-04-07T13:19:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sof.beauty/webao/commit/?id=aa4c30bb6d1e46b5019065fba6c0eb3c08aa1f34'/>
<id>aa4c30bb6d1e46b5019065fba6c0eb3c08aa1f34</id>
<content type='text'>
Bring in the subprotocol (the same as what's used on the desktop client
for public-key authentication) to carry the relevant messages:

- AuthRequest: first step in the flow, the client sends it to signal the
  intent to authenticate to the server.

- AssertCredential and AssertionFinish: server's challenge and client's
  response, respectively, to finalize the flow.

- RegisterCredential and RegistrationFinish: same structure as the
  above. Unlike the simple public-key auth with an out-of-band setup,
  passkeys require user interaction to register. User must be
  authorized.

Validate all relevant checks on the API side, and hand the data over to
the server for it to verify attestations and assertions.

Because it's a primary auth mechanism (not a second factor), require
user verification.

As we don't use any other method on web, add a passkey button as the
only sign-in interface. Passkeys are discoverable, we don't even need a
username.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Bring in the subprotocol (the same as what's used on the desktop client
for public-key authentication) to carry the relevant messages:

- AuthRequest: first step in the flow, the client sends it to signal the
  intent to authenticate to the server.

- AssertCredential and AssertionFinish: server's challenge and client's
  response, respectively, to finalize the flow.

- RegisterCredential and RegistrationFinish: same structure as the
  above. Unlike the simple public-key auth with an out-of-band setup,
  passkeys require user interaction to register. User must be
  authorized.

Validate all relevant checks on the API side, and hand the data over to
the server for it to verify attestations and assertions.

Because it's a primary auth mechanism (not a second factor), require
user verification.

As we don't use any other method on web, add a passkey button as the
only sign-in interface. Passkeys are discoverable, we don't even need a
username.
</pre>
</div>
</content>
</entry>
<entry>
<title>Remove defunct CAPTCHA</title>
<updated>2026-04-18T16:52:23+00:00</updated>
<author>
<name>Osmium Sorcerer</name>
<email>os@sof.beauty</email>
</author>
<published>2026-04-07T03:16:18+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sof.beauty/webao/commit/?id=ae7ef2c6c76947ea12cbb1592152d9c80fd1a8f3'/>
<id>ae7ef2c6c76947ea12cbb1592152d9c80fd1a8f3</id>
<content type='text'>
The hCaptcha integration has been abandoned for a while. It added yet
another questionable third-party API (which also set a Cloudflare
cookie), and its effectiveness is unclear considering its client-side
nature.

A custom CAPTCHA implementation (such as PoW challenge) is an
interesting prospect, but it'll require proper server-side support.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The hCaptcha integration has been abandoned for a while. It added yet
another questionable third-party API (which also set a Cloudflare
cookie), and its effectiveness is unclear considering its client-side
nature.

A custom CAPTCHA implementation (such as PoW challenge) is an
interesting prospect, but it'll require proper server-side support.
</pre>
</div>
</content>
</entry>
<entry>
<title>Replace cookies with localStorage</title>
<updated>2026-04-18T16:52:23+00:00</updated>
<author>
<name>Osmium Sorcerer</name>
<email>os@sof.beauty</email>
</author>
<published>2026-04-07T02:55:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sof.beauty/webao/commit/?id=4bd750ca1f3e446f68e0f88fabf0682fd4d61848'/>
<id>4bd750ca1f3e446f68e0f88fabf0682fd4d61848</id>
<content type='text'>
Cookies's use case is to store persistent data and send it to the server
in subsequent requests, such as to remember logged-in sessions. WebAO is
using them to store site settings like ad-hoc hash tables that require
parsing and serialization.

As a nasty side-effect of how cookies work, clients send all their
settings every time they connect to the server. Server has absolutely no
use for them, but each client sends them anyway, which is an
uncalled-for privacy leak.

Remove this mechanism entirely, switch to localStorage which serves
exactly the purpose of per-origin store with data that never leaves the
browser.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Cookies's use case is to store persistent data and send it to the server
in subsequent requests, such as to remember logged-in sessions. WebAO is
using them to store site settings like ad-hoc hash tables that require
parsing and serialization.

As a nasty side-effect of how cookies work, clients send all their
settings every time they connect to the server. Server has absolutely no
use for them, but each client sends them anyway, which is an
uncalled-for privacy leak.

Remove this mechanism entirely, switch to localStorage which serves
exactly the purpose of per-origin store with data that never leaves the
browser.
</pre>
</div>
</content>
</entry>
<entry>
<title>Avoid bothering the upstream</title>
<updated>2026-04-18T16:52:23+00:00</updated>
<author>
<name>Osmium Sorcerer</name>
<email>os@sof.beauty</email>
</author>
<published>2026-04-06T22:18:29+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sof.beauty/webao/commit/?id=45b706909323ba82035c49eb9d2b2546eeab6a78'/>
<id>45b706909323ba82035c49eb9d2b2546eeab6a78</id>
<content type='text'>
Delete reference to the AO2 Discord server so users don't accidentally
complain there if I break something here.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Delete reference to the AO2 Discord server so users don't accidentally
complain there if I break something here.
</pre>
</div>
</content>
</entry>
<entry>
<title>Add source code links in About section</title>
<updated>2026-04-18T16:52:22+00:00</updated>
<author>
<name>Osmium Sorcerer</name>
<email>os@sof.beauty</email>
</author>
<published>2026-03-25T20:03:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sof.beauty/webao/commit/?id=f628de1f9726fa734b1787cb587091013bbb518d'/>
<id>f628de1f9726fa734b1787cb587091013bbb518d</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>bigger evidense description</title>
<updated>2026-04-10T11:51:09+00:00</updated>
<author>
<name>stonedDiscord</name>
<email>Tukz@gmx.de</email>
</author>
<published>2026-04-10T11:51:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sof.beauty/webao/commit/?id=0fe5422373c60214c6d99931239fed00abcd7198'/>
<id>0fe5422373c60214c6d99931239fed00abcd7198</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>remove UI related changes</title>
<updated>2026-03-28T13:09:06+00:00</updated>
<author>
<name>David Skoland</name>
<email>davidskoland@gmail.com</email>
</author>
<published>2026-03-28T13:09:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sof.beauty/webao/commit/?id=6f407b54c3251b90463bc508852b031d72b0c673'/>
<id>6f407b54c3251b90463bc508852b031d72b0c673</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>no initial text</title>
<updated>2026-03-24T13:12:30+00:00</updated>
<author>
<name>David Skoland</name>
<email>davidskoland@gmail.com</email>
</author>
<published>2026-03-24T13:12:30+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sof.beauty/webao/commit/?id=95145c824e252b030a5e53950c9f1ed39774c79a'/>
<id>95145c824e252b030a5e53950c9f1ed39774c79a</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Add Connected and Disconnected notices</title>
<updated>2026-03-24T11:35:41+00:00</updated>
<author>
<name>David Skoland</name>
<email>davidskoland@gmail.com</email>
</author>
<published>2026-03-24T11:35:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sof.beauty/webao/commit/?id=28a140dc8ab8adf32c783c6887e29c245981ab51'/>
<id>28a140dc8ab8adf32c783c6887e29c245981ab51</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Add reconnect UI, disconnect button, and visual cleanup</title>
<updated>2026-03-24T11:23:45+00:00</updated>
<author>
<name>David Skoland</name>
<email>davidskoland@gmail.com</email>
</author>
<published>2026-03-24T11:23:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sof.beauty/webao/commit/?id=1a1ed4e1d0568a1610d5f5da3d541a59afe2b863'/>
<id>1a1ed4e1d0568a1610d5f5da3d541a59afe2b863</id>
<content type='text'>
- Redesign disconnect overlay as a full-screen modal with dark backdrop
- Add working Reconnect button that properly re-establishes WebSocket connection
- Add Disconnect button in Settings for testing
- Separate disconnect and ban/kick codepaths (no reconnect on ban)
- Log disconnect notice in IC log using hrtext style
- Refactor area list rendering from client state (renderAreaList)
- Extract appendICNotice for reusable IC log notices
- Clean up charselect: hide during loading, simplify toolbar layout
- Freshen loading screen and charselect styling
- Remove loading progress text updates (just show "Loading...")
- Guard against undefined client.chars and client.serv

Co-Authored-By: Claude Opus 4.6 (1M context) &lt;noreply@anthropic.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
- Redesign disconnect overlay as a full-screen modal with dark backdrop
- Add working Reconnect button that properly re-establishes WebSocket connection
- Add Disconnect button in Settings for testing
- Separate disconnect and ban/kick codepaths (no reconnect on ban)
- Log disconnect notice in IC log using hrtext style
- Refactor area list rendering from client state (renderAreaList)
- Extract appendICNotice for reusable IC log notices
- Clean up charselect: hide during loading, simplify toolbar layout
- Freshen loading screen and charselect styling
- Remove loading progress text updates (just show "Loading...")
- Guard against undefined client.chars and client.serv

Co-Authored-By: Claude Opus 4.6 (1M context) &lt;noreply@anthropic.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
