Oauth2 Scope for invoices in Xero API? - xero-api

What is the correct scope to generate invoices using the Xero API?
The docs say I should direct users to the following URL:
https://login.xero.com/identity/connect/authorize?
response_type=code&
client_id=YOURCLIENTID&
redirect_uri=YOURREDIRECTURI&
scope=openid profile email accounting.transactions&
state=123
And says:
scope permissions to request (links to here)
But I can't see anything that clearly states "Invoicing" or "Create invoice" unless its one of the following:
Accounting API
accounting.transactions
accounting.transactions.read
accounting.reports.read
accounting.journals.read
accounting.settings
accounting.settings.read
accounting.contacts
accounting.contacts.read
accounting.attachments
accounting.attachments.read
What values do I need to pass as the scope parameter?

Invoice interactions are included in the set of business transactions covered by the accounting.transactions scope (and accounting.transactions.read for read-only actions).

Related

Express REST API with JWT and Routes

I am trying to create an Express API with JWT authentication.
However, I was wondering how to best allow users to only access their own resources.
For example if there is a user with id 1 and each user has a list of books in the database:
The id is already part of the JWT Token but commonly there would be a request to something like /users/1/books to get all of the books belonging to user 1.
Would my routes typically still look like this and I would just check the id in the token is the same the request is made for, or is there any other/simpler way?
Thank you for your help!
You can define, some access rights permissions base on the user role or id.
Example: roles : {root, admin, staff}
Then, in your routes you can have some checking whether this user have the permission to access the functions or you can do in the controller level to check the access rights.
You need to define model relations between User, UserModel. In your case as I understand you need to have the relations between UserModel and BooksModels.
UserModel hasMany BooksModel
When you call findOne() to retrieve specific user's data, you can just define include: 'aliasModelName', to retrieve the users related book data.
With this way, you can only have 1endpoint users/:id to retrieve users data and book data. It depends on what you really want, you can also have an endpoint users/:id/books to get all books that belongs to this user.
Your model definition will then become
BooksModel belongsTo UserModel
If you use hasMany you can get all the results that you need in just one query.
Hope this helps!
When user sends the login credentials, you check database if the email exists, if yes then you check if the password matches. If user successfully signins you create the token.
const token = jwt.sign({ _id: user._id, email: user.email }, "this-is-secret", {
expiresIn: "1h",
});
this token is sent to the browser, whenever user make requests, it manually attachs this token to the req, and sends the request to your server. You check if the token is valid, by using the secret key (in this case "this-is-secret").
const decodedToken = jwt.verify(token, "this-is-secret")
req.userId = decodedToken.userId;
now "userId" is attached to the req object. Now when you fetch the data from database, the items that you are fetching, you write a query that (implementation depends on which database you are using)
book.userId=req.userId

googleapis.com/oauth2/v2/userinfo returns null value

