Why does Quickbooks Web Connector not call closeConnection? - quickbooks

I have a working prototype implementation of the Quickbooks Web Connector (QBWC) interface. Everything works as expected except that the closeConnection method is not getting called most of the time.
Expected Behavior
The QuickBooks Web Connector Programmer’s Guide states the following (pg. 21):
What happens when QBWC gets this string array? If the second member of
the string array contains “none” or “nvu”, QBWC will display a
message, call closeConnection, and stop the session.
Also, the Guide indicates the same info in the "clientVersion and authenticate callbacks" illustration (Figure 2-2, pg. 20):
Call authenticate
If return is "none" or "nvu",
Display message, call closeConnection and stop
Actual Behavior
When the authenticate method returns a value of "none", these (and only these) web methods are called (in the order listed):
serverVersion
clientVersion
authenticate
Note that this is only when there is no work available for QBWC/Quickbooks. When there is work, the authenticate web method returns an empty string and QBWC subsequently calls the following web methods:
sendRequestXml
receiveResponseXml
closeConnection
EDIT 1: After forcing the clientVersion web method to return an "E" result, it does halt the update process as documented in the Programmer's Guide but the closeConnection web method is not called under these circumstances either. It's interesting to note that QBWC does still call the serverVersion web method after the clientVersion returns an "E" result.
Troubleshooting Efforts
Verified (through tracing) that the second member of the string array does in fact contain a value of "none". However, the closeConnection callback never fires for that session.
Double-checked the QBWC client log (QWCLog.txt) and find no mention of closeConnection being called and consequently no errors related to such a call.
Verified that the method code used for closeConnection is identical to the example found in the Programmer's Guide (pg. 68).
Supporting Info
For what it's worth, here are a few details of the implementation.
ASP.Net 3.5 (c#)
QBWC 2.0.0.139

Related

Studio MAKE HTTP REQUEST return sid

This is from a Studio Flow.
I'd like to return the conversation sid. The same "sid" that is used in the Twilio log system. This sid is returned when the conversation is created via a REST call. On the screen below, you can see that I've figured out how to return some flow.data values using this widget. When I look through the available sids (the list is long, but there were approximately six different variable.variable.sid type variables to choose from), none of them seem to return the value that I am looking for. I did add all of them into the JSON return packet and only two returned values. Both values were not what I was looking for.
I'm hopeful that it is something simple like {{message.sid}}, but just haven't discovered the correct variable name yet.
You want: {{flow.sid}} for the Studio Execution SID.

ADALiOS - how to refresh accessToken silently?

I'm using ADALiOS v3.0.0-pre.2 to connect to Azure AD B2C and authorize a given user. I successfully obtain an accessToken for the user, who gets prompted with UI to login in the process. I use the acquireTokenWithScopes method on ADAuthenticationContext instance to do so.
Somewhere down the line, I want to make sure that the accessToken I obtained earlier is still valid and hasn't been revoked. So, I use acquireTokenSilentWithScopes to check. However, I get an immediate error back saying:
Error raised: 10. Additional Information: Domain: ADAuthenticationErrorDomain Details: The user credentials are need to obtain access token. Please call the non-silent acquireTokenWithResource methods.
What's the right usage of this API such that the token gets silently refreshed or throws an error only when it has been revoked on the server side?
I've managed to beat acquireTokenSilentWithScopes into submission by making the following changes to ADALiOS v3.0.0-pre.2.
Change #1:
ADUserIdentifier has the following class method:
+(BOOL) identifier:(ADUserIdentifier*)identifier matchesInfo:(ADProfileInfo*)info
In it, there are the following lines of code:
NSString* matchString = [identifier userIdMatchString:info];
if (!matchString || [matchString isEqualToString:identifier.userId])
{
return YES;
}
For one reason or another, matchString can sometimes come back as NSNull and calling isEqualToString: method on it will throw. I changed it thusly:
id matchString = [identifier userIdMatchString:info];
if (!matchString || ![matchString isKindOfClass:[NSString class]] || [matchString isEqualToString:identifier.userId])
{
return YES;
}
This seems like a legit bug in the framework that's worth fixing.
Change #2:
When a token is received from AD, ADALiOS tries to store that value in the cache. At some point, it calls ADTokenCacheStoreItem's userCacheKey property, which is defined as follows:
-(NSString*)userCacheKey
{
switch (_identifierType)
{
case OptionalDisplayableId:
case RequiredDisplayableId:
return _profileInfo.username;
case UniqueId:
return _profileInfo.subject;
}
}
In my case, I use RequiredDisplayableId to identify users. In the switch statement above, that translates to _profileInfo.username, which, in turn, returns the preferred_username value from the user profile dictionary. For me that value is not set. So, userCacheKey returns NSNull and the caching mechanism fails.
The values that are set in the user profile dictionary are name and tid. This could be a server misconfiguration, but I worked around the issue by changing the return value of this method to _profileInfo.friendlyName (which maps to name in the user profile dictionary).
Change #3:
The ADKeychainTokenCacheStore, which I use as the concrete ADTokenCacheStoring cache of choice, exposes a sharedGroup property that allows multiple applications to share common keychain secrets. By default, sharedGroup is set to com.microsoft.adalcache. However, since the class is currently private, there is no way to override this value. Also, having that value set requires the iOS app to declare the shared group name in its entitlements. Without these entitlements properly configured, setting values into the keychain fails. So, to work around this issue, I manually set the default sharedGroup value to nil in the ADKeychainTokenCacheStore class itself. I suspect eventually this class will be exposed by the framework as public, but currently that's not the case so I had to hack into it.
Change #4
When I request an auth token from the AD server via the ADALiOS framework, I do so using a policy and a set of scopes. The framework code uses this policy/scope pair to create a lookup key and see if any tokens for that key have already been cached. If none are found, the code contacts the server as expected. Once the server returns an auth token, the framework attempts to cache the value. It constructs a brand new policy/scope key object. However, this time, it uses the policy and scope values that are returned by the server, not the ones I passed in. And, for some reason, the server returns those values to nil. As a result, the new policy/scope key that gets constructed for storage is valid but different from the one I used to look up the cached token initially. So, while the caching operation succeeds, next time I try to look up the auth token using my valid policy/scope pair, the lookup fails.
This may, once again, be a server misconfiguration issue.
Regardless, to fix the problem, I now reset the policy and scope values in the response from the server to the original values I used to generate the server request in the first place. This happens in the following method in ADAuthenticationContext(TokenCaching):
- (void)updateCacheToResult:(ADAuthenticationResult*)result
cacheInstance:(id<ADTokenCacheStoring>)tokenCacheStoreInstance
cacheItem:(ADTokenCacheStoreItem*)cacheItem
withRefreshToken:(NSString*)refreshToken
After all these changes, getting the AD auth token and refreshing it silently seems to work as expected. I'm a little worried about how much I needed to hack into the codebase to make it work. It would be helpful if some MS folks could direct me as to whether these changes were warranted or whether there is a more straight-forward solution.
UPDATE:
It turns out that you don't need to hack into ADKeychainTokenCacheStore directly (change #3 above). The ADAutheticationSettings class exposes a method for you to do so thusly:
[[ADAuthenticationSettings sharedInstance] setSharedCacheKeychainGroup:nil];
I'm Brandon Werner from the Azure Active Directory team. I answered this question here: https://stackoverflow.com/a/44170226/1232116 for the specific question asked.

How can I implement this type of redirect after post method in MVC

I am currently creating an MVC application that is currently getting a value from a post from a webhook. I think that the problem is that the application is getting the value from the POST verb but then it is not displaying it because the Get verb is being used to display the View so both Verbs are counter acting each other.
The webhook will fire A Json payload to my application successfully because I have code in it that will send the Json payload in a variable via email to my email account.
Dim body = issue.issue.key
mail.Body = body
That is in a try catch block because in order for it to have a value it must have a value in it and the application will perform the GET first, so there is a null value in the body variable, then it does the POST to get the value but it will not display the value, refreshing will just perform the GET preventing it from being displayed. How can I perform both actions at the same time so I can display a value in a ViewBag for example.
ViewBag.response = status + key
This is the type of structure that I would like to implement to try and fix the error but I do not know how to complete all of the steps:
This is what I have got so far:
The POST is coming in from a webhook and I am reading it like this.
Dim reader As System.IO.StreamReader = New System.IO.StreamReader(HttpContext.Request.InputStream)
Dim rawSendGridJSON As String = reader.ReadToEnd()
Dim tempVar As Rootobject = JsonConvert.DeserializeObject(Of Rootobject)(rawSendGridJSON)
System.Diagnostics.Trace.TraceError(rawSendGridJSON)
I am then trying to store the post values in a table like this:
Public Function CallBack(tempTable as temporaryTable)
Dim tempVar As Rootobject = JsonConvert.DeserializeObject(Of Rootobject)(rawSendGridJSON)
tempVar = temporaryTable.tempVar
I then save the new items in the actual table in the database, then I try to display it in a view on another page. This is not working correctly and the problem lies with this line, as the post is not being correctly read in at the right time. (The value is processing correctly as I can use an email method to send the variables in an email back to the application but this application needs to be real-time efficient code).
Is there a better way to use this method and how can I invoke this process that I want to do properly so that I can display the correct information?
Update
To clarify, there are two posts that are happening, the first one is when the user enters in information and submits it. This is then stored in a database and send to JIRA via email. Once JIRA receives the information, it is sends a HTTP POST webhook JSON Payload back to my application with updated information. I then have deserialized the JSON Payload into a variable called issueKey.
The problem is that on the View page that the information is sent to will automatically display a null value first before the value is sent to it, I want the application to work so that it will actually display/store in a database the values from the Webhook JSON Payload but I cannot figure out how to display the values.
I have now set up a communication channel from SignalR to my MVC application, at the moment it is being received by the MVC and I have set up a SignalR chat Hub in my MVC application, but I don't know how to integrate them, how can this be done?
As I understand it, there are two flows at work here. The user posts data, which triggers an email to Jira. Then sometime later (usually quite fast, but not always) JIRA triggers a webhook in the web application with some updated information, and you want to display this updated information to the user somehow, or at least inform the user when the updated information comes back from JIRA.
I would implement a standard Post-Redirect-Get for the user initiated part (as per br4d's comment). I.e. a post to store the data in the database and send email to jira, which returns a redirect to a get which shows the data stored in the database.
Now for the other part I would use signalr to set up some sort of communications channel to the user. The webook could then send a signal (of sorts) through the communication channel to the users browser and either display the data, or trigger a refresh of the page (if you are updating the database with data from Jira).
It is unclear if you are doing straigt mvc, or some sort of SPA application, but it is not really important. The users browser has no way of knowing about the webhook (which is a part of the webapplication and unrelated to the users session), and you need some sort of communication between the webapplication and the browser, and for this signalr is very very good.

WIF Error: "ID3094: Cannot create WS-Federation message from the given URI 'http://myurl'"

Can anyone tell me what this error means?
I just starting getting it from the STS I build using WIF and I can't find any documentation.
The URL is missing some required parameters.
A message instance is created from the information present in the URL using the WSFederationMessage.CreateFromUri method.
This fragment from the MSDN page should provide an idea of what's going on:
Returns an appropriate implementation of WSFederationMessage based on the wa parameter in the query string; for example, if wa parameter is "wsignout1.0" then a SignOutRequestMessage object is returned.
Other exceptions may be thrown depending on the combination and values of parameters present in the query string.
Invokes the TryCreateFromUri method.

CallLogs in Blackberry

i am working on CallLogs Sync Application in Blackberry and partially i have done it, one point that i didn't understand is how to add information to CallLogs. I have retrieved information from CallLogs and Store on Server but now i retrieved information from Server but how to add info to CallLogs didn't come in my mind as i retrieved all the information in Strings from Server and PhoneCallLog Constructor look like this:
PhoneCallLog call = new PhoneCallLog(Date,int Type,int Duration,int Status,participantID participant,String Notes);
Please tell me as soon as Possible, i will be very thankful to you.
class net.rim.blackberry.api.phone.phonelogs.PhoneLogs has method addCall(CallLog call) that adds a log item.
create PhoneCallLog instance with the constructor you posted and add it to PhoneLogs. You need to have the app signed to use these methods. (see http://www.blackberry.com/go/codesigning )
API documentation:
http://docs.blackberry.com/en/developers/deliverables/6022/net/rim/blackberry/api/phone/phonelogs/PhoneLogs.html
http://docs.blackberry.com/en/developers/deliverables/6022/net/rim/blackberry/api/phone/phonelogs/PhoneCallLog.html

Resources