121 lines
6.0 KiB
HTML
121 lines
6.0 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Tuesday, 15 July 2026 — Roject</title>
|
|
<link rel="stylesheet" href="../../../../_assets_/styles.css">
|
|
<link rel="stylesheet" href="../../../../_assets_/nav.css">
|
|
</head>
|
|
<body>
|
|
<div class="page">
|
|
|
|
<header>
|
|
<p class="date">Tuesday, 15 July 2026</p>
|
|
<h1>Session History</h1>
|
|
<p class="subtitle">styles.rokojori.com built and deployed; Roject font migration; add-subdomain deployment guide.</p>
|
|
</header>
|
|
|
|
<section>
|
|
<h2>What we built</h2>
|
|
|
|
<div class="card">
|
|
<h3>styles.rokojori.com — new service</h3>
|
|
<p>
|
|
Built a new standalone asset hosting service from scratch at
|
|
<code>styles.rokojori.com</code>. Same stack as the other rokojori services:
|
|
Node.js + Express + ts-node, no external database, Web Components + raw CSS on
|
|
the frontend.
|
|
</p>
|
|
<p style="margin-top:0.75rem">Key pieces:</p>
|
|
<ul style="margin-top:0.5rem;padding-left:1.25rem;line-height:1.9;font-size:0.9rem;color:var(--muted)">
|
|
<li><strong style="color:var(--text)">GET /get-font</strong> — public CSS endpoint; three modes: all weights, specific weights (+ auto-italic), or explicit variations. Returns <code>@font-face</code> CSS; font files served statically from <code>storage/fonts/</code>.</li>
|
|
<li><strong style="color:var(--text)">POST /api/fonts/download</strong> — auth-gated; hits Google Fonts API with a browser User-Agent to get woff2 URLs, downloads each file, writes <code>meta.json</code>.</li>
|
|
<li><strong style="color:var(--text)">GET /api/fonts</strong> — auth-gated; lists all downloaded font families and their available weights/italics.</li>
|
|
<li><strong style="color:var(--text)">CORS allowlist middleware</strong> — checks <code>Origin</code> header against <code>*.rokojori.com</code> regex; echoes origin back only if matched. Public <code>*</code> header explicitly avoided.</li>
|
|
<li><strong style="color:var(--text)">Auth</strong> — shared JWT cookie from rokojori-auth; <code>requireAccess</code> middleware copied from auth workspace (role: admin, or user + product: styles / premium). HTML pages redirect to login; API routes return 401/403 JSON.</li>
|
|
<li><strong style="color:var(--text)">Pages</strong> — <code>/</code> detects auth state via fetch and shows hero or sections list; <code>/list-fonts</code> renders all families with live preview sentence; <code>/add-fonts</code> takes family name + optional weights, downloads, shows inline preview.</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h3>Roject — font migration and page cleanup</h3>
|
|
<p>
|
|
Removed three stale pages: <code>dashboard.html</code>, <code>groups.html</code>,
|
|
<code>projects.html</code> — all superseded by the project-home redesign from the
|
|
previous session.
|
|
</p>
|
|
<p style="margin-top:0.75rem">
|
|
Migrated Barlow font loading from Google Fonts to styles.rokojori.com:
|
|
removed the three Google Fonts <code><link></code> tags from
|
|
<code>source/pages/index.html</code> and added
|
|
<code>@import url('https://styles.rokojori.com/get-font?family=barlow&weights=100,400,700,900')</code>
|
|
at the top of <code>project-list-default.css</code>. The theme now self-describes
|
|
its font dependency; no Google dependency at runtime.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h3>rokojori-auth workspace — add-subdomain deployment guide</h3>
|
|
<p>
|
|
Created <code>workspace/add-subdomain.html</code> — a step-by-step deployment
|
|
checklist for adding any new rokojori subdomain service to Server A. Covers:
|
|
Gitea repo creation, .gitignore, DNS on IONOS, server clone, install/build/env,
|
|
nginx HTTP config, Let's Encrypt via certbot, nginx HTTPS verification, and
|
|
systemd service setup.
|
|
</p>
|
|
<p style="margin-top:0.75rem">
|
|
The guide has an interactive variables bar at the top (subdomain, port, service
|
|
name) — all commands throughout the page update live via JS as you type.
|
|
systemd unit file format matched to the Roject convention:
|
|
<code>/usr/bin/npx ts-node</code>, <code>Restart=on-failure</code>,
|
|
<code>StandardOutput/Error=journal</code>.
|
|
Added a step 0 explaining the CORS allowlist pattern with full code example.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<section>
|
|
<h2>Key decisions</h2>
|
|
|
|
<div class="card">
|
|
<h3>Font files are woff2-only, named numerically</h3>
|
|
<p>
|
|
Convention: <code>400.woff2</code>, <code>400-italic.woff2</code>. No "bold"
|
|
alias — numeric weights only. woff2 has near-universal browser support; no
|
|
fallback formats needed.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h3>CORS restricted to *.rokojori.com, not wildcard</h3>
|
|
<p>
|
|
<code>Access-Control-Allow-Origin: *</code> was rejected in favour of an
|
|
allowlist that echoes back the matched origin. The regex
|
|
<code>/^https?:\/\/([\w-]+\.)?rokojori\.com$/</code> covers all current and
|
|
future subdomains. Extra origins can be added as strings or regexes to the
|
|
<code>CORS_ALLOWED</code> array.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h3>styles.rokojori.com scope expanded</h3>
|
|
<p>
|
|
Initially conceived as a font host; scope widened to a general shared-asset
|
|
platform: fonts now, shared HTML components / Web Components, CSS presets, and
|
|
binary assets (images, sounds, video) planned.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<footer>
|
|
Roject — session history
|
|
</footer>
|
|
|
|
</div>
|
|
<script>var NAV_ROOT = '../../../../';</script>
|
|
<script src="../../../../_assets_/nav-data.js"></script>
|
|
<script src="../../../../_assets_/nav.js"></script>
|
|
</body>
|
|
</html>
|