Data4Autos-Shopify-Frontend/app/utils/turn14Token.server.js
MOHAN d54bda3179 fix: use client-side navigation for nav cards and auto-refresh expired Turn14 tokens
- NavCard now uses useNavigate() instead of <a href> to prevent full-page
  reloads that trigger Shopify re-auth (login page prompt)
- Browse Brands and Manage Brands links changed from absolute admin.shopify.com
  URLs (caused iframe 'refused to connect') to relative /app/* paths
- turn14Token.server.js: add forceRefresh param to skip cached token check
- app.brands.jsx: detect 401/internal_error from Turn14 and retry once with
  a forced token refresh to recover from server-side token expiry

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-02 23:19:05 +05:30

92 lines
2.3 KiB
JavaScript

import { authenticate } from "../shopify.server";
export async function getTurn14AccessTokenFromMetafield(request, forceRefresh = false) {
const { admin, session } = await authenticate.admin(request);
const shop = session.shop;
// Step 1: Get credentials from metafield
const gqlRes = await admin.graphql(`
{
shop {
id
metafield(namespace: "turn14", key: "credentials") {
value
}
}
}
`);
const result = await gqlRes.json();
const shopId = result?.data?.shop?.id;
const raw = result?.data?.shop?.metafield?.value;
if (!raw) {
throw new Error("❌ No Turn14 credentials found in Shopify metafield.");
}
let creds;
try {
creds = JSON.parse(raw);
} catch (err) {
console.error("❌ Failed to parse Turn14 metafield JSON:", err);
throw new Error("Malformed Turn14 credential metafield.");
}
const now = new Date();
const expiresAt = new Date(creds.expiresAt);
const isExpired = now > expiresAt;
if (!forceRefresh && !isExpired && creds.accessToken) {
return creds.accessToken;
}
// ⏰ Expired — refresh token from Turn14 API
const response = await fetch("https://turn14.data4autos.com/v1/auth/token", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
grant_type: "client_credentials",
client_id: creds.clientId,
client_secret: creds.clientSecret,
}),
});
const data = await response.json();
if (!response.ok) {
console.error("❌ Failed to refresh Turn14 token:", data);
throw new Error(data.error || "Failed to refresh Turn14 token");
}
const newToken = data.access_token;
const newExpiresAt = new Date(Date.now() + 3600 * 1000).toISOString();
const newValue = JSON.stringify({
clientId: creds.clientId,
clientSecret: creds.clientSecret,
accessToken: newToken,
expiresAt: newExpiresAt,
}).replace(/"/g, '\\"');
// Step 3: Update metafield in Shopify
await admin.graphql(`
mutation {
metafieldsSet(metafields: [
{
ownerId: "${shopId}"
namespace: "turn14"
key: "credentials"
type: "json"
value: "${newValue}"
}
]) {
userErrors {
field
message
}
}
}
`);
return newToken;
}