history+outline: Roject JWT integration with rokojori-auth
This commit is contained in:
parent
e89a372152
commit
ea58d0d102
|
|
@ -12,10 +12,11 @@
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<p class="date">Sunday, 13 July 2026</p>
|
<p class="date">Sunday, 13 July 2026</p>
|
||||||
<h1>rokojori-auth — built and deployed</h1>
|
<h1>rokojori-auth built + Roject integration</h1>
|
||||||
<p class="subtitle">
|
<p class="subtitle">
|
||||||
Full centralized auth service created from scratch, deployed to
|
Full centralized auth service created and deployed to
|
||||||
<code>account.rokojori.com</code>, and documented.
|
<code>account.rokojori.com</code>; Roject's local user system replaced
|
||||||
|
with JWT verification against rokojori-auth.
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
|
|
@ -152,15 +153,75 @@
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>What we built — Roject integration</h2>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>Local auth system removed</h3>
|
||||||
|
<p>
|
||||||
|
Deleted <code>routes/auth.ts</code>, <code>sessionStore.ts</code>,
|
||||||
|
<code>email/</code>, <code>login.html</code>, <code>register.html</code>,
|
||||||
|
and the <code>login-form</code> and <code>register-form</code> components.
|
||||||
|
Removed <code>bcryptjs</code> and <code>express-session</code> from
|
||||||
|
<code>package.json</code>. Removed the <code>User</code> model and
|
||||||
|
<code>users</code> store from <code>db.ts</code>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>JWT verification middleware</h3>
|
||||||
|
<p>
|
||||||
|
New <code>source/server/middleware/auth.ts</code> reads the
|
||||||
|
<code>accessToken</code> cookie (or <code>Authorization: Bearer</code> header),
|
||||||
|
verifies it with the shared <code>JWT_SECRET</code>, and attaches
|
||||||
|
<code>req.user</code>. Expired tokens on page requests are transparently
|
||||||
|
redirected to <code>account.rokojori.com/api/auth/refresh-session?redirect=...</code>.
|
||||||
|
API routes return <code>401</code> when unauthenticated.
|
||||||
|
Added <code>cookie-parser</code> and <code>jsonwebtoken</code>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>app-nav updated</h3>
|
||||||
|
<p>
|
||||||
|
<code>app-nav.ts</code> now calls <code>GET /api/auth/me</code> on Roject
|
||||||
|
(which returns <code>req.user</code> from the JWT). On 401 it renders a
|
||||||
|
"Log in" link pointing to
|
||||||
|
<code>account.rokojori.com/login.html?redirect=https://roject.rokojori.com</code>.
|
||||||
|
When authenticated it shows the user's email and a logout link to
|
||||||
|
<code>account.rokojori.com/api/auth/logout?redirect=...</code>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>GET /logout added to rokojori-auth</h3>
|
||||||
|
<p>
|
||||||
|
Added <code>GET /api/auth/logout?redirect=...</code> to rokojori-auth,
|
||||||
|
mirroring the <code>refresh-session</code> pattern. Clears both cookies,
|
||||||
|
invalidates the refresh token, and redirects to the given URL.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<h3>systemd EnvironmentFile</h3>
|
||||||
|
<p>
|
||||||
|
Roject's systemd service had no environment variables configured, so
|
||||||
|
<code>JWT_SECRET</code> was silently empty and all JWT verifications failed.
|
||||||
|
Fixed by adding <code>EnvironmentFile=/opt/roject/.env</code> via
|
||||||
|
<code>systemctl edit roject</code> followed by a daemon-reload and restart.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h2>What's next</h2>
|
<h2>What's next</h2>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<p>
|
<p>
|
||||||
Integrate Roject with rokojori-auth: remove the local user system from Roject,
|
Landing screen for unauthenticated users — instead of crashing on dashboard
|
||||||
add JWT verification middleware, redirect login/logout to
|
components, show a page that explains the app and offers a login link.
|
||||||
<code>account.rokojori.com</code>, and update all data references from local
|
Also: graceful 401 handling in data-fetching components (groups, projects, etc.)
|
||||||
user records to <code>userId</code> from the JWT payload.
|
so they display a sensible message instead of throwing a JS error.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h3><a href="2026/07-July/13-Sunday/index.html">Sunday, 13 July 2026</a></h3>
|
<h3><a href="2026/07-July/13-Sunday/index.html">Sunday, 13 July 2026</a></h3>
|
||||||
<p>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.</p>
|
<p>rokojori-auth built and deployed; Roject local auth replaced with JWT middleware — cookie-based login via account.rokojori.com, systemd EnvironmentFile fix.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
|
|
||||||
|
|
@ -252,37 +252,31 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h3>Next — Roject integration with rokojori-auth</h3>
|
<h3>Done — Roject integration with rokojori-auth</h3>
|
||||||
<p>
|
<p>
|
||||||
Roject needs to be updated to become a JWT-validating client. The work involves
|
Roject is now a JWT-validating client. The local session-based user system has
|
||||||
removing the existing session-based user system and replacing it with JWT
|
been removed and replaced with a JWT verification middleware that reads the shared
|
||||||
verification middleware that reads the shared <code>.rokojori.com</code> cookie.
|
<code>accessToken</code> cookie on <code>.rokojori.com</code>. Expired tokens are
|
||||||
Login and register links will point to <code>account.rokojori.com</code>.
|
transparently refreshed via
|
||||||
Expired tokens are refreshed via
|
|
||||||
<code>account.rokojori.com/api/auth/refresh-session?redirect=...</code>.
|
<code>account.rokojori.com/api/auth/refresh-session?redirect=...</code>.
|
||||||
All data models that currently reference a local user record will switch to
|
Login and logout links in <code>app-nav</code> point to
|
||||||
referencing <code>userId</code> from the JWT payload.
|
<code>account.rokojori.com</code>. All data references use <code>userId</code>
|
||||||
|
from the JWT payload. A <code>GET /api/auth/logout?redirect=...</code> endpoint
|
||||||
|
was also added to rokojori-auth to support browser-based logout links.
|
||||||
</p>
|
</p>
|
||||||
<ul style="line-height:1.9;margin-top:0.75rem;font-size:0.9rem">
|
|
||||||
<li>Remove <code>source/server/routes/auth.ts</code> and <code>middleware/auth.ts</code></li>
|
|
||||||
<li>Remove user storage from <code>source/server/db.ts</code></li>
|
|
||||||
<li>Remove <code>bcryptjs</code>, <code>express-session</code></li>
|
|
||||||
<li>Remove <code>source/pages/login.html</code>, <code>register.html</code></li>
|
|
||||||
<li>Remove <code>source/server/email/</code> (already lives in rokojori-auth)</li>
|
|
||||||
<li>Add JWT verification middleware</li>
|
|
||||||
<li>Point login/logout nav links at <code>account.rokojori.com</code></li>
|
|
||||||
</ul>
|
|
||||||
<div class="tags">
|
<div class="tags">
|
||||||
<span class="tag">JWT middleware</span>
|
<span class="tag">JWT middleware</span>
|
||||||
<span class="tag">remove express-session</span>
|
<span class="tag">cookie-parser</span>
|
||||||
<span class="tag">remove bcryptjs</span>
|
<span class="tag">jsonwebtoken</span>
|
||||||
<span class="tag">account.rokojori.com login redirect</span>
|
<span class="tag">account.rokojori.com</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h3>Smaller open improvements</h3>
|
<h3>Smaller open improvements</h3>
|
||||||
<ul style="line-height:1.9">
|
<ul style="line-height:1.9">
|
||||||
|
<li>Unauthenticated users should land on a landing screen that explains the app and shows a login link, rather than crashing on dashboard components.</li>
|
||||||
|
<li>Components that fetch data (groups, projects, etc.) do not handle <code>401</code> responses gracefully — they crash when the API returns an error object instead of an array.</li>
|
||||||
<li>The Right panel has no default content and relies on manual tab dragging to populate.</li>
|
<li>The Right panel has no default content and relies on manual tab dragging to populate.</li>
|
||||||
<li>Portrait mode's secondary section switcher (when a panel has multiple side-by-side sections) is not yet wired up.</li>
|
<li>Portrait mode's secondary section switcher (when a panel has multiple side-by-side sections) is not yet wired up.</li>
|
||||||
<li>The member list UI shows raw UUIDs instead of usernames.</li>
|
<li>The member list UI shows raw UUIDs instead of usernames.</li>
|
||||||
|
|
@ -302,8 +296,10 @@
|
||||||
<p>
|
<p>
|
||||||
Node.js + Express, TypeScript compiled on the fly with <code>ts-node</code>.
|
Node.js + Express, TypeScript compiled on the fly with <code>ts-node</code>.
|
||||||
No database — all data lives as JSON files in <code>data/</code>
|
No database — all data lives as JSON files in <code>data/</code>
|
||||||
(auto-created on first run). Auth uses <code>express-session</code> +
|
(auto-created on first run). Auth is handled by <code>rokojori-auth</code>
|
||||||
<code>bcryptjs</code>. All entity IDs are UUIDs via
|
at <code>account.rokojori.com</code>; Roject verifies the shared
|
||||||
|
<code>accessToken</code> JWT cookie using <code>jsonwebtoken</code> +
|
||||||
|
<code>cookie-parser</code>. All entity IDs are UUIDs via
|
||||||
<code>crypto.randomUUID()</code> — no central counter, safe for parallel
|
<code>crypto.randomUUID()</code> — no central counter, safe for parallel
|
||||||
instances. Start the server with <code>npm start</code>.
|
instances. Start the server with <code>npm start</code>.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -311,8 +307,8 @@
|
||||||
<span class="tag">Node.js</span>
|
<span class="tag">Node.js</span>
|
||||||
<span class="tag">Express</span>
|
<span class="tag">Express</span>
|
||||||
<span class="tag">ts-node</span>
|
<span class="tag">ts-node</span>
|
||||||
<span class="tag">express-session</span>
|
<span class="tag">jsonwebtoken</span>
|
||||||
<span class="tag">bcryptjs</span>
|
<span class="tag">cookie-parser</span>
|
||||||
<span class="tag">UUID IDs</span>
|
<span class="tag">UUID IDs</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue