BigCommerce Hello World app - using app in the store - javascript

I installed successfully the Hello World app.
I'm trying to use the app in the storefront.
Following the instructions, I added the code provided to the script manager :
<script>
var appClientId = "**BC_CLIENT_ID**"; // TODO: Fill this in with your app's client ID.
var storeHash = "**TEST_STORE_HASH**"; // TODO: Fill this in wit the test store's store hash (found in base url before the `store-` part)
var appUrl = "**APP_URL**"; // TODO: Replace this with the URL to your app.
// Get the JWT token from the BC server signed first.
$.get('/customer/current.jwt?app_client_id=' + appClientId, function(jwtToken) {
// Now that we have the JWT token, use it to get the recent purchases block.
$.get(appUrl + '/storefront/' + storeHash + '/customers/' + jwtToken + '/recently_purchased.html', function(htmlContent) {
$('#recent_purchases_block').html(htmlContent, true);
});
});
</script>
I first ran into a "Uncaught ReferenceError: $ is not defined" error, which I solved including jquery-3.3.1.
But then, I get a 404 error with the GET request. I tried different values for APP_URL, but still get this error.
Here is the GET request :
https://www.marineff.com/rebates/load/storefront/STORE_HASH/customers/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJjdXN0b21lciI6eyJpZCI6MSwiZW1haWwiOiJqam9yaW9AaG90bWFpbC5jb20iLCJncm91cF9pZCI6IjAifSwiaXNzIjoiYmMvYXBwcyIsInN1YiI6Imt6N3Nma20yZHgiLCJpYXQiOjE1NTE5NDI5NTEsImV4cCI6MTU1MTk0Mzg1MSwidmVyc2lvbiI6MSwiYXVkIjoiNGZocWNvOTBha21qMzI5Z2lmMXY4dzFqdzRqN3FzZyIsImFwcGxpY2F0aW9uX2lkIjoiNGZocWNvOTBha21qMzI5Z2lmMXY4dzFqdzRqN3FzZyIsInN0b3JlX2hhc2giOiJrejdzZmttMmR4Iiwib3BlcmF0aW9uIjoiY3VycmVudF9jdXN0b21lciJ9.i7mguILu_jGue9nO5wZbtG8IhXqFkKuY71fAEsZTe27Tyxfjm4SAhUZUUxNvTbVhADP4Qm9kqY6BjU7I-SDgWA/recently_purchased.html
Any idea ?
Thanks

Related

Integrate Salesforce registration page with VanillaJS oidc-client-js, getting the error - No matching state found in storage

Integrate Salesforce registration page with VanillaJS, getting the error - No matching state found in storage
We are redirecting the user to Salesforce registration page when Create Account button is created.
Once the User registers in Salesforce, the user is redirected to our site but we are getting this error. ('No matching state found in storage').
We tried the below solution but still getting the same error.
As I stated in my answer, the oidc client maintains state information
in the local storage so that it can verify that it got the response
back from the intended server. You can mimic this by generating a
secure random string and saving it in localStorage. Do this before
sending a request to your auth server to register a new user.
Reference- Integrate third party login in from my registration page with IdentityServer4 and Angular 6 - 'No matching state found in storage'
Is there a function related to creating registration? How to fix this issue?
Thanks.
Appreciate your help.
After spending days on this issue. Finally found the workaround as registration is not a feature of OIDC.
To overcome this issue, need to follow the Sign In process same as for Sign Up process, created the startSignupMainWindow method same as startSigninMainWindow and passing the signUpFlag:true as shown below in code.
/* This function is written to mimic the oidc library sign in process flow */
function startSignupMainWindow() {
var someState = {
message: window.location.href,
signUpFlag: true
};
mgr.signinRedirect({
state: someState,
useReplaceToNavigate: true
}).then(function() {
log("signinRedirect done");
}).catch(function(err) {
log(err);
});
}
Reading the signUpFlag:true in UserManager.js and swapping the Salesforce Sign In page Url with Sign Up page url and calling the Register function in Code.
UserManager.js(oidc - client - dev - js / src / UserManager.js)
//UserManager Customised Code :
return this.createSigninRequest(args).then(signinRequest => {
Log.debug("UserManager._signinStart: got signin request");
navigatorParams.url = signinRequest.url;
navigatorParams.id = signinRequest.state.id;
if (signinRequest.state._data.signUpFlag) {
register(signinRequest.state._id, signinRequest.state._code_challenge);
} else {
return handle.navigate(navigatorParams);
}
})
The below code is Register function written in code.
/* This function is written to send the code_challenge to salesforce server so that
salesforce server holds the code challenge and used to verify the further requests(token-request)
against the code_challenge it received initially.*/
//Customised register function written outside the library (Inside our App):
function register(_id, code_challenge) {
var date = new Date();
var baseUrl = "SALESFORCE_URL/login/SelfRegister?expid=id";
var expId = "id";
var userPage = encodeURIComponent(window.location.href);
var appDetails = "response_type=code&" +
"client_id=CLIENT_ID" +
"client_secret=CLIENT_SECRET&" +
"redirect_uri=CALLBACK_URL&" +
"state=" + _id + "&code_challenge=" + code_challenge + "&code_challenge_method=S256&response_mode=query";
var encodedapp = encodeURIComponent(appDetails);
var startUrl = "/services/oauth2/authorize/expid?" + encodedapp;
var signUpUrl = baseUrl + "&startURL=" + startUrl;
window.open(signUpUrl, "_self");
};

