Ver Fonte

fix: improve ShopRenter token acquisition logic #79

- Check alt_data for client credentials first (most reliable)
- Fall back to api_key if it matches client_id pattern (32 hex chars)
- Use global SHOPRENTER_CLIENT_ID/SECRET from environment as last resort
- Always preserve client credentials in alt_data for future renewals
- Properly handle expired tokens with client_credentials flow

This fixes the issue where manually added stores or stores with expired
tokens would fail with 'Invalid token' error.
Claude há 5 meses atrás
pai
commit
770f2abed0
1 ficheiros alterados com 52 adições e 25 exclusões
  1. 52 25
      supabase/functions/_shared/shoprenter-client.ts

+ 52 - 25
supabase/functions/_shared/shoprenter-client.ts

@@ -291,35 +291,62 @@ export async function getValidAccessToken(storeId: string): Promise<string> {
     throw new Error('ShopRenter store not found')
   }
 
+  // Try to get client credentials from alt_data first (most reliable)
+  let clientId = store.alt_data?.client_id
+  let clientSecret = store.alt_data?.client_secret
+
   // Check if api_key contains a client_id (32 hex chars) instead of a token
-  // Client credentials are typically 32 hex characters
   const isClientId = store.api_key && /^[a-f0-9]{32}$/i.test(store.api_key)
 
-  if (isClientId && store.api_secret) {
-    console.log('[ShopRenter] Detected client credentials, obtaining access token via client_credentials flow')
-
-    // Use client_credentials flow to get access token
-    const tokenData = await getTokenWithClientCredentials(store.store_name, store.api_key, store.api_secret)
-
-    const expiresAt = new Date(Date.now() + (tokenData.expires_in * 1000)).toISOString()
-
-    // Update store with the new access token (use token_expires_at column, not alt_data)
-    await supabase
-      .from('stores')
-      .update({
-        api_key: tokenData.access_token,
-        api_secret: tokenData.refresh_token || store.api_secret,
-        token_expires_at: expiresAt,
-        alt_data: {
-          ...store.alt_data,
-          client_id: store.api_key, // Store original client_id for reference
-          client_secret: store.api_secret // Store original client_secret for reference
-        }
-      })
-      .eq('id', storeId)
+  // If not in alt_data and api_key looks like client_id, use it
+  if (!clientId && isClientId) {
+    clientId = store.api_key
+    clientSecret = store.api_secret
+  }
+
+  // If still no client credentials, try environment variables (global app credentials)
+  if (!clientId || !clientSecret) {
+    const envClientId = Deno.env.get('SHOPRENTER_CLIENT_ID')
+    const envClientSecret = Deno.env.get('SHOPRENTER_CLIENT_SECRET')
+
+    if (envClientId && envClientSecret) {
+      console.log('[ShopRenter] Using global client credentials from environment')
+      clientId = envClientId
+      clientSecret = envClientSecret
+    }
+  }
+
+  // If we have client credentials, use client_credentials flow to get a fresh token
+  if (clientId && clientSecret) {
+    console.log('[ShopRenter] Using client_credentials flow to obtain access token')
 
-    console.log('[ShopRenter] Access token obtained and stored successfully, expires at:', expiresAt)
-    return tokenData.access_token
+    try {
+      const tokenData = await getTokenWithClientCredentials(store.store_name, clientId, clientSecret)
+
+      const expiresAt = new Date(Date.now() + (tokenData.expires_in * 1000)).toISOString()
+
+      // Update store with the new access token
+      // IMPORTANT: Always preserve client credentials in alt_data for future token renewals
+      await supabase
+        .from('stores')
+        .update({
+          api_key: tokenData.access_token,
+          api_secret: tokenData.refresh_token || clientSecret,
+          token_expires_at: expiresAt,
+          alt_data: {
+            ...store.alt_data,
+            client_id: clientId,
+            client_secret: clientSecret
+          }
+        })
+        .eq('id', storeId)
+
+      console.log('[ShopRenter] Access token obtained and stored successfully, expires at:', expiresAt)
+      return tokenData.access_token
+    } catch (error) {
+      console.error('[ShopRenter] Failed to get token via client_credentials:', error)
+      // Continue to try other methods below
+    }
   }
 
   // Check if we have tokens in api_key/api_secret (legacy)