fix: harden review findings and Netlify install

This commit is contained in:
Josh Creek
2026-09-14 12:56:09 +01:00
parent 86f1c21e4d
commit 3ea194f87c
18 changed files with 171 additions and 7759 deletions
+9 -7
View File
@@ -23,12 +23,10 @@ const LOOPBACK_HOSTS = new Set(['127.0.0.1', 'localhost', '[::1]']);
/**
* These endpoints receive the OAuth client secret and the user's refresh token, so an override
* is only ever a local test seam - never a deployment knob. Two guards, because the env is
* read at runtime (`$env/dynamic/private`) and a single injected variable would otherwise be
* enough to redirect those credentials to an arbitrary host:
*
* 1. overrides are ignored unless ALLOW_PROVIDER_ENDPOINT_OVERRIDES is exactly "true", and
* 2. even then, only loopback URLs are accepted.
* is only ever a local test seam - never a deployment knob. The guards require the explicit
* override flag, the BDD service-role context, and a loopback test stack. Each override must also
* be loopback, so a single injected variable cannot redirect credentials to an arbitrary host.
* Values are read at runtime from `$env/dynamic/private`.
*/
function isLocalOverride(value: string): boolean {
try {
@@ -44,7 +42,11 @@ function isLocalOverride(value: string): boolean {
export function resolveProviderEndpoints(
env: Record<string, string | undefined>
): ProviderEndpoints {
const overridesAllowed = env.ALLOW_PROVIDER_ENDPOINT_OVERRIDES === 'true';
const overridesAllowed =
env.ALLOW_PROVIDER_ENDPOINT_OVERRIDES === 'true' &&
!!env.E2E_SERVICE_ROLE_KEY &&
!!env.TEST_SUPABASE_URL &&
isLocalOverride(env.TEST_SUPABASE_URL);
const pick = (override: string | undefined, fallback: string) =>
overridesAllowed && override && isLocalOverride(override) ? override : fallback;
+1
View File
@@ -122,6 +122,7 @@ export function startOfflineSync(getUserId: () => string | null): () => void {
)
)
);
if (getUserId() !== userId) throw new Error('Session changed during offline synchronization');
const result = await workerMessage({
type: 'SYNC_OFFLINE_SNAPSHOT',
snapshot,
+31 -7
View File
@@ -5,15 +5,35 @@ import type { CookieSerializeOptions } from 'cookie';
export const load: LayoutLoad = async ({ fetch, data, depends }) => {
depends('supabase:auth');
const recoveryIntent =
isBrowser() &&
window.location.pathname === '/reset-password' &&
(new URLSearchParams(window.location.hash.slice(1)).get('type') === 'recovery' ||
new URL(window.location.href).searchParams.has('code'));
let recoveryExchangeSucceeded = false;
let hashRecoveryCallback = false;
let codeRecoveryCallback = false;
if (isBrowser() && window.location.pathname === '/reset-password') {
const hash = new URLSearchParams(window.location.hash.slice(1));
hashRecoveryCallback =
hash.get('type') === 'recovery' && hash.has('access_token') && hash.has('refresh_token');
codeRecoveryCallback = new URL(window.location.href).searchParams.has('code');
}
const authFetch: typeof fetch = async (input, init) => {
const response = await fetch(input, init);
if (codeRecoveryCallback && response.ok) {
const requestUrl = new URL(
typeof input === 'string' || input instanceof URL ? input : input.url,
window.location.origin
);
if (
requestUrl.pathname.endsWith('/auth/v1/token') &&
requestUrl.searchParams.get('grant_type') === 'pkce'
) {
recoveryExchangeSucceeded = true;
}
}
return response;
};
const supabase = createBrowserClient(PUBLIC_SUPABASE_URL, PUBLIC_SUPABASE_ANON_KEY, {
global: {
fetch
fetch: authFetch
},
cookies: {
get(key: string) {
@@ -44,5 +64,9 @@ export const load: LayoutLoad = async ({ fetch, data, depends }) => {
data: { session }
} = await supabase.auth.getSession();
return { supabase, session, recoveryIntent };
return {
supabase,
session,
recoveryIntent: !!session && (hashRecoveryCallback || recoveryExchangeSucceeded)
};
};
+15 -4
View File
@@ -108,10 +108,7 @@
successMessage = 'Password updated successfully! Redirecting to sign in...';
sessionStorage.removeItem(recoveryMarkerKey);
setTimeout(async () => {
await supabase.auth.signOut();
await goto('/signin');
}, 1_000);
setTimeout(() => void finishPasswordReset(), 1_000);
} catch (err) {
console.error('Update password error:', err);
errorMessage = 'An unexpected error occurred. Please try again.';
@@ -120,6 +117,20 @@
}
}
async function finishPasswordReset() {
try {
const { error } = await supabase.auth.signOut();
if (error) {
errorMessage = `Password updated, but sign out failed: ${error.message}`;
return;
}
await goto('/signin');
} catch (error) {
console.error('Sign out after password reset failed:', error);
errorMessage = 'Password updated, but sign out failed. Please try again.';
}
}
function handleKeyPress(event: KeyboardEvent) {
if (event.key === 'Enter') {
updatePassword();