cors.ts 1.2 KB

12345678910111213141516171819202122232425262728293031323334
  1. import { Context } from "effect"
  2. const opencodeOrigin = /^https:\/\/([a-z0-9-]+\.)*opencode\.ai$/
  3. export type CorsOptions = { readonly cors?: ReadonlyArray<string> }
  4. export const CorsConfig = Context.Reference<CorsOptions | undefined>("@kirincode/ServerCorsConfig", {
  5. defaultValue: () => undefined,
  6. })
  7. export function isAllowedCorsOrigin(input: string | undefined, opts?: CorsOptions) {
  8. if (!input) return true
  9. if (input.startsWith("http://localhost:")) return true
  10. if (input.startsWith("http://127.0.0.1:")) return true
  11. if (input.startsWith("oc://renderer")) return true
  12. if (input === "tauri://localhost" || input === "http://tauri.localhost" || input === "https://tauri.localhost")
  13. return true
  14. if (opencodeOrigin.test(input)) return true
  15. return opts?.cors?.includes(input) ?? false
  16. }
  17. export function isAllowedRequestOrigin(input: string | undefined, host: string | undefined, opts?: CorsOptions) {
  18. if (!input) return true
  19. if (host && sameHost(input, host)) return true
  20. return isAllowedCorsOrigin(input, opts)
  21. }
  22. function sameHost(origin: string, host: string) {
  23. try {
  24. return new URL(origin).host === host
  25. } catch {
  26. return false
  27. }
  28. }