diff --git a/packages/server/src/plugins/cors.ts b/packages/server/src/plugins/cors.ts index 899073584..2baaf35d8 100644 --- a/packages/server/src/plugins/cors.ts +++ b/packages/server/src/plugins/cors.ts @@ -4,7 +4,8 @@ import type { Plugin } from './base' import { value, type Value } from '@orpc/shared' export interface CORSOptions { - origin: Value]> + origin?: Value]> + timingOrigin?: Value]> allowMethods?: string[] allowHeaders?: string[] maxAge?: number @@ -21,6 +22,10 @@ export class CORSPlugin implements Plugin { allowMethods: ['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH'], } + if (options?.credentials) { + defaults.origin = origin => origin + } + this.options = { ...defaults, ...options, @@ -76,17 +81,29 @@ export class CORSPlugin implements Plugin { : interceptorOptions.request.headers.origin || '' const allowedOrigin = await value(this.options.origin, origin, interceptorOptions) - const allowedOriginArr = Array.isArray(allowedOrigin) ? allowedOrigin : [allowedOrigin] - if (allowedOriginArr.includes(origin) || allowedOriginArr.includes('*')) { - result.response.headers['access-control-allow-origin'] = origin + if (allowedOriginArr.includes('*')) { + result.response.headers['access-control-allow-origin'] = '*' } + else { + if (allowedOriginArr.includes(origin)) { + result.response.headers['access-control-allow-origin'] = origin + } - if (!allowedOriginArr.includes('*')) { result.response.headers.vary = interceptorOptions.request.headers.vary ?? 'origin' } + const allowedTimingOrigin = await value(this.options.timingOrigin, origin, interceptorOptions) + const allowedTimingOriginArr = Array.isArray(allowedTimingOrigin) ? allowedTimingOrigin : [allowedTimingOrigin] + + if (allowedTimingOriginArr.includes('*')) { + result.response.headers['timing-allow-origin'] = '*' + } + else if (allowedTimingOriginArr.includes(origin)) { + result.response.headers['timing-allow-origin'] = origin + } + if (this.options.credentials) { result.response.headers['access-control-allow-credentials'] = 'true' }