@shopware-ag/app-server-sdk
Advanced tools
Comparing version 1.1.2 to 1.1.3
@@ -20,2 +20,6 @@ "use strict"; | ||
const webHookBody = JSON.parse(webHookContent); | ||
if (webHookBody.source === undefined || | ||
webHookBody.source.shopId === undefined) { | ||
throw new Error("Invalid request"); | ||
} | ||
const shop = await this.app.repository.getShopById(webHookBody.source.shopId); | ||
@@ -22,0 +26,0 @@ if (shop === null) { |
@@ -13,11 +13,71 @@ import { AppServer } from "../app.js"; | ||
interface MiddlewareConfig { | ||
/** | ||
* The name of the app | ||
*/ | ||
appName: string | ((c: HonoContext) => string); | ||
/** | ||
* The secret of the app. When the app is published in the Shopware Store, the Shopware Store provides this value. | ||
*/ | ||
appSecret: string | ((c: HonoContext) => string); | ||
/** | ||
* The URL of the app. This is the base URL of the app. This will automatically determined by default | ||
*/ | ||
appUrl?: string | null; | ||
/** | ||
* The relative url of the app registration endpoint | ||
* | ||
* @default "/app/register" | ||
*/ | ||
registrationUrl?: string | null; | ||
/** | ||
* The relative url of the app registration confirmation endpoint | ||
* | ||
* @default "/app/register/confirm" | ||
*/ | ||
registerConfirmationUrl?: string | null; | ||
/** | ||
* The relative url of the app activation lifecycle endpoint | ||
* | ||
* @default "/app/activate" | ||
*/ | ||
appActivateUrl?: string | null; | ||
/** | ||
* The relative url of the app deactivation lifecycle endpoint | ||
* | ||
* @default "/app/deactivate" | ||
*/ | ||
appDeactivateUrl?: string | null; | ||
/** | ||
* The relative url of the app deletion lifecycle endpoint | ||
* | ||
* @default "/app/delete" | ||
*/ | ||
appDeleteUrl?: string | null; | ||
/** | ||
* The relative url of the app scope. All requests matching this will be the signature automatically validated and the response will be signed | ||
* | ||
* @default "/app/*" | ||
*/ | ||
appPath?: string | null; | ||
/** | ||
* Enable the app iframe integration. This will automatically set a cookie to identifiy the shopware shop and validate the request from a client side application. See appIframeRedirects | ||
*/ | ||
appIframeEnable?: boolean; | ||
/** | ||
* The relative url of the app iframe scope. All requests matching this will require that the request has an cookie set with the shopware shop. This cookie will be automatically set by | ||
* | ||
* @default "/client-api/*" | ||
*/ | ||
appIframePath?: string | null; | ||
/** | ||
* A mapping of the app iframe paths to the actual paths. This route will set a cookie automatically before the redirect to the actual path. In that way the client side application can send requests to /app-iframe/* with the cookie set and the server will automatically validate the request and knows which shop the request is for. | ||
* | ||
* @default { | ||
* "/app/module": "https://my-static-client-side-app.com" | ||
* } | ||
*/ | ||
appIframeRedirects?: Record<string, string>; | ||
/** | ||
* The repository to fetch and store the shop data | ||
*/ | ||
shopRepository: ShopRepositoryInterface | ((c: HonoContext) => ShopRepositoryInterface); | ||
@@ -24,0 +84,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.configureAppServer = configureAppServer; | ||
const cookie_1 = require("hono/cookie"); | ||
const app_js_1 = require("../app.js"); | ||
@@ -17,2 +18,3 @@ /** | ||
cfg.appPath = cfg.appPath || "/app/*"; | ||
cfg.appIframePath = cfg.appIframePath || "/client-api/*"; | ||
hono.use("*", async (ctx, next) => { | ||
@@ -93,2 +95,34 @@ if (app === null) { | ||
}); | ||
if (cfg.appIframeEnable) { | ||
hono.use(cfg.appIframePath, async (ctx, next) => { | ||
const shopId = await (0, cookie_1.getSignedCookie)(ctx, ctx.get("app").cfg.appSecret, "shop"); | ||
if (!shopId) { | ||
return ctx.json({ message: "Shop not found" }, { status: 400 }); | ||
} | ||
const shop = await ctx.get("app").repository.getShopById(shopId); | ||
if (!shop) { | ||
return ctx.json({ message: "Shop not found" }, { status: 400 }); | ||
} | ||
ctx.set("shop", shop); | ||
await next(); | ||
}); | ||
for (let [path, redirect] of Object.entries(cfg.appIframeRedirects || {})) { | ||
hono.get(path, async (ctx) => { | ||
const url = new URL(ctx.req.url); | ||
if (redirect.startsWith("/")) { | ||
url.pathname = redirect; | ||
redirect = url.toString(); | ||
} | ||
else { | ||
const newUrl = new URL(redirect); | ||
for (const [key, value] of url.searchParams) { | ||
newUrl.searchParams.set(key, value); | ||
} | ||
redirect = newUrl.toString(); | ||
} | ||
await (0, cookie_1.setSignedCookie)(ctx, "shop", ctx.get("shop").getShopId(), ctx.get("app").cfg.appSecret); | ||
return ctx.redirect(redirect); | ||
}); | ||
} | ||
} | ||
} | ||
@@ -95,0 +129,0 @@ function jsonResponse(body, status = 200) { |
@@ -17,2 +17,6 @@ import { HttpClient } from "./http-client.js"; | ||
const webHookBody = JSON.parse(webHookContent); | ||
if (webHookBody.source === undefined || | ||
webHookBody.source.shopId === undefined) { | ||
throw new Error("Invalid request"); | ||
} | ||
const shop = await this.app.repository.getShopById(webHookBody.source.shopId); | ||
@@ -19,0 +23,0 @@ if (shop === null) { |
@@ -13,11 +13,71 @@ import { AppServer } from "../app.js"; | ||
interface MiddlewareConfig { | ||
/** | ||
* The name of the app | ||
*/ | ||
appName: string | ((c: HonoContext) => string); | ||
/** | ||
* The secret of the app. When the app is published in the Shopware Store, the Shopware Store provides this value. | ||
*/ | ||
appSecret: string | ((c: HonoContext) => string); | ||
/** | ||
* The URL of the app. This is the base URL of the app. This will automatically determined by default | ||
*/ | ||
appUrl?: string | null; | ||
/** | ||
* The relative url of the app registration endpoint | ||
* | ||
* @default "/app/register" | ||
*/ | ||
registrationUrl?: string | null; | ||
/** | ||
* The relative url of the app registration confirmation endpoint | ||
* | ||
* @default "/app/register/confirm" | ||
*/ | ||
registerConfirmationUrl?: string | null; | ||
/** | ||
* The relative url of the app activation lifecycle endpoint | ||
* | ||
* @default "/app/activate" | ||
*/ | ||
appActivateUrl?: string | null; | ||
/** | ||
* The relative url of the app deactivation lifecycle endpoint | ||
* | ||
* @default "/app/deactivate" | ||
*/ | ||
appDeactivateUrl?: string | null; | ||
/** | ||
* The relative url of the app deletion lifecycle endpoint | ||
* | ||
* @default "/app/delete" | ||
*/ | ||
appDeleteUrl?: string | null; | ||
/** | ||
* The relative url of the app scope. All requests matching this will be the signature automatically validated and the response will be signed | ||
* | ||
* @default "/app/*" | ||
*/ | ||
appPath?: string | null; | ||
/** | ||
* Enable the app iframe integration. This will automatically set a cookie to identifiy the shopware shop and validate the request from a client side application. See appIframeRedirects | ||
*/ | ||
appIframeEnable?: boolean; | ||
/** | ||
* The relative url of the app iframe scope. All requests matching this will require that the request has an cookie set with the shopware shop. This cookie will be automatically set by | ||
* | ||
* @default "/client-api/*" | ||
*/ | ||
appIframePath?: string | null; | ||
/** | ||
* A mapping of the app iframe paths to the actual paths. This route will set a cookie automatically before the redirect to the actual path. In that way the client side application can send requests to /app-iframe/* with the cookie set and the server will automatically validate the request and knows which shop the request is for. | ||
* | ||
* @default { | ||
* "/app/module": "https://my-static-client-side-app.com" | ||
* } | ||
*/ | ||
appIframeRedirects?: Record<string, string>; | ||
/** | ||
* The repository to fetch and store the shop data | ||
*/ | ||
shopRepository: ShopRepositoryInterface | ((c: HonoContext) => ShopRepositoryInterface); | ||
@@ -24,0 +84,0 @@ } |
@@ -0,1 +1,2 @@ | ||
import { getSignedCookie, setSignedCookie } from "hono/cookie"; | ||
import { AppServer } from "../app.js"; | ||
@@ -14,2 +15,3 @@ /** | ||
cfg.appPath = cfg.appPath || "/app/*"; | ||
cfg.appIframePath = cfg.appIframePath || "/client-api/*"; | ||
hono.use("*", async (ctx, next) => { | ||
@@ -90,2 +92,34 @@ if (app === null) { | ||
}); | ||
if (cfg.appIframeEnable) { | ||
hono.use(cfg.appIframePath, async (ctx, next) => { | ||
const shopId = await getSignedCookie(ctx, ctx.get("app").cfg.appSecret, "shop"); | ||
if (!shopId) { | ||
return ctx.json({ message: "Shop not found" }, { status: 400 }); | ||
} | ||
const shop = await ctx.get("app").repository.getShopById(shopId); | ||
if (!shop) { | ||
return ctx.json({ message: "Shop not found" }, { status: 400 }); | ||
} | ||
ctx.set("shop", shop); | ||
await next(); | ||
}); | ||
for (let [path, redirect] of Object.entries(cfg.appIframeRedirects || {})) { | ||
hono.get(path, async (ctx) => { | ||
const url = new URL(ctx.req.url); | ||
if (redirect.startsWith("/")) { | ||
url.pathname = redirect; | ||
redirect = url.toString(); | ||
} | ||
else { | ||
const newUrl = new URL(redirect); | ||
for (const [key, value] of url.searchParams) { | ||
newUrl.searchParams.set(key, value); | ||
} | ||
redirect = newUrl.toString(); | ||
} | ||
await setSignedCookie(ctx, "shop", ctx.get("shop").getShopId(), ctx.get("app").cfg.appSecret); | ||
return ctx.redirect(redirect); | ||
}); | ||
} | ||
} | ||
} | ||
@@ -92,0 +126,0 @@ function jsonResponse(body, status = 200) { |
{ | ||
"name": "@shopware-ag/app-server-sdk", | ||
"version": "1.1.2", | ||
"version": "1.1.3", | ||
"description": "App Server SDK for JavaScript", | ||
@@ -5,0 +5,0 @@ "type": "module", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
452755
4808