ApplePay completeMerchantValidation fails - applepay

We have a site example.com behind ssl that runs a page with ApplePay.
We've got a server side that returns a Merchant Session that looks like the following:
{"epochTimestamp":1581975586106,"expiresAt":1581979186106,"merchantSessionIdentifier":"SSH8E666B0...","nonce":"1239e567","merchantIdentifier":"...8557220BAF491419A...","domainName":"example.com","displayName":"ApplePay","signature":"...20101310f300d06096086480165030402010500308..."}
We receive this response in session.onvalidatemerchant as a string and convert it to a Json Object and pass to session.completeMerchantValidation.
As a result we get the following error:
Code: "InvalidAccessError"
Message: "The object does not support the operation or argument"
We run the following code on our page:
.....
session.onvalidatemerchant = (event) => {
const validationURL = event.validationURL;
getApplePaySession(validationURL).then(function (response) {
try {
let resp = JSON.parse(response);
session.completeMerchantValidation(resp);
} catch (e) {
console.error(JSON.stringify(e));
}
});
};
....
Additional questions:
Is the object described above a "correct" Merchant Session opaque that needs to be passed to completeMerchantValidation or it's missing some fields?
Is this object needs to be passed as is or it needs to be base64 encoded?
Does it need to be wrapped into another object?
Any help or lead is greatly appreciated.

Related

How can I save a response of HTTP GET Request in variable?

Here is my API code
#GetMapping("/api/test")
public String test() {
return "hello";
}
Then I will send request to this API by using ajax.
function test() {
$.ajax({
type: "GET",
url: "/api/test",
success: function(response) {
}
})
}
I want to save the value of ajax call response (In this case "hello") in variable. Please let me know how to do it.
Several ways of doing it !
As far as only a String message is concerned you can just store it like below
`var myResponse=response;`
Alternatively, you can also access values if response is an object (JSON reponse I mean)
for e.g. `var resp=response.message; //Assuming message is a key in response JSON`
For testing, use alert(response) or console.log(response) to see how your response is coming and manipulate accordingly !
Feel free to refer this link for detailed Ajax walkthrough https://www.tutorialspoint.com/jquery/jquery-ajax.htm
Hope these helps!

GET request with query parameters returns 403 error (signature does not match) - AWS Amplify

Problem
I was trying to use 'aws-amplify' GET API request with query parameters on the client side, but it turned out to be Request failed with status code 403, and the response showed:
"message":"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
Note: React.js as front-end, Javascript as back-end.
My code
Front-end
function getData() {
const apiName = 'MyApiName';
const path = '/path';
const content = {
body:{
data:'myData',
},
};
return API.get(apiName, path, content);
}
Back-end
try {
const result = await dynamoDbLib.call("query", params);
} catch (e) {
return failure({ status: false });
}
What I did to debug
The GET lambda function works fine in Amazon Console (Tested)
If I change the backend lambda function so that the frontend request can be made without parameters, i.e. return API.get(apiName, path), then no error shows up.
My question
How can I make this GET request with query parameters works?
I changed GET to POST (return API.post()), everything works fine now.
If anyone can provide a more detailed explanation, it would be very helpful.

Angular HttpClientModule Body Syntax Issue

I am trying to make an HTTP request like this:
login(username, password) {
let body = {
userid: username,
password: password
}
let options = {
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded'),
withCredentials: true
};
let request = this.http.post(this.baseUrl, body, options);
request.subscribe();
}
which is returning a 500 internal server error. However, if I modify the body variable to look like this:
login(username, password) {
let body = 'userid=' + username + '&password=' + password;
let options = {
headers: new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded'),
withCredentials: true
};
let request = this.http.post(this.baseUrl, body, options);
request.subscribe();
}
it works fine. I have seen the first version used in the documentation, but for some reason it doesn't work this way for me. I'm wondering:
A) Are these statements supposed to be equivalent? Is there a syntax issue? -or-
B) Is there a problem on the backend? In our server log, we're getting something like 'parameter #userIdentifier is expected but not supplied.'
I have to go with the one that works, but I'd like to use the syntax of the first statement if possible. Thanks!
Without more information on the backend or on the specific 500 error message you are receiving, the only suggestion I have is to verify that your back-end schema matches the front-end model. Judging by the limited error message provided, it looks as though you may have mislabeled userid as userIdentifier in the backend.

Making a POST request using Superagent, AWS Lambda, API Gateway

