@stonyx/oauth 0.1.1-alpha.24 → 0.1.1-alpha.25
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/README.md +6 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -118,7 +118,9 @@ providers: {
|
|
|
118
118
|
|
|
119
119
|
## Login CSRF protection — the `oauth_state` cookie
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
### Breaking changes
|
|
122
|
+
|
|
123
|
+
**As of the fix for [#36](https://github.com/abofs/stonyx-oauth/issues/36).** Two separate breaks — an integration can hit either one independently.
|
|
122
124
|
|
|
123
125
|
**1. The login flow now requires a cookie jar.** A client that cannot hold a cookie between `/auth/login/:provider` and `/auth/callback/:provider` can no longer complete a login. That is the point of the change — see [Migration](#migration-from-a-cookie-less-client) below.
|
|
124
126
|
|
|
@@ -132,7 +134,7 @@ providers: {
|
|
|
132
134
|
|
|
133
135
|
None of these throws at import time, and a `typeof … === 'function'` surface check passes on all three: the arity and the return type change, not the presence. Callers must be updated by inspection.
|
|
134
136
|
|
|
135
|
-
The HTTP contract is otherwise unchanged —
|
|
137
|
+
The HTTP contract is otherwise unchanged — the [route table](#routes) is the same, no config key was added or changed, and both routes still `302` on their success paths. One status is new: `/auth/login/:provider` returns `500` when the binding cookie cannot be set, which it never did before (see below).
|
|
136
138
|
|
|
137
139
|
`GET /auth/login/:provider` issues an `oauth_state` cookie carrying a per-flow binding value, and keeps only its SHA-256 server-side. `GET /auth/callback/:provider` accepts an OAuth2 `state` only from a caller that also presents the matching cookie value.
|
|
138
140
|
|
|
@@ -155,7 +157,7 @@ If the runtime cannot set the cookie, `/auth/login/:provider` returns `500` and
|
|
|
155
157
|
|
|
156
158
|
- **Start the login as a top-level navigation** (`window.location = '/auth/login/discord'`, or a plain link). This is the documented pattern and it avoids CORS entirely.
|
|
157
159
|
- **Serve login and callback from the same host.** The cookie is host-scoped and carries no `Domain` attribute. A **different port on the same host is fine** — port is not part of cookie scope (RFC 6265 §8.5) — but a different *hostname* is not: the cookie is never sent and the login fails. Both routes are mounted on the same `AuthRequest`, so this only bites when something in front of the app splits them across hostnames (a proxy split, or `app.example.com` for login and `example.com` for the callback).
|
|
158
|
-
- **Keep your configured `redirectUri` on the same scheme the login endpoint is served over.** `Secure` is derived from `redirectUri`, so an `https` `redirectUri` behind a plaintext login endpoint issues a `Secure` cookie that the browser silently discards. Every login then fails the binding check **with no server-side signal** — the callback simply reports `auth_failed
|
|
160
|
+
- **Keep your configured `redirectUri` on the same scheme the login endpoint is served over.** `Secure` is derived from `redirectUri`, so an `https` `redirectUri` behind a plaintext login endpoint issues a `Secure` cookie that the browser silently discards. Every login then fails the binding check **with no server-side signal** — the callback simply reports `error=auth_failed` if `frontendCallbackUrl` is configured, or a bare `500` if it is not. Check this first if logins start failing after a TLS or proxy change.
|
|
159
161
|
- An XHR-initiated login will not work: `@stonyx/rest-server` never passes `credentials: true` to CORS, so the browser will neither store nor send the cookie on a cross-origin XHR. Narrowing `REST_CORS_ORIGIN` from its `*` default does not change this.
|
|
160
162
|
|
|
161
163
|
### Migration from a cookie-less client
|
|
@@ -178,7 +180,7 @@ In a browser, `fetch` needs `credentials: 'include'` for a cross-origin request
|
|
|
178
180
|
|
|
179
181
|
### Concurrent logins in the same browser
|
|
180
182
|
|
|
181
|
-
The cookie name is fixed and its `Path` is `/`, so a second login started in the same browser overwrites the first tab's binding value. The first tab's callback then presents the second tab's value
|
|
183
|
+
The cookie name is fixed and its `Path` is `/`, so a second login started in the same browser overwrites the first tab's binding value. The first tab's callback then presents the second tab's value and fails the binding check — redirecting with `error=auth_failed` if `frontendCallbackUrl` is configured, or returning `500` if it is not.
|
|
182
184
|
|
|
183
185
|
This fails closed — no session is minted for the wrong flow, and it is not a way past the binding — but it is an availability regression against the previous behaviour, where two concurrent logins both completed. A user who opens two login tabs has to finish in the one they started last, or retry.
|
|
184
186
|
|