5 changed files with 210 additions and 41 deletions
@ -0,0 +1,77 @@ |
|||||||
|
import type { RequestHandler } from '@sveltejs/kit'; |
||||||
|
|
||||||
|
/** |
||||||
|
* Proxy endpoint for Gitea API requests to avoid CORS issues |
||||||
|
* Usage: /api/gitea-proxy/{baseUrl}/repos/{owner}/{repo}/... |
||||||
|
* Example: /api/gitea-proxy/https%3A%2F%2Fgit.imwald.eu/api/v1/repos/silberengel/aitherboard |
||||||
|
*/ |
||||||
|
export const GET: RequestHandler = async ({ params, url }: { params: { path?: string }; url: URL }) => { |
||||||
|
try { |
||||||
|
// Reconstruct the full path from params
|
||||||
|
const pathParts = params.path?.split('/') || []; |
||||||
|
|
||||||
|
// Extract base URL (first part should be the encoded base URL)
|
||||||
|
if (pathParts.length < 1) { |
||||||
|
return new Response(JSON.stringify({ error: 'Missing base URL' }), { |
||||||
|
status: 400, |
||||||
|
headers: { 'Content-Type': 'application/json' } |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
// Decode the base URL (it's URL-encoded)
|
||||||
|
const baseUrl = decodeURIComponent(pathParts[0]); |
||||||
|
|
||||||
|
// Reconstruct the API path (everything after the base URL)
|
||||||
|
const apiPath = pathParts.slice(1).join('/'); |
||||||
|
|
||||||
|
// Add query parameters from the original request
|
||||||
|
const queryString = url.search; |
||||||
|
const fullUrl = `${baseUrl}/${apiPath}${queryString}`; |
||||||
|
|
||||||
|
// Fetch from Gitea API
|
||||||
|
const response = await fetch(fullUrl, { |
||||||
|
method: 'GET', |
||||||
|
headers: { |
||||||
|
'Accept': 'application/json', |
||||||
|
'User-Agent': 'aitherboard/1.0' |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
// Get response body
|
||||||
|
const contentType = response.headers.get('content-type') || 'application/json'; |
||||||
|
const body = await response.text(); |
||||||
|
|
||||||
|
// Return response with CORS headers
|
||||||
|
return new Response(body, { |
||||||
|
status: response.status, |
||||||
|
statusText: response.statusText, |
||||||
|
headers: { |
||||||
|
'Content-Type': contentType, |
||||||
|
'Access-Control-Allow-Origin': '*', |
||||||
|
'Access-Control-Allow-Methods': 'GET, OPTIONS', |
||||||
|
'Access-Control-Allow-Headers': 'Content-Type' |
||||||
|
} |
||||||
|
}); |
||||||
|
} catch (error) { |
||||||
|
const message = error instanceof Error ? error.message : 'Unknown error'; |
||||||
|
console.error('Gitea proxy error:', message); |
||||||
|
return new Response(JSON.stringify({ error: message }), { |
||||||
|
status: 500, |
||||||
|
headers: { |
||||||
|
'Content-Type': 'application/json', |
||||||
|
'Access-Control-Allow-Origin': '*' |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
export const OPTIONS: RequestHandler = async (): Promise<Response> => { |
||||||
|
return new Response(null, { |
||||||
|
status: 204, |
||||||
|
headers: { |
||||||
|
'Access-Control-Allow-Origin': '*', |
||||||
|
'Access-Control-Allow-Methods': 'GET, OPTIONS', |
||||||
|
'Access-Control-Allow-Headers': 'Content-Type' |
||||||
|
} |
||||||
|
}); |
||||||
|
}; |
||||||
Loading…
Reference in new issue