Skip to content

Instantly share code, notes, and snippets.

@phawk
Created August 23, 2019 16:19
Show Gist options
  • Select an option

  • Save phawk/afc0e1acd5f9194f19e27702c348fad2 to your computer and use it in GitHub Desktop.

Select an option

Save phawk/afc0e1acd5f9194f19e27702c348fad2 to your computer and use it in GitHub Desktop.

Revisions

  1. phawk created this gist Aug 23, 2019.
    75 changes: 75 additions & 0 deletions getToken.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,75 @@
    const crypto = require("crypto")
    const querystring = require("querystring")
    const fetch = require("isomorphic-fetch")
    const Account = require("./models/account")

    exports.handler = async (event, context) => {
    const { shop, hmac, code, timestamp } = event.queryStringParameters
    const apiKey = process.env.SHOPIFY_API_KEY
    const apiSecret = process.env.SHOPIFY_API_SECRET


    if (shop && hmac && code) {
    const map = { code, shop, timestamp }
    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 {
    statusCode: 400,
    body: "HMAC validation failed"
    }
    }

    const accessTokenRequestUrl = `https://${shop}/admin/oauth/access_token`
    const accessTokenPayload = {
    client_id: apiKey,
    client_secret: apiSecret,
    code,
    }

    const tokenRes = await fetch(accessTokenRequestUrl, {
    method: "POST",
    headers: {
    "Accept": "application/json",
    "Content-Type": "application/json"
    },
    body: JSON.stringify(accessTokenPayload)
    })

    const tokenJson = await tokenRes.json()

    const acc = new Account({
    id: shop,
    shopifyToken: tokenJson.access_token
    })

    const { id, token } = await acc.save()

    return {
    statusCode: 200,
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ id, token })
    }
    } else {
    return {
    statusCode: 400,
    body: "Required parameters missing"
    }
    }
    }