diff options
| author | Osmium Sorcerer <os@sof.beauty> | 2026-04-07 02:55:26 +0000 |
|---|---|---|
| committer | Osmium Sorcerer <os@sof.beauty> | 2026-04-18 16:52:23 +0000 |
| commit | 4bd750ca1f3e446f68e0f88fabf0682fd4d61848 (patch) | |
| tree | 055290f5f171d71bb9b2d0ec43107b30d59d7c1f | |
| parent | 085204dbdf17f379c9a32ea11660accb51b4311d (diff) | |
Replace cookies with localStorage
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.
| -rw-r--r-- | public/client.html | 10 | ||||
| -rw-r--r-- | webAO/client.ts | 6 | ||||
| -rw-r--r-- | webAO/client/loadResources.ts | 32 | ||||
| -rw-r--r-- | webAO/client/sender/sendOOC.ts | 3 | ||||
| -rw-r--r-- | webAO/dom/changeBlipVolume.ts | 3 | ||||
| -rw-r--r-- | webAO/dom/changeCallwords.ts | 3 | ||||
| -rw-r--r-- | webAO/dom/changeMusicVolume.ts | 3 | ||||
| -rw-r--r-- | webAO/dom/changeVolume.ts | 12 | ||||
| -rw-r--r-- | webAO/dom/reloadTheme.ts | 3 | ||||
| -rw-r--r-- | webAO/dom/setChatbox.ts | 3 | ||||
| -rw-r--r-- | webAO/dom/showNameClick.ts | 6 | ||||
| -rw-r--r-- | webAO/dom/twofactor.ts | 3 | ||||
| -rw-r--r-- | webAO/utils/getCookie.ts | 26 | ||||
| -rw-r--r-- | webAO/utils/setCookie.ts | 12 |
14 files changed, 35 insertions, 90 deletions
diff --git a/public/client.html b/public/client.html index 5c3c561..5d862d8 100644 --- a/public/client.html +++ b/public/client.html @@ -946,12 +946,10 @@ ></textarea> <br /> <br /> - <span style="color: blue" - >Changing these settings will save them as a cookie.<br /> - By doing so, you agree to it being saved.<br /> - If you don't agree, disable cookies for this site in your - browser.</span - > + <span> + Changing these settings will save them locally in your browser.<br /> + Saved settings are never transmitted. + </span> <br /> <br /> <button id="client_disconnect" onclick="DisconnectButton()"> diff --git a/webAO/client.ts b/webAO/client.ts index 0501325..ab39ee9 100644 --- a/webAO/client.ts +++ b/webAO/client.ts @@ -21,8 +21,6 @@ import { fetchEvidenceList, fetchCharacterList, } from "./client/fetchLists"; -import getCookie from "./utils/getCookie"; -import setCookie from "./utils/setCookie"; const { ip: serverIP, connect, mode, theme, serverName, char: autoChar, area: autoArea } = queryParser(); export { autoChar, autoArea }; @@ -260,8 +258,8 @@ class Client extends EventEmitter { */ joinServer() { this.sender.sendServer(`HI#${hdid}#%`); - if (this.enableCaptcha && getCookie("hdid") !== hdid) { - this.sender.sendServer(getCookie("hdid")); + if (this.enableCaptcha && localStorage.getItem("hdid") !== hdid) { + this.sender.sendServer(localStorage.getItem("hdid")); document.getElementById("client_secondfactor").style.display = "block"; document.getElementById("client_charselect").remove(); document.getElementById("client_ooc").remove(); diff --git a/webAO/client/loadResources.ts b/webAO/client/loadResources.ts index 2608ace..27538fd 100644 --- a/webAO/client/loadResources.ts +++ b/webAO/client/loadResources.ts @@ -1,4 +1,3 @@ -import getCookie from "../utils/getCookie"; import vanilla_evidence_arr from "../constants/evidence.js"; import vanilla_background_arr from "../constants/backgrounds.js"; import { changeMusicVolume } from "../dom/changeMusicVolume"; @@ -36,49 +35,48 @@ export const loadResources = () => { evidence_select.add(new Option(evidence)); }); - // Read cookies and set the UI to its values + // Read local storage and set the UI to its values (<HTMLInputElement>document.getElementById("OOC_name")).value = - getCookie("OOC_name") || + localStorage.getItem("OOC_name") || `web${String(Math.round(Math.random() * 100 + 10))}`; - // Read cookies and set the UI to its values - const cookietheme = getCookie("theme") || "default"; + const storedTheme = localStorage.getItem("theme") || "default"; (<HTMLOptionElement>( - document.querySelector(`#client_themeselect [value="${cookietheme}"]`) + document.querySelector(`#client_themeselect [value="${storedTheme}"]`) )).selected = true; reloadTheme(); - const cookiechatbox = getCookie("chatbox") || "dynamic"; + const storedChatbox = localStorage.getItem("chatbox") || "dynamic"; (<HTMLOptionElement>( - document.querySelector(`#client_chatboxselect [value="${cookiechatbox}"]`) + document.querySelector(`#client_chatboxselect [value="${storedChatbox}"]`) )).selected = true; - setChatbox(cookiechatbox); + setChatbox(storedChatbox); (<HTMLInputElement>document.getElementById("client_mvolume")).value = - getCookie("musicVolume") || "1"; + localStorage.getItem("musicVolume") || "1"; changeMusicVolume(); (<HTMLAudioElement>document.getElementById("client_sfxaudio")).volume = - Number(getCookie("sfxVolume")) || 1; + Number(localStorage.getItem("sfxVolume")) || 1; changeSFXVolume(); (<HTMLAudioElement>document.getElementById("client_shoutaudio")).volume = - Number(getCookie("shoutVolume")) || 1; + Number(localStorage.getItem("shoutVolume")) || 1; changeShoutVolume(); (<HTMLAudioElement>document.getElementById("client_testimonyaudio")).volume = - Number(getCookie("testimonyVolume")) || 1; + Number(localStorage.getItem("testimonyVolume")) || 1; changeTestimonyVolume(); (<HTMLInputElement>document.getElementById("client_bvolume")).value = - getCookie("blipVolume") || "1"; + localStorage.getItem("blipVolume") || "1"; changeBlipVolume(); (<HTMLInputElement>document.getElementById("ic_chat_name")).value = - getCookie("ic_chat_name"); + localStorage.getItem("ic_chat_name"); (<HTMLInputElement>document.getElementById("showname")).checked = Boolean( - getCookie("showname"), + localStorage.getItem("showname"), ); showname_click(null); (<HTMLInputElement>document.getElementById("client_callwords")).value = - getCookie("callwords"); + localStorage.getItem("callwords"); }; diff --git a/webAO/client/sender/sendOOC.ts b/webAO/client/sender/sendOOC.ts index 43c3773..d1baaa7 100644 --- a/webAO/client/sender/sendOOC.ts +++ b/webAO/client/sender/sendOOC.ts @@ -1,13 +1,12 @@ import { client } from "../../client"; import { escapeChat } from "../../encoding"; -import setCookie from "../../utils/setCookie"; import { saveChatlogHandle } from "../../client/saveChatLogHandle"; /** * Sends an out-of-character chat message. * @param {string} message the message to send */ export const sendOOC = (message: string) => { - setCookie( + localStorage.setItem( "OOC_name", (<HTMLInputElement>document.getElementById("OOC_name")).value, ); diff --git a/webAO/dom/changeBlipVolume.ts b/webAO/dom/changeBlipVolume.ts index 2e77403..e3a3313 100644 --- a/webAO/dom/changeBlipVolume.ts +++ b/webAO/dom/changeBlipVolume.ts @@ -1,4 +1,3 @@ -import setCookie from "../utils/setCookie"; import { client } from "../client"; /** * Triggered by the blip volume slider. @@ -10,6 +9,6 @@ export const changeBlipVolume = () => { client.viewport.blipChannels.forEach( (channel: HTMLAudioElement) => (channel.volume = Number(blipVolume)), ); - setCookie("blipVolume", blipVolume); + localStorage.setItem("blipVolume", blipVolume); }; window.changeBlipVolume = changeBlipVolume; diff --git a/webAO/dom/changeCallwords.ts b/webAO/dom/changeCallwords.ts index e125817..3777ce1 100644 --- a/webAO/dom/changeCallwords.ts +++ b/webAO/dom/changeCallwords.ts @@ -1,5 +1,4 @@ import { client } from "../client"; -import setCookie from "../utils/setCookie"; /** * Triggered by a changed callword list @@ -8,6 +7,6 @@ export function changeCallwords() { client.callwords = (<HTMLInputElement>( document.getElementById("client_callwords") )).value.split("\n"); - setCookie("callwords", client.callwords.join("\n")); + localStorage.setItem("callwords", client.callwords.join("\n")); } window.changeCallwords = changeCallwords; diff --git a/webAO/dom/changeMusicVolume.ts b/webAO/dom/changeMusicVolume.ts index df0a656..a564cc7 100644 --- a/webAO/dom/changeMusicVolume.ts +++ b/webAO/dom/changeMusicVolume.ts @@ -1,5 +1,4 @@ import { client } from "../client"; -import setCookie from "../utils/setCookie"; export const changeMusicVolume = (volume: number = -1) => { const clientVolume = Number( @@ -9,6 +8,6 @@ export const changeMusicVolume = (volume: number = -1) => { client.viewport.music.forEach( (channel: HTMLAudioElement) => (channel.volume = musicVolume), ); - setCookie("musicVolume", String(musicVolume)); + localStorage.setItem("musicVolume", String(musicVolume)); }; window.changeMusicVolume = changeMusicVolume; diff --git a/webAO/dom/changeVolume.ts b/webAO/dom/changeVolume.ts index 0c94aa6..dc258fb 100644 --- a/webAO/dom/changeVolume.ts +++ b/webAO/dom/changeVolume.ts @@ -1,5 +1,3 @@ -import setCookie from "../utils/setCookie"; - declare global { interface Window { changeSFXVolume: () => void; @@ -14,7 +12,7 @@ declare global { export function changeSFXVolume(): void { const sfxAudioElement = document.getElementById("client_sfxaudio") as HTMLAudioElement; if (sfxAudioElement) { - setCookie("sfxVolume", sfxAudioElement.volume); + localStorage.setItem("sfxVolume", sfxAudioElement.volume.toString()); } } if (typeof window.changeSFXVolume !== 'function') { @@ -27,9 +25,9 @@ if (typeof window.changeSFXVolume !== 'function') { export function changeTestimonyVolume(): void { const testimonyAudioElement = document.getElementById("client_testimonyaudio") as HTMLAudioElement; if (testimonyAudioElement) { - setCookie( + localStorage.setItem( "testimonyVolume", - testimonyAudioElement.volume + testimonyAudioElement.volume.toString() ); } } @@ -43,9 +41,9 @@ if (typeof window.changeTestimonyVolume !== 'function') { export function changeShoutVolume(): void { const shoutAudioElement = document.getElementById("client_shoutaudio") as HTMLAudioElement; if (shoutAudioElement) { - setCookie("shoutVolume", shoutAudioElement.volume); + localStorage.setItem("shoutVolume", shoutAudioElement.volume.toString()); } } if (typeof window.changeShoutVolume !== 'function') { window.changeShoutVolume = changeShoutVolume; -}
\ No newline at end of file +} diff --git a/webAO/dom/reloadTheme.ts b/webAO/dom/reloadTheme.ts index c65ac6d..eccb934 100644 --- a/webAO/dom/reloadTheme.ts +++ b/webAO/dom/reloadTheme.ts @@ -1,5 +1,4 @@ import { client } from "../client"; -import setCookie from "../utils/setCookie"; /** * Triggered by the theme selector. @@ -9,7 +8,7 @@ export const reloadTheme = () => { (<HTMLSelectElement>document.getElementById("client_themeselect")).value, ); - setCookie("theme", client.viewport.getTheme()); + localStorage.setItem("theme", client.viewport.getTheme()); (<HTMLAnchorElement>document.getElementById("client_theme")).href = `styles/${client.viewport.getTheme()}.css`; }; diff --git a/webAO/dom/setChatbox.ts b/webAO/dom/setChatbox.ts index c75559d..2618292 100644 --- a/webAO/dom/setChatbox.ts +++ b/webAO/dom/setChatbox.ts @@ -1,6 +1,5 @@ import { CHATBOX, setCHATBOX } from "../client"; import chatbox_arr from "../styles/chatbox/chatboxes.js"; -import setCookie from "../utils/setCookie"; /** * Set the style of the chatbox @@ -14,7 +13,7 @@ export function setChatbox(setstyle: string) { ); setCHATBOX(themeselect.value); - setCookie("chatbox", CHATBOX); + localStorage.setItem("chatbox", CHATBOX); if (CHATBOX === "dynamic") { const style = setstyle.replace("chat", ""); if (chatbox_arr.includes(style)) { diff --git a/webAO/dom/showNameClick.ts b/webAO/dom/showNameClick.ts index 005bfd5..375c67b 100644 --- a/webAO/dom/showNameClick.ts +++ b/webAO/dom/showNameClick.ts @@ -1,15 +1,13 @@ -import setCookie from "../utils/setCookie"; - /** * Triggered when the showname checkboc is clicked * @param {MouseEvent} event */ export function showname_click(_event: Event | null) { - setCookie( + localStorage.setItem( "showname", String((<HTMLInputElement>document.getElementById("showname")).checked), ); - setCookie( + localStorage.setItem( "ic_chat_name", (<HTMLInputElement>document.getElementById("ic_chat_name")).value, ); diff --git a/webAO/dom/twofactor.ts b/webAO/dom/twofactor.ts index 58bbc4c..4f5fa81 100644 --- a/webAO/dom/twofactor.ts +++ b/webAO/dom/twofactor.ts @@ -1,8 +1,7 @@ import { client } from "../client"; -import setCookie from "../utils/setCookie"; export function hcallback(hcaptcharesponse: string) { - setCookie("hdid", client.hdid); + localStorage.setItem("hdid", client.hdid); client.sender.sendServer(`2T#${hcaptcharesponse}#%`); location.reload(); } diff --git a/webAO/utils/getCookie.ts b/webAO/utils/getCookie.ts deleted file mode 100644 index 7373688..0000000 --- a/webAO/utils/getCookie.ts +++ /dev/null @@ -1,26 +0,0 @@ -/** - * read a cookie from storage - * got this from w3schools - * https://www.w3schools.com/js/js_cookies.asp - * @param {string} cname The name of the cookie to return - */ -const getCookie = (cname: string) => { - try { - const name = `${cname}=`; - const decodedCookie = decodeURIComponent(document.cookie); - const ca = decodedCookie.split(";"); - for (let i = 0; i < ca.length; i++) { - let c = ca[i]; - while (c.charAt(0) === " ") { - c = c.substring(1); - } - if (c.indexOf(name) === 0) { - return c.substring(name.length, c.length); - } - } - return ""; - } catch (error) { - return ""; - } -}; -export default getCookie; diff --git a/webAO/utils/setCookie.ts b/webAO/utils/setCookie.ts deleted file mode 100644 index 421fe81..0000000 --- a/webAO/utils/setCookie.ts +++ /dev/null @@ -1,12 +0,0 @@ -/* eslint @typescript-eslint/no-explicit-any: "off" */ - -/** - * set a cookie - * the version from w3schools expects these to expire - * @param {string} cname The name of the cookie to return - * @param {any} value The value of that cookie option - */ -const setCookie = (cname: string, value: any) => { - document.cookie = `${cname}=${value};SameSite=Strict`; -}; -export default setCookie; |
