Skip to content

Instantly share code, notes, and snippets.

@devdarren7
Last active May 19, 2019 21:05
Show Gist options
  • Select an option

  • Save devdarren7/a42201816639d4252263c5399c95e8f6 to your computer and use it in GitHub Desktop.

Select an option

Save devdarren7/a42201816639d4252263c5399c95e8f6 to your computer and use it in GitHub Desktop.
const express = require('express');
const Shop = require('../models/Shop');
const Shopify = require('shopify-node-api');
const config = require('../config');
const generateNonce = require('../helpers').generateNonce;
const buildWebhook = require('../helpers').buildWebhook;
const bodyParser = require('body-parser');
const url = require('url');
const querystring = require('querystring');
const router = express.Router();
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
let shopAPI ;
let shopName ;
let redirectURI
const nonce = generateNonce();
console.log(generateNonce);
function BuildAuth( req, res , next){
var shop = req.query.shop;
console.log(shop);
if (shop) {
const state = nonce;
const redirectUri = forwardingAddress + '/shopify/callback';
const installUrl = 'https://' + shop +
'/admin/oauth/authorize?client_id=' + apiKey +
'&scope=' + scopes +
'&state=' + state +
'&redirect_uri=' + redirectUri;
res.cookie('state', state);
res.redirect(installUrl);
} else {
return res.status(400).send('Missing shop parameter. Please add ?shop=your-development-shop.myshopify.com to your request');
}
}
function Auth(req,res,next){
const params = req.query;
const query = Shop.findOne({ shopify_domain: params.shop }).exec();
query.then((result) => {
const shop = result;
const shopAPI = new Shopify({
shop: params.shop,
shopify_api_key: config.SHOPIFY_API_KEY,
shopify_shared_secret: config.SHOPIFY_SHARED_SECRET,
nonce: shop.nonce,
});
shopAPI.exchange_temporary_token(params, (error, data) => {
if (error) {
console.log(error);
res.redirect('/error');
}
console.log(data);
shop.accessToken = data.access_token;
shop.isActive = true;
shop.save((saveError) => {
if (saveError) {
console.log('Cannot save shop: ', saveError);
res.redirect('/error');
}
if (config.APP_STORE_NAME) {
res.redirect(`https://${shop.shopify_domain}/admin/apps/${config.APP_STORE_NAME}`);
} else {
res.redirect(`https://${shop.shopify_domain}/admin/apps`);
}
});
});
});
}
function queryDB(req,res ,next){
var shopName = req.query.shop + '.myshopify.com';
const query = Shop.findOne({ shopify_domain: shopName }).exec();
shopAPI = new Shopify({
shop: shopName,
shopify_api_key: config.SHOPIFY_API_KEY,
shopify_shared_secret: config.SHOPIFY_SHARED_SECRET,
shopify_scope: config.APP_SCOPE,
nonce,
redirect_uri: `${config.APP_URI}/install/callback`,
});
var redirectURI = shopAPI.buildAuthURL();
next()
}
function saveDomain(req,res ,next){
let save;
const shop = shopAPI;
if (!shop) {
save = new Shop({ shopify_domain: shopName, nonce }).save();
} else {
shop.shopify_domain = shopName;
shop.nonce = nonce;
Shop({ shopify_domain: shopName, nonce }).save();
}
}
function callBack(req,res){
const { shop, hmac, code, state } = req.query;
const stateCookie = cookie.parse(req.headers.cookie).state;
if (state !== stateCookie) {
return res.status(403).send('Request origin cannot be verified');
}
if (shop && hmac && code) {
// DONE: Validate request is from Shopify
const map = Object.assign({}, req.query);
delete map['signature'];
delete map['hmac'];
const message = querystring.stringify(map);
const providedHmac = Buffer.from(hmac, 'utf-8');
const generatedHash = Buffer.from(
crypto
.createHmac('sha256', apiSecret)
.update(message)
.digest('hex'),
'utf-8'
);
let hashEquals = false;
try {
hashEquals = crypto.timingSafeEqual(generatedHash, providedHmac)
} catch (e) {
hashEquals = false;
};
if (!hashEquals) {
return res.status(400).send('HMAC validation failed');
}
// DONE: Exchange temporary code for a permanent access token
const accessTokenRequestUrl = 'https://' + shop + '/admin/oauth/access_token';
const accessTokenPayload = {
client_id: apiKey,
client_secret: apiSecret,
code,
};
request.post(accessTokenRequestUrl, { json: accessTokenPayload })
.then((accessTokenResponse) => {
const accessToken = accessTokenResponse.access_token;
// DONE: Use access token to make API call to 'shop' endpoint
const shopRequestUrl = 'https://' + shop + '/admin/api/2019-04/shop.json';
const shopRequestHeaders = {
'X-Shopify-Access-Token': accessToken,
};
request.get(shopRequestUrl, { headers: shopRequestHeaders })
.then((shopResponse) => {
res.status(200).end(shopResponse);
})
.catch((error) => {
res.status(error.statusCode).send(error.error.error_description);
});
})
.catch((error) => {
res.status(error.statusCode).send(error.error.error_description);
});
} else {
res.status(400).send('Required parameters missing');
}
}
let shop ;
router.all('/', BuildAuth, queryDB ,(req, res) => {
});
module.exports = router;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment