JavaScript and Google API Service Account Private Key formatting - javascript

I am struggling with authorisation to Google OAuth2.0 for Service Account.
The script I am writing is pure ECMASCript5, it is running on special purpose server and the communication will be my server - Google server.
I am following this documentation:
https://developers.google.com/identity/protocols/oauth2/service-account#jwt-auth
I have created my signed JWT as described in the documentation.
The problem I have is that after I send access token request, the response form Google server is :
{"error":"invalid_grant","error_description":"Invalid JWT Signature."}
My suspicion is that I may have my private key formatted in wrong way. Google documentation seems to confirm that too.
The key is saved in JSON file downloaded from Google dev console / service account dashboard, and it is in following format:
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEugIBADANBgkqhkiG9w0BAQEFAASCBKQwggSgAgEAAoIBAQDE5vuC4GeikWBu\n8ZQEkcJMFBHJAW40b2WogwWc46pSAnvPVtbeEoVI4n8qx3r2IfpURqQgRr............................=\n-----END PRIVATE KEY-----\n"
The questions is - should I format the key in some way before using it in my encryption method for JWT sign? I noticed it has lots of '\n' and some '=' characters. Should it have newlines or just one line? Should it have the headers?
I have tried .replace(/\\n/g, '\n') and even .replace(/\\n/g, '') but that does not seem to work either.
I am using server's dedicated library and it is closed system without possibility of importing external libraries.
One more confusing thing:
Google documentation says the JWT should be following format:
{Base64url encoded header}.
{Base64url encoded claim set}.
{Base64url encoded signature}
But then in error description they say:
Alternatively, the JWT assertion might be encoded incorrectly - it
must be Base64-encoded, without newlines or padding equal signs.
Is this a mistake when they say in the error description about base64 encoding as opposed to earlier base64url encoding?
Thanks for any help!

Related

Computing JWS Signature for Google oAuth2 (Javascript)

I'm in the process of setting up server-to-server auth for my react app to be able to pull data from the Google Spreadsheet API without the user having to authenticate.
I'm going through the docs: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
I'm having an issue with this bit:
Sign the UTF-8 representation of the input using SHA256withRSA (also known as RSASSA-PKCS1-V1_5-SIGN with the SHA-256 hash function) with the private key obtained from the Google API Console. The output will be a byte array.
What would this look like using javascript?
I've got the private key from my Google API console, and i've got the UTF-8 representation of the input ready to go.
I'm just not sure how I go about signing it using SHA256withRSA with the private key.
Thanks!
Okay, so you've got all the ingredients, now you just want to make the product!
Here's how you can sign input:
Use the crypto lib: https://github.com/thenativeweb/crypto2
Find the correct hashing algorithm (they are listed on there github) and away you go. Here is an example
crypto2.sign(YOUR_INPUT_HERE, your_private_key, (err, signature) => {
console.log (signature); // View the contents
});

Attaching image to email through Parse's Sendgrid module using JavaScript

