All files / src/utils decode-session-token.ts

100% Statements 14/14
100% Branches 4/4
100% Functions 1/1
100% Lines 14/14

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 5210x   10x 10x   10x                                         22x 22x   3x         19x 1x     18x 1x     17x     10x     10x      
import jwt from 'jsonwebtoken';
 
import {Context} from '../context';
import * as ShopifyErrors from '../error';
 
import validateShop from './shop-validator';
 
interface JwtPayload {
  iss: string;
  dest: string;
  aud: string;
  sub: string;
  exp: number;
  nbf: number;
  iat: number;
  jti: string;
  sid: string;
}
 
/**
 * Decodes the given session token, and extracts the session information from it
 *
 * @param token Received session token
 */
function decodeSessionToken(token: string): JwtPayload {
  let payload: JwtPayload;
  try {
    payload = jwt.verify(token, Context.API_SECRET_KEY, {algorithms: ['HS256']}) as JwtPayload;
  } catch (error) {
    throw new ShopifyErrors.InvalidJwtError(`Failed to parse session token '${token}': ${error.message}`);
  }
 
  // The exp and nbf fields are validated by the JWT library
 
  if (payload.aud !== Context.API_KEY) {
    throw new ShopifyErrors.InvalidJwtError('Session token had invalid API key');
  }
 
  if (!validateShop(payload.dest.replace(/^https:\/\//, ''))) {
    throw new ShopifyErrors.InvalidJwtError('Session token had invalid shop');
  }
 
  return payload;
}
 
export default decodeSessionToken;
 
export {
  decodeSessionToken,
  JwtPayload,
};