I am using AWS Lambda and API Gateway to create a custom endpoint for load tests. I have uploaded my handler function which is in a file, along with the node modules needed for the function in a zip, and set up the API Gateway API correctly according the instructions (in line with the way that I had made it work before), but I keep getting the error: {"error": "Missing Authentication Token"}. Everything I have seen online thus far points to the idea that the url that I am passing in with the POST request is invalid, but I have made a similar endpoint work with a GET request. As far as I know I have set up the POST request (using Superagent) correctly, and am passing in a valid access-token, as well as hardcoded params as part of the URL (valid params).
// Dependencies
var request = require('superagent');
var sync = require('synchronize');
exports.handler = function(event, context) {
sync.fiber(function() {
// Grabs params passed into the URL as a JSON object
var querystring = (event.querystring);
// Replaces params with an updated version which includes a single quotation
var queryStringUpdate = querystring.replace(/=/g, ":").replace(/}/g, "'}").replace(/:/g, ":'").replace(/,/g, "',");
// Updates the param information and sets it as a new string
eval('var queryString2 =' + queryStringUpdate);
// Define specific query params to be used in the REST calls
var userId = (queryString2.userId === undefined ? '229969' : queryString2.userId);
var roomdId = (queryString2.roomId === undefined ? '4' : queryString2.roomId);
var inviterId = (queryString2.inviterId === undefined ? '212733' : queryString2.inviterId);
var createInvitePost = function() {
request
.post('https://some_url/v2/invites/212733/create')
.set({'access-token': 'some_access_token'})
.set('Content-Type', 'application/json')
.query({user_id: "229969"})
.query({room_jid: "4"})
.end(function(err, res){
if (err) {
context.fail("Uh oh, something went wrong");
} else {
context.done(null, "Hurray, it worked!!");
}
});
};
try {
createInvitePost();
} catch(errOne) {
alert("No bueno!!");
}
});
};
Any thoughts on this?? Thanks
I usually get this error when I've missed some part of the URL needed for my API. In the past it's either been the name of the stage, misspelled resource name, or a missing Path parameter.
I'm from the Api Gateway team.
As others have said, the most common cause of the 403 response you're getting is an incorrect path/method. I'm not familiar with Superagent, but if you've run the same request in Postman and cURL then I would be surprised if you had the wrong path/method.
Maybe also check on a wire log if possible, to make sure that your querystring logic isn't appending a forward slash prior to the '?'.
Some things to check:
Have you deployed any recent changes to your API?
Is the stage 'v2' (I'm assuming that's the stage) pointing at a deployed version of the API that has the POST to invites/212733/create?
The 'access-token' should have no effect on the Api Gateway layer. If you're trying to use a native Api Gateway Api Key, the header is 'x-api-key'.
Jack

Cloud Code: Creating a Parse.File from URL

I'm working on a Cloud Code function that uses facebook graph API to retrieve users profile picture. So I have access to the proper picture URL but I'm not being able to acreate a Parse.File from this URL.
This is pretty much what I'm trying:
Parse.Cloud.httpRequest({
url: httpResponse.data["attending"]["data"][key]["picture"]["data"]["url"],
success: function(httpImgFile)
{
var imgFile = new Parse.File("file", httpImgFile);
fbPerson.set("profilePicture", imgFile);
},
error: function(httpResponse)
{
console.log("unsuccessful http request");
}
});
And its returning the following:
Result: TypeError: Cannot create a Parse.File with that data.
at new e (Parse.js:13:25175)
at Object.Parse.Cloud.httpRequest.success (main.js:57:26)
at Object.<anonymous> (<anonymous>:842:19)
Ideas?
I was having trouble with this exact same problem right now. For some reason this question is already top on Google results for parsefile from httprequest buffer!
The Parse.File documentation says
The data for the file, as 1. an Array of byte value Numbers, or 2. an Object like { base64: "..." } with a base64-encoded String. 3. a File object selected with a file upload control. (3) only works in Firefox 3.6+, Safari 6.0.2+, Chrome 7+, and IE 10+.
I believe for CloudCode the easiest solution is 2. The thing that was tripping me earlier is that I didn't notice it expects an Object with the format { base64: {{your base64 encoded data here}} }.
Also Parse.Files can only be set to a Parse.Object after being saved (this behaviour is also present on all client SDKs). I strongly recommend using the Promise version of the API as it makes much easier to compose such asynchronous operations.
So the following code will solve your problem:
Parse.Cloud.httpRequest({...}).then(function (httpImgFile) {
var data = {
base64: httpImgFile.buffer.toString('base64')
};
var file = new Parse.File("file", data);
return file.save();
}).then(function (file) {
fbPerson.set("profilePicture", file);
return fbPerson.save();
}).then(function (fbPerson) {
// fbPerson is saved with the image
});

Resources