diff --git a/src/runtime/plugins/supabase.server.ts b/src/runtime/plugins/supabase.server.ts index 4e522dabf..1e28b3660 100644 --- a/src/runtime/plugins/supabase.server.ts +++ b/src/runtime/plugins/supabase.server.ts @@ -1,7 +1,8 @@ import { createServerClient, parseCookieHeader } from '@supabase/ssr' -import { getHeader, setCookie } from 'h3' +import { getHeader } from 'h3' import type { SupabaseClient } from '@supabase/supabase-js' import { fetchWithRetry } from '../utils/fetch-retry' +import { setCookies } from '../utils/cookies' import { serverSupabaseUser, serverSupabaseSession } from '../server/services' import { useSupabaseSession } from '../composables/useSupabaseSession' import { useSupabaseUser } from '../composables/useSupabaseUser' @@ -21,13 +22,7 @@ export default defineNuxtPlugin({ ...clientOptions, cookies: { getAll: () => parseCookieHeader(getHeader(event, 'Cookie') ?? ''), - setAll: ( - cookies: { - name: string - value: string - options: CookieOptions - }[], - ) => cookies.forEach(({ name, value, options }) => setCookie(event, name, value, options)), + setAll: (cookies: { name: string, value: string, options: CookieOptions }[]) => setCookies(event, cookies), }, cookieOptions: { ...cookieOptions, diff --git a/src/runtime/server/services/serverSupabaseClient.ts b/src/runtime/server/services/serverSupabaseClient.ts index 8064bc6d8..eeb9b4c13 100644 --- a/src/runtime/server/services/serverSupabaseClient.ts +++ b/src/runtime/server/services/serverSupabaseClient.ts @@ -1,7 +1,9 @@ import type { SupabaseClient } from '@supabase/supabase-js' -import { createServerClient, parseCookieHeader, type CookieOptions } from '@supabase/ssr' -import { getHeader, setCookie, type H3Event } from 'h3' +import { createServerClient, parseCookieHeader } from '@supabase/ssr' +import { getHeader, type H3Event } from 'h3' import { fetchWithRetry } from '../../utils/fetch-retry' +import { setCookies } from '../../utils/cookies' +import type { CookieOptions } from '#app' import { useRuntimeConfig } from '#imports' // @ts-expect-error - `#supabase/database` is a runtime alias import type { Database } from '#supabase/database' @@ -17,13 +19,7 @@ export const serverSupabaseClient: (event: H3Event) => Promise parseCookieHeader(getHeader(event, 'Cookie') ?? ''), - setAll: ( - cookies: { - name: string - value: string - options: CookieOptions - }[], - ) => cookies.forEach(({ name, value, options }) => setCookie(event, name, value, options)), + setAll: (cookies: { name: string, value: string, options: CookieOptions }[]) => setCookies(event, cookies), }, cookieOptions: { ...cookieOptions, diff --git a/src/runtime/utils/cookies.ts b/src/runtime/utils/cookies.ts new file mode 100644 index 000000000..ee91125d8 --- /dev/null +++ b/src/runtime/utils/cookies.ts @@ -0,0 +1,25 @@ +import { setCookie, type H3Event } from 'h3' +import type { CookieOptions } from '#app' + +export function setCookies( + event: H3Event, + cookies: { + name: string + value: string + options: CookieOptions + }[], +) { + const response = event.node.res + const headersWritable = () => !response.headersSent && !response.writableEnded + + if (!headersWritable()) { + return + } + + for (const { name, value, options } of cookies) { + if (!headersWritable()) { + break + } + setCookie(event, name, value, options) + } +}