Просмотр исходного кода

fix: use X-ShopRenter-Token header to avoid Supabase JWT interception #55

Claude 5 месяцев назад
Родитель
Сommit
fa9424aa42
1 измененных файлов с 32 добавлено и 24 удалено
  1. 32 24
      supabase/functions/shoprenter-proxy/index.ts

+ 32 - 24
supabase/functions/shoprenter-proxy/index.ts

@@ -2,7 +2,7 @@ import { serve } from 'https://deno.land/std@0.168.0/http/server.ts'
 
 const corsHeaders = {
   'Access-Control-Allow-Origin': '*',
-  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type, x-shoprenter-shop, x-shoprenter-domain',
+  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type, x-shoprenter-shop, x-shoprenter-token',
   'Access-Control-Allow-Methods': 'GET, POST, PUT, PATCH, DELETE, OPTIONS',
 }
 
@@ -14,15 +14,12 @@ const corsHeaders = {
  * but ShopRenter API requires HTTP/1.0.
  *
  * Usage from n8n:
- * 1. Set Authorization header with Bearer token (from ShopRenter OAuth)
- * 2. Set X-ShopRenter-Shop header with shop name (e.g., "myshop" or "elektromosroller")
- * 3. (Optional) Set X-ShopRenter-Domain header:
- *    - "shoprenter.hu" (default) - forwards to https://{shop}.shoprenter.hu
- *    - "oauth.app.shoprenter.net" - forwards to https://oauth.app.shoprenter.net/{shop}
- * 4. Make requests to: /shoprenter-proxy/api/{endpoint}
+ * 1. Set X-ShopRenter-Token header with access token (from ShopRenter OAuth)
+ *    - Use X-ShopRenter-Token instead of Authorization to avoid Supabase JWT validation
+ * 2. Set X-ShopRenter-Shop header with shop name (e.g., "elektromosroller")
+ * 3. Make requests to: /shoprenter-proxy/api/{endpoint}
  *
  * All request methods (GET, POST, PUT, PATCH, DELETE) are supported.
- * All headers (except Host and X-ShopRenter-*) are forwarded transparently.
  * Request and response bodies are proxied as-is.
  */
 
@@ -39,7 +36,7 @@ serve(async (req) => {
       return new Response(
         JSON.stringify({
           error: 'Missing X-ShopRenter-Shop header',
-          message: 'Please provide the shop name in the X-ShopRenter-Shop header (e.g., "myshop" or "elektromosroller")'
+          message: 'Please provide the shop name in the X-ShopRenter-Shop header (e.g., "elektromosroller")'
         }),
         {
           status: 400,
@@ -48,8 +45,20 @@ serve(async (req) => {
       )
     }
 
-    // Extract domain preference (defaults to shoprenter.hu)
-    const domain = req.headers.get('X-ShopRenter-Domain') || 'shoprenter.hu'
+    // Extract ShopRenter token from custom header
+    const shopRenterToken = req.headers.get('X-ShopRenter-Token')
+    if (!shopRenterToken) {
+      return new Response(
+        JSON.stringify({
+          error: 'Missing X-ShopRenter-Token header',
+          message: 'Please provide the ShopRenter access token in the X-ShopRenter-Token header'
+        }),
+        {
+          status: 400,
+          headers: { ...corsHeaders, 'Content-Type': 'application/json' }
+        }
+      )
+    }
 
     // Extract API endpoint from URL path
     const url = new URL(req.url)
@@ -70,29 +79,30 @@ serve(async (req) => {
 
     const apiPath = pathMatch[1]
 
-    // Construct ShopRenter API URL based on domain
-    let shopRenterUrl: string
-    if (domain === 'oauth.app.shoprenter.net') {
-      // For OAuth API: https://oauth.app.shoprenter.net/{shop}{apiPath}
-      shopRenterUrl = `https://oauth.app.shoprenter.net/${shopName}${apiPath}${url.search}`
-    } else {
-      // For standard API: https://{shop}.shoprenter.hu{apiPath}
-      shopRenterUrl = `https://${shopName}.shoprenter.hu${apiPath}${url.search}`
-    }
+    // Construct ShopRenter API URL - always use standard .shoprenter.hu domain
+    const shopRenterUrl = `https://${shopName}.shoprenter.hu${apiPath}${url.search}`
 
     console.log(`[ShopRenter Proxy] Forwarding ${req.method} request to: ${shopRenterUrl}`)
 
     // Prepare headers for ShopRenter API request
     const shopRenterHeaders = new Headers()
 
-    // Copy all headers from the original request except Host and custom headers
+    // Copy all headers from the original request except Host, Authorization, and custom headers
     for (const [key, value] of req.headers.entries()) {
       const lowerKey = key.toLowerCase()
-      if (lowerKey !== 'host' && !lowerKey.startsWith('x-shoprenter-')) {
+      if (
+        lowerKey !== 'host' &&
+        lowerKey !== 'authorization' && // Skip Supabase auth
+        !lowerKey.startsWith('x-shoprenter-') &&
+        !lowerKey.startsWith('x-client-info')
+      ) {
         shopRenterHeaders.set(key, value)
       }
     }
 
+    // Set Authorization header with ShopRenter token
+    shopRenterHeaders.set('Authorization', `Bearer ${shopRenterToken}`)
+
     // Ensure required headers are present
     if (!shopRenterHeaders.has('Content-Type')) {
       shopRenterHeaders.set('Content-Type', 'application/json')
@@ -120,8 +130,6 @@ serve(async (req) => {
       method: req.method,
       headers: shopRenterHeaders,
       body: body,
-      // Force HTTP/1.1 to avoid ShopRenter API issues
-      // Note: This is handled by Deno's fetch by default
     })
 
     console.log(`[ShopRenter Proxy] ShopRenter API responded with status: ${shopRenterResponse.status}`)