This commit is contained in:
Andreas Knuth 2026-02-17 10:18:31 -06:00
parent eb19b2785e
commit c34f0391b3
1 changed files with 17 additions and 18 deletions

View File

@ -1,4 +1,4 @@
// qbo_helper.js // qbo_helper.js - FINALE VERSION
require('dotenv').config(); require('dotenv').config();
const OAuthClient = require('intuit-oauth'); const OAuthClient = require('intuit-oauth');
const fs = require('fs'); const fs = require('fs');
@ -19,17 +19,23 @@ const getOAuthClient = () => {
let savedToken = null; let savedToken = null;
try { try {
if (fs.existsSync(tokenFile)) { if (fs.existsSync(tokenFile)) {
savedToken = JSON.parse(fs.readFileSync(tokenFile, 'utf8')); // Wir lesen nur, wenn es kein Ordner ist (für lokale Tests ohne Docker)
const stat = fs.statSync(tokenFile);
if (stat.isFile()) {
const content = fs.readFileSync(tokenFile, 'utf8');
if (content.trim() !== "{}") {
savedToken = JSON.parse(content);
}
}
} }
} catch (e) { } catch (e) {
console.error("❌ Fehler beim Laden des gespeicherten Tokens:", e); console.error("❌ Fehler beim Laden des gespeicherten Tokens:", e.message);
} }
if (savedToken) { if (savedToken) {
oauthClient.setToken(savedToken); oauthClient.setToken(savedToken);
console.log("✅ Gespeicherter Token geladen."); console.log("✅ Gespeicherter Token aus qbo_token.json geladen.");
} else { } else {
// Fallback auf .env (initiale Tokens)
const envToken = { const envToken = {
access_token: process.env.QBO_ACCESS_TOKEN || '', access_token: process.env.QBO_ACCESS_TOKEN || '',
refresh_token: process.env.QBO_REFRESH_TOKEN || '', refresh_token: process.env.QBO_REFRESH_TOKEN || '',
@ -48,20 +54,19 @@ function saveTokens() {
fs.writeFileSync(tokenFile, JSON.stringify(token, null, 2)); fs.writeFileSync(tokenFile, JSON.stringify(token, null, 2));
console.log("💾 Tokens erfolgreich in qbo_token.json gespeichert."); console.log("💾 Tokens erfolgreich in qbo_token.json gespeichert.");
} catch (e) { } catch (e) {
console.error("❌ Fehler beim Speichern der Tokens:", e); console.error("❌ Fehler beim Speichern der Tokens:", e.message);
} }
} }
async function makeQboApiCall(requestOptions) { async function makeQboApiCall(requestOptions) {
const client = getOAuthClient(); const client = getOAuthClient();
// Funktion zum Aktualisieren des Tokens
const doRefresh = async () => { const doRefresh = async () => {
console.log("🔄 QBO Token Refresh wird ausgeführt..."); console.log("🔄 QBO Token Refresh wird ausgeführt...");
try { try {
const authResponse = await client.refresh(); const authResponse = await client.refresh();
console.log("✅ Token erfolgreich erneuert."); console.log("✅ Token erfolgreich erneuert.");
saveTokens(); // Neue Tokens persistent speichern saveTokens();
return authResponse; return authResponse;
} catch (e) { } catch (e) {
console.error("❌ Refresh fehlgeschlagen:", e.originalMessage || e); console.error("❌ Refresh fehlgeschlagen:", e.originalMessage || e);
@ -69,17 +74,13 @@ async function makeQboApiCall(requestOptions) {
} }
}; };
// Vorab-Prüfung: Wenn Token ungültig (basierend auf expires_at), refreshen // --- WICHTIG: KEINE isAccessTokenValid() PRÜFUNG HIER! ---
if (!client.isAccessTokenValid()) { // Wir vertrauen darauf, dass der Token (egal ob Datei oder .env) funktioniert.
console.log("⚠️ Access Token ist ungültig oder abgelaufen. Refresh wird durchgeführt."); // Wir refreshen nur, wenn QBO uns abweist.
await doRefresh();
}
try { try {
// API-Aufruf durchführen
const response = await client.makeApiCall(requestOptions); const response = await client.makeApiCall(requestOptions);
// Prüfen, ob QBO eine Fehlermeldung im Body sendet
const data = response.getJson ? response.getJson() : response.json; const data = response.getJson ? response.getJson() : response.json;
if (data.fault && data.fault.error) { if (data.fault && data.fault.error) {
@ -92,12 +93,11 @@ async function makeQboApiCall(requestOptions) {
throw new Error(`QBO API Error ${errorCode}: ${data.fault.error[0].message}`); throw new Error(`QBO API Error ${errorCode}: ${data.fault.error[0].message}`);
} }
// Erfolgreichen Aufruf: Tokens speichern (falls geändert) // Bei Erfolg: Speichern (falls sich intern was geändert hat durch die Lib)
saveTokens(); saveTokens();
return response; return response;
} catch (e) { } catch (e) {
// HTTP 401 Unauthorized fangen
const isAuthError = e.response?.status === 401 || (e.authResponse && e.authResponse.response && e.authResponse.response.status === 401); const isAuthError = e.response?.status === 401 || (e.authResponse && e.authResponse.response && e.authResponse.response.status === 401);
if (isAuthError) { if (isAuthError) {
@ -106,7 +106,6 @@ async function makeQboApiCall(requestOptions) {
return await client.makeApiCall(requestOptions); return await client.makeApiCall(requestOptions);
} }
// Alle anderen Fehler weiterwerfen
throw e; throw e;
} }
} }