← back to Filemaker Mcp
fix: resolve George basic-auth from live fleet cred (was empty 'admin:', 401'd since 2026-07-13 rotation → froze Shopify→FileMaker sync at order #32600)
aa0cdddff7fe8aa7783feb9100ca16ab80155b55 · 2026-07-14 10:24:40 -0700 · Steve Abrams
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Files touched
M bin/shopify-sync.jsA lib/george-auth.jsM lib/notify.js
Diff
commit aa0cdddff7fe8aa7783feb9100ca16ab80155b55
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Tue Jul 14 10:24:40 2026 -0700
fix: resolve George basic-auth from live fleet cred (was empty 'admin:', 401'd since 2026-07-13 rotation → froze Shopify→FileMaker sync at order #32600)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---
bin/shopify-sync.js | 5 +++--
lib/george-auth.js | 40 ++++++++++++++++++++++++++++++++++++++++
lib/notify.js | 6 ++++--
3 files changed, 47 insertions(+), 4 deletions(-)
diff --git a/bin/shopify-sync.js b/bin/shopify-sync.js
index e78fa80..953cfcf 100644
--- a/bin/shopify-sync.js
+++ b/bin/shopify-sync.js
@@ -7,6 +7,7 @@ import { readFileSync, writeFileSync, existsSync, mkdirSync, appendFileSync } fr
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
import { syncOrder } from '../lib/sync-core.js';
+import { georgeAuthHeader, GEORGE_URL } from '../lib/george-auth.js';
const __dir = dirname(fileURLToPath(import.meta.url));
const ROOT = join(__dir, '..');
@@ -20,8 +21,8 @@ if (!existsSync(DATA)) mkdirSync(DATA, { recursive: true });
const STATE_F = join(DATA, 'sync-state.json');
const LEDGER = join(DATA, 'sync-ledger.jsonl');
-const GEORGE = 'http://127.0.0.1:9850';
-const GEORGE_AUTH = 'Basic ' + Buffer.from('admin:').toString('base64');
+const GEORGE = GEORGE_URL;
+const GEORGE_AUTH = georgeAuthHeader(); // fleet cred, resolved from canonical DW-MCP/.env (rotated 2026-07-13)
const DW_SENDER = 'store+1541177456@t.shopifyemail.com'; // the DW customer-order sender (excludes vendor confirmations)
const STORE = process.env.FM_SHOPIFY_STORE || process.env.SHOPIFY_STORE;
const SHOP_TOKEN = process.env.SHOPIFY_ORDERS_TOKEN;
diff --git a/lib/george-auth.js b/lib/george-auth.js
new file mode 100644
index 0000000..ff9e77e
--- /dev/null
+++ b/lib/george-auth.js
@@ -0,0 +1,40 @@
+// Resolve the George (Gmail agent, :9850) basic-auth credential from the SAME
+// canonical fleet source George itself reads, so a rotation there propagates
+// here automatically instead of silently breaking this pipeline.
+//
+// History: before 2026-07-13 these callers hardcoded an empty password
+// ('admin:'). On 2026-07-13 the fleet cred was rotated to a real 32-char pass
+// AND George was hardened to fail-closed on empty/invalid creds. The empty
+// password started returning 401, which made bin/shopify-sync.js throw
+// 'George search failed: 401' at its first step — freezing the Shopify→FileMaker
+// order sync at order #32600 (see data/sync.out.log FATAL loop). This resolver
+// prevents a recurrence: it always tracks the live fleet cred.
+//
+// Priority: GEORGE_BASIC_AUTH env → fleet DW-MCP/.env → local filemaker-mcp/.env.
+import { readFileSync } from 'node:fs';
+import { join } from 'node:path';
+
+function fromEnvFile(path, key) {
+ try {
+ const m = readFileSync(path, 'utf8').match(new RegExp('^' + key + '=(.+)$', 'm'));
+ return m ? m[1].trim() : '';
+ } catch {
+ return '';
+ }
+}
+
+export function georgeCred() {
+ const HOME = process.env.HOME || '';
+ return (
+ process.env.GEORGE_BASIC_AUTH ||
+ fromEnvFile(join(HOME, 'Projects/Designer-Wallcoverings/DW-MCP/.env'), 'GEORGE_BASIC_AUTH') ||
+ fromEnvFile(join(HOME, 'Projects/filemaker-mcp/.env'), 'GEORGE_BASIC_AUTH') ||
+ 'admin:' // legacy fallback — now rejected by George, so it 401s loudly rather than silently
+ );
+}
+
+export function georgeAuthHeader() {
+ return 'Basic ' + Buffer.from(georgeCred()).toString('base64');
+}
+
+export const GEORGE_URL = process.env.GEORGE_URL || 'http://127.0.0.1:9850';
diff --git a/lib/notify.js b/lib/notify.js
index 26f12ee..8c04f48 100644
--- a/lib/notify.js
+++ b/lib/notify.js
@@ -2,10 +2,12 @@ import { appendFileSync, readFileSync, mkdirSync, existsSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { dirname, join } from 'node:path';
+import { georgeAuthHeader, GEORGE_URL } from './george-auth.js';
+
const NOTIFY_ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
const FLAGGED_QUEUE = join(NOTIFY_ROOT, 'data', 'flagged-skus.jsonl');
-const GEORGE = process.env.GEORGE_URL || 'http://127.0.0.1:9850';
-const GEORGE_AUTH = 'Basic ' + Buffer.from((process.env.GEORGE_BASIC || 'admin:')).toString('base64');
+const GEORGE = GEORGE_URL;
+const GEORGE_AUTH = georgeAuthHeader(); // fleet cred, resolved from canonical DW-MCP/.env (rotated 2026-07-13)
// Idempotency key for a flagged SKU: one row per (order, invoice, sku).
const flagKey = (orderId, invoiceNumber, sku) => `${orderId}:${invoiceNumber}:${sku}`;
← 22d9eff Add Greenland cork disco script: stamps Date Discontinued on
·
back to Filemaker Mcp
·
fix: idempotency guard — skip invoice creation when FileMake 65eb72c →