diff --git a/server.js b/server.js index 24ee1c7..53edfcb 100644 --- a/server.js +++ b/server.js @@ -1091,9 +1091,9 @@ app.get( } ); -app.get("/api/sseUpdates", requireLogin, async (req, res) => { +app.get("/api/sseUpdates/:clientSessionId", requireLogin, async (req, res) => { const userid = getUserId(req); - SE.connectClient(userid, req, res); + SE.connectClient(userid, req.params.clientSessionId, req, res); }); app.get( diff --git a/src/Library.tsx b/src/Library.tsx index 1a0de99..ddc1722 100644 --- a/src/Library.tsx +++ b/src/Library.tsx @@ -180,7 +180,7 @@ export default function Library({ mobile = false }) { // TODO handle encryption before enabling // This doesn't handle multiple tabs in the same browser. - // useSSEUpdates(setSettings); + useSSEUpdates(setSettings); async function saveAllBooks() { setLoading(true); @@ -428,7 +428,9 @@ export default function Library({ mobile = false }) { await Promise.all([fetchBooks(), fetchSettings()]); //await Promise.all([fetchBooks(), fetchSettings(), fetchBookTitles()]); }; - setCookie("clientid", nanoid(), 1); + sessionStorage.setItem("clientSessionId", nanoid()); + + //setCookie("clientid", nanoid(), 1); func(); }, []); diff --git a/src/LibraryDesktop.tsx b/src/LibraryDesktop.tsx index dddb35b..e7c2bb9 100644 --- a/src/LibraryDesktop.tsx +++ b/src/LibraryDesktop.tsx @@ -210,7 +210,7 @@ export default function LibraryDesktop() { className="h-full w-full absolute top-0 left-0 bg-editor dark:bg-dmeditor z-0" id="editor" > -
+ {/*
{!bookid && !currentChapter && ( @@ -220,7 +220,7 @@ export default function LibraryDesktop() { )} -
+
*/}
{/* Has to be chapterid and not currentChapter! Otherwise book editor loads and kicks off a save. This bug is now fixed but leaving comment */} diff --git a/src/SimpleSearchSidebar.tsx b/src/SimpleSearchSidebar.tsx index 3457739..77921d7 100644 --- a/src/SimpleSearchSidebar.tsx +++ b/src/SimpleSearchSidebar.tsx @@ -10,7 +10,7 @@ import ListItem from "./components/ListItem"; import LibraryContext from "./LibraryContext"; import { useColors } from "./lib/hooks"; import { RootState } from "./store"; -import { getChapterText, getStringContext } from "./utils"; +import { getChapterText, getStringContext, useLocalStorage } from "./utils"; function SearchResult({ book, chapter, index }) { return ( @@ -35,7 +35,7 @@ export default function SimpleSearchSidebar() { const navigate = useNavigate(); const { settings } = useContext(LibraryContext) as LibraryContextType; const colors = useColors(); - const [searchTerm, setSearchTerm] = React.useState(""); + const [searchTerm, setSearchTerm] = useLocalStorage("searchTerm", ""); const searchRef = React.useRef(null); useEffect(() => { diff --git a/src/lib/fetchData.ts b/src/lib/fetchData.ts index 8657ac0..287b267 100644 --- a/src/lib/fetchData.ts +++ b/src/lib/fetchData.ts @@ -198,7 +198,11 @@ export async function postWithCsrf(url: string, body: any) { headers: { "Content-Type": "application/json", }, - body: JSON.stringify({ ...body, csrfToken: getCsrfToken() }), + body: JSON.stringify({ + ...body, + csrfToken: getCsrfToken(), + clientSessionId: sessionStorage.getItem("clientSessionId"), + }), }); return res; } diff --git a/src/lib/hooks.ts b/src/lib/hooks.ts index 95fcff3..7fcde73 100644 --- a/src/lib/hooks.ts +++ b/src/lib/hooks.ts @@ -211,7 +211,8 @@ export function lightColors() { export function useSSEUpdates(setSettings) { // TODO this solution doesn't handle multiple tabs in the same browser - const clientid = getCookie("clientid"); + const clientSessionId = sessionStorage.getItem("clientSessionId"); + console.log({ clientSessionId }); const dispatch = useDispatch(); function listen(eventName, eventSource, func) { @@ -226,8 +227,8 @@ export function useSSEUpdates(setSettings) { } return useEffect(() => { - if (clientid) { - const eventSourceUrl = `/api/sseUpdates`; + if (clientSessionId) { + const eventSourceUrl = `/api/sseUpdates/${clientSessionId}`; const eventSource = new EventSource(eventSourceUrl, { withCredentials: true, }); @@ -267,7 +268,7 @@ export function useSSEUpdates(setSettings) { eventSource.close(); }; } - }, [clientid]); + }, [clientSessionId]); } export function useRecording() { diff --git a/src/storage/storageEngine.js b/src/storage/storageEngine.js index e275a33..b30de98 100644 --- a/src/storage/storageEngine.js +++ b/src/storage/storageEngine.js @@ -21,7 +21,8 @@ export function getLastEdited(userid) { // 3. Edits the created at timestamp to send back to the client and in the last edited cache on the server. And // 4. Updates other clients if updateData is given. export async function save(req, res, updateData, saveFunc) { - const clientidOfWriter = req.cookies.clientid; + const clientidOfWriter = req.body.clientSessionId; + console.log({ clientidOfWriter }, "in save"); const userid = getUserId(req); const lastHeardFromServer = Date.now(); if (updateData) { @@ -73,7 +74,7 @@ export function updateClients(userid, clientidOfWriter, eventName, _data) { } } -export function connectClient(userid, req, res) { +export function connectClient(userid, clientid, req, res) { res.setHeader("Cache-Control", "no-cache"); res.setHeader("Content-Type", "text/event-stream"); res.setHeader("Access-Control-Allow-Origin", "*"); @@ -83,7 +84,6 @@ export function connectClient(userid, req, res) { // flush the headers to establish SSE with client // needs to be done if using compression res.flushHeaders(); - const clientid = req.cookies.clientid; const newConnection = { clientid, res }; console.log("New connection", { userid, clientid }); if (clientsToUpdate[userid]) {