@@ -51,11 +51,28 @@ app.get('/', function (req, res) {
5151 * Get the AuthorizeUri
5252 */
5353app . get ( '/authUri' , urlencodedParser , function ( req , res ) {
54+ // Trim all input values to prevent whitespace issues
55+ const clientId = ( req . query . json . clientId || '' ) . trim ( ) ;
56+ const clientSecret = ( req . query . json . clientSecret || '' ) . trim ( ) ;
57+ const environment = ( req . query . json . environment || '' ) . trim ( ) ;
58+ const redirectUri = ( req . query . json . redirectUri || '' ) . trim ( ) ;
59+
60+ // Validate inputs
61+ if ( ! clientId || ! clientSecret || ! environment || ! redirectUri ) {
62+ return res . status ( 400 ) . send ( 'Missing required parameters' ) ;
63+ }
64+
65+ console . log ( '\n=== Creating OAuth Client ===' ) ;
66+ console . log ( 'Client ID:' , clientId . substring ( 0 , 10 ) + '...' ) ;
67+ console . log ( 'Environment:' , environment ) ;
68+ console . log ( 'Redirect URI:' , redirectUri ) ;
69+ console . log ( '=============================\n' ) ;
70+
5471 oauthClient = new OAuthClient ( {
55- clientId : req . query . json . clientId ,
56- clientSecret : req . query . json . clientSecret ,
57- environment : req . query . json . environment ,
58- redirectUri : req . query . json . redirectUri ,
72+ clientId,
73+ clientSecret,
74+ environment,
75+ redirectUri,
5976 logging : true , //NOTE: a "logs" folder will be created/used in the current working directory, this will have oAuthClient-log.log
6077 } ) ;
6178
@@ -70,13 +87,34 @@ app.get('/authUri', urlencodedParser, function (req, res) {
7087 * Handle the callback to extract the `Auth Code` and exchange them for `Bearer-Tokens`
7188 */
7289app . get ( '/callback' , function ( req , res ) {
90+ console . log ( '\n=== OAuth Callback Received ===' ) ;
91+ console . log ( 'Full callback URL:' , req . url ) ;
92+ console . log ( 'Query params:' , req . query ) ;
93+ console . log ( '===============================\n' ) ;
94+
7395 oauthClient
7496 . createToken ( req . url )
7597 . then ( function ( authResponse ) {
7698 oauth2_token_json = JSON . stringify ( authResponse . json , null , 2 ) ;
99+ console . log ( '✅ Token creation successful!' ) ;
100+ console . log ( 'Token details:' , {
101+ has_access_token : ! ! authResponse . json . access_token ,
102+ has_refresh_token : ! ! authResponse . json . refresh_token ,
103+ realmId : authResponse . json . realmId ,
104+ } ) ;
77105 } )
78106 . catch ( function ( e ) {
79- console . error ( e ) ;
107+ console . error ( '\n❌ Token creation failed!' ) ;
108+ console . error ( 'Error:' , e . error || e . message ) ;
109+ console . error ( 'Error description:' , e . error_description ) ;
110+ console . error ( 'Intuit TID:' , e . intuit_tid ) ;
111+ console . error ( 'Full error:' , e ) ;
112+ console . error ( '\nPossible causes:' ) ;
113+ console . error ( '1. Authorization code already used (codes are single-use)' ) ;
114+ console . error ( '2. Redirect URI mismatch' ) ;
115+ console . error ( '3. Invalid client credentials' ) ;
116+ console . error ( '4. Authorization code expired (10 minute limit)' ) ;
117+ console . error ( '\nSolution: Try authorizing again with "Connect to QuickBooks"\n' ) ;
80118 } ) ;
81119
82120 res . send ( '' ) ;
@@ -109,13 +147,55 @@ app.get('/refreshAccessToken', function (req, res) {
109147 * getCompanyInfo ()
110148 */
111149app . get ( '/getCompanyInfo' , function ( req , res ) {
112- const companyID = oauthClient . getToken ( ) . realmId ;
150+ // Validate that we have a valid oauth client and tokens
151+ if ( ! oauthClient ) {
152+ return res . status ( 400 ) . json ( {
153+ error : true ,
154+ message : 'OAuth client not initialized. Please connect to QuickBooks first.' ,
155+ } ) ;
156+ }
157+
158+ const token = oauthClient . getToken ( ) ;
159+
160+ // Check if we have a valid access token
161+ if ( ! token . access_token ) {
162+ return res . status ( 401 ) . json ( {
163+ error : true ,
164+ message : 'No access token available. Please connect to QuickBooks first.' ,
165+ hint : 'Click "Connect to QuickBooks" button and complete authorization.' ,
166+ } ) ;
167+ }
168+
169+ // Check if access token is still valid
170+ if ( ! oauthClient . isAccessTokenValid ( ) ) {
171+ return res . status ( 401 ) . json ( {
172+ error : true ,
173+ message : 'Access token has expired. Please refresh the token or reconnect.' ,
174+ hint : 'Click "Refresh Token" button to get a new access token.' ,
175+ } ) ;
176+ }
177+
178+ const companyID = token . realmId ;
179+
180+ if ( ! companyID ) {
181+ return res . status ( 400 ) . json ( {
182+ error : true ,
183+ message : 'No company ID (realmId) available.' ,
184+ } ) ;
185+ }
113186
114187 const url =
115188 oauthClient . environment == 'sandbox'
116189 ? OAuthClient . environment . sandbox
117190 : OAuthClient . environment . production ;
118191
192+ console . log ( `\n=== Making API Call ===` ) ;
193+ console . log ( `Company ID: ${ companyID } ` ) ;
194+ console . log ( `Environment: ${ oauthClient . environment } ` ) ;
195+ console . log ( `URL: ${ url } v3/company/${ companyID } /companyinfo/${ companyID } ` ) ;
196+ console . log ( `Access Token Length: ${ token . access_token . length } ` ) ;
197+ console . log ( '======================\n' ) ;
198+
119199 oauthClient
120200 . makeApiCall ( { url : `${ url } v3/company/${ companyID } /companyinfo/${ companyID } ` } )
121201 . then ( function ( authResponse ) {
@@ -124,14 +204,31 @@ app.get('/getCompanyInfo', function (req, res) {
124204 res . send ( resp ) ;
125205 } )
126206 . catch ( function ( e ) {
207+ // Check if it's an OAuthError with detailed information
208+ console . error ( '\n=== API Call Error ===' ) ;
209+ console . error ( 'Error Name:' , e . name ) ;
210+ console . error ( 'Error Message:' , e . message ) ;
211+
212+ if ( e . code ) {
213+ console . error ( 'Error Code:' , e . code ) ;
214+ }
215+
216+ if ( e . description ) {
217+ console . error ( 'Error Description:' , e . description ) ;
218+ }
219+
220+ if ( e . intuitTid ) {
221+ console . error ( 'Intuit Transaction ID:' , e . intuitTid ) ;
222+ }
223+
127224 // Detailed error analysis
128225 const errorAnalysis = {
129226 // Basic error properties
130227 basic : {
131228 name : e . name ,
132229 message : e . message ,
133230 stack : e . stack ,
134- code : e . code
231+ code : e . code ,
135232 } ,
136233 // Response analysis
137234 response : e . response ? {
@@ -148,41 +245,49 @@ app.get('/getCompanyInfo', function (req, res) {
148245 detail : err . Detail ,
149246 code : err . code ,
150247 element : err . element ,
151- additionalInfo : err . additionalInfo
248+ additionalInfo : err . additionalInfo ,
152249 } ) ) : null ,
153- timestamp : e . response . data . time
250+ timestamp : e . response . data . time ,
154251 } : null ) ,
155252 // OAuth error fields
156253 oauth : {
157- error :e . response . data && e . response . data . error ,
158- error_description : e . response . data && e . response . data . error_description
159- }
254+ error : e . response . data && e . response . data . error ,
255+ error_description : e . response . data && e . response . data . error_description ,
256+ } ,
160257 } : null ,
161258 // Request analysis
162259 request : e . request ? {
163260 method : e . request . method ,
164261 path : e . request . path ,
165- headers : e . request . headers
166- } : null
262+ headers : e . request . headers ,
263+ } : null ,
167264 } ;
168265
169266 // Log the detailed error analysis
170267 console . error ( 'Exception Analysis:' , {
171268 hasFaultObject : ! ! ( e . response && e . response . data && e . response . data . Fault ) ,
172269 faultType : e . response && e . response . data && e . response . data . Fault && e . response . data . Fault . type ,
173270 faultErrors : e . response && e . response . data && e . response . data . Fault && e . response . data . Fault . Error ,
174- fullAnalysis : errorAnalysis
271+ fullAnalysis : errorAnalysis ,
175272 } ) ;
273+
274+ console . error ( '======================\n' ) ;
176275
177- // Send error response to client
178- res . status ( e . response ? e . response . status : 500 ) . json ( {
276+ // Send error response to client with more detail
277+ const status = e . response ? e . response . status : 500 ;
278+ const errorResponse = {
179279 error : true ,
180280 message : e . message ,
281+ code : e . code ,
282+ description : e . description ,
283+ intuitTid : e . intuitTid ,
181284 fault : e . response && e . response . data && e . response . data . Fault ? {
182285 type : e . response . data . Fault . type ,
183- errors : e . response . data . Fault . Error
184- } : null
185- } ) ;
286+ errors : e . response . data . Fault . Error ,
287+ } : null ,
288+ } ;
289+
290+ res . status ( status ) . json ( errorResponse ) ;
186291 } ) ;
187292} ) ;
188293
0 commit comments