I was wondering if anyone knew how to send an email with an image attached to it from Parse's Sendgrid module (by this, I mean Facebook's Parse BaaS, not SendGrid's Parse API). So far, I can send out emails, but not with an image attached to it. I tried two different things. One is sending the email as Base64, but I read that is not supported by A LOT of email providers, therefore I was discouraged in using this method since compatibility is kind of an issue here (not critical though). My second approach was to try to mimic sendgrid's process of using a cid, but maybe I was doing something wrong and it did not work
var sendGridInstance = require('sendgrid');
sendGridInstance.initialize(sendGridUser, sendGridKey);
sendGridInstance.sendEmail({
to:endCustomerEmail,
from: 'test#test.com',
subject: 'Test subject',
html: 'My HTML goes here..',
replyto: 'donotreply#test.com'
The code above works whenever it is called in CloudCode, and indeed sends an email. But the cid thing does not work.
Has anyone successfully sent an email w/image using the sendgrid module with Parse? If so, could you please tell me what am I missing?
All help is much appreaciated!
Thank you!
Cheers!
This module doesn't support binary files - it calls SendGrid API with application/x-www-form-urlencoded request and you can't urlencode contents of binary file.
Take a look at https://github.com/m1gu3l/parse-sendgrid-mailer instead - it calls API with multipart/form-data request which is better suited for this case.

Twitter OAuth Pin based authorization 'oob' in Google Apps Script

I am trying to use Twitter Pin-based authorization in my Google Apps Script to eventually send tweets on behalf of other uses.
I freely admit that I don't relay know what I'm doing but I have read a lot of info on the internet and feel I have tried everything.
My current Google Apps Script JavaScript code:
var method = 'post';
var url = 'https://api.twitter.com/oauth/request_token';
var consumerKey = '[my consumer key]';
var ticks = '1422745454';
var nonce = '6826266';
var options = {
'method': method,
'oauth_callback': 'oob',
'oauth_consumer_key': consumerKey,
'oauth_nonce': nonce,
'oauth_signature': 'cIFeptE5HjHp7xrp%2BZt9xFhHox4%3D',
'oauth_signature_method': 'HMAC-SHA1',
'oauth_timestamp': ticks,
'oauth_version': '1.0'
};
var response = UrlFetchApp.fetch(url, options);
For testing I set the ticks just before each test run to the value here
The nonce is a random number between 111111 and 9999999 which is regenerated before each test run.
The oauth signature I have been generating with some c# code lifted from the linq2twitter project
I suspect the problem is the signature. I have read the twitter documentation on creating a signature and I think the C# code is doing it correctly but I am not sure.
The problem is that whatever I try I always get this error:
"Request failed for https://api.twitter.com/oauth/request_token returned code 401. Truncated server response: Failed to validate oauth signature and token (use muteHttpExceptions option to examine full response)"
I have been trying to find an example of Twitter Pin-based authorization in a Google Apps Script but have so far not found anything.
My attempts to translate examples in C#, PHP, etc. have also failed.
Please help.
Apps Script provides an Oauth API that works with UrlFetchApp, they even use twitter in their examples. Work with those if at all possible, troubleshooting signature generation is a real hassle.
https://developers.google.com/apps-script/reference/url-fetch/o-auth-config
https://developers.google.com/apps-script/articles/twitter_tutorial
If you absolutely must do it from scratch, the best approach is to get requests working with an existing library (like the c# one you mention), then work on getting your apps script to generate the exact same request.
I get the sense that is what you are doing now, so it may just be a matter of base64 encoding your Signature in the outgoing request:
https://developers.google.com/apps-script/reference/utilities/utilities#base64Encode(String)
Ultimately, it's very difficult to do the whole Oauth process manually in Apps Script. When I tried something like this from scratch about a year ago I ultimately gave up and used a Python application deployed to Google App Engine instead. I submit requests from Apps Script to the App Engine application, and the App Engine application handles Oauth and relays my requests on to the external service, before returning requests to my Apps Script. This approach comes with complications of it's own.

Missing draft message - javascript Gmail API - how to structure body of the request?

At the recent Google IO conference new Gmail APIs were announced. Client libraries are missing examples and documentation which is understandable given the short time that has gone by.
UPDATE: It wasn't clear in the original question - I've already tried encoding the whole message as Base64 string.
I'm trying to create a new draft message:
var request = gapi.client.gmail.users.drafts.create({
'message' : {
'raw' : Base64.encode("To: someguy#example.com\r\nFrom: myself#example.com\r\nSubject: my subject\r\n\r\nBody goes here")
// 'raw' : "VG86IHNvbWVndXlAZXhhbXBsZS5jb20KRnJvbTogbXlzZWxmQGV4YW1wbGUuY29tClN1YmplY3Q6IG15IHN1YmplY3QKCkJvZHkgZ29lcyBoZXJl"
// 'raw' : "From: me#example.com\nTo:you#example.com\nSubject:Ignore\n\nTest message\n"
}
});
request.execute(function(response) {
});
Can you please provide me with the correct syntax to do that?
(Base64.encode is coming from http://www.webtoolkit.info/javascript-base64.html - tried using plain text, encoded version on the fly and hardcoded values from other question)
Related questions:
Gmail api with .Net CLient library: Missing draft message [400]
Creating a Gmail Draft with Recipients through Gmail API
Creating draft via Google Gmail API
Handy links just for reference:
Google Developers Console: https://console.developers.google.com/project?authuser=0
Gmail API nodejs: https://github.com/google/google-api-nodejs-client/blob/master/apis/gmail/v1.js
Gmail API overview: https://developers.google.com/gmail/api/overview
Quickstart: https://developers.google.com/api-client-library/javascript/start/start-js
Sample code from repo: https://code.google.com/p/google-api-javascript-client/source/browse/samples/simpleRequest.html
So I'm trying to find a solution in related questions addressing Ruby and C# by recreating JSON structure but I've reached the point that I need a Rubber Duck or Stack Overflow.
Thank you in advance for providing a hint on how to structure the object passed to the API method.
While #rds answer is technically correct: "base64 encode complete message", the fully working answer is as follows... The correct structure of the request:
'draft': {
'message': {
'raw': base64EncodedEmail
}
}
Source: https://developers.google.com/gmail/api/v1/reference/users/drafts/create (scroll down and then choose JavaScript from dropdown menu)
I was missing the essential draft property.
Since the question is the same, the answer will be identical:
'raw' should contain the entire (RFC822) email, complete with body and headers.
The trick is it's not just normal base64 encoding it's WEB SAFE (aka URL SAFE) base64 encoding. It's similar except two characters in the alphabet are different to make sure the entire blob works well in URLs and javascript/json.

How do I get a PEM file into the javascript object required for node-bignumber?

I want to configure my Node app to decode public key encrypted messages POST'ed to it using its private key. The private key is in PEM format.
I wanted to use a javascript only solution on the server side for maximum portability (hence ursa is out), this appear to leave node-bignumber ( on the phone app side, I will be using C# and probably something like Scrypt). The single example given for node-bignumber seems to work well so long as yo use the Key method to generate the certificate, however I already have certificates (the public one installed in my phone app and the private one used by my server) - how do I get this into a format recognised by the the library?
I admit I am totally new to NodeJS and javascript and would greatly appreciate any more general advice you may have in providing backends for phone apps ...

Categories