This commit is contained in:
2026-02-17 13:33:39 -06:00
parent 272f325d98
commit 52dcdce8bb
5 changed files with 195 additions and 12 deletions

View File

@@ -1,4 +1,4 @@
// qbo_helper.js - FIX FÜR ERROR 3200
// qbo_helper.js - MIT OAUTH FLOW & VERBESSERTEM TOKEN HANDLING
require('dotenv').config();
const OAuthClient = require('intuit-oauth');
const fs = require('fs');
@@ -31,7 +31,7 @@ const getOAuthClient = () => {
console.error("❌ Fehler beim Laden des gespeicherten Tokens:", e.message);
}
if (savedToken) {
if (savedToken && savedToken.refresh_token) {
oauthClient.setToken(savedToken);
console.log("✅ Gespeicherter Token aus qbo_token.json geladen.");
} else {
@@ -40,13 +40,25 @@ const getOAuthClient = () => {
refresh_token: process.env.QBO_REFRESH_TOKEN || '',
realmId: process.env.QBO_REALM_ID
};
oauthClient.setToken(envToken);
console.log(" Token aus .env geladen (Fallback).");
if (envToken.refresh_token) {
oauthClient.setToken(envToken);
console.log(" Token aus .env geladen (Fallback).");
} else {
console.warn("⚠️ Kein gültiger Token vorhanden. Bitte unter Settings → QBO autorisieren.");
}
}
}
return oauthClient;
};
/**
* Setzt den oauthClient zurück, damit beim nächsten getOAuthClient()
* der Token frisch aus der Datei geladen wird.
*/
function resetOAuthClient() {
oauthClient = null;
}
function saveTokens() {
try {
const token = getOAuthClient().getToken();
@@ -60,6 +72,12 @@ function saveTokens() {
async function makeQboApiCall(requestOptions) {
const client = getOAuthClient();
// Prüfen ob überhaupt ein Refresh Token vorhanden ist
const currentToken = client.getToken();
if (!currentToken || !currentToken.refresh_token) {
throw new Error("Kein gültiger QBO Token vorhanden. Bitte unter Settings → 'Authorize QBO' klicken.");
}
const doRefresh = async () => {
console.log("🔄 QBO Token Refresh wird ausgeführt...");
try {
@@ -68,7 +86,15 @@ async function makeQboApiCall(requestOptions) {
saveTokens();
return authResponse;
} catch (e) {
console.error("❌ Refresh fehlgeschlagen:", e.originalMessage || e);
const errMsg = e.originalMessage || e.message || String(e);
console.error("❌ Refresh fehlgeschlagen:", errMsg);
// Wenn der Refresh Token komplett ungültig ist → klare Meldung
if (errMsg.includes('invalid') || errMsg.includes('Authorize again')) {
throw new Error(
"Der Refresh Token ist abgelaufen. Bitte unter Settings → 'Authorize QBO' neu autorisieren."
);
}
throw e;
}
};
@@ -82,7 +108,7 @@ async function makeQboApiCall(requestOptions) {
if (data.fault && data.fault.error) {
const errorCode = data.fault.error[0].code;
// --- FIX: 3200 (Auth Failed) HINZUGEFÜGT ---
// 3200 (Auth Failed), 3202, 3100 → Refresh versuchen
if (errorCode === '3200' || errorCode === '3202' || errorCode === '3100') {
console.log(`⚠️ QBO meldet Token-Fehler (${errorCode}). Versuche Refresh und Retry...`);
await doRefresh();
@@ -114,5 +140,7 @@ async function makeQboApiCall(requestOptions) {
module.exports = {
getOAuthClient,
makeQboApiCall
makeQboApiCall,
saveTokens,
resetOAuthClient
};