knowless 1.1.1 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/GUIDE.md +42 -1
- package/knowless.context.md +7 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -30,6 +30,30 @@ v1.0.0 are:
|
|
|
30
30
|
- Documentation corrections
|
|
31
31
|
- Helper exports that pull existing mechanism back into the library
|
|
32
32
|
|
|
33
|
+
## [1.1.2] — 2026-05-03
|
|
34
|
+
|
|
35
|
+
Documentation-only release. Adopters were repeatedly missing that
|
|
36
|
+
`auth.loginForm` is an unstyled contract-minimal fallback they
|
|
37
|
+
should override, and that `/login` is also where every silent-miss
|
|
38
|
+
failure (used / expired / sham / malformed token) redirects — so
|
|
39
|
+
the page deserves first-class UI in the host app, not the bundled
|
|
40
|
+
default. No code changes.
|
|
41
|
+
|
|
42
|
+
### Documented
|
|
43
|
+
|
|
44
|
+
- `GUIDE.md` FAQ — added section "Branding the GET /login page
|
|
45
|
+
(you almost certainly want to override it)" with the three
|
|
46
|
+
reasons (brand consistency, silent-miss redirect target, opt-in
|
|
47
|
+
fallback) and the override pattern. Extended the existing
|
|
48
|
+
custom-form contract with `next` validation against
|
|
49
|
+
`baseUrl` + `cookieDomain` and the optional honeypot field name
|
|
50
|
+
from `cfg.honeypotFieldName`.
|
|
51
|
+
- `knowless.context.md` gotcha #10 — expanded the "operators
|
|
52
|
+
wanting branding fork the project" note to surface the more
|
|
53
|
+
common path (skip mounting `auth.loginForm`, serve your own
|
|
54
|
+
`GET /login`) and call out that `/login` is the silent-miss
|
|
55
|
+
redirect target.
|
|
56
|
+
|
|
33
57
|
## [1.1.1] — 2026-05-02
|
|
34
58
|
|
|
35
59
|
Documentation-only release. Adds the wrong-shape-integration
|
package/GUIDE.md
CHANGED
|
@@ -929,7 +929,48 @@ own form, provided it satisfies the handler contract:
|
|
|
929
929
|
stream itself. A body-parser middleware mounted before `auth.login`
|
|
930
930
|
will silently steal the data (see gotcha #15 in
|
|
931
931
|
[`knowless.context.md`](knowless.context.md)).
|
|
932
|
-
- Optional: include a `next` field for the post-callback redirect URL
|
|
932
|
+
- Optional: include a `next` field for the post-callback redirect URL
|
|
933
|
+
(knowless validates `next` against `baseUrl` + `cookieDomain`).
|
|
934
|
+
- Optional but recommended: include the honeypot field using the name
|
|
935
|
+
from `cfg.honeypotFieldName`.
|
|
936
|
+
|
|
937
|
+
### Branding the GET /login page (you almost certainly want to override it)
|
|
938
|
+
|
|
939
|
+
Knowless ships `auth.loginForm(req, res)` as a turnkey fallback so
|
|
940
|
+
adopters can wire `GET /login` in one line and have a working magic-link
|
|
941
|
+
form. The page is intentionally unstyled — it's the contract-minimal
|
|
942
|
+
renderer needed to make the flow demonstrable, not a UI you ship to
|
|
943
|
+
end users. Three reasons most adopters override it:
|
|
944
|
+
|
|
945
|
+
1. **Brand consistency.** The fallback page has no header, footer, nav,
|
|
946
|
+
or styling, so users redirected here from elsewhere in your app land
|
|
947
|
+
on what looks like a different site. That's especially jarring after
|
|
948
|
+
a sham-token failure (a deliberate part of the silent-miss design —
|
|
949
|
+
see "Silent miss" in [`knowless.context.md`](knowless.context.md)),
|
|
950
|
+
where a user clicked a magic link and ended up on a "Sign in" page
|
|
951
|
+
that looks unrelated to where they started.
|
|
952
|
+
2. **`/login` is load-bearing in the silent-miss contract.** Knowless
|
|
953
|
+
redirects to `loginPath` on every failure mode that must be
|
|
954
|
+
indistinguishable from success — used token, expired token, sham
|
|
955
|
+
token, malformed token. That redirect is correct and required. But
|
|
956
|
+
it means `/login` is the page users actually land on during
|
|
957
|
+
anti-enumeration failures, not just the page they navigate to
|
|
958
|
+
deliberately. It deserves first-class UI in your app.
|
|
959
|
+
3. **`auth.loginForm` is opt-in, not opt-out.** Adopters who never wire
|
|
960
|
+
the GET route still get a working app — just without a friendly
|
|
961
|
+
`/login` page. Override it whenever you want your app's chrome on
|
|
962
|
+
the page. The POST handler can stay as-is (or also be wrapped — for
|
|
963
|
+
example, plato wraps it for the "we sent a link" confirmation).
|
|
964
|
+
|
|
965
|
+
Override pattern (mount your own handler instead of `auth.loginForm`):
|
|
966
|
+
|
|
967
|
+
```js
|
|
968
|
+
app.get('/login', (req, res) => renderMyOwnLogin(req, res));
|
|
969
|
+
app.post('/login', auth.login); // unchanged
|
|
970
|
+
```
|
|
971
|
+
|
|
972
|
+
The form just needs to satisfy the contract listed in the previous
|
|
973
|
+
question.
|
|
933
974
|
|
|
934
975
|
### How do I add 2FA / WebAuthn / TOTP?
|
|
935
976
|
|
package/knowless.context.md
CHANGED
|
@@ -699,7 +699,13 @@ rate-limits) belongs above the library.
|
|
|
699
699
|
10. **No JavaScript in any HTML page.** The login form, the
|
|
700
700
|
confirmation page, error pages — all static HTML5. Works in
|
|
701
701
|
text-mode browsers (Lynx, w3m). Operators wanting branding
|
|
702
|
-
fork the project
|
|
702
|
+
fork the project — **or, more commonly, skip mounting
|
|
703
|
+
`auth.loginForm` and serve their own `GET /login`**. The
|
|
704
|
+
fallback is intentionally a contract-minimal renderer, not a
|
|
705
|
+
UI to ship. `/login` is also where every silent-miss failure
|
|
706
|
+
redirects (used / expired / sham / malformed token), so it
|
|
707
|
+
deserves first-class chrome in the host app. See GUIDE.md
|
|
708
|
+
§ "Branding the GET /login page".
|
|
703
709
|
|
|
704
710
|
11. **Process cleanup matters.** `auth.close()` stops the
|
|
705
711
|
sweeper and closes the SQLite handle. Without it, your
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "knowless",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"description": "Small, opinionated, full-stack passwordless auth for Node.js services that don't need to email their users for anything but the sign-in link.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|