@shopware-ag/app-server-sdk 1.1.20 → 1.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commonjs/hooks.d.ts +2 -1
- package/dist/commonjs/hooks.d.ts.map +1 -1
- package/dist/commonjs/hooks.js +3 -3
- package/dist/commonjs/hooks.js.map +1 -1
- package/dist/commonjs/registration.d.ts +9 -0
- package/dist/commonjs/registration.d.ts.map +1 -1
- package/dist/commonjs/registration.js +24 -1
- package/dist/commonjs/registration.js.map +1 -1
- package/dist/esm/hooks.d.ts +2 -1
- package/dist/esm/hooks.d.ts.map +1 -1
- package/dist/esm/hooks.js +3 -3
- package/dist/esm/hooks.js.map +1 -1
- package/dist/esm/registration.d.ts +9 -0
- package/dist/esm/registration.d.ts.map +1 -1
- package/dist/esm/registration.js +22 -0
- package/dist/esm/registration.js.map +1 -1
- package/package.json +1 -1
package/dist/commonjs/hooks.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AppActivateEvent, AppDeactivateEvent, AppInstallEvent, AppUninstallEvent, AppUpdateEvent, ShopAuthorizeEvent } from "./registration.js";
|
|
1
|
+
import type { AppActivateEvent, AppDeactivateEvent, AppInstallEvent, AppUninstallEvent, AppUpdateEvent, ShopAuthorizeEvent, BeforeRegistrationEvent } from "./registration.js";
|
|
2
2
|
import type { ShopInterface } from "./repository.js";
|
|
3
3
|
interface HookRegistry<Shop extends ShopInterface> {
|
|
4
4
|
onAuthorize: (event: ShopAuthorizeEvent<Shop>) => Promise<void>;
|
|
@@ -7,6 +7,7 @@ interface HookRegistry<Shop extends ShopInterface> {
|
|
|
7
7
|
onAppActivate: (event: AppActivateEvent<Shop>) => Promise<void>;
|
|
8
8
|
onAppDeactivate: (event: AppDeactivateEvent<Shop>) => Promise<void>;
|
|
9
9
|
onAppUpdate: (event: AppUpdateEvent<Shop>) => Promise<void>;
|
|
10
|
+
onBeforeRegistrationEvent: (event: BeforeRegistrationEvent) => Promise<void>;
|
|
10
11
|
}
|
|
11
12
|
export declare class Hooks<Shop extends ShopInterface = ShopInterface> {
|
|
12
13
|
private eventListeners;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,UAAU,YAAY,CAAC,IAAI,SAAS,aAAa;IAChD,WAAW,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,YAAY,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,cAAc,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,aAAa,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,eAAe,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,WAAW,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,uBAAuB,EACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,UAAU,YAAY,CAAC,IAAI,SAAS,aAAa;IAChD,WAAW,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,YAAY,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,cAAc,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,aAAa,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,eAAe,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,WAAW,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,yBAAyB,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7E;AAED,qBAAa,KAAK,CAAC,IAAI,SAAS,aAAa,GAAG,aAAa;IAC5D,OAAO,CAAC,cAAc,CAGlB;IAEJ,YAAY,CAAC,KAAK,EAAE,MAAM,YAAY,CAAC,IAAI,CAAC,GAAG,OAAO;IAItD,EAAE,CACD,KAAK,EAAE,MAAM,YAAY,CAAC,IAAI,CAAC,EAC/B,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IAS3C,OAAO,CACZ,KAAK,EAAE,MAAM,YAAY,CAAC,IAAI,CAAC,EAC/B,GAAG,IAAI,EAAE,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,GAC/D,OAAO,CAAC,IAAI,CAAC;CAgBhB"}
|
package/dist/commonjs/hooks.js
CHANGED
|
@@ -13,11 +13,11 @@ class Hooks {
|
|
|
13
13
|
this.eventListeners.get(event)?.push(cb);
|
|
14
14
|
}
|
|
15
15
|
async publish(event, ...args) {
|
|
16
|
-
const
|
|
17
|
-
if (!
|
|
16
|
+
const listeners = this.eventListeners.get(event);
|
|
17
|
+
if (!listeners) {
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
|
-
for (const cb of
|
|
20
|
+
for (const cb of listeners) {
|
|
21
21
|
// @ts-expect-error
|
|
22
22
|
const res = cb(...args);
|
|
23
23
|
if (res instanceof Promise) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/hooks.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/hooks.ts"],"names":[],"mappings":";;;AAqBA,MAAa,KAAK;IACT,cAAc,GAAG,IAAI,GAAG,EAG7B,CAAC;IAEJ,YAAY,CAAC,KAA+B;QAC3C,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC;IAED,EAAE,CACD,KAA+B,EAC/B,EAAgD;QAEhD,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACpC,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,OAAO,CACZ,KAA+B,EAC/B,GAAG,IAA8D;QAEjE,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEjD,IAAI,CAAC,SAAS,EAAE,CAAC;YAChB,OAAO;QACR,CAAC;QAED,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;YAC5B,mBAAmB;YACnB,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;YAExB,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC5B,MAAM,GAAG,CAAC;YACX,CAAC;QACF,CAAC;IACF,CAAC;CACD;AAxCD,sBAwCC","sourcesContent":["import type {\n\tAppActivateEvent,\n\tAppDeactivateEvent,\n\tAppInstallEvent,\n\tAppUninstallEvent,\n\tAppUpdateEvent,\n\tShopAuthorizeEvent,\n\tBeforeRegistrationEvent,\n} from \"./registration.js\";\nimport type { ShopInterface } from \"./repository.js\";\n\ninterface HookRegistry<Shop extends ShopInterface> {\n\tonAuthorize: (event: ShopAuthorizeEvent<Shop>) => Promise<void>;\n\tonAppInstall: (event: AppInstallEvent<Shop>) => Promise<void>;\n\tonAppUninstall: (event: AppUninstallEvent<Shop>) => Promise<void>;\n\tonAppActivate: (event: AppActivateEvent<Shop>) => Promise<void>;\n\tonAppDeactivate: (event: AppDeactivateEvent<Shop>) => Promise<void>;\n\tonAppUpdate: (event: AppUpdateEvent<Shop>) => Promise<void>;\n\tonBeforeRegistrationEvent: (event: BeforeRegistrationEvent) => Promise<void>;\n}\n\nexport class Hooks<Shop extends ShopInterface = ShopInterface> {\n\tprivate eventListeners = new Map<\n\t\tkeyof HookRegistry<Shop>,\n\t\tHookRegistry<Shop>[keyof HookRegistry<Shop>][]\n\t>();\n\n\thasListeners(event: keyof HookRegistry<Shop>): boolean {\n\t\treturn this.eventListeners.has(event);\n\t}\n\n\ton(\n\t\tevent: keyof HookRegistry<Shop>,\n\t\tcb: HookRegistry<Shop>[keyof HookRegistry<Shop>],\n\t) {\n\t\tif (!this.eventListeners.has(event)) {\n\t\t\tthis.eventListeners.set(event, []);\n\t\t}\n\n\t\tthis.eventListeners.get(event)?.push(cb);\n\t}\n\n\tasync publish(\n\t\tevent: keyof HookRegistry<Shop>,\n\t\t...args: Parameters<HookRegistry<Shop>[keyof HookRegistry<Shop>]>\n\t): Promise<void> {\n\t\tconst listeners = this.eventListeners.get(event);\n\n\t\tif (!listeners) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const cb of listeners) {\n\t\t\t// @ts-expect-error\n\t\t\tconst res = cb(...args);\n\n\t\t\tif (res instanceof Promise) {\n\t\t\t\tawait res;\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
|
|
@@ -92,4 +92,13 @@ export declare class AppUninstallEvent<Shop extends ShopInterface = ShopInterfac
|
|
|
92
92
|
keepUserData: boolean | null;
|
|
93
93
|
constructor(request: Request, shop: Shop, keepUserData?: boolean | null);
|
|
94
94
|
}
|
|
95
|
+
export declare class BeforeRegistrationEvent<Shop extends ShopInterface = ShopInterface> {
|
|
96
|
+
request: Request;
|
|
97
|
+
shopId: string;
|
|
98
|
+
shopUrl: string;
|
|
99
|
+
private cancellationReason;
|
|
100
|
+
constructor(request: Request, shopId: string, shopUrl: string);
|
|
101
|
+
rejectRegistration(reason: string): void;
|
|
102
|
+
get reason(): string | null;
|
|
103
|
+
}
|
|
95
104
|
//# sourceMappingURL=registration.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registration.d.ts","sourceRoot":"","sources":["../../src/registration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,qBAAa,YAAY,CAAC,IAAI,SAAS,aAAa,GAAG,aAAa;IACvD,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC;IAExC;;;;OAIG;IACU,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"registration.d.ts","sourceRoot":"","sources":["../../src/registration.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AppUninstallEvent = exports.AppUpdateEvent = exports.AppDeactivateEvent = exports.AppActivateEvent = exports.AppInstallEvent = exports.ShopAuthorizeEvent = exports.Registration = void 0;
|
|
3
|
+
exports.BeforeRegistrationEvent = exports.AppUninstallEvent = exports.AppUpdateEvent = exports.AppDeactivateEvent = exports.AppActivateEvent = exports.AppInstallEvent = exports.ShopAuthorizeEvent = exports.Registration = void 0;
|
|
4
4
|
exports.randomString = randomString;
|
|
5
5
|
class Registration {
|
|
6
6
|
app;
|
|
@@ -23,6 +23,11 @@ class Registration {
|
|
|
23
23
|
const shopId = url.searchParams.get("shop-id");
|
|
24
24
|
const shopUrl = url.searchParams.get("shop-url");
|
|
25
25
|
const timestamp = url.searchParams.get("timestamp");
|
|
26
|
+
const beforeRegistrationEvent = new BeforeRegistrationEvent(req, shopId, shopUrl);
|
|
27
|
+
this.app.hooks.publish('onBeforeRegistrationEvent', beforeRegistrationEvent);
|
|
28
|
+
if (beforeRegistrationEvent.reason) {
|
|
29
|
+
return new InvalidRequestResponse(beforeRegistrationEvent.reason, 400);
|
|
30
|
+
}
|
|
26
31
|
const v = await this.app.signer.verify(req.headers.get("shopware-app-signature"), `shop-id=${shopId}&shop-url=${shopUrl}×tamp=${timestamp}`, this.app.cfg.appSecret);
|
|
27
32
|
if (!v) {
|
|
28
33
|
return new InvalidRequestResponse("Cannot validate app signature");
|
|
@@ -235,4 +240,22 @@ class AppUninstallEvent {
|
|
|
235
240
|
}
|
|
236
241
|
}
|
|
237
242
|
exports.AppUninstallEvent = AppUninstallEvent;
|
|
243
|
+
class BeforeRegistrationEvent {
|
|
244
|
+
request;
|
|
245
|
+
shopId;
|
|
246
|
+
shopUrl;
|
|
247
|
+
cancellationReason = null;
|
|
248
|
+
constructor(request, shopId, shopUrl) {
|
|
249
|
+
this.request = request;
|
|
250
|
+
this.shopId = shopId;
|
|
251
|
+
this.shopUrl = shopUrl;
|
|
252
|
+
}
|
|
253
|
+
rejectRegistration(reason) {
|
|
254
|
+
this.cancellationReason = reason;
|
|
255
|
+
}
|
|
256
|
+
get reason() {
|
|
257
|
+
return this.cancellationReason;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
exports.BeforeRegistrationEvent = BeforeRegistrationEvent;
|
|
238
261
|
//# sourceMappingURL=registration.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registration.js","sourceRoot":"","sources":["../../src/registration.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AppServer } from \"./app.js\";\nimport type { ShopInterface } from \"./repository.js\";\n\nexport class Registration<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(private app: AppServer<Shop>) {}\n\n\t/**\n\t * This method checks the request for the handshake with the Shopware Shop.\n\t * if it's valid a Shop will be created, and a proof will be responded with a confirmation url.\n\t * then the Shop will call the confirmation url, and this should be handled by the authorizeCallback method to finish the handshake.\n\t */\n\tpublic async authorize(req: Request): Promise<Response> {\n\t\tconst url = new URL(req.url);\n\n\t\tif (\n\t\t\t!url.searchParams.has(\"shop-url\") ||\n\t\t\t!req.headers.has(\"shopware-app-signature\") ||\n\t\t\t!url.searchParams.has(\"shop-id\") ||\n\t\t\t!url.searchParams.has(\"timestamp\")\n\t\t) {\n\t\t\treturn new InvalidRequestResponse(\"Invalid Request\", 400);\n\t\t}\n\n\t\tconst shopId = url.searchParams.get(\"shop-id\") as string;\n\t\tconst shopUrl = url.searchParams.get(\"shop-url\") as string;\n\t\tconst timestamp = url.searchParams.get(\"timestamp\") as string;\n\n\t\tconst v = await this.app.signer.verify(\n\t\t\treq.headers.get(\"shopware-app-signature\") as string,\n\t\t\t`shop-id=${shopId}&shop-url=${shopUrl}×tamp=${timestamp}`,\n\t\t\tthis.app.cfg.appSecret,\n\t\t);\n\n\t\tif (!v) {\n\t\t\treturn new InvalidRequestResponse(\"Cannot validate app signature\");\n\t\t}\n\n\t\tconst shopSecret = randomString();\n\t\tconst sanitizedShopUrl = shopUrl\n\t\t\t.replace(/([^:])(\\/\\/+)/g, \"$1/\")\n\t\t\t.replace(/\\/+$/, \"\");\n\n\t\tawait this.app.repository.createShop(shopId, sanitizedShopUrl, shopSecret);\n\n\t\treturn new Response(\n\t\t\tJSON.stringify({\n\t\t\t\tproof: await this.app.signer.sign(\n\t\t\t\t\tshopId + shopUrl + this.app.cfg.appName,\n\t\t\t\t\tthis.app.cfg.appSecret,\n\t\t\t\t),\n\t\t\t\tsecret: shopSecret,\n\t\t\t\tconfirmation_url: this.app.cfg.authorizeCallbackUrl,\n\t\t\t}),\n\t\t\t{\n\t\t\t\theaders: {\n\t\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * This method is called by the Shopware Shop to confirm the handshake.\n\t * It will update the shop with the given oauth2 credentials.\n\t */\n\tpublic async authorizeCallback(req: Request): Promise<Response> {\n\t\tconst bodyContent = await req.text();\n\n\t\tconst body = JSON.parse(bodyContent);\n\n\t\tif (\n\t\t\ttypeof body.shopId !== \"string\" ||\n\t\t\ttypeof body.apiKey !== \"string\" ||\n\t\t\ttypeof body.secretKey !== \"string\" ||\n\t\t\t!req.headers.has(\"shopware-shop-signature\")\n\t\t) {\n\t\t\treturn new InvalidRequestResponse(\"Invalid Request\", 400);\n\t\t}\n\n\t\tconst shop = await this.app.repository.getShopById(body.shopId as string);\n\n\t\tif (shop === null) {\n\t\t\treturn new InvalidRequestResponse(\"Invalid shop given\");\n\t\t}\n\n\t\tconst v = await this.app.signer.verify(\n\t\t\treq.headers.get(\"shopware-shop-signature\") as string,\n\t\t\tbodyContent,\n\t\t\tshop.getShopSecret(),\n\t\t);\n\n\t\tif (!v) {\n\t\t\t// Shop has failed the verification. Delete it from our DB.\n\t\t\tawait this.app.repository.deleteShop(shop.getShopId());\n\n\t\t\treturn new InvalidRequestResponse(\"Cannot validate app signature\");\n\t\t}\n\n\t\tshop.setShopCredentials(body.apiKey, body.secretKey);\n\n\t\tconst event = new ShopAuthorizeEvent(req, shop);\n\t\tawait this.app.hooks.publish(\"onAuthorize\", event);\n\n\t\tif (event.reason) {\n\t\t\tawait this.app.repository.deleteShop(shop.getShopId());\n\n\t\t\treturn new InvalidRequestResponse(event.reason, 403);\n\t\t}\n\n\t\tawait this.app.repository.updateShop(shop);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware Shop to set the shop active.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appActivate\" url=\"http://localhost:3000/app/activate\" event=\"app.activated\"/>\n\t * </webhooks>\n\t */\n\tpublic async activate(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI(req);\n\n\t\tconst event = new AppActivateEvent(req, ctx.shop);\n\t\tawait this.app.hooks.publish(\"onAppActivate\", event);\n\n\t\tctx.shop.setShopActive(true);\n\n\t\tawait this.app.repository.updateShop(ctx.shop);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware when the app was installed.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appInstall\" url=\"http://localhost:3000/app/install\" event=\"app.installed\"/>\n\t * </webhooks>\n\t */\n\tpublic async install(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI<{\n\t\t\tdata: { payload: { appVersion: string } };\n\t\t}>(req);\n\n\t\tconst event = new AppInstallEvent(\n\t\t\treq,\n\t\t\tctx.shop,\n\t\t\tctx.payload?.data?.payload?.appVersion ?? null,\n\t\t);\n\t\tawait this.app.hooks.publish(\"onAppInstall\", event);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware Shop to set the shop in-active.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appDeactivated\" url=\"http://localhost:3000/app/deactivated\" event=\"app.deactivated\"/>\n\t * </webhooks>\n\t */\n\tpublic async deactivate(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI(req);\n\n\t\tconst event = new AppDeactivateEvent(req, ctx.shop);\n\t\tawait this.app.hooks.publish(\"onAppDeactivate\", event);\n\n\t\tctx.shop.setShopActive(false);\n\n\t\tawait this.app.repository.updateShop(ctx.shop);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware when the app was updated.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appUpdated\" url=\"http://localhost:3000/app/update\" event=\"app.updated\"/>\n\t * </webhooks>\n\t */\n\tpublic async update(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI<{\n\t\t\tdata: { payload: { appVersion: string } };\n\t\t}>(req);\n\n\t\tconst event = new AppUpdateEvent(\n\t\t\treq,\n\t\t\tctx.shop,\n\t\t\tctx.payload?.data?.payload?.appVersion ?? null,\n\t\t);\n\t\tawait this.app.hooks.publish(\"onAppUpdate\", event);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware Shop to delete the app.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appDelete\" url=\"http://localhost:3000/app/delete\" event=\"app.deleted\"/>\n\t * </webhooks>\n\t */\n\tpublic async delete(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI<{\n\t\t\tdata: { payload: { keepUserData?: boolean } };\n\t\t}>(req);\n\n\t\tconst event = new AppUninstallEvent(\n\t\t\treq,\n\t\t\tctx.shop,\n\t\t\tctx.payload?.data?.payload?.keepUserData ?? null,\n\t\t);\n\t\tawait this.app.hooks.publish(\"onAppUninstall\", event);\n\n\t\tif (event.keepUserData === false) {\n\t\t\tawait this.app.repository.deleteShop(ctx.shop.getShopId());\n\t\t}\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n}\n\nexport function randomString(length = 120) {\n\tlet result = \"\";\n\tconst characters =\n\t\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\tconst charactersLength = characters.length;\n\tfor (let i = 0; i < length; i++) {\n\t\tresult += characters.charAt(Math.floor(Math.random() * charactersLength));\n\t}\n\n\treturn result;\n}\n\nclass InvalidRequestResponse extends Response {\n\tconstructor(message: string, status = 401) {\n\t\tsuper(JSON.stringify({ message }), {\n\t\t\tstatus,\n\t\t\theaders: {\n\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t},\n\t\t});\n\t}\n}\n\nexport class ShopAuthorizeEvent<Shop extends ShopInterface = ShopInterface> {\n\tprivate reject: string | null = null;\n\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t) {}\n\n\tpublic rejectRegistration(reason: string) {\n\t\tthis.reject = reason;\n\t}\n\n\tpublic get reason() {\n\t\treturn this.reject;\n\t}\n}\n\nexport class AppInstallEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t\tpublic appVersion: string | null = null,\n\t) {}\n}\n\nexport class AppActivateEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t) {}\n}\n\nexport class AppDeactivateEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t) {}\n}\n\nexport class AppUpdateEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t\tpublic appVersion: string | null = null,\n\t) {}\n}\n\nexport class AppUninstallEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t\tpublic keepUserData: boolean | null = null,\n\t) {}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"registration.js","sourceRoot":"","sources":["../../src/registration.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AppServer } from \"./app.js\";\nimport type { ShopInterface } from \"./repository.js\";\n\nexport class Registration<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(private app: AppServer<Shop>) {}\n\n\t/**\n\t * This method checks the request for the handshake with the Shopware Shop.\n\t * if it's valid a Shop will be created, and a proof will be responded with a confirmation url.\n\t * then the Shop will call the confirmation url, and this should be handled by the authorizeCallback method to finish the handshake.\n\t */\n\tpublic async authorize(req: Request): Promise<Response> {\n\t\tconst url = new URL(req.url);\n\n\t\tif (\n\t\t\t!url.searchParams.has(\"shop-url\") ||\n\t\t\t!req.headers.has(\"shopware-app-signature\") ||\n\t\t\t!url.searchParams.has(\"shop-id\") ||\n\t\t\t!url.searchParams.has(\"timestamp\")\n\t\t) {\n\t\t\treturn new InvalidRequestResponse(\"Invalid Request\", 400);\n\t\t}\n\n\t\tconst shopId = url.searchParams.get(\"shop-id\") as string;\n\t\tconst shopUrl = url.searchParams.get(\"shop-url\") as string;\n\t\tconst timestamp = url.searchParams.get(\"timestamp\") as string;\n\n\t\tconst beforeRegistrationEvent = new BeforeRegistrationEvent(req, shopId, shopUrl);\n\t\tthis.app.hooks.publish('onBeforeRegistrationEvent', beforeRegistrationEvent);\n\n\t\tif (beforeRegistrationEvent.reason) {\n\t\t\treturn new InvalidRequestResponse(beforeRegistrationEvent.reason, 400);\n\t\t}\n\n\t\tconst v = await this.app.signer.verify(\n\t\t\treq.headers.get(\"shopware-app-signature\") as string,\n\t\t\t`shop-id=${shopId}&shop-url=${shopUrl}×tamp=${timestamp}`,\n\t\t\tthis.app.cfg.appSecret,\n\t\t);\n\n\t\tif (!v) {\n\t\t\treturn new InvalidRequestResponse(\"Cannot validate app signature\");\n\t\t}\n\n\t\tconst shopSecret = randomString();\n\t\tconst sanitizedShopUrl = shopUrl\n\t\t\t.replace(/([^:])(\\/\\/+)/g, \"$1/\")\n\t\t\t.replace(/\\/+$/, \"\");\n\n\t\tawait this.app.repository.createShop(shopId, sanitizedShopUrl, shopSecret);\n\n\t\treturn new Response(\n\t\t\tJSON.stringify({\n\t\t\t\tproof: await this.app.signer.sign(\n\t\t\t\t\tshopId + shopUrl + this.app.cfg.appName,\n\t\t\t\t\tthis.app.cfg.appSecret,\n\t\t\t\t),\n\t\t\t\tsecret: shopSecret,\n\t\t\t\tconfirmation_url: this.app.cfg.authorizeCallbackUrl,\n\t\t\t}),\n\t\t\t{\n\t\t\t\theaders: {\n\t\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * This method is called by the Shopware Shop to confirm the handshake.\n\t * It will update the shop with the given oauth2 credentials.\n\t */\n\tpublic async authorizeCallback(req: Request): Promise<Response> {\n\t\tconst bodyContent = await req.text();\n\n\t\tconst body = JSON.parse(bodyContent);\n\n\t\tif (\n\t\t\ttypeof body.shopId !== \"string\" ||\n\t\t\ttypeof body.apiKey !== \"string\" ||\n\t\t\ttypeof body.secretKey !== \"string\" ||\n\t\t\t!req.headers.has(\"shopware-shop-signature\")\n\t\t) {\n\t\t\treturn new InvalidRequestResponse(\"Invalid Request\", 400);\n\t\t}\n\n\t\tconst shop = await this.app.repository.getShopById(body.shopId as string);\n\n\t\tif (shop === null) {\n\t\t\treturn new InvalidRequestResponse(\"Invalid shop given\");\n\t\t}\n\n\t\tconst v = await this.app.signer.verify(\n\t\t\treq.headers.get(\"shopware-shop-signature\") as string,\n\t\t\tbodyContent,\n\t\t\tshop.getShopSecret(),\n\t\t);\n\n\t\tif (!v) {\n\t\t\t// Shop has failed the verification. Delete it from our DB.\n\t\t\tawait this.app.repository.deleteShop(shop.getShopId());\n\n\t\t\treturn new InvalidRequestResponse(\"Cannot validate app signature\");\n\t\t}\n\n\t\tshop.setShopCredentials(body.apiKey, body.secretKey);\n\n\t\tconst event = new ShopAuthorizeEvent(req, shop);\n\t\tawait this.app.hooks.publish(\"onAuthorize\", event);\n\n\t\tif (event.reason) {\n\t\t\tawait this.app.repository.deleteShop(shop.getShopId());\n\n\t\t\treturn new InvalidRequestResponse(event.reason, 403);\n\t\t}\n\n\t\tawait this.app.repository.updateShop(shop);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware Shop to set the shop active.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appActivate\" url=\"http://localhost:3000/app/activate\" event=\"app.activated\"/>\n\t * </webhooks>\n\t */\n\tpublic async activate(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI(req);\n\n\t\tconst event = new AppActivateEvent(req, ctx.shop);\n\t\tawait this.app.hooks.publish(\"onAppActivate\", event);\n\n\t\tctx.shop.setShopActive(true);\n\n\t\tawait this.app.repository.updateShop(ctx.shop);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware when the app was installed.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appInstall\" url=\"http://localhost:3000/app/install\" event=\"app.installed\"/>\n\t * </webhooks>\n\t */\n\tpublic async install(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI<{\n\t\t\tdata: { payload: { appVersion: string } };\n\t\t}>(req);\n\n\t\tconst event = new AppInstallEvent(\n\t\t\treq,\n\t\t\tctx.shop,\n\t\t\tctx.payload?.data?.payload?.appVersion ?? null,\n\t\t);\n\t\tawait this.app.hooks.publish(\"onAppInstall\", event);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware Shop to set the shop in-active.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appDeactivated\" url=\"http://localhost:3000/app/deactivated\" event=\"app.deactivated\"/>\n\t * </webhooks>\n\t */\n\tpublic async deactivate(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI(req);\n\n\t\tconst event = new AppDeactivateEvent(req, ctx.shop);\n\t\tawait this.app.hooks.publish(\"onAppDeactivate\", event);\n\n\t\tctx.shop.setShopActive(false);\n\n\t\tawait this.app.repository.updateShop(ctx.shop);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware when the app was updated.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appUpdated\" url=\"http://localhost:3000/app/update\" event=\"app.updated\"/>\n\t * </webhooks>\n\t */\n\tpublic async update(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI<{\n\t\t\tdata: { payload: { appVersion: string } };\n\t\t}>(req);\n\n\t\tconst event = new AppUpdateEvent(\n\t\t\treq,\n\t\t\tctx.shop,\n\t\t\tctx.payload?.data?.payload?.appVersion ?? null,\n\t\t);\n\t\tawait this.app.hooks.publish(\"onAppUpdate\", event);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware Shop to delete the app.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appDelete\" url=\"http://localhost:3000/app/delete\" event=\"app.deleted\"/>\n\t * </webhooks>\n\t */\n\tpublic async delete(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI<{\n\t\t\tdata: { payload: { keepUserData?: boolean } };\n\t\t}>(req);\n\n\t\tconst event = new AppUninstallEvent(\n\t\t\treq,\n\t\t\tctx.shop,\n\t\t\tctx.payload?.data?.payload?.keepUserData ?? null,\n\t\t);\n\t\tawait this.app.hooks.publish(\"onAppUninstall\", event);\n\n\t\tif (event.keepUserData === false) {\n\t\t\tawait this.app.repository.deleteShop(ctx.shop.getShopId());\n\t\t}\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n}\n\nexport function randomString(length = 120) {\n\tlet result = \"\";\n\tconst characters =\n\t\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\tconst charactersLength = characters.length;\n\tfor (let i = 0; i < length; i++) {\n\t\tresult += characters.charAt(Math.floor(Math.random() * charactersLength));\n\t}\n\n\treturn result;\n}\n\nclass InvalidRequestResponse extends Response {\n\tconstructor(message: string, status = 401) {\n\t\tsuper(JSON.stringify({ message }), {\n\t\t\tstatus,\n\t\t\theaders: {\n\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t},\n\t\t});\n\t}\n}\n\nexport class ShopAuthorizeEvent<Shop extends ShopInterface = ShopInterface> {\n\tprivate reject: string | null = null;\n\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t) {}\n\n\tpublic rejectRegistration(reason: string) {\n\t\tthis.reject = reason;\n\t}\n\n\tpublic get reason() {\n\t\treturn this.reject;\n\t}\n}\n\nexport class AppInstallEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t\tpublic appVersion: string | null = null,\n\t) {}\n}\n\nexport class AppActivateEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t) {}\n}\n\nexport class AppDeactivateEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t) {}\n}\n\nexport class AppUpdateEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t\tpublic appVersion: string | null = null,\n\t) {}\n}\n\nexport class AppUninstallEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t\tpublic keepUserData: boolean | null = null,\n\t) {}\n}\n\nexport class BeforeRegistrationEvent<Shop extends ShopInterface = ShopInterface> {\n\tprivate cancellationReason: string | null = null;\n\t\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shopId: string,\n\t\tpublic shopUrl: string,\n\t) {}\n\n\tpublic rejectRegistration(reason: string) {\n\t\tthis.cancellationReason = reason;\n\t}\n\n\tpublic get reason() {\n\t\treturn this.cancellationReason;\n\t}\n}\n"]}
|
package/dist/esm/hooks.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AppActivateEvent, AppDeactivateEvent, AppInstallEvent, AppUninstallEvent, AppUpdateEvent, ShopAuthorizeEvent } from "./registration.js";
|
|
1
|
+
import type { AppActivateEvent, AppDeactivateEvent, AppInstallEvent, AppUninstallEvent, AppUpdateEvent, ShopAuthorizeEvent, BeforeRegistrationEvent } from "./registration.js";
|
|
2
2
|
import type { ShopInterface } from "./repository.js";
|
|
3
3
|
interface HookRegistry<Shop extends ShopInterface> {
|
|
4
4
|
onAuthorize: (event: ShopAuthorizeEvent<Shop>) => Promise<void>;
|
|
@@ -7,6 +7,7 @@ interface HookRegistry<Shop extends ShopInterface> {
|
|
|
7
7
|
onAppActivate: (event: AppActivateEvent<Shop>) => Promise<void>;
|
|
8
8
|
onAppDeactivate: (event: AppDeactivateEvent<Shop>) => Promise<void>;
|
|
9
9
|
onAppUpdate: (event: AppUpdateEvent<Shop>) => Promise<void>;
|
|
10
|
+
onBeforeRegistrationEvent: (event: BeforeRegistrationEvent) => Promise<void>;
|
|
10
11
|
}
|
|
11
12
|
export declare class Hooks<Shop extends ShopInterface = ShopInterface> {
|
|
12
13
|
private eventListeners;
|
package/dist/esm/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,UAAU,YAAY,CAAC,IAAI,SAAS,aAAa;IAChD,WAAW,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,YAAY,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,cAAc,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,aAAa,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,eAAe,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,WAAW,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,gBAAgB,EAChB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,uBAAuB,EACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,UAAU,YAAY,CAAC,IAAI,SAAS,aAAa;IAChD,WAAW,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,YAAY,EAAE,CAAC,KAAK,EAAE,eAAe,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,cAAc,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,aAAa,EAAE,CAAC,KAAK,EAAE,gBAAgB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,eAAe,EAAE,CAAC,KAAK,EAAE,kBAAkB,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,WAAW,EAAE,CAAC,KAAK,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,yBAAyB,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7E;AAED,qBAAa,KAAK,CAAC,IAAI,SAAS,aAAa,GAAG,aAAa;IAC5D,OAAO,CAAC,cAAc,CAGlB;IAEJ,YAAY,CAAC,KAAK,EAAE,MAAM,YAAY,CAAC,IAAI,CAAC,GAAG,OAAO;IAItD,EAAE,CACD,KAAK,EAAE,MAAM,YAAY,CAAC,IAAI,CAAC,EAC/B,EAAE,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC;IAS3C,OAAO,CACZ,KAAK,EAAE,MAAM,YAAY,CAAC,IAAI,CAAC,EAC/B,GAAG,IAAI,EAAE,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,GAC/D,OAAO,CAAC,IAAI,CAAC;CAgBhB"}
|
package/dist/esm/hooks.js
CHANGED
|
@@ -10,11 +10,11 @@ export class Hooks {
|
|
|
10
10
|
this.eventListeners.get(event)?.push(cb);
|
|
11
11
|
}
|
|
12
12
|
async publish(event, ...args) {
|
|
13
|
-
const
|
|
14
|
-
if (!
|
|
13
|
+
const listeners = this.eventListeners.get(event);
|
|
14
|
+
if (!listeners) {
|
|
15
15
|
return;
|
|
16
16
|
}
|
|
17
|
-
for (const cb of
|
|
17
|
+
for (const cb of listeners) {
|
|
18
18
|
// @ts-expect-error
|
|
19
19
|
const res = cb(...args);
|
|
20
20
|
if (res instanceof Promise) {
|
package/dist/esm/hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/hooks.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/hooks.ts"],"names":[],"mappings":"AAqBA,MAAM,OAAO,KAAK;IACT,cAAc,GAAG,IAAI,GAAG,EAG7B,CAAC;IAEJ,YAAY,CAAC,KAA+B;QAC3C,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACvC,CAAC;IAED,EAAE,CACD,KAA+B,EAC/B,EAAgD;QAEhD,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACpC,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,OAAO,CACZ,KAA+B,EAC/B,GAAG,IAA8D;QAEjE,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAEjD,IAAI,CAAC,SAAS,EAAE,CAAC;YAChB,OAAO;QACR,CAAC;QAED,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;YAC5B,mBAAmB;YACnB,MAAM,GAAG,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;YAExB,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;gBAC5B,MAAM,GAAG,CAAC;YACX,CAAC;QACF,CAAC;IACF,CAAC;CACD","sourcesContent":["import type {\n\tAppActivateEvent,\n\tAppDeactivateEvent,\n\tAppInstallEvent,\n\tAppUninstallEvent,\n\tAppUpdateEvent,\n\tShopAuthorizeEvent,\n\tBeforeRegistrationEvent,\n} from \"./registration.js\";\nimport type { ShopInterface } from \"./repository.js\";\n\ninterface HookRegistry<Shop extends ShopInterface> {\n\tonAuthorize: (event: ShopAuthorizeEvent<Shop>) => Promise<void>;\n\tonAppInstall: (event: AppInstallEvent<Shop>) => Promise<void>;\n\tonAppUninstall: (event: AppUninstallEvent<Shop>) => Promise<void>;\n\tonAppActivate: (event: AppActivateEvent<Shop>) => Promise<void>;\n\tonAppDeactivate: (event: AppDeactivateEvent<Shop>) => Promise<void>;\n\tonAppUpdate: (event: AppUpdateEvent<Shop>) => Promise<void>;\n\tonBeforeRegistrationEvent: (event: BeforeRegistrationEvent) => Promise<void>;\n}\n\nexport class Hooks<Shop extends ShopInterface = ShopInterface> {\n\tprivate eventListeners = new Map<\n\t\tkeyof HookRegistry<Shop>,\n\t\tHookRegistry<Shop>[keyof HookRegistry<Shop>][]\n\t>();\n\n\thasListeners(event: keyof HookRegistry<Shop>): boolean {\n\t\treturn this.eventListeners.has(event);\n\t}\n\n\ton(\n\t\tevent: keyof HookRegistry<Shop>,\n\t\tcb: HookRegistry<Shop>[keyof HookRegistry<Shop>],\n\t) {\n\t\tif (!this.eventListeners.has(event)) {\n\t\t\tthis.eventListeners.set(event, []);\n\t\t}\n\n\t\tthis.eventListeners.get(event)?.push(cb);\n\t}\n\n\tasync publish(\n\t\tevent: keyof HookRegistry<Shop>,\n\t\t...args: Parameters<HookRegistry<Shop>[keyof HookRegistry<Shop>]>\n\t): Promise<void> {\n\t\tconst listeners = this.eventListeners.get(event);\n\n\t\tif (!listeners) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const cb of listeners) {\n\t\t\t// @ts-expect-error\n\t\t\tconst res = cb(...args);\n\n\t\t\tif (res instanceof Promise) {\n\t\t\t\tawait res;\n\t\t\t}\n\t\t}\n\t}\n}\n"]}
|
|
@@ -92,4 +92,13 @@ export declare class AppUninstallEvent<Shop extends ShopInterface = ShopInterfac
|
|
|
92
92
|
keepUserData: boolean | null;
|
|
93
93
|
constructor(request: Request, shop: Shop, keepUserData?: boolean | null);
|
|
94
94
|
}
|
|
95
|
+
export declare class BeforeRegistrationEvent<Shop extends ShopInterface = ShopInterface> {
|
|
96
|
+
request: Request;
|
|
97
|
+
shopId: string;
|
|
98
|
+
shopUrl: string;
|
|
99
|
+
private cancellationReason;
|
|
100
|
+
constructor(request: Request, shopId: string, shopUrl: string);
|
|
101
|
+
rejectRegistration(reason: string): void;
|
|
102
|
+
get reason(): string | null;
|
|
103
|
+
}
|
|
95
104
|
//# sourceMappingURL=registration.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registration.d.ts","sourceRoot":"","sources":["../../src/registration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,qBAAa,YAAY,CAAC,IAAI,SAAS,aAAa,GAAG,aAAa;IACvD,OAAO,CAAC,GAAG;gBAAH,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC;IAExC;;;;OAIG;IACU,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"registration.d.ts","sourceRoot":"","sources":["../../src/registration.ts"],"names":[],"mappings":"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"}
|
package/dist/esm/registration.js
CHANGED
|
@@ -19,6 +19,11 @@ export class Registration {
|
|
|
19
19
|
const shopId = url.searchParams.get("shop-id");
|
|
20
20
|
const shopUrl = url.searchParams.get("shop-url");
|
|
21
21
|
const timestamp = url.searchParams.get("timestamp");
|
|
22
|
+
const beforeRegistrationEvent = new BeforeRegistrationEvent(req, shopId, shopUrl);
|
|
23
|
+
this.app.hooks.publish('onBeforeRegistrationEvent', beforeRegistrationEvent);
|
|
24
|
+
if (beforeRegistrationEvent.reason) {
|
|
25
|
+
return new InvalidRequestResponse(beforeRegistrationEvent.reason, 400);
|
|
26
|
+
}
|
|
22
27
|
const v = await this.app.signer.verify(req.headers.get("shopware-app-signature"), `shop-id=${shopId}&shop-url=${shopUrl}×tamp=${timestamp}`, this.app.cfg.appSecret);
|
|
23
28
|
if (!v) {
|
|
24
29
|
return new InvalidRequestResponse("Cannot validate app signature");
|
|
@@ -224,4 +229,21 @@ export class AppUninstallEvent {
|
|
|
224
229
|
this.keepUserData = keepUserData;
|
|
225
230
|
}
|
|
226
231
|
}
|
|
232
|
+
export class BeforeRegistrationEvent {
|
|
233
|
+
request;
|
|
234
|
+
shopId;
|
|
235
|
+
shopUrl;
|
|
236
|
+
cancellationReason = null;
|
|
237
|
+
constructor(request, shopId, shopUrl) {
|
|
238
|
+
this.request = request;
|
|
239
|
+
this.shopId = shopId;
|
|
240
|
+
this.shopUrl = shopUrl;
|
|
241
|
+
}
|
|
242
|
+
rejectRegistration(reason) {
|
|
243
|
+
this.cancellationReason = reason;
|
|
244
|
+
}
|
|
245
|
+
get reason() {
|
|
246
|
+
return this.cancellationReason;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
227
249
|
//# sourceMappingURL=registration.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registration.js","sourceRoot":"","sources":["../../src/registration.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AppServer } from \"./app.js\";\nimport type { ShopInterface } from \"./repository.js\";\n\nexport class Registration<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(private app: AppServer<Shop>) {}\n\n\t/**\n\t * This method checks the request for the handshake with the Shopware Shop.\n\t * if it's valid a Shop will be created, and a proof will be responded with a confirmation url.\n\t * then the Shop will call the confirmation url, and this should be handled by the authorizeCallback method to finish the handshake.\n\t */\n\tpublic async authorize(req: Request): Promise<Response> {\n\t\tconst url = new URL(req.url);\n\n\t\tif (\n\t\t\t!url.searchParams.has(\"shop-url\") ||\n\t\t\t!req.headers.has(\"shopware-app-signature\") ||\n\t\t\t!url.searchParams.has(\"shop-id\") ||\n\t\t\t!url.searchParams.has(\"timestamp\")\n\t\t) {\n\t\t\treturn new InvalidRequestResponse(\"Invalid Request\", 400);\n\t\t}\n\n\t\tconst shopId = url.searchParams.get(\"shop-id\") as string;\n\t\tconst shopUrl = url.searchParams.get(\"shop-url\") as string;\n\t\tconst timestamp = url.searchParams.get(\"timestamp\") as string;\n\n\t\tconst v = await this.app.signer.verify(\n\t\t\treq.headers.get(\"shopware-app-signature\") as string,\n\t\t\t`shop-id=${shopId}&shop-url=${shopUrl}×tamp=${timestamp}`,\n\t\t\tthis.app.cfg.appSecret,\n\t\t);\n\n\t\tif (!v) {\n\t\t\treturn new InvalidRequestResponse(\"Cannot validate app signature\");\n\t\t}\n\n\t\tconst shopSecret = randomString();\n\t\tconst sanitizedShopUrl = shopUrl\n\t\t\t.replace(/([^:])(\\/\\/+)/g, \"$1/\")\n\t\t\t.replace(/\\/+$/, \"\");\n\n\t\tawait this.app.repository.createShop(shopId, sanitizedShopUrl, shopSecret);\n\n\t\treturn new Response(\n\t\t\tJSON.stringify({\n\t\t\t\tproof: await this.app.signer.sign(\n\t\t\t\t\tshopId + shopUrl + this.app.cfg.appName,\n\t\t\t\t\tthis.app.cfg.appSecret,\n\t\t\t\t),\n\t\t\t\tsecret: shopSecret,\n\t\t\t\tconfirmation_url: this.app.cfg.authorizeCallbackUrl,\n\t\t\t}),\n\t\t\t{\n\t\t\t\theaders: {\n\t\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * This method is called by the Shopware Shop to confirm the handshake.\n\t * It will update the shop with the given oauth2 credentials.\n\t */\n\tpublic async authorizeCallback(req: Request): Promise<Response> {\n\t\tconst bodyContent = await req.text();\n\n\t\tconst body = JSON.parse(bodyContent);\n\n\t\tif (\n\t\t\ttypeof body.shopId !== \"string\" ||\n\t\t\ttypeof body.apiKey !== \"string\" ||\n\t\t\ttypeof body.secretKey !== \"string\" ||\n\t\t\t!req.headers.has(\"shopware-shop-signature\")\n\t\t) {\n\t\t\treturn new InvalidRequestResponse(\"Invalid Request\", 400);\n\t\t}\n\n\t\tconst shop = await this.app.repository.getShopById(body.shopId as string);\n\n\t\tif (shop === null) {\n\t\t\treturn new InvalidRequestResponse(\"Invalid shop given\");\n\t\t}\n\n\t\tconst v = await this.app.signer.verify(\n\t\t\treq.headers.get(\"shopware-shop-signature\") as string,\n\t\t\tbodyContent,\n\t\t\tshop.getShopSecret(),\n\t\t);\n\n\t\tif (!v) {\n\t\t\t// Shop has failed the verification. Delete it from our DB.\n\t\t\tawait this.app.repository.deleteShop(shop.getShopId());\n\n\t\t\treturn new InvalidRequestResponse(\"Cannot validate app signature\");\n\t\t}\n\n\t\tshop.setShopCredentials(body.apiKey, body.secretKey);\n\n\t\tconst event = new ShopAuthorizeEvent(req, shop);\n\t\tawait this.app.hooks.publish(\"onAuthorize\", event);\n\n\t\tif (event.reason) {\n\t\t\tawait this.app.repository.deleteShop(shop.getShopId());\n\n\t\t\treturn new InvalidRequestResponse(event.reason, 403);\n\t\t}\n\n\t\tawait this.app.repository.updateShop(shop);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware Shop to set the shop active.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appActivate\" url=\"http://localhost:3000/app/activate\" event=\"app.activated\"/>\n\t * </webhooks>\n\t */\n\tpublic async activate(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI(req);\n\n\t\tconst event = new AppActivateEvent(req, ctx.shop);\n\t\tawait this.app.hooks.publish(\"onAppActivate\", event);\n\n\t\tctx.shop.setShopActive(true);\n\n\t\tawait this.app.repository.updateShop(ctx.shop);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware when the app was installed.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appInstall\" url=\"http://localhost:3000/app/install\" event=\"app.installed\"/>\n\t * </webhooks>\n\t */\n\tpublic async install(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI<{\n\t\t\tdata: { payload: { appVersion: string } };\n\t\t}>(req);\n\n\t\tconst event = new AppInstallEvent(\n\t\t\treq,\n\t\t\tctx.shop,\n\t\t\tctx.payload?.data?.payload?.appVersion ?? null,\n\t\t);\n\t\tawait this.app.hooks.publish(\"onAppInstall\", event);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware Shop to set the shop in-active.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appDeactivated\" url=\"http://localhost:3000/app/deactivated\" event=\"app.deactivated\"/>\n\t * </webhooks>\n\t */\n\tpublic async deactivate(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI(req);\n\n\t\tconst event = new AppDeactivateEvent(req, ctx.shop);\n\t\tawait this.app.hooks.publish(\"onAppDeactivate\", event);\n\n\t\tctx.shop.setShopActive(false);\n\n\t\tawait this.app.repository.updateShop(ctx.shop);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware when the app was updated.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appUpdated\" url=\"http://localhost:3000/app/update\" event=\"app.updated\"/>\n\t * </webhooks>\n\t */\n\tpublic async update(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI<{\n\t\t\tdata: { payload: { appVersion: string } };\n\t\t}>(req);\n\n\t\tconst event = new AppUpdateEvent(\n\t\t\treq,\n\t\t\tctx.shop,\n\t\t\tctx.payload?.data?.payload?.appVersion ?? null,\n\t\t);\n\t\tawait this.app.hooks.publish(\"onAppUpdate\", event);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware Shop to delete the app.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appDelete\" url=\"http://localhost:3000/app/delete\" event=\"app.deleted\"/>\n\t * </webhooks>\n\t */\n\tpublic async delete(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI<{\n\t\t\tdata: { payload: { keepUserData?: boolean } };\n\t\t}>(req);\n\n\t\tconst event = new AppUninstallEvent(\n\t\t\treq,\n\t\t\tctx.shop,\n\t\t\tctx.payload?.data?.payload?.keepUserData ?? null,\n\t\t);\n\t\tawait this.app.hooks.publish(\"onAppUninstall\", event);\n\n\t\tif (event.keepUserData === false) {\n\t\t\tawait this.app.repository.deleteShop(ctx.shop.getShopId());\n\t\t}\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n}\n\nexport function randomString(length = 120) {\n\tlet result = \"\";\n\tconst characters =\n\t\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\tconst charactersLength = characters.length;\n\tfor (let i = 0; i < length; i++) {\n\t\tresult += characters.charAt(Math.floor(Math.random() * charactersLength));\n\t}\n\n\treturn result;\n}\n\nclass InvalidRequestResponse extends Response {\n\tconstructor(message: string, status = 401) {\n\t\tsuper(JSON.stringify({ message }), {\n\t\t\tstatus,\n\t\t\theaders: {\n\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t},\n\t\t});\n\t}\n}\n\nexport class ShopAuthorizeEvent<Shop extends ShopInterface = ShopInterface> {\n\tprivate reject: string | null = null;\n\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t) {}\n\n\tpublic rejectRegistration(reason: string) {\n\t\tthis.reject = reason;\n\t}\n\n\tpublic get reason() {\n\t\treturn this.reject;\n\t}\n}\n\nexport class AppInstallEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t\tpublic appVersion: string | null = null,\n\t) {}\n}\n\nexport class AppActivateEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t) {}\n}\n\nexport class AppDeactivateEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t) {}\n}\n\nexport class AppUpdateEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t\tpublic appVersion: string | null = null,\n\t) {}\n}\n\nexport class AppUninstallEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t\tpublic keepUserData: boolean | null = null,\n\t) {}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"registration.js","sourceRoot":"","sources":["../../src/registration.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AppServer } from \"./app.js\";\nimport type { ShopInterface } from \"./repository.js\";\n\nexport class Registration<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(private app: AppServer<Shop>) {}\n\n\t/**\n\t * This method checks the request for the handshake with the Shopware Shop.\n\t * if it's valid a Shop will be created, and a proof will be responded with a confirmation url.\n\t * then the Shop will call the confirmation url, and this should be handled by the authorizeCallback method to finish the handshake.\n\t */\n\tpublic async authorize(req: Request): Promise<Response> {\n\t\tconst url = new URL(req.url);\n\n\t\tif (\n\t\t\t!url.searchParams.has(\"shop-url\") ||\n\t\t\t!req.headers.has(\"shopware-app-signature\") ||\n\t\t\t!url.searchParams.has(\"shop-id\") ||\n\t\t\t!url.searchParams.has(\"timestamp\")\n\t\t) {\n\t\t\treturn new InvalidRequestResponse(\"Invalid Request\", 400);\n\t\t}\n\n\t\tconst shopId = url.searchParams.get(\"shop-id\") as string;\n\t\tconst shopUrl = url.searchParams.get(\"shop-url\") as string;\n\t\tconst timestamp = url.searchParams.get(\"timestamp\") as string;\n\n\t\tconst beforeRegistrationEvent = new BeforeRegistrationEvent(req, shopId, shopUrl);\n\t\tthis.app.hooks.publish('onBeforeRegistrationEvent', beforeRegistrationEvent);\n\n\t\tif (beforeRegistrationEvent.reason) {\n\t\t\treturn new InvalidRequestResponse(beforeRegistrationEvent.reason, 400);\n\t\t}\n\n\t\tconst v = await this.app.signer.verify(\n\t\t\treq.headers.get(\"shopware-app-signature\") as string,\n\t\t\t`shop-id=${shopId}&shop-url=${shopUrl}×tamp=${timestamp}`,\n\t\t\tthis.app.cfg.appSecret,\n\t\t);\n\n\t\tif (!v) {\n\t\t\treturn new InvalidRequestResponse(\"Cannot validate app signature\");\n\t\t}\n\n\t\tconst shopSecret = randomString();\n\t\tconst sanitizedShopUrl = shopUrl\n\t\t\t.replace(/([^:])(\\/\\/+)/g, \"$1/\")\n\t\t\t.replace(/\\/+$/, \"\");\n\n\t\tawait this.app.repository.createShop(shopId, sanitizedShopUrl, shopSecret);\n\n\t\treturn new Response(\n\t\t\tJSON.stringify({\n\t\t\t\tproof: await this.app.signer.sign(\n\t\t\t\t\tshopId + shopUrl + this.app.cfg.appName,\n\t\t\t\t\tthis.app.cfg.appSecret,\n\t\t\t\t),\n\t\t\t\tsecret: shopSecret,\n\t\t\t\tconfirmation_url: this.app.cfg.authorizeCallbackUrl,\n\t\t\t}),\n\t\t\t{\n\t\t\t\theaders: {\n\t\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t\t},\n\t\t\t},\n\t\t);\n\t}\n\n\t/**\n\t * This method is called by the Shopware Shop to confirm the handshake.\n\t * It will update the shop with the given oauth2 credentials.\n\t */\n\tpublic async authorizeCallback(req: Request): Promise<Response> {\n\t\tconst bodyContent = await req.text();\n\n\t\tconst body = JSON.parse(bodyContent);\n\n\t\tif (\n\t\t\ttypeof body.shopId !== \"string\" ||\n\t\t\ttypeof body.apiKey !== \"string\" ||\n\t\t\ttypeof body.secretKey !== \"string\" ||\n\t\t\t!req.headers.has(\"shopware-shop-signature\")\n\t\t) {\n\t\t\treturn new InvalidRequestResponse(\"Invalid Request\", 400);\n\t\t}\n\n\t\tconst shop = await this.app.repository.getShopById(body.shopId as string);\n\n\t\tif (shop === null) {\n\t\t\treturn new InvalidRequestResponse(\"Invalid shop given\");\n\t\t}\n\n\t\tconst v = await this.app.signer.verify(\n\t\t\treq.headers.get(\"shopware-shop-signature\") as string,\n\t\t\tbodyContent,\n\t\t\tshop.getShopSecret(),\n\t\t);\n\n\t\tif (!v) {\n\t\t\t// Shop has failed the verification. Delete it from our DB.\n\t\t\tawait this.app.repository.deleteShop(shop.getShopId());\n\n\t\t\treturn new InvalidRequestResponse(\"Cannot validate app signature\");\n\t\t}\n\n\t\tshop.setShopCredentials(body.apiKey, body.secretKey);\n\n\t\tconst event = new ShopAuthorizeEvent(req, shop);\n\t\tawait this.app.hooks.publish(\"onAuthorize\", event);\n\n\t\tif (event.reason) {\n\t\t\tawait this.app.repository.deleteShop(shop.getShopId());\n\n\t\t\treturn new InvalidRequestResponse(event.reason, 403);\n\t\t}\n\n\t\tawait this.app.repository.updateShop(shop);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware Shop to set the shop active.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appActivate\" url=\"http://localhost:3000/app/activate\" event=\"app.activated\"/>\n\t * </webhooks>\n\t */\n\tpublic async activate(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI(req);\n\n\t\tconst event = new AppActivateEvent(req, ctx.shop);\n\t\tawait this.app.hooks.publish(\"onAppActivate\", event);\n\n\t\tctx.shop.setShopActive(true);\n\n\t\tawait this.app.repository.updateShop(ctx.shop);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware when the app was installed.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appInstall\" url=\"http://localhost:3000/app/install\" event=\"app.installed\"/>\n\t * </webhooks>\n\t */\n\tpublic async install(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI<{\n\t\t\tdata: { payload: { appVersion: string } };\n\t\t}>(req);\n\n\t\tconst event = new AppInstallEvent(\n\t\t\treq,\n\t\t\tctx.shop,\n\t\t\tctx.payload?.data?.payload?.appVersion ?? null,\n\t\t);\n\t\tawait this.app.hooks.publish(\"onAppInstall\", event);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware Shop to set the shop in-active.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appDeactivated\" url=\"http://localhost:3000/app/deactivated\" event=\"app.deactivated\"/>\n\t * </webhooks>\n\t */\n\tpublic async deactivate(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI(req);\n\n\t\tconst event = new AppDeactivateEvent(req, ctx.shop);\n\t\tawait this.app.hooks.publish(\"onAppDeactivate\", event);\n\n\t\tctx.shop.setShopActive(false);\n\n\t\tawait this.app.repository.updateShop(ctx.shop);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware when the app was updated.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appUpdated\" url=\"http://localhost:3000/app/update\" event=\"app.updated\"/>\n\t * </webhooks>\n\t */\n\tpublic async update(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI<{\n\t\t\tdata: { payload: { appVersion: string } };\n\t\t}>(req);\n\n\t\tconst event = new AppUpdateEvent(\n\t\t\treq,\n\t\t\tctx.shop,\n\t\t\tctx.payload?.data?.payload?.appVersion ?? null,\n\t\t);\n\t\tawait this.app.hooks.publish(\"onAppUpdate\", event);\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n\n\t/**\n\t * This method should be called by Shopware Shop to delete the app.\n\t *\n\t * <webhooks>\n\t * <webhook name=\"appDelete\" url=\"http://localhost:3000/app/delete\" event=\"app.deleted\"/>\n\t * </webhooks>\n\t */\n\tpublic async delete(req: Request): Promise<Response> {\n\t\tconst ctx = await this.app.contextResolver.fromAPI<{\n\t\t\tdata: { payload: { keepUserData?: boolean } };\n\t\t}>(req);\n\n\t\tconst event = new AppUninstallEvent(\n\t\t\treq,\n\t\t\tctx.shop,\n\t\t\tctx.payload?.data?.payload?.keepUserData ?? null,\n\t\t);\n\t\tawait this.app.hooks.publish(\"onAppUninstall\", event);\n\n\t\tif (event.keepUserData === false) {\n\t\t\tawait this.app.repository.deleteShop(ctx.shop.getShopId());\n\t\t}\n\n\t\treturn new Response(null, { status: 204 });\n\t}\n}\n\nexport function randomString(length = 120) {\n\tlet result = \"\";\n\tconst characters =\n\t\t\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\tconst charactersLength = characters.length;\n\tfor (let i = 0; i < length; i++) {\n\t\tresult += characters.charAt(Math.floor(Math.random() * charactersLength));\n\t}\n\n\treturn result;\n}\n\nclass InvalidRequestResponse extends Response {\n\tconstructor(message: string, status = 401) {\n\t\tsuper(JSON.stringify({ message }), {\n\t\t\tstatus,\n\t\t\theaders: {\n\t\t\t\t\"content-type\": \"application/json\",\n\t\t\t},\n\t\t});\n\t}\n}\n\nexport class ShopAuthorizeEvent<Shop extends ShopInterface = ShopInterface> {\n\tprivate reject: string | null = null;\n\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t) {}\n\n\tpublic rejectRegistration(reason: string) {\n\t\tthis.reject = reason;\n\t}\n\n\tpublic get reason() {\n\t\treturn this.reject;\n\t}\n}\n\nexport class AppInstallEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t\tpublic appVersion: string | null = null,\n\t) {}\n}\n\nexport class AppActivateEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t) {}\n}\n\nexport class AppDeactivateEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t) {}\n}\n\nexport class AppUpdateEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t\tpublic appVersion: string | null = null,\n\t) {}\n}\n\nexport class AppUninstallEvent<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shop: Shop,\n\t\tpublic keepUserData: boolean | null = null,\n\t) {}\n}\n\nexport class BeforeRegistrationEvent<Shop extends ShopInterface = ShopInterface> {\n\tprivate cancellationReason: string | null = null;\n\t\n\tconstructor(\n\t\tpublic request: Request,\n\t\tpublic shopId: string,\n\t\tpublic shopUrl: string,\n\t) {}\n\n\tpublic rejectRegistration(reason: string) {\n\t\tthis.cancellationReason = reason;\n\t}\n\n\tpublic get reason() {\n\t\treturn this.cancellationReason;\n\t}\n}\n"]}
|