Repository navigation
fix(routing): apply authored headers without overwriting auth cache policy #669
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
894c6f9
49544f7
d896254
e406dff
933062d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -333,6 +333,36 @@ function bareCacheDirectives(policy: string | null): Set<string> { | |
| * `s-maxage` and a field-scoped `private` give way to a leading `private`. | ||
| * A policy that is already private or no-store stays as it is. | ||
| */ | ||
| /** | ||
| * True when the response sets a Better Auth cookie, such as the session from a | ||
| * sign-in reached through a rewrite or fallback. A cookie the app sets itself | ||
| * keeps the route's own cache policy. | ||
| */ | ||
| function setsAuthCookie( | ||
| headers: Headers, | ||
| advanced: | ||
| | { cookiePrefix?: string; cookies?: Record<string, { name?: string } | undefined> } | ||
| | undefined, | ||
| ): boolean { | ||
| const prefix = `${advanced?.cookiePrefix || 'better-auth'}.`; | ||
| const custom = new Set<string>(); | ||
| for (const cookie of Object.values(advanced?.cookies ?? {})) { | ||
| if (cookie?.name) { | ||
| custom.add(cookie.name); | ||
| } | ||
| } | ||
| return headers.getSetCookie().some((value) => { | ||
| const equals = value.indexOf('='); | ||
| let name = (equals === -1 ? value : value.slice(0, equals)).trim(); | ||
| for (const secure of ['__Secure-', '__Host-']) { | ||
| if (name.startsWith(secure)) { | ||
| name = name.slice(secure.length); | ||
| } | ||
| } | ||
| return name.startsWith(prefix) || custom.has(name); | ||
| }); | ||
| } | ||
|
|
||
| export function privateCachePolicy(policy: string | null): string { | ||
| const directives = splitCacheDirectives(policy ?? ''); | ||
| if (directives.length === 0) { | ||
|
|
@@ -629,7 +659,12 @@ export function createVoidAuthRuntime( | |
| appendAuthHeaders( | ||
| c, | ||
| result.headers, | ||
| state !== null || credentialed || result.headers?.has('set-cookie') === true, | ||
| state !== null || | ||
| credentialed || | ||
| result.headers?.has('set-cookie') === true || | ||
| setsAuthCookie(c.res.headers, auth.options.advanced) || | ||
| c.req.path === '/api/auth' || | ||
| c.req.path.startsWith('/api/auth/'), | ||
|
Comment on lines
+665
to
+667
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
In a native/local app with a public cache rule, an anonymous Useful? React with 👍 / 👎. |
||
| isUnchangedStaticAsset(c), | ||
| ); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If auth initialization or
auth.api.getSession()throws beforenext()—for example, on a transient database failure—registering the header middleware after auth means it is never entered.createErrorRenderer.onErrorreturns the error response without applying header rules, so a configuredAccess-Control-Allow-Originis absent and cross-origin clients cannot read the error response; previously the outer header middleware still decorated it. Keep non-cache header finalization outside this failure boundary, or explicitly apply it to auth error responses, while retaining auth's control over the final cache policy.Useful? React with 👍 / 👎.