APNSwork on apn provider but not through nodeJS - Production

I have a nodeJS script set up to send APNs. When in development it always works but when i go to production they never get through. I tried taking the same notification Id it's sending and sending something using my production certificate in Easy Apn Provider and and it goes through. Im not sure why i could be failing. If my profile or certificates were wrong the easy apn wouldnt go through either?
apn config
var options = {
token: {
cert: "certificate.pem",
pfx: "Certificate.p12",
key: "AuthKey_XCVK62CSQF.p8",
keyId: "3Z6SEF7GE5",
teamId: "ASQJ3L7765"
},
production: true,
gateway: 'gateway.push.apple.com', // gateway address
port: 2195
};
var apnProvider = new apn.Provider(options);
Result of:
//IOS notif function
function SendIOSNotification(token, message, sound, payload, badge){
var deviceToken = token; //phone notification id
var notification = new apn.Notification(); //prepare notif
notification.topic = 'com.GL.Greek-Life'; // Specify your iOS app's Bundle ID (accessible within the project editor)
notification.expiry = Math.floor(Date.now() / 1000) + 3600; // Set expiration to 1 hour from now (in case device is offline)
notification.badge = badge; //selected badge
notification.sound = sound; //sound is configurable
notification.alert = message; //supports emoticon codes
notification.payload = {id: payload}; // Send any extra payload data with the notification which will be accessible to your app in didReceiveRemoteNotification
apnProvider.send(notification, deviceToken).then(function(result) { //send actual notifcation
// Check the result for any failed devices
var subToken = token.substring(0, 6);
console.log("Succesfully sent message to ", subToken);
}).catch( function (error) {
console.log("Faled to send message to ", subToken);
})
}
is successfully sent message to 5D..
Edit:
When displaying my response i see that the notification actually failed with a 403 error (id doesnt exist however it works just fine with easy apn).
I assume its because im generating a non production id but i dont understand how thats possible. I signed my build and have it on testflight and ive removed all signes of development profiles and only have production profiles and certificates. Not sure how thiis is happening
The issue was that when i changed to production and it wasnt working I tried creating a new .p8 key. It was likely working at that point but i only changed the reference to .p8 and not the key parameter to the key of the .p8 found on my developer account. Once i updated that key all my problems were solved

How to properly generate Facebook Graph API App Secret Proof in Javascript

I am making a server side Facebook Graph API call to the all_mutual_friends edge: https://developers.facebook.com/docs/graph-api/reference/user-context/all_mutual_friends/
The call works when the two users are friends, but returns no useful data when they users aren't friends. According to the docs, this is because I must sign the call with the appsecret_proof parameter. No matter what I try, I am not able to successfully pass this parameter. I am using jsrsasign running on Parse. I have tried every configuration of using the access token as the message and my appSecret as the key, and vice versa. I have also tried multiple combinations of utf8 and hex. Every time I receive the error: invalid appsecret_proof provided in the API argument
Code:
var Signer = require("cloud/vendor/jsrsasign/lib/jsrsasign.js");
var userId = request.params.userId;
var accessToken = request.params.accessToken;
var appSecret = "redactedStringPastedFromFacebook";
var signer = new Signer.Mac({alg: "hmacsha256", pass: appSecret});
var appSecretString = signer.doFinalString(accessToken);
var appSecretHex = signer.doFinalHex(accessToken);
var graphRequestURL = "https://graph.facebook.com/v2.5/" + userId;
var fields = "?fields=context.fields(all_mutual_friends.fields(name,picture.width(200).height(200)))";
//var authorization = "&access_token=" + accessToken; //this works, but only for existing friends
var authorization = "&access_token=" + accessToken + "&appsecret_proof=" + appSecretHex;
return Parse.Cloud.httpRequest({
url: graphRequestURL + fields + authorization,
method: "GET",
})
Most examples I have seen are in PHP or Python and the crypto routines are a bit more clear. This works in that both appSecretString and appSecretHex don't throw errors and look reasonable, however the values are always rejected by Facebook.
Notes:
I have triple checked the App Secret value provided by Facebook
I have been approved by Facebook to use the all_mutual_friends feature, which is a requirement for this particular call
I am using Parse, which isn't Node, and can't use NPM modules that have external dependencies, which is why I am using jsrsasign. I also tried using CryptoJS directly, but it is no longer maintained and doesn't have proper module support and jsrsasign seems to wrap it anyway.
Here it is:
import CryptoJS from 'crypto-js';
const accessToken = <your_page_access_token>;
const clientSecret = <your_app_client_secret>;
const appsecretProof = CryptoJS.HmacSHA256(accessToken, clientSecret).toString(CryptoJS.enc.Hex);

