|
|
@@ -291,23 +291,35 @@ export async function getValidAccessToken(storeId: string): Promise<string> {
|
|
|
throw new Error('ShopRenter store not found')
|
|
|
}
|
|
|
|
|
|
- // Try to get client credentials from api_key/api_secret first (primary location)
|
|
|
+ // Get client credentials - prioritize database, fallback to environment variables
|
|
|
let clientId = store.api_key
|
|
|
let clientSecret = store.api_secret
|
|
|
|
|
|
- // If api_key looks like an access_token (JWT format), get credentials from alt_data
|
|
|
+ // If api_key looks like an access_token (JWT format), it was corrupted - get from alt_data
|
|
|
const isAccessToken = store.api_key && store.api_key.includes('.')
|
|
|
|
|
|
if (isAccessToken) {
|
|
|
- // api_key contains a token (old bug), try alt_data for client credentials
|
|
|
- console.log('[ShopRenter] WARNING: api_key appears to be an access_token, retrieving credentials from alt_data')
|
|
|
+ console.log('[ShopRenter] WARNING: api_key appears to be an access_token (corrupted), retrieving credentials from alt_data')
|
|
|
clientId = store.alt_data?.client_id
|
|
|
clientSecret = store.alt_data?.client_secret
|
|
|
}
|
|
|
|
|
|
+ // If api_key/api_secret are NULL/empty (manual testing), try alt_data backup
|
|
|
+ if (!clientId || !clientSecret) {
|
|
|
+ clientId = store.alt_data?.client_id
|
|
|
+ clientSecret = store.alt_data?.client_secret
|
|
|
+ }
|
|
|
+
|
|
|
+ // Final fallback: use global credentials from environment (for testing or when store has NULL credentials)
|
|
|
+ if (!clientId || !clientSecret) {
|
|
|
+ console.log('[ShopRenter] No client credentials in database, using global credentials from environment')
|
|
|
+ clientId = Deno.env.get('SHOPRENTER_CLIENT_ID')
|
|
|
+ clientSecret = Deno.env.get('SHOPRENTER_CLIENT_SECRET')
|
|
|
+ }
|
|
|
+
|
|
|
// Validate client credentials are available
|
|
|
if (!clientId || !clientSecret) {
|
|
|
- throw new Error('ShopRenter client credentials not found in database. Please reconnect the store.')
|
|
|
+ throw new Error('ShopRenter client credentials not found in database or environment. Please reconnect the store or configure SHOPRENTER_CLIENT_ID and SHOPRENTER_CLIENT_SECRET.')
|
|
|
}
|
|
|
|
|
|
// If we have client credentials, use client_credentials flow to get a fresh token
|
|
|
@@ -320,8 +332,9 @@ export async function getValidAccessToken(storeId: string): Promise<string> {
|
|
|
const expiresAt = new Date(Date.now() + (tokenData.expires_in * 1000)).toISOString()
|
|
|
|
|
|
// Update store with the new access token
|
|
|
- // IMPORTANT: Store tokens in access_token/refresh_token columns
|
|
|
- // Keep client credentials in api_key/api_secret for future token renewals
|
|
|
+ // IMPORTANT: Only update access_token, refresh_token, and token_expires_at
|
|
|
+ // NEVER update api_key or api_secret (preserve them for manual testing or per-store credentials)
|
|
|
+ // Always backup client credentials to alt_data for recovery
|
|
|
await supabase
|
|
|
.from('stores')
|
|
|
.update({
|
|
|
@@ -329,9 +342,10 @@ export async function getValidAccessToken(storeId: string): Promise<string> {
|
|
|
refresh_token: tokenData.refresh_token || null,
|
|
|
token_expires_at: expiresAt,
|
|
|
alt_data: {
|
|
|
- ...store.alt_data,
|
|
|
+ ...(store.alt_data || {}),
|
|
|
client_id: clientId,
|
|
|
- client_secret: clientSecret
|
|
|
+ client_secret: clientSecret,
|
|
|
+ last_token_refresh: new Date().toISOString()
|
|
|
}
|
|
|
})
|
|
|
.eq('id', storeId)
|
|
|
@@ -367,7 +381,9 @@ export async function getValidAccessToken(storeId: string): Promise<string> {
|
|
|
const newExpiresAt = new Date(Date.now() + (newTokenData.expires_in * 1000)).toISOString()
|
|
|
|
|
|
// Update store with new tokens
|
|
|
- // IMPORTANT: Also preserve client credentials in alt_data for backup
|
|
|
+ // IMPORTANT: Only update access_token, refresh_token, and token_expires_at
|
|
|
+ // NEVER update api_key or api_secret (preserve them)
|
|
|
+ // Always backup client credentials to alt_data for recovery
|
|
|
await supabase
|
|
|
.from('stores')
|
|
|
.update({
|
|
|
@@ -375,9 +391,10 @@ export async function getValidAccessToken(storeId: string): Promise<string> {
|
|
|
refresh_token: newTokenData.refresh_token || store.refresh_token,
|
|
|
token_expires_at: newExpiresAt,
|
|
|
alt_data: {
|
|
|
- ...store.alt_data,
|
|
|
+ ...(store.alt_data || {}),
|
|
|
client_id: clientId,
|
|
|
- client_secret: clientSecret
|
|
|
+ client_secret: clientSecret,
|
|
|
+ last_token_refresh: new Date().toISOString()
|
|
|
}
|
|
|
})
|
|
|
.eq('id', storeId)
|
|
|
@@ -399,7 +416,9 @@ export async function getValidAccessToken(storeId: string): Promise<string> {
|
|
|
const expiresAt = new Date(Date.now() + (tokenData.expires_in * 1000)).toISOString()
|
|
|
|
|
|
// Update store with new tokens
|
|
|
- // IMPORTANT: Also preserve client credentials in alt_data for backup
|
|
|
+ // IMPORTANT: Only update access_token, refresh_token, and token_expires_at
|
|
|
+ // NEVER update api_key or api_secret (preserve them)
|
|
|
+ // Always backup client credentials to alt_data for recovery
|
|
|
await supabase
|
|
|
.from('stores')
|
|
|
.update({
|
|
|
@@ -407,9 +426,10 @@ export async function getValidAccessToken(storeId: string): Promise<string> {
|
|
|
refresh_token: tokenData.refresh_token || null,
|
|
|
token_expires_at: expiresAt,
|
|
|
alt_data: {
|
|
|
- ...store.alt_data,
|
|
|
+ ...(store.alt_data || {}),
|
|
|
client_id: clientId,
|
|
|
- client_secret: clientSecret
|
|
|
+ client_secret: clientSecret,
|
|
|
+ last_token_refresh: new Date().toISOString()
|
|
|
}
|
|
|
})
|
|
|
.eq('id', storeId)
|