the below URLs I have been using for google sign in my website.
log in URL
https://accounts.google.com/o/oauth2/auth?scope='.urlencode('https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email') . '&redirect_uri=' . urlencode(CLIENT_REDIRECT_URL) . '&response_type=code&client_id=' . CLIENT_ID . '&access_type=online
access token URL
https://accounts.google.com/o/oauth2/token
UserInfo endpoint URL(new URL)
https://www.googleapis.com/oauth2/v2/userinfo (returns null values)
Google+ endpoint URL that I'm currently using
https://www.googleapis.com/plus/v1/people/me (returns email, names, etc)
I want to get user name & email to save in my DB.
how can I get name & email with UserInfo endpoint URL which I have mentioned above?
UPDATED:
I've changed my userinfo endpoint as 'https://www.googleapis.com/plus/v1/people/me' and now it's working well
Based on the sample code you linked to, there are at least a couple of changes you need to make or try.
The first is that you may need to request different scopes, since the scopes determine what will be returned. That code relies on scopes that will be invalid or no longer suggested. The scopes you should be using to get the profile and email are:
openid
profile
email
(The longer scope names you use should also work, but you may want to try these simpler ones as well.)
So the login_url in step 2 might look more like this:
$login_url = 'https://accounts.google.com/o/oauth2/v2/auth?scope=' . urlencode('openid profile email') . '&redirect_uri=' . urlencode(CLIENT_REDIRECT_URL) . '&response_type=code&client_id=' . CLIENT_ID . '&access_type=online';
Although the userinfo v2 endpoint is still semi-maintained, it has been deprecated.
Instead, try one of the following:
The userinfo v3 endpoint at https://www.googleapis.com/oauth2/v3/userinfo
Get the discovery document at https://accounts.google.com/.well-known/openid-configuration and using the url associated with the userinfo_endpoint value.
There are still some things to pay attention to, however:
Not all the data may be available. If the user has not set some profile information, the API can't provide it.
The fields will not be the same as in the Plus endpoint. So while the data may be there, it may be in a different location in the object returned.
access token URL https://www.googleapis.com/oauth2/v2/userinfo (returns null values)
You should provide valid credentials to get a response from these openid endpoint
either by Authorization header or QueryParams; for instance:
https://www.googleapis.com/oauth2/v2/userinfo?access_token=FOO_BAR...
Either access_token, id_token, or token_handle
also applies to v3 (https://www.googleapis.com/oauth2/v3/userinfo)

PayPal API - cancel_url gives only token?

Is it possible to get the Payer ID?
The return_url provides Payer ID, amount etc .. while the cancel_url gives only token.
There was no payment, so no payer, so no payer ID. There was no transaction, so no transaction ID. No money was paid, so no amount.
If you are using the Paypal-PHP-SDK is not possible at this moment, the unique solution for now is save the token when you create the payment. In DEV-MASTER branch they have added a new method called "getToken()" to Payment class, so you will get the token easily when you create a payment. You can track the issue using the next URL Paypal-PHP-SDK issue 832
$payment->create($apiContext);
$token = $payment->getToken();
PS: Remember, this method "getToken()" is only available in DEV-MASTER for now.

Disqus - How to pass current logged in user?

I am using Disqus API to fetch details of the logged in user. I am not sure how to pass the current logged in user.
I have both api_key(public) and remote_auth and I am using Jquery ajax to send api request over http.
If I do something like this,
https://disqus.com/api/3.0/users/details.json?api_key=[apikey]
It says "You must either provide a user or authenticate the user." Now I have the loggedin users remote_auth.
FYI: This is how I am creating the remote_auth. Example User Id: 3096795, email = "a#a.com", Name="Test". Now when this user logs in to the website, it logs in to Disqus as well. I can see this user in http://disqus.com/api/sso/users/ with id = 3096795.
I have couple of questions:
1) Can I use jquery ajax to send a authenticated user and get user details? Or this can be done only via Server side? (Java/Php)
2) If I pass ?remote_auth=[remote_auth] as a query string, will it work?
3) if yes, remote_auth value has spaces in between HMAC->SHA1(secret_key, message + ' ' + timestamp) so how can I pass it as query string parameter?
4) If no, then how to pass a user to the listActivity.json endpoint? If I am passing the userid, then it returns me some other user and not the user I created.
The below request returns a different user.
https://disqus.com/api/3.0/users/details.json?api_key=[apikey]&user=3096795
How can I ensure the userid I am passing is unique and not already taken by a different disqus account?
Am I missing something?
Your remote_auth is a form of authentication, just like access_token, so you'll want to pass that in your request as remote_auth=<YOUR_PAYLOAD>.
If you pass "user=" that ID would have to be the Disqus user ID, which isn't the same as your remote_auth ID. Your remote_auth is a form of authentication, just like the access_token. However, keep in mind that we don't return as many details for SSO users as authenticated Disqus users. This is because the details are managed by you, the SSO site owner.
To answer your other questions:
You can use the client-side API to get these details, but we recommend the server-side API + caching the results to avoid bumping into API limits.
URL-encode the payload and this will work
Easier using https://github.com/anthavio/disquo
DisqusApplicationKeys keys = new DisqusApplicationKeys("...api_key...", "...secret_key...", "...access_token...");
DisqusApi disqus = new DisqusApi(keys);
//SSO is available only to premium accounts
SsoAuthData ssoauth = new SsoAuthData("custom-12345-id", "Firstname", "Surname");
//SSO User identity is used to create post
disqus.posts().create(ssoauth, keys.getApiSecret(), threadId, "Hello world " + new Date(), null);

Is there a programmatic interface for retrieving/exporting Report results from Salesforce?

I am trying to retrieve the results of a Salesforce Report programmatically.
Often referenced is this blog about scraping the results from the web side, but the method is unsupported: http://sfdc-heretic.warped-minds.com/2006/04/10/progmatic-access-to-salesforcecom-reports/.
I can get a list of reports via the REST api:
require 'restforce'
restforce_client = Restforce.new(
:refresh_token => <refresh token>,
:client_id => <client id>,
:client_secret => <client secret>
)
reports = restforce.query("SELECT Id,DeveloperName FROM Report")
reports.last.DeveloperName
=> "Rob_Test_Report"
I've also tried retrieving via the Metadata SOAP API ReportFolder object:
require 'metaforce'
metaforce = Metaforce.new(
:username => <username>,
:password => <password>,
:security_token => <security token>
)
report_folders = metaforce.list_metadata('ReportFolder')
report_folders.last.full_name
=> "RobTestReportFolder"
I can see the folder. I haven't retrieved the contents yet but even when I do it seems that I would just be getting the metadata around the report itself (i.e. the filter criteria), not the results of the report. The metadata api is discussed here: https://success.salesforce.com/questiondetail?qId=a1X30000000IQ8pEAG. Is this correct?
I saw this similar question from a couple years ago but did not know if it was correct or anything had changed in the API:
How to I access reports programmatically in SalesForce using Apex
Is it possible to export or pull the results of a Report through a supported Salesforce API?
You cannot retrieve the results of a report without using the Analytics API, which as of the Summer '13 release will be available only as a pilot. If you want to participate in the pilot, let me know and I will submit your request.
Once in the Pilot, you use a REST endpoint passing in the Id of the report. You will have two endpoints-- a describereport endpoint and a runreport enndpoint. What is returned from describeReport is a JSON representation of the metadata for the report (describes the dimensions and facts and such) and from runReport a JSON representation of the data.
Once you have the data you can do with it what you will. The report data is only available at the summary level and for the pilot only summary and matrix reports are supported.
I'm not aware of any programmatic way to do that. Conga app could be one option but I believe they get the filters from the report's metadata and construct a matching SOQL query...
The blog post you've mentioned should work. You probably missing something like setting session id in cookie.
Hack, error-prone, web-scraping way would be to use something similar to trick I did with Apex: https://salesforce.stackexchange.com/questions/4303/scheduled-reports-as-attachment. Theoretically you'd be able to pull off similar thing from any other API access as long as you have the user's session Id (whether passed from logged in session or generated yourself from SOAP login call...)
Do also check out metadaddy's answer to my related question: https://salesforce.stackexchange.com/questions/4692/screen-scrape-salesforce-with-rest-get-call-from-apex