Trouble with authenticating a test web app using keyrock

First we set up our app in the fiware lab:
the code that we are using to create the app is on this site
The only thing we changed from that link is the config.js:
var config = {}
config.idmURL = 'https://account.lab.fiware.org/';
config.client_id = 'f9b5940d67a741a38039690e4d6e6c6f';
config.client_secret = 'c9f854c96c9e4c70a0d402bce3233a17';
config.callbackURL = 'http://panonit.com:8802/user_info';
// Depending on Grant Type:
// Authorization Code Grant: code
// Implicit Grant: token
config.response_type = 'code';
module.exports = config;
When deploying the node server we have the following site up and running (on a colleagues laptop):
You can see it for yourself between the hours of 09h and 18h CET.
After we click log in we are properly taken to the fiware site where the user can authenticate:
And this is where the site breaks (it says page unavailable):
To over come this issue we only changed the server.js to output only the response:
// Ask IDM for user info
app.get('/user_info', function(req, res){
var url = config.idmURL + '/user/';
// Using the access token asks the IDM for the user info
oa.get(url, req.session.access_token, function (e, response) {
//var user = JSON.parse(response);
var user = response;
console.log("Getting user response is: " + user)
//res.send("Welcome " + user.displayName + "<br> Your email address is " + user.email + "<br><br><button onclick='window.location.href=\"/logout\"'>Log out</button>");
res.send("Welcome " + user)
});
});
After doing this we have restarted the server. From here we once again pressed the log in and authenticated the app usage and instead of the site break we get:
here we have concluded that the response is an empty object because undefined is printed out.
What are we doing wrong here?
Checking it, the problem is that you are using a wrong callback URL. If you check the server.js, the path for the callback URL you are using is /user_info, and to use that, first you need the req.session.access_token that you retrieve at /login. Just change the callback url for:
config.callbackURL = 'http://panonit.com:8802/login';
And everything should work. Also remember to change it in your IdM app configuration!
yes, the issue is what albertinisg has pointed out. The callbackURL must be /login in order to get the code and from it retrieve the access token. Then with the access token you will be able to retrieve the user info.
BR

Dashboard data with Good data SDK

I need to consume my company 'Target Social R3 V3' dashboard data with Good data Javascript SDK. First I'm trying to get pinterest data as start but I'm receiving error 400 Bad request. I'm newbie to good data api and following methods given in good data examples in Java script SDK.
$('#root').append('<div class="login-loader">Logging in...</div>');
gooddata.user.login(user, passwd).then(function() {
// Loged in
$('div.login-loader').remove();
$('#root').append('<div class="loading">Logged in... Loading metrics</div>');
// Do your stuff here
// ...
gooddata.md.getMetrics(projectId).then(function(dataSets) {
$('div.loading').remove();
$('#root').append('<div class="dataLoading">Laoding data...</div>');
$('#root').append('<p>Total number of metrics ' + dataSets.length + '</p>');
elements=[];
dataSets.forEach(function(ds) {
var dstr = JSON.stringify(ds.title);
if(dstr.toLowerCase().indexOf("pinterest account followers") > 0)
{
var did = JSON.stringify(ds.identifier);
$('#datasets').append('<li>'+did+'</li>');
elements.push(did);
}
});
$('#root').append('<p>Total number of choosen metrics '+elements.length + ' and element '+elements[0] +'</p>');
gooddata.execution.getData(projectId, elements).then(function(dataResult)
{
$('div.dataLoading').remove();
console.log('Social Data:\n'+ JSON.stringify(dataResult));
});
});
});
I'd appreciate if some one could explain about attributes and metrics passed here as parameters.
Make sure your sample is under gooddata-js/examples/ folder (let's assume is named 'mysample') and it has index.html file in that directory. Set user and passwd variables in your script file to your real GoodData user name and password. Run grunt dev and access your sample at https://localhost:8443/mysample/index.html. It should work.
If it does not work, please provide the details (message body) of the 400 error you are getting.

Categories