diff --git a/workspace/history/2026/07-July/13-Sunday/index.html b/workspace/history/2026/07-July/13-Sunday/index.html
index 0495396..d18de89 100644
--- a/workspace/history/2026/07-July/13-Sunday/index.html
+++ b/workspace/history/2026/07-July/13-Sunday/index.html
@@ -12,10 +12,11 @@
Sunday, 13 July 2026
- Full centralized auth service created from scratch, deployed to
-
+ Deleted
+ New
+
+ Added
+ Roject's systemd service had no environment variables configured, so
+
- Integrate Roject with rokojori-auth: remove the local user system from Roject,
- add JWT verification middleware, redirect login/logout to
- rokojori-auth — built and deployed
+ rokojori-auth built + Roject integration
account.rokojori.com, and documented.
+ Full centralized auth service created and deployed to
+ account.rokojori.com; Roject's local user system replaced
+ with JWT verification against rokojori-auth.
What we built — Roject integration
+
+ Local auth system removed
+ routes/auth.ts, sessionStore.ts,
+ email/, login.html, register.html,
+ and the login-form and register-form components.
+ Removed bcryptjs and express-session from
+ package.json. Removed the User model and
+ users store from db.ts.
+ JWT verification middleware
+ source/server/middleware/auth.ts reads the
+ accessToken cookie (or Authorization: Bearer header),
+ verifies it with the shared JWT_SECRET, and attaches
+ req.user. Expired tokens on page requests are transparently
+ redirected to account.rokojori.com/api/auth/refresh-session?redirect=....
+ API routes return 401 when unauthenticated.
+ Added cookie-parser and jsonwebtoken.
+ app-nav updated
+ app-nav.ts now calls GET /api/auth/me on Roject
+ (which returns req.user from the JWT). On 401 it renders a
+ "Log in" link pointing to
+ account.rokojori.com/login.html?redirect=https://roject.rokojori.com.
+ When authenticated it shows the user's email and a logout link to
+ account.rokojori.com/api/auth/logout?redirect=....
+ GET /logout added to rokojori-auth
+ GET /api/auth/logout?redirect=... to rokojori-auth,
+ mirroring the refresh-session pattern. Clears both cookies,
+ invalidates the refresh token, and redirects to the given URL.
+ systemd EnvironmentFile
+ JWT_SECRET was silently empty and all JWT verifications failed.
+ Fixed by adding EnvironmentFile=/opt/roject/.env via
+ systemctl edit roject followed by a daemon-reload and restart.
+ What's next
account.rokojori.com, and update all data references from local
- user records to userId from the JWT payload.
+ Landing screen for unauthenticated users — instead of crashing on dashboard
+ components, show a page that explains the app and offers a login link.
+ Also: graceful 401 handling in data-fetching components (groups, projects, etc.)
+ so they display a sensible message instead of throwing a JS error.
rokojori-auth built and deployed — standalone auth service at account.rokojori.com with JWT tokens, refresh cookies, roles, rate limiting, admin panel, and workspace documentation.
+rokojori-auth built and deployed; Roject local auth replaced with JWT middleware — cookie-based login via account.rokojori.com, systemd EnvironmentFile fix.
- Roject needs to be updated to become a JWT-validating client. The work involves
- removing the existing session-based user system and replacing it with JWT
- verification middleware that reads the shared .rokojori.com cookie.
- Login and register links will point to account.rokojori.com.
- Expired tokens are refreshed via
+ Roject is now a JWT-validating client. The local session-based user system has
+ been removed and replaced with a JWT verification middleware that reads the shared
+ accessToken cookie on .rokojori.com. Expired tokens are
+ transparently refreshed via
account.rokojori.com/api/auth/refresh-session?redirect=....
- All data models that currently reference a local user record will switch to
- referencing userId from the JWT payload.
+ Login and logout links in app-nav point to
+ account.rokojori.com. All data references use userId
+ from the JWT payload. A GET /api/auth/logout?redirect=... endpoint
+ was also added to rokojori-auth to support browser-based logout links.
source/server/routes/auth.ts and middleware/auth.tssource/server/db.tsbcryptjs, express-sessionsource/pages/login.html, register.htmlsource/server/email/ (already lives in rokojori-auth)account.rokojori.com401 responses gracefully — they crash when the API returns an error object instead of an array.
Node.js + Express, TypeScript compiled on the fly with ts-node.
No database — all data lives as JSON files in data/
- (auto-created on first run). Auth uses express-session +
- bcryptjs. All entity IDs are UUIDs via
+ (auto-created on first run). Auth is handled by rokojori-auth
+ at account.rokojori.com; Roject verifies the shared
+ accessToken JWT cookie using jsonwebtoken +
+ cookie-parser. All entity IDs are UUIDs via
crypto.randomUUID() — no central counter, safe for parallel
instances. Start the server with npm start.