Remove README.md
This commit is contained in:
@@ -1,104 +0,0 @@
|
|||||||
# Personal Blog
|
|
||||||
|
|
||||||
A small static personal blog. No build step, no backend — plain HTML, CSS, and
|
|
||||||
vanilla JavaScript.
|
|
||||||
|
|
||||||
## Pages
|
|
||||||
|
|
||||||
- `index.html` — home page
|
|
||||||
- `reading.html` — reading list page (curated links grouped by category,
|
|
||||||
rendered from `data/reading-list.js`)
|
|
||||||
- `contact.html` — contact page (opens the visitor's mail client with the form
|
|
||||||
fields pre-filled via a `mailto:` link)
|
|
||||||
- `newsletter.html` — newsletter signup page (posts the visitor's email to a
|
|
||||||
configured serverless endpoint; no self-hosted backend or subscriber list
|
|
||||||
management)
|
|
||||||
|
|
||||||
## Newsletter signup
|
|
||||||
|
|
||||||
The signup form on `newsletter.html` POSTs the visitor's email to a serverless
|
|
||||||
endpoint. The client ships only the endpoint URL — no credential is ever sent
|
|
||||||
in the request:
|
|
||||||
|
|
||||||
- `NEWSLETTER_ENDPOINT` — the serverless endpoint the form POSTs to. This is
|
|
||||||
the **only** thing configured in `js/newsletter-config.js`, and it is
|
|
||||||
enforced `https://`-only at config load time and by tests (mirroring the
|
|
||||||
protocol allowlist in `js/reading-list.js`).
|
|
||||||
|
|
||||||
**Authentication is server-side only.** The serverless function reads its API
|
|
||||||
token from platform env/secrets at deploy time — never from this repository and
|
|
||||||
never from any client-served asset. Do not add a token to `js/newsletter-config.js`
|
|
||||||
or anywhere else in the tree; anything committed here is public.
|
|
||||||
|
|
||||||
When the endpoint is unavailable or rejects the submission, the visitor sees a
|
|
||||||
fixed, user-safe error message — the server-held token, the endpoint, the status
|
|
||||||
code, and any raw response body are never surfaced. After a successful signup a
|
|
||||||
confirmation message is shown.
|
|
||||||
|
|
||||||
**Server-side validation (required follow-up on the function, not this diff):**
|
|
||||||
the serverless function must authoritatively validate submissions before
|
|
||||||
processing — email syntax, length caps, pinned `Content-Type`, and rejection of
|
|
||||||
unknown fields. Client-side checks here are UX only and are bypassable by
|
|
||||||
direct API calls.
|
|
||||||
|
|
||||||
**Residual signup-abuse risk (accepted, out of scope):** this pass adds no spam
|
|
||||||
filtering or captcha. Scripted signups remain possible, so the serverless
|
|
||||||
function must mitigate abuse server-side with rate limiting and an origin
|
|
||||||
allowlist.
|
|
||||||
|
|
||||||
## Reading list
|
|
||||||
|
|
||||||
The reading list is a single data file: `data/reading-list.js`. The page code
|
|
||||||
renders whatever is in it, so it can grow to hundreds of entries without code
|
|
||||||
changes.
|
|
||||||
|
|
||||||
To add a link, edit `data/reading-list.js` only — add an entry with a `title`,
|
|
||||||
a `url`, a `category`, and an optional one-line `note`:
|
|
||||||
|
|
||||||
```js
|
|
||||||
{
|
|
||||||
category: "Engineering",
|
|
||||||
title: "A new article",
|
|
||||||
url: "https://example.com/article",
|
|
||||||
note: "Optional one-liner shown under the title.",
|
|
||||||
},
|
|
||||||
```
|
|
||||||
|
|
||||||
Categories appear on the page in the order they are first used; entries keep
|
|
||||||
the order they are listed in.
|
|
||||||
|
|
||||||
## Development
|
|
||||||
|
|
||||||
Serve the directory with any static file server, e.g.:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
python3 -m http.server 8000
|
|
||||||
```
|
|
||||||
|
|
||||||
Then open <http://localhost:8000>.
|
|
||||||
|
|
||||||
## Tests
|
|
||||||
|
|
||||||
Tests use Node's built-in test runner (no dependencies to install):
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm test
|
|
||||||
```
|
|
||||||
|
|
||||||
## Project layout
|
|
||||||
|
|
||||||
```text
|
|
||||||
index.html Home page
|
|
||||||
reading.html Reading list page
|
|
||||||
contact.html Contact page
|
|
||||||
newsletter.html Newsletter signup page
|
|
||||||
css/style.css Global + responsive styles
|
|
||||||
data/reading-list.js Curated reading list data (edit to add links)
|
|
||||||
js/newsletter-config.js Newsletter endpoint (non-secret, https-only) — edit at deploy time
|
|
||||||
js/newsletter.js Newsletter signup wiring: credential-free POST + user-safe errors (tested)
|
|
||||||
js/mailto.js Pure mailto: URL builder (unit tested)
|
|
||||||
js/contact.js Contact form wiring (browser + tests)
|
|
||||||
js/reading-list.js Reading list renderer: data file -> grouped HTML (tested)
|
|
||||||
tests/ Node built-in test suite
|
|
||||||
.gitea/workflows/ ci.yml runs `npm test` plus a gitleaks secret scan (fails on any hit) on PRs and pushes to main
|
|
||||||
```
|
|
||||||
Reference in New Issue
Block a user