Last active
December 6, 2018 13:40
-
-
Save devdarren7/5c8058d08f1fad0ed44a4fdf8d58179b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const express = require('express'); | |
| const app = express(); | |
| app.use(express.static(__dirname + '/assets')); | |
| const dotenv = require('dotenv').config(); | |
| const crypto = require('crypto'); | |
| const cookie = require('cookie'); | |
| const nonce = require('nonce')(); | |
| const querystring = require('querystring'); | |
| const request = require('request-promise'); | |
| const apiKey = process.env.SHOPIFY_API_KEY; | |
| const apiSecret = process.env.SHOPIFY_API_SECRET; | |
| const scopes = 'read_products'; | |
| const forwardingAddress = "https://arcane-savannah-70578.herokuapp.com/"; // Replace this with your HTTPS Forwarding address | |
| // https://687d8c81.ngrok.io/shopify?shop=dreamcatcherscom.myshopify.com | |
| const FroalaEditor = require('froala-editor'); | |
| app.set('views', __dirname + '/views'); | |
| app.set('view engine', 'jade'); | |
| const server_port = process.env.YOUR_PORT || process.env.PORT || 80; | |
| const server_host = process.env.YOUR_HOST || '0.0.0.0'; | |
| app.get('/shopify', (req, res) => { | |
| const shop = req.query.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'); | |
| } | |
| }); | |
| app.get('/shopify/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/metafields.json'; | |
| const shopRequestHeaders = { | |
| 'X-Shopify-Access-Token': accessToken, | |
| }; | |
| const info = { json: accessTokenPayload } ; | |
| request.get(shopRequestUrl, { headers: shopRequestHeaders }) | |
| .then((shopResponse) => { | |
| res.status(200).send(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'); | |
| } | |
| }); | |
| app.listen(server_port, server_host, function() { | |
| console.log('Listening on port %d', server_port); | |
| console.log(__dirname); | |
| }); | |
| app.get('/', function (req, res) { | |
| res.render('map', | |
| { title : 'Home', | |
| api_Key: apiKey, | |
| shop : req.headers.cookie && cookie.parse(req.headers.cookie).shop, | |
| }); | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment