shopify-app-template-node icon indicating copy to clipboard operation
shopify-app-template-node copied to clipboard

Does not work in offline mode, throws Type Error

Open supa-freak opened this issue 3 years ago • 1 comments

Issue summary

If this is run in offline mode (const USE_ONLINE_TOKENS = false;), it runs into an error: TypeError: Cannot read properties of undefined (reading 'shop') at Function. (/home/xxxxx/node_modules/@shopify/shopify-api/dist/base-rest-resource.js:47:56) at step (/home/xxxxx/node_modules/tslib/tslib.js:143:27) at Object.next (/home/xxxxx/node_modules/tslib/tslib.js:124:57) at /home/xxxxx/node_modules/tslib/tslib.js:117:75 at new Promise () at Object.__awaiter (/home/xxxxx/node_modules/tslib/tslib.js:113:16) at Function.Base.request (/home/xxxxx/node_modules/@shopify/shopify-api/dist/base-rest-resource.js:41:24) at Function. (/home/xxxxxx/node_modules/@shopify/shopify-api/dist/rest-resources/2022-04/product.js:76:58)
at step (/home/xxxxxx/node_modules/tslib/tslib.js:143:27) at Object.next (/home/xxxxxx/node_modules/tslib/tslib.js:124:57)

Expected behavior

It should not run into an error as soon the session is accessed (which doenst exist in offline mode)

Actual behavior

It throw a type error because the code does always expect a session

Steps to reproduce the problem

  1. Set const USE_ONLINE_TOKENS = false in server/index.js line 16
  2. nvm run start
  3. install app
  4. --> Error occurs

Specifications

  • Browser: CHrome
  • Device: Server
  • Operating System: Ubuntu18 LTS, node.js v16.15.1

supa-freak avatar Jul 03 '22 10:07 supa-freak

You need to have offline and online access token

here's my solution:

import { Shopify } from "@shopify/shopify-api";

import topLevelAuthRedirect from "../helpers/top-level-auth-redirect.js";

export default function applyAuthMiddleware(app) {
  app.get("/auth", async (req, res) => {
    if (!req.signedCookies[app.get("top-level-oauth-cookie")]) {
      return res.redirect(
        `/auth/toplevel?${new URLSearchParams(req.query).toString()}`
      );
    }

    console.log(app.get("use-online-tokens"));
    const redirectUrl = await Shopify.Auth.beginAuth(
      req,
      res,
      req.query.shop,
      "/offlineAuth/callback",
      false
    );

    res.redirect(redirectUrl);
  });

  app.get("/auth/toplevel", (req, res) => {
    res.cookie(app.get("top-level-oauth-cookie"), "1", {
      signed: true,
      httpOnly: true,
      sameSite: "strict",
    });

    res.set("Content-Type", "text/html");

    res.send(
      topLevelAuthRedirect({
        apiKey: Shopify.Context.API_KEY,
        hostName: Shopify.Context.HOST_NAME,
        host: req.query.host,
        query: req.query,
      })
    );
  });
  app.get("/offlineAuth/callback", async (req, res) => {
    try {
      const session = await Shopify.Auth.validateAuthCallback(
        req,
        res,
        req.query
      );

      console.log(session.accessToken, "Offline");

      const response = await Shopify.Webhooks.Registry.register({
        shop: session.shop,
        accessToken: session.accessToken,
        topic: "APP_UNINSTALLED",
        path: "/webhooks",
      });

      if (!response["APP_UNINSTALLED"].success) {
        console.log(
          `Failed to register APP_UNINSTALLED webhook: ${response.result}`
        );
      }
      const redirectUrl = await Shopify.Auth.beginAuth(
        req,
        res,
        req.query.shop,
        "/auth/callback",
        true
      );

      res.redirect(redirectUrl);
    } catch (e) {
      switch (true) {
        case e instanceof Shopify.Errors.InvalidOAuthError:
          res.status(400);
          res.send(e.message);
          break;
        case e instanceof Shopify.Errors.CookieNotFound:
        case e instanceof Shopify.Errors.SessionNotFound:
          // This is likely because the OAuth session cookie expired before the merchant approved the request
          res.redirect(`/auth?shop=${req.query.shop}`);
          break;
        default:
          res.status(500);
          res.send(e.message);
          break;
      }
    }
  });

  app.get("/auth/callback", async (req, res) => {
    try {
      const session = await Shopify.Auth.validateAuthCallback(
        req,
        res,
        req.query
      );

      const host = req.query.host;
      app.set(
        "active-shopify-shops",
        Object.assign(app.get("active-shopify-shops"), {
          [session.shop]: session.scope,
        })
      );
      console.log(session.accessToken, "Online");

      const response = await Shopify.Webhooks.Registry.register({
        shop: session.shop,
        accessToken: session.accessToken,
        topic: "APP_UNINSTALLED",
        path: "/webhooks",
      });

      if (!response["APP_UNINSTALLED"].success) {
        console.log(
          `Failed to register APP_UNINSTALLED webhook: ${response.result}`
        );
      }

      // Redirect to app with shop parameter upon auth
      res.redirect(`/?shop=${session.shop}&host=${host}`);
    } catch (e) {
      switch (true) {
        case e instanceof Shopify.Errors.InvalidOAuthError:
          res.status(400);
          res.send(e.message);
          break;
        case e instanceof Shopify.Errors.CookieNotFound:
        case e instanceof Shopify.Errors.SessionNotFound:
          // This is likely because the OAuth session cookie expired before the merchant approved the request
          res.redirect(`/auth?shop=${req.query.shop}`);
          break;
        default:
          res.status(500);
          res.send(e.message);
          break;
      }
    }
  });
}

Note: Update Authorized callback in your Shopify app partner page with new offline callback route

IliasHad avatar Jul 03 '22 13:07 IliasHad

This issue is stale because it has been open for 90 days with no activity. It will be closed if no further action occurs in 14 days.

github-actions[bot] avatar Sep 28 '22 02:09 github-actions[bot]

We are closing this issue because it has been inactive for a few months. This probably means that it is not reproducible or it has been fixed in a newer version. If it’s an enhancement and hasn’t been taken on since it was submitted, then it seems other issues have taken priority.

If you still encounter this issue with the latest stable version, please reopen using the issue template. You can also contribute directly by submitting a pull request– see the CONTRIBUTING.md file for guidelines

Thank you!

github-actions[bot] avatar Oct 13 '22 02:10 github-actions[bot]