Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Merge pull request #94 from Shopify/reauth-outdated-session
Browse files Browse the repository at this point in the history
Test Authentication with API request
  • Loading branch information
mllemango authored Apr 22, 2021
2 parents 976e95a + a404112 commit 97e9d13
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 17 deletions.
22 changes: 8 additions & 14 deletions src/verify-request/tests/verify-request.test.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,19 @@
import '../../test/test_helper';

import {createMockContext} from '@shopify/jest-koa-mocks';
import {fetch} from '@shopify/jest-dom-mocks';
import {StatusCode} from '@shopify/network';
import Shopify from '@shopify/shopify-api';
import Shopify, { RequestReturn } from '@shopify/shopify-api';
import jwt from 'jsonwebtoken';

import verifyRequest from '../verify-request';
import {clearSession} from '../utilities';
import {TEST_COOKIE_NAME, TOP_LEVEL_OAUTH_COOKIE_NAME} from '../../index';
import {REAUTH_HEADER, REAUTH_URL_HEADER} from '../verify-token';
import { clear } from 'console';

const TEST_SHOP = 'testshop.myshopify.io';
const TEST_USER = '1';

describe('verifyRequest', () => {
afterEach(fetch.restore);

describe('when there is an accessToken and shop in session', () => {
let jwtToken: string;
Expand All @@ -43,6 +40,13 @@ describe('verifyRequest', () => {
session.accessToken = 'test_token';
session.scope = 'test_scope';
await Shopify.Utils.storeSession(session);

// mocking metafields call from client.get()
Shopify.Clients.Rest.prototype.get = jest.fn(({path, query}) => {
expect(path).toEqual('metafields');
expect(query).toEqual({'limit': 1})
return Promise.resolve({ "body": "" } as RequestReturn);
});
});

it('calls next', async () => {
Expand All @@ -53,7 +57,6 @@ describe('verifyRequest', () => {
} as any);
const next = jest.fn();

fetch.mock(metaFieldsUrl(TEST_SHOP), StatusCode.Ok);
await verifyRequestMiddleware(ctx, next);

expect(next).toHaveBeenCalled();
Expand All @@ -75,7 +78,6 @@ describe('verifyRequest', () => {
} as any);
const next = jest.fn();

fetch.mock(metaFieldsUrl(TEST_SHOP), StatusCode.Ok);
await verifyRequestMiddleware(ctx, next);

expect(next).toHaveBeenCalled();
Expand All @@ -89,7 +91,6 @@ describe('verifyRequest', () => {
});
const next = jest.fn();

fetch.mock(metaFieldsUrl(TEST_SHOP), StatusCode.Ok);
await verifyRequestMiddleware(ctx, next);

expect(next).toHaveBeenCalled();
Expand All @@ -103,7 +104,6 @@ describe('verifyRequest', () => {
});
const next = jest.fn();

fetch.mock(metaFieldsUrl(TEST_SHOP), StatusCode.Ok);
await verifyRequestMiddleware(ctx, next);

expect(ctx.cookies.set).toHaveBeenCalledWith(TOP_LEVEL_OAUTH_COOKIE_NAME);
Expand Down Expand Up @@ -139,7 +139,6 @@ describe('verifyRequest', () => {
headers: { authorization: `Bearer ${jwtToken}` }
});

fetch.mock(metaFieldsUrl(TEST_SHOP), StatusCode.Ok);
await verifyRequestMiddleware(ctx, next);

expect(ctx.redirect).toHaveBeenCalledWith(
Expand All @@ -162,7 +161,6 @@ describe('verifyRequest', () => {
headers: { authorization: `Bearer ${jwtToken}` }
});

fetch.mock(metaFieldsUrl(TEST_SHOP), StatusCode.Ok);
await verifyRequestMiddleware(ctx, next);

expect(ctx.redirect).toHaveBeenCalledWith(
Expand Down Expand Up @@ -321,10 +319,6 @@ describe('verifyRequest', () => {
});
});

function metaFieldsUrl(shop: string) {
return `https://${shop}/admin/metafields.json`;
}

function appUrl(shop?: string) {
return shop == null ? '/foo' : `/foo?shop=${shop}`;
}
Expand Down
19 changes: 16 additions & 3 deletions src/verify-request/verify-token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {TEST_COOKIE_NAME, TOP_LEVEL_OAUTH_COOKIE_NAME} from '../index';
import {Routes} from './types';
import {redirectToAuth} from './utilities';
import {DEFAULT_ACCESS_MODE} from '../auth';
import { HttpResponseError } from '@shopify/shopify-api/dist/error';

export const REAUTH_HEADER = 'X-Shopify-API-Request-Failure-Reauthorize';
export const REAUTH_URL_HEADER = 'X-Shopify-API-Request-Failure-Reauthorize-Url';
Expand All @@ -25,9 +26,21 @@ export function verifyToken(routes: Routes, accessMode: AccessMode = DEFAULT_ACC
const scopesChanged = !Shopify.Context.SCOPES.equals(session.scope);

if (!scopesChanged && session.accessToken && (!session.expires || session.expires >= new Date())) {
ctx.cookies.set(TOP_LEVEL_OAUTH_COOKIE_NAME);
await next();
return;
try {
// make a request to make sure oauth has succeeded, retry otherwise
const client = new Shopify.Clients.Rest(session.shop, session.accessToken)
await client.get({ path: "metafields", query: {'limit': 1} })

ctx.cookies.set(TOP_LEVEL_OAUTH_COOKIE_NAME);
await next();
return;
} catch(e) {
if (e instanceof HttpResponseError && e.code == 401){
// only catch 401 errors
} else {
throw e
}
}
}
}

Expand Down

0 comments on commit 97e9d13

Please sign in to comment.