Focuses on API authentication, access scopes, and permission management.
Hey,
I am trying to get my old shopify app back up and running but I am having an issue in that when there is no shop in the active shopify shops object then the app screen is simply blank. I remember that it should create a new session when there is no active session in the shopify active shops object but now it sends the request to /auth but nothing happens and the screen remains blank. How do I create a new auth session? I also wanted to note that the app installs and uninstalls just fine.
if (ACTIVE_SHOPIFY_SHOPS[shop] === undefined) {
console.log("If you see this you are here");
ctx.redirect(`/auth?shop=${shop}`);
} else {
await handleRequest(ctx);
}
This is the code that is supposed to redirect to create a new auth session but it just returns a 200 code and nothing happens afterwards. Can someone help? I will also attach the complete code for the server of my app. I know this is old code but like I said earlier it still works just fine when installing and uninstalling but the problem is when it is supposed to redirect to create a new session nothing happens. Here is the code for my server if anyone has any pointers.
import "@babel/polyfill";
import dotenv from "dotenv";
import "isomorphic-fetch";
import { gql } from "apollo-boost";
import createShopifyAuth, { verifyRequest } from "@shopify/koa-shopify-auth";
import Shopify, { ApiVersion } from "@shopify/shopify-api";
import Koa from "koa";
import next from "next";
import Router from "koa-router";
import { createReadStream } from "fs";
import isVerified from "shopify-jwt-auth-verify";
import replaceFirstLineOfFile from "file-firstline-replace";
import {
createClient,
getOneTimeUrl,
getSubscriptionUrl,
} from "./handlers/index";
const cors = require("@koa/cors");
import { storeCallback, loadCallback, deleteCallback } from "./redis-store.js";
dotenv.config();
const axios = require("axios");
const koaBody = require("koa-body");
const port = parseInt(process.env.PORT, 10) || 8081;
const dev = process.env.NODE_ENV !== "production";
const app = next({
dev,
});
const handle = app.getRequestHandler();
Shopify.Context.initialize({
API_KEY: process.env.SHOPIFY_API_KEY,
API_SECRET_KEY: process.env.SHOPIFY_API_SECRET,
SCOPES: process.env.SCOPES.split(","),
HOST_NAME: process.env.HOST.replace(/https:\/\//, ""),
API_VERSION: ApiVersion.October20,
IS_EMBEDDED_APP: true,
// This should be replaced with your preferred storage strategy
SESSION_STORAGE: new Shopify.Session.MemorySessionStorage(),
});
// Storing the currently active shops in memory will force them to re-login when your server restarts. You should
// persist this object in your app.
const activeshopschema = new mongoose.Schema({
activeshopifyshops: {
type: String,
required: true,
},
});
const productschema = new mongoose.Schema({
products: {
type: String,
required: true,
},
});
//mongodb+srv://.r89st.mongodb.net/LSEDATABASE?retryWrites=true&w=majority populated database
//mongodb+srv://@lsedatabaseupdated.pyeumwz.mongodb.net/?retryWrites=true&w=majority&appName=LSEDatabaseUpdated
const activeshop = mongoose.model("ActiveShop", activeshopschema);
const products = mongoose.model("Products", productschema);
import mongoose from "mongoose";
const connectStr =
"mongodb+srv://admin:HappyDragon08*****@lsedatabase.r89st.mongodb.net/LSEDATABASE?retryWrites=true&w=majority";
mongoose
.connect(connectStr, { useNewUrlParser: true, useUnifiedTopology: true })
.then(
() => {
console.log(`Connected to ${connectStr}.`);
var admin = new mongoose.mongo.Admin(mongoose.connection.db);
admin.buildInfo(function (err, info) {
console.log(info.version);
});
},
(err) => {
console.error(`Error connecting to ${connectStr}: ${err}`);
}
);
var ACTIVE_SHOPIFY_SHOPS = {};
var ACTIVE_SHOPS_PRODUCTS = {};
startGetCollection();
async function startGetCollection() {
const retreivedShops = await getCollection();
const retreivedProducts = await getProducts();
try {
//console.log(retreivedShops);
ACTIVE_SHOPIFY_SHOPS = JSON.parse(retreivedShops.activeshopifyshops);
//console.log(retreivedProducts);
ACTIVE_SHOPS_PRODUCTS = JSON.parse(retreivedProducts.products);
} catch (error) {
console.log("1", error);
ACTIVE_SHOPS_PRODUCTS = {};
}
createWebHooks();
}
async function getCollection() {
return await activeshop.findById("615fa1984d918ee530e3ed5e");
}
async function getProducts() {
return await products.findById("615fa1984d918ee530e3ed5e");
}
//var filename = './script.js'
//var newHeader = "const HOSTURL = \"https://" + process.env.HOST.replace(/https:\/\//, "") + "\";\n"
//replaceFirstLineOfFile(filename, newHeader, function (err) {
// if (err) throw err
/* ... */
//})
//
async function updateCollection() {
activeshop.findByIdAndUpdate(
"615fa1984d918ee530e3ed5e",
{ activeshopifyshops: JSON.stringify(ACTIVE_SHOPIFY_SHOPS) },
function (err, docs) {
if (err) {
console.log("2", err);
} else {
//console.log("Updated active shopify shops : ", docs);
}
}
);
}
async function updateProductsStats() {
products.findByIdAndUpdate(
"615fa1984d918ee530e3ed5e",
{ products: JSON.stringify(ACTIVE_SHOPS_PRODUCTS) },
function (err, docs) {
if (err) {
console.log("3", err);
} else {
//console.log("Updated active shopify shops products : ", docs);
}
}
);
}
// upsert:true, new:true
async function createWebHooks() {
for (const shopname in ACTIVE_SHOPIFY_SHOPS) {
try {
//console.log(`${shopname}: ${ACTIVE_SHOPIFY_SHOPS[shopname][1]}`);
const response = await Shopify.Webhooks.Registry.register({
shop: shopname,
accessToken: ACTIVE_SHOPIFY_SHOPS[shopname][1],
path: "/webhooks",
topic: "APP_UNINSTALLED",
webhookHandler: async (topic, shop, body) => {
delete ACTIVE_SHOPIFY_SHOPS[shop];
updateCollection();
},
});
if (!response.success) {
console.log(
`Failed to register APP_UNINSTALLED webhook: ${response.result}`
);
}
if (response.success) {
//console.log("00", response.result);
}
} catch (error) {
//console.log("4", error);
}
}
}
app.prepare().then(async () => {
const server = new Koa();
const router = new Router();
server.keys = [Shopify.Context.API_SECRET_KEY];
// server.use(cors());
server.use(cors({ origin: "*" }));
server.use(
createShopifyAuth({
accessMode: "offline",
async afterAuth(ctx) {
// Access token and shop available in ctx.state.shopify
const { shop, accessToken, scope } = ctx.state.shopify;
//console.log("TESTTTTTT", shop);
const host = ctx.query.host;
var flag = 0;
ACTIVE_SHOPIFY_SHOPS[shop] = [scope, accessToken];
//console.log(ACTIVE_SHOPIFY_SHOPS);
//console.log(accessToken);
const response = await Shopify.Webhooks.Registry.register({
shop,
accessToken,
path: "/webhooks",
topic: "APP_UNINSTALLED",
webhookHandler: async (topic, shop, body) => {
delete ACTIVE_SHOPIFY_SHOPS[shop];
updateCollection();
},
});
if (!response.success) {
console.log(
`Failed to register APP_UNINSTALLED webhook: ${response.result}`
);
}
if (response.success) {
console.log("5", response.result);
}
axios
.get(`https://${shop}/admin/api/2022-07/script_tags.json`, {
headers: {
"X-Shopify-Access-Token": accessToken,
},
})
.then((response) => {
const scripttags = response.data.script_tags;
console.log(scripttags);
var found = false;
for (let i = 0; i < scripttags.length; i++) {
var curScriptsrc=scripttags[i].src;
if (curScriptSrc.substr(-10) === "/scriptLSE") {
found = true;
console.log("Found existing LSE scripttag, update!");
var data = JSON.stringify({
script_tag: {
id: scripttags[i].id,
src:
"https://" +
process.env.HOST.replace(/https:\/\//, "") +
"/scriptLSE",
},
});
var config = {
method: "put",
url:
`https://${shop}/admin/api/2022-07/script_tags/` +
scripttags[i].id +
".json",
headers: {
"X-Shopify-Access-Token": accessToken,
"Content-Type": "application/json",
},
data: data,
};
axios(config)
.then(function (response) {
console.log("27", JSON.stringify(response.data));
})
.catch(function (error) {
console.log("28", error);
});
break;
}
}
if (found === false) {
console.log(
"Existing LSE scripttag not found, install scripttag"
);
var data = JSON.stringify({
script_tag: {
event: "onload",
src:
"https://" +
process.env.HOST.replace(/https:\/\//, "") +
"/scriptLSE",
},
});
var config = {
method: "post",
url: `https://${shop}/admin/api/2022-07/script_tags.json`,
headers: {
"X-Shopify-Access-Token": accessToken,
"Content-Type": "application/json",
},
data: data,
};
axios(config)
.then(function (response) {
console.log("26", JSON.stringify(response.data));
})
.catch(function (error) {
console.log("25", error);
});
}
})
.catch((error) => {
console.log("24", error);
});
var config = {
method: "get",
url: `https://${shop}/admin/api/2022-07/metafields.json`,
headers: {
"X-Shopify-Access-Token": accessToken,
},
};
axios(config)
.then(function (response) {
var metafields = response.data.metafields;
var found = false;
//console.log("LOOK FOR THIS", metafields);
//look for metafield with namespace LSESETTINGS
for (let i = 0; i < metafields.length; i++) {
if (metafields[i].namespace === "LSESETTINGSFINAL") {
console.log("Found existing LSE metafield!");
found = true;
ACTIVE_SHOPIFY_SHOPS[shop].push(JSON.parse(metafields[i].id));
break;
}
}
if (found === false) {
console.log("Did not find metafield, creating new one!");
var data = JSON.stringify({
metafield: {
namespace: "LSESETTINGSFINAL",
key: "appsettings",
value:
'{"isenabled": true, "isenabledVar": true, "isenabledProd": true, "buttonclasses": ["btn","button"],"buttontwoclasses": ["btn","button"],"modalcolor": "rgb(255,255,255)","modaloverlay": "rgba(0,0,0,0.4)","bordercolor": "rgb(0,0,0)","toptextcolor":"undefined","modaltext": "Do you want to add additional products?","crosssellbutton": "Add more products","cartbutton":"Go to cart","addedtocarttext":"added to cart","borderradius": 0}',
type: "json",
},
});
var config = {
method: "post",
url: `https://${shop}/admin/api/2022-07/metafields.json`,
headers: {
"Content-Type": "application/json",
"X-Shopify-Access-Token": accessToken,
},
data: data,
};
axios(config)
.then(function (response) {
ACTIVE_SHOPIFY_SHOPS[shop].push(
JSON.parse(response.data.metafield.id)
);
//console.log(response.data.metafield);
//console.log(ACTIVE_SHOPIFY_SHOPS);
})
.catch(function (error) {
console.log("6", error);
});
}
})
.catch(function (error) {
console.log("7", error);
});
// Redirect to app with shop parameter upon auth
//const client = new Shopify.Clients.Graphql(shop, accessToken);
const client = createClient(shop, accessToken);
const createdDefinition = await client
.mutate({
mutation: createNewMetafieldDef(),
})
.then((response) =>
console.log("8", response.data.metafieldDefinitionCreate.userErrors)
)
.catch(function (error) {
console.log("9", error);
});
const createdDefinition2 = await client
.mutate({
mutation: createNewMetafieldDef2(),
})
.then((response) =>
console.log(
"20",
response.data.metafieldDefinitionCreate.userErrors
)
)
.catch(function (error) {
console.log("21", error);
});
const createdDefinition3 = await client
.mutate({
mutation: createVarMetafieldDef(),
})
.then((response) =>
console.log(response.data.metafieldDefinitionCreate.userErrors)
)
.catch(function (error) {
console.log(error);
});
const createdDefinition4 = await client
.mutate({
mutation: createVarMetafieldDef2(),
})
.then((response) =>
console.log(response.data.metafieldDefinitionCreate.userErrors)
)
.catch(function (error) {
console.log(error);
});
console.log(createdDefinition);
console.log(createdDefinition2);
console.log(createdDefinition3);
console.log(createdDefinition4);
console.log(ACTIVE_SHOPIFY_SHOPS[shop]);
updateCollection();
//ctx.redirect(`https://${shop}/admin/themes/current/editor?context=apps&activateAppId=58fa9d45-581a-4007-af38-190febe3f71d/LSEThemeApp`)
ctx.redirect(`/?shop=${shop}&host=${host}`);
},
})
);
function createNewMetafieldDef() {
return gql`
mutation {
metafieldDefinitionCreate(
definition: {
name: "Cross-Sell"
namespace: "jadepuma"
key: "crosssell_destination"
description: "Creates definition for crosssell url."
type: "single_line_text_field"
ownerType: PRODUCT
}
) {
createdDefinition {
id
}
userErrors {
field
message
code
}
}
}
`;
}
function createNewMetafieldDef2() {
return gql`
mutation {
metafieldDefinitionCreate(
definition: {
name: "Cross-Sell Message"
namespace: "jadepuma"
key: "crosssell_message"
description: "Creates definition for crosssell message for specific product."
type: "single_line_text_field"
ownerType: PRODUCT
}
) {
createdDefinition {
id
}
userErrors {
field
message
code
}
}
}
`;
}
function createVarMetafieldDef() {
return gql`
mutation {
metafieldDefinitionCreate(
definition: {
name: "Cross-Sell"
namespace: "jadepuma"
key: "crosssell_destination"
description: "Creates definition for crosssell url."
type: "single_line_text_field"
ownerType: PRODUCTVARIANT
}
) {
createdDefinition {
id
}
userErrors {
field
message
code
}
}
}
`;
}
function createVarMetafieldDef2() {
return gql`
mutation {
metafieldDefinitionCreate(
definition: {
name: "Cross-Sell Message"
namespace: "jadepuma"
key: "crosssell_message"
description: "Creates definition for crosssell message for specific variant."
type: "single_line_text_field"
ownerType: PRODUCTVARIANT
}
) {
createdDefinition {
id
}
userErrors {
field
message
code
}
}
}
`;
}
const handleRequest = async (ctx) => {
await handle(ctx.req, ctx.res);
ctx.respond = false;
ctx.res.statusCode = 200;
};
router.post("/webhooks", async (ctx) => {
console.log("444", ctx);
try {
await Shopify.Webhooks.Registry.process(ctx.req, ctx.res);
console.log(`Webhook processed, returned status code 200`, ctx);
} catch (error) {
console.log(`Failed to process webhook: ${error}`);
}
});
router.post(
"/graphql",
verifyRequest({ returnHeader: true }),
async (ctx, next) => {
await Shopify.Utils.graphqlProxy(ctx.req, ctx.res);
}
);
router.post("/me", async (ctx) => {
const bearer = ctx.request.header.authorization;
const secret = process.env.SHOPIFY_API_SECRET;
const valid = isVerified(bearer, secret);
if (valid) {
ctx.body = "Success";
} else {
ctx.body = "Invalid";
}
});
router.put("/getSettings", koaBody(), async (ctx) => {
// returns js code to be injected into frontend
//console.log(ctx.request.body);
//console.log("| " + ACTIVE_SHOPIFY_SHOPS + " |");
var finalstringarray = ['"'];
var finalstringarraytwo = ['"'];
var stringclass = ctx.request.body.buttonclasses.join('","');
var stringtwoclass = ctx.request.body.buttontwoclasses.join('","');
finalstringarray.push(stringclass);
finalstringarraytwo.push(stringtwoclass);
finalstringarray.push('"');
finalstringarraytwo.push('"');
var formattedstring = finalstringarray.join("");
var formattedstringtwo = finalstringarraytwo.join("");
//console.log(formattedstring, typeof formattedstring);
var data = JSON.stringify({
metafield: {
namespace: "LSESETTINGSFINAL",
key: "appsettings",
value:
'{"isenabled": ' +
ctx.request.body.isenabled +
',"isenabledVar":' +
ctx.request.body.isenabledVar +
',"isenabledProd":' +
ctx.request.body.isenabledProd +
',"buttonclasses": [' +
formattedstring +
'],"buttontwoclasses": [' +
formattedstringtwo +
'],"modalcolor": "' +
ctx.request.body.modalcolor +
'","modaloverlay": "' +
ctx.request.body.modaloverlay +
'","bordercolor": "' +
ctx.request.body.bordercolor +
'","toptextcolor": "' +
ctx.request.body.toptextcolor +
'","modaltext": "' +
ctx.request.body.modaltext +
'","crosssellbutton": "' +
ctx.request.body.crosssellbutton +
'","cartbutton": "' +
ctx.request.body.cartbutton +
'","addedtocarttext": "' +
ctx.request.body.addedtocarttext +
'","borderradius": ' +
ctx.request.body.borderradius +
"}",
type: "json",
},
});
var config = {
method: "put",
url: `https://${ctx.query.shopName}/admin/api/2022-07/metafields/${ACTIVE_SHOPIFY_SHOPS[ctx.query.shopName][2]
}.json`,
headers: {
"Content-Type": "application/json",
"X-Shopify-Access-Token": ACTIVE_SHOPIFY_SHOPS[ctx.query.shopName][1],
},
data: data,
};
axios(config)
.then(function (response) {
console.log("Save Success");
console.log(response.data);
})
.catch(function (error) {
console.log("Error saving");
console.log(error);
});
ctx.body = "Success";
});
router.get("/getSettings", async (ctx) => {
// returns js code to be injected into frontend
var config = {
method: "get",
url: `https://${ctx.query.shopName}/admin/api/2022-07/metafields/${ACTIVE_SHOPIFY_SHOPS[ctx.query.shopName][2]
}.json`,
headers: {
"Content-Type": "application/json",
"X-Shopify-Access-Token": ACTIVE_SHOPIFY_SHOPS[ctx.query.shopName][1],
},
};
return axios(config)
.then(function (response) {
var metafield = response.data.metafield;
//console.log(JSON.stringify(response.data));
ctx.body = metafield.value;
})
.catch(function (error) {
console.log("10", error);
});
});
router.get("/getStats", async (ctx) => {
const retreivedProducts = await getProducts();
try {
ACTIVE_SHOPS_PRODUCTS = JSON.parse(retreivedProducts.products);
} catch (error) {
ACTIVE_SHOPS_PRODUCTS = {};
}
let shop = ctx.query.shopName;
let products = ACTIVE_SHOPS_PRODUCTS[shop];
ctx.body = products;
});
router.get("/getSettingspublic", async (ctx) => {
// returns js code to be injected into frontend
var config = {
method: "get",
url: `https://${ctx.query.shopName}/admin/api/2022-07/metafields/${ACTIVE_SHOPIFY_SHOPS[ctx.query.shopName][2]
}.json`,
headers: {
"Content-Type": "application/json",
"X-Shopify-Access-Token": ACTIVE_SHOPIFY_SHOPS[ctx.query.shopName][1],
},
};
return axios(config)
.then(function (response) {
var metafield = response.data.metafield;
//console.log(JSON.stringify(response.data));
ctx.body = metafield.value;
})
.catch(function (error) {
console.log("11", error);
});
});
router.post("/startSubscription", async (ctx) => {
//server.context.client = await createClient(ctx.query.shopName, ACTIVE_SHOPIFY_SHOPS[ctx.query.shopName][1]);
//await getSubscriptionUrl(ctx);
//ctx.body = "Success";
var data = JSON.stringify({
recurring_application_charge: {
name: "Premium Plan",
price: 9.95,
//return_url: process.env.HOST + "?shop=" + ctx.query.shopName + "?host=" + process.env.HOST,
//return_url: "https://www.google.com/",
return_url:
"https://" +
ctx.query.shopName +
"/admin/oauth/redirect_from_cli?client_id=" +
process.env.SHOPIFY_API_KEY,
trial_days: 0,
test: true,
},
});
var config = {
method: "post",
url: `https://${ctx.query.shopName}/admin/api/2024-01/recurring_application_charges.json`,
headers: {
"Content-Type": "application/json",
"X-Shopify-Access-Token": ACTIVE_SHOPIFY_SHOPS[ctx.query.shopName][1],
},
data: data,
};
return axios(config)
.then(function (response) {
//console.log(response.data);
var billingresponse = response.data;
ctx.body = billingresponse;
//ctx.redirect(response.data.recurring_application_charge.confirmation_url);
//ctx.body = "Success";
})
.catch(function (error) {
console.log("12", error);
});
});
router.get("/getSubscription", async (ctx) => {
var config = {
method: "get",
url: `https://${ctx.query.shopName}/admin/api/2022-07/recurring_application_charges.json`,
headers: {
"Content-Type": "application/json",
"X-Shopify-Access-Token": ACTIVE_SHOPIFY_SHOPS[ctx.query.shopName][1],
},
};
return axios(config)
.then(function (response) {
//console.log(response.data);
ctx.body = response.data;
//ctx.redirect(response.data.recurring_application_charge.confirmation_url);
//ctx.body = "Success";
})
.catch(function (error) {
console.log("909", error);
});
});
router.get("/scriptLSE", async (ctx) => {
// returns js code to be injected into frontend
ctx.type = "js";
ctx.body = createReadStream("./script.js");
});
router.post("/cust/redact", async (ctx) => {
ctx.status = 200;
ctx.body = "ok";
});
router.post("/cust/request", async (ctx) => {
ctx.status = 200;
ctx.body = "ok";
});
router.post("/shop/delete", async (ctx) => {
ctx.status = 200;
ctx.body = "ok";
});
/*
router.get("/activeshops", async (ctx) => {// returns js code to be injected into frontend
ctx.body = JSON.stringify(ACTIVE_SHOPIFY_SHOPS);
});
*/
router.get("/productMeta", async (ctx) => {
// returns the metafields of particular shops product
var config = {
method: "get",
url: `https://${ctx.query.shopName}/admin/api/2022-07/products/${ctx.query.productID}/metafields.json`,
headers: {
"X-Shopify-Access-Token": ACTIVE_SHOPIFY_SHOPS[ctx.query.shopName][1],
},
};
console.log("23", config);
return axios(config)
.then(function (response) {
ctx.body = JSON.stringify(response.data);
})
.catch(function (error) {
console.log("14", error);
});
});
router.get("/stats", async (ctx) => {
let shop = ctx.query.shopName;
let productID = ctx.query.productID;
var config = {
method: "get",
url: `https://${ctx.query.shopName}/admin/api/2022-07/products/${ctx.query.productID}.json`,
headers: {
"X-Shopify-Access-Token": ACTIVE_SHOPIFY_SHOPS[shop][1],
},
};
let res = await axios(config);
let product = res.data.product;
// get prodcut title
let title = product.title;
let show = ctx.query.show;
let yes = ctx.query.yes;
let no = ctx.query.no;
console.log(ACTIVE_SHOPS_PRODUCTS);
if (
ACTIVE_SHOPS_PRODUCTS[shop] === undefined ||
ACTIVE_SHOPS_PRODUCTS[shop][productID] === undefined
) {
if (ACTIVE_SHOPS_PRODUCTS[shop] === undefined) {
ACTIVE_SHOPS_PRODUCTS[shop] = {};
}
// ACTIVE_SHOPS_PRODUCTS[shop][productID] = {yes:0,no:0,show:0}
if (show) {
ACTIVE_SHOPS_PRODUCTS[shop][productID] = {
yes: 0,
no: 0,
show: 1,
title: title,
};
}
if (yes) {
ACTIVE_SHOPS_PRODUCTS[shop][productID] = {
yes: 1,
no: 0,
show: 0,
title: title,
};
}
if (no) {
ACTIVE_SHOPS_PRODUCTS[shop][productID] = {
yes: 0,
no: 1,
show: 0,
title: title,
};
}
} else {
if (show) {
ACTIVE_SHOPS_PRODUCTS[shop][productID].show =
ACTIVE_SHOPS_PRODUCTS[shop][productID].show + 1;
}
if (yes) {
ACTIVE_SHOPS_PRODUCTS[shop][productID].yes =
ACTIVE_SHOPS_PRODUCTS[shop][productID].yes + 1;
}
if (no) {
ACTIVE_SHOPS_PRODUCTS[shop][productID].no =
ACTIVE_SHOPS_PRODUCTS[shop][productID].no + 1;
}
ACTIVE_SHOPS_PRODUCTS[shop][productID].title = title;
}
updateProductsStats();
// returns the metafields of particular shops product
var config = {
method: "get",
url: `https://${ctx.query.shopName}/admin/api/2022-07/products/${ctx.query.productID}/metafields.json`,
headers: {
"X-Shopify-Access-Token": ACTIVE_SHOPIFY_SHOPS[ctx.query.shopName][1],
},
};
return axios(config)
.then(function (response) {
ctx.body = JSON.stringify(product);
})
.catch(function (error) {
console.log("15", error);
});
});
router.get("(/_next/static/.*)", handleRequest); // Static content is clear
router.get("/_next/webpack-hmr", handleRequest); // Webpack content is clear
router.get("/shopname", async (ctx) => {
ctx.body = ctx.query.shop;
});
router.get("(.*)", async (ctx) => {
const shop = ctx.query.shop;
if (shop) {
ctx.res.setHeader(
"Content-Security-Policy",
`frame-ancestors https://${ctx.query.shop} https://admin.shopify.com;`
);
}
// This shop hasn't been seen yet, go through OAuth to create a session
if (ACTIVE_SHOPIFY_SHOPS[shop] === undefined) {
console.log("If you see this you are here");
ctx.redirect(`/auth?shop=${shop}`);
} else {
await handleRequest(ctx);
}
});
server.use(router.allowedMethods());
server.use(router.routes());
server.listen(port, () => {
console.log(`> Ready on http://localhost:${port}`);
});