This is beta software. Use in production at your own risk.
Currently validateRequest and handleCallback only support online mode.
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
Note: requires NodeJS >= 8.6.0
npm install @satel/shopify-app-utils
or
yarn add @satel/shopify-app-utils
- createOAuth
- validateRequest
- validateRequest~generateNonce
- validateRequest~onAuthenticated
- validateRequest~onRedirect
- validateRequest~onFailed
- handleCallback
- handleCallback~validateNonce
- handleCallback~onAuthenticated
- handleCallback~onFailed
- validateHMAC
- generateRedirect
- generateJSRedirect
- validateDomain
- validateTimestamp
- validateSignature
- computeHMAC
Creates instances of validateRequest & handleCallback wrapped in a closure
optionsobjectoptions.hoststring the base url of the appoptions.redirectRoutestring the route where oauth2 redirects will be handledoptions.scopeArray<string> scope your app will requireoptions.keystring shopify app api keyoptions.secretstring shopify app shared secretoptions.onlineboolean do you require an online token (optional, defaultfalse)options.offlineboolean do you require an offline token (optional, defaultfalse)
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,
});TODO
optionsobjectoptions.urlstring url of the request to validateoptions.jwtstring jwt associated with the current requestoptions.hoststring the base url of the appoptions.redirectRoutestring the route where oauth2 redirects will be handledoptions.scopeArray<string> scope your app will requireoptions.keystring shopify app api keyoptions.secretstring shopify app shared secretoptions.onlineboolean do you require an online token (optional, defaultfalse)options.offlineboolean do you require an offline token (optional, defaultfalse)options.generateNoncevalidateRequest~generateNonceoptions.onAuthenticatedvalidateRequest~onAuthenticatedoptions.onRedirectvalidateRequest~onRedirectoptions.onFailedvalidateRequest~onFailed
Used to generate a nonce to be used in a redirect url
Type: Function
Returns string
Called when a request is authorized
Type: Function
optionsobject
Called when a redirect is required
Type: Function
optionsobject
Called when unable to redirect or authorize
Type: Function
optionsobject
optionsobjectoptions.urlstringoptions.keystring shopify app api keyoptions.secretstring shopify app shared secretoptions.validateNoncehandleCallback~validateNonceoptions.onAuthenticatedhandleCallback~onAuthenticatedoptions.onFailedhandleCallback~onFailedoptions.marginnumber (optional, default60)
Used to validate a previously generated nonce
Type: Function
Returns (boolean | Promise<boolean>)
Called when a request is authorized
Type: Function
optionsobjectoptions.tokenstring the shopify access tokenoptions.onlinestring indicates if the current token is online or offlineoptions.jwtstring a jwt tokenoptions.shopstring the .myshopify domainoptions.appScopeArray<string> the application scope (when jwt was generated)options.userScope(Array<string> | undefined) the user scope (only applicable to online tokens)
Called when request cannot be authorized
Type: Function
optionsobject
Parses the url and validates the HMAC provided by shopify
// 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
Generates the url / html based redirect to start the oauth2 process
optionsObject
// 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
Pass in a url and it returns an html document that will redirect top rather than the iFrame
Returns string
Checks if a string is a valid .myshopify.com domain (exclude the protocol)
const validDomain = validateDomain({ shop: 'my-shop.myshopify.com' });Returns boolean
Verifies the shopify timestamp generally provided with authenticated responses from shopify
$0Object$0.timestamp$0.margin(optional, default60)
optionsObjecttimestampstringmarginnumber Timestamp must be withing margin of now (optional, default60)
const validTimestamp = validateTimestamp({ timestamp: '1533160800', margin: 60 * 5 });Returns boolean
Parses the url and validates proxied requests from Shopify
// 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
Produces a hex encoded Sha256 hmac
const hash = computeHMAC({
text: 'message',
secret: 'hush',
});Returns string