@satel/shopify-app-utils

Authentication & Validation for Shopify Apps

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
@satel/shopify-app-utils
112.0.0-beta.06 years ago6 years agoMinified + gzip package size for @satel/shopify-app-utils in KB

Readme

Disclaimers
This is beta software. Use in production at your own risk.
Currently validateRequest and handleCallback only support online mode.
About
Provides functionality for some of the more tedious requirements when building a Shopify app such as consistent hmac validation behavior for authentication, proxies, etc. Provided as general use functions but can easily be adapted for use as express middleware.
This is not meant to be a batteries included solution. For that checkout shopify-express
Installation
Note: requires NodeJS >= 8.6.0
npm install @satel/shopify-app-utils
or
yarn add @satel/shopify-app-utils
Documentation

Table of Contents

-   [Parameters](#parameters)
-   [Examples](#examples)
-   [Parameters](#parameters-1)
-   [Parameters](#parameters-2)
-   [Parameters](#parameters-3)
-   [Parameters](#parameters-4)
-   [Parameters](#parameters-5)
-   [Parameters](#parameters-6)
-   [Parameters](#parameters-7)
-   [Parameters](#parameters-8)
-   [Parameters](#parameters-9)
-   [Parameters](#parameters-10)
-   [Examples](#examples-1)
-   [Parameters](#parameters-11)
-   [Examples](#examples-2)
-   [Parameters](#parameters-12)
-   [Parameters](#parameters-13)
-   [Examples](#examples-3)
-   [Parameters](#parameters-14)
-   [Examples](#examples-4)
-   [Parameters](#parameters-15)
-   [Examples](#examples-5)
-   [Parameters](#parameters-16)
-   [Examples](#examples-6)

createOAuth

Creates instances of validateRequest & handleCallback wrapped in a closure

Parameters

-   `options.host` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the base url of the app
-   `options.redirectRoute` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the route where oauth2 redirects will be handled
-   `options.scope` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>** scope your app will require
-   `options.key` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** shopify app api key
-   `options.secret` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** shopify app shared secret
-   `options.online` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** do you require an online token (optional, default `false`)
-   `options.offline` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** do you require an offline token (optional, default `false`)

Examples

const oauth = require('@satel/shopify-app-utils');

const { validateRequest, handleCallback } = oauth.create({
  host: 'https://my-app.com',
  redirectRoute: '/redirect',
  scope: ['read_products'],
  key: 'MY_KEY',
  secret: 'MY_SECRET',
  online: true,
});

validateRequest

TODO

Parameters

-   `options.url` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** url of the request to validate
-   `options.jwt` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** jwt associated with the current request
-   `options.host` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the base url of the app
-   `options.redirectRoute` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the route where oauth2 redirects will be handled
-   `options.scope` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>** scope your app will require
-   `options.key` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** shopify app api key
-   `options.secret` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** shopify app shared secret
-   `options.online` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** do you require an online token (optional, default `false`)
-   `options.offline` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)** do you require an offline token (optional, default `false`)
-   `options.generateNonce` **[validateRequest~generateNonce](#validaterequestgeneratenonce)** 
-   `options.onAuthenticated` **[validateRequest~onAuthenticated](#validaterequestonauthenticated)** 
-   `options.onRedirect` **[validateRequest~onRedirect](#validaterequestonredirect)** 
-   `options.onFailed` **[validateRequest~onFailed](#validaterequestonfailed)** 

validateRequest~generateNonce

Used to generate a nonce to be used in a redirect url
Type: Function

Parameters

-   `options.shop` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the .myshopify domain
Returns string

validateRequest~onAuthenticated

Called when a request is authorized
Type: Function

Parameters

-   `options.shop` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the .myshopify domain
-   `options.appScope` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>** the application scope (when jwt was generated)
-   `options.userScope` **([Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)> | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** the user scope (only applicable to online tokens)
-   `options.decoded` **[object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)** decoded body of the jwt

validateRequest~onRedirect

Called when a redirect is required
Type: Function

Parameters

-   `options.url` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the redirect url
-   `options.html` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** a js based redirect for use in iframes

validateRequest~onFailed

Called when unable to redirect or authorize
Type: Function

Parameters

handleCallback

Parameters

-   `options.url` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
-   `options.key` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** shopify app api key
-   `options.secret` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** shopify app shared secret
-   `options.validateNonce` **[handleCallback~validateNonce](#handlecallbackvalidatenonce)** 
-   `options.onAuthenticated` **[handleCallback~onAuthenticated](#handlecallbackonauthenticated)** 
-   `options.onFailed` **[handleCallback~onFailed](#handlecallbackonfailed)** 
-   `options.margin` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)**  (optional, default `60`)

handleCallback~validateNonce

Used to validate a previously generated nonce
Type: Function

Parameters

-   `options.shop` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the .myshopify domain
-   `options.nonce` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the retrieved nonce
Returns (boolean \| Promise<boolean>)

handleCallback~onAuthenticated

Called when a request is authorized
Type: Function

Parameters

-   `options.token` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the shopify access token
-   `options.online` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** indicates if the current token is online or offline
-   `options.jwt` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** a jwt token
-   `options.shop` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the .myshopify domain
-   `options.appScope` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>** the application scope (when jwt was generated)
-   `options.userScope` **([Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)> | [undefined](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/undefined))** the user scope (only applicable to online tokens)

handleCallback~onFailed

Called when request cannot be authorized
Type: Function

Parameters

validateHMAC

  • See:

Parses the url and validates the HMAC provided by shopify

Parameters

-   `options.url` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
-   `options.secret` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 

Examples

// Import
import { oauth } from '@satel/shopify-app-utils';
const { oauth } = require('@satel/shopify-app-utils');
const { validateHMAC } = oauth;

// Directly
const validateHMAC = require('@satel/shopify-app-utils/oauth/hmac');

// General
const validHMAC = validateHMAC({ url, secret: 'hush' });

// Express
app.use(req => {
  const validHMAC = validateHMAC({ url: req.url, secret: 'hush' });
});

Returns boolean

generateRedirect

Generates the url / html based redirect to start the oauth2 process

Parameters

-   `options.shop` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
-   `options.apiKey` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
-   `options.nonce` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
-   `options.redirect` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
-   `options.scope` **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>** 
-   `options.online` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**  (optional, default `false`)
-   `options.iframe` **[boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)**  (optional, default `false`)

Examples

// Full Page App
res.redirect(
  generateRedirect({
    shop: 'example.myshopify.com',
    apiKey: 'MY_APP_API_KEY',
    nonce: 'unique-request-identifier',
    redirect: 'https://my-app.com/path/to/redirect',
    scope: ['read_products', 'write_products', 'etc'],
  }),
);

// Embedded online app
res.send(
  generateRedirect({
    shop: 'example.myshopify.com',
    apiKey: 'MY_APP_API_KEY',
    nonce: 'unique-request-identifier',
    redirect: 'https://my-app.com/path/to/redirect',
    scope: ['read_products', 'write_products', 'etc'],
    online: true,
    iframe: true,
  }),
);

Returns
string

generateJSRedirect

Pass in a url and it returns an html document that will redirect top rather than the iFrame

Parameters

-   `options.url` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
Returns
string

validateDomain

Checks if a string is a valid .myshopify.com domain (exclude the protocol)

Parameters

-   `options.shop` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 

Examples

const validDomain = validateDomain({ shop: 'my-shop.myshopify.com' });

Returns
boolean

validateTimestamp

Verifies the shopify timestamp generally provided with authenticated responses from shopify

Parameters

-   `$0.timestamp`  
-   `$0.margin`   (optional, default `60`)
string
  • margin
  • number Timestamp must be withing margin of now (optional, default 60)

    Examples

    const validTimestamp = validateTimestamp({ timestamp: '1533160800', margin: 60 * 5 });

    Returns boolean

    validateSignature

    • See:

    Parses the url and validates proxied requests from Shopify

    Parameters

    -   `options.url` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
    -   `options.secret` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 

    Examples

    // Import
    import { proxy } from '@satel/shopify-app-utils';
    const { proxy } = require('@satel/shopify-app-utils');
    const { validateSignature } = proxy;
    
    // Directly
    const validateSignature = require('@satel/shopify-app-utils/oauth/proxy');
    
    // General
    const valid = validateSignature({ url, secret: 'hush' });
    
    // Express
    app.use(req => {
      const valid = validateSignature({ url: req.url, secret: 'hush' });
    });

    Returns
    boolean

    computeHMAC

    Produces a hex encoded Sha256 hmac

    Parameters

    -   `options.text` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 
    -   `options.secret` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** 

    Examples

    const hash = computeHMAC({
      text: 'message',
      secret: 'hush',
    });

    Returns
    string