@shopware-ag/app-server-sdk 1.1.29 → 2.0.0
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/app.d.ts +8 -2
- package/dist/commonjs/app.d.ts.map +1 -1
- package/dist/commonjs/app.js +3 -0
- package/dist/commonjs/app.js.map +1 -1
- package/dist/commonjs/context-resolver.d.ts.map +1 -1
- package/dist/commonjs/context-resolver.js +2 -8
- package/dist/commonjs/context-resolver.js.map +1 -1
- package/dist/commonjs/dual-signature-verifier.d.ts +31 -0
- package/dist/commonjs/dual-signature-verifier.d.ts.map +1 -0
- package/dist/commonjs/dual-signature-verifier.js +136 -0
- package/dist/commonjs/dual-signature-verifier.js.map +1 -0
- package/dist/commonjs/integration/better-sqlite3.d.ts.map +1 -1
- package/dist/commonjs/integration/better-sqlite3.js +35 -11
- package/dist/commonjs/integration/better-sqlite3.js.map +1 -1
- package/dist/commonjs/integration/bun-sqlite.d.ts.map +1 -1
- package/dist/commonjs/integration/bun-sqlite.js +40 -10
- package/dist/commonjs/integration/bun-sqlite.js.map +1 -1
- package/dist/commonjs/integration/cloudflare-kv.d.ts.map +1 -1
- package/dist/commonjs/integration/cloudflare-kv.js +24 -1
- package/dist/commonjs/integration/cloudflare-kv.js.map +1 -1
- package/dist/commonjs/integration/deno-kv.d.ts.map +1 -1
- package/dist/commonjs/integration/deno-kv.js +18 -0
- package/dist/commonjs/integration/deno-kv.js.map +1 -1
- package/dist/commonjs/integration/dynamodb.d.ts.map +1 -1
- package/dist/commonjs/integration/dynamodb.js +31 -1
- package/dist/commonjs/integration/dynamodb.js.map +1 -1
- package/dist/commonjs/integration/hono.d.ts +6 -0
- package/dist/commonjs/integration/hono.d.ts.map +1 -1
- package/dist/commonjs/integration/hono.js +1 -0
- package/dist/commonjs/integration/hono.js.map +1 -1
- package/dist/commonjs/mod.d.ts +2 -0
- package/dist/commonjs/mod.d.ts.map +1 -1
- package/dist/commonjs/mod.js +3 -1
- package/dist/commonjs/mod.js.map +1 -1
- package/dist/commonjs/registration.d.ts +4 -0
- package/dist/commonjs/registration.d.ts.map +1 -1
- package/dist/commonjs/registration.js +55 -11
- package/dist/commonjs/registration.js.map +1 -1
- package/dist/commonjs/repository.d.ts +53 -1
- package/dist/commonjs/repository.d.ts.map +1 -1
- package/dist/commonjs/repository.js +64 -1
- package/dist/commonjs/repository.js.map +1 -1
- package/dist/esm/app.d.ts +8 -2
- package/dist/esm/app.d.ts.map +1 -1
- package/dist/esm/app.js +3 -0
- package/dist/esm/app.js.map +1 -1
- package/dist/esm/context-resolver.d.ts.map +1 -1
- package/dist/esm/context-resolver.js +2 -8
- package/dist/esm/context-resolver.js.map +1 -1
- package/dist/esm/dual-signature-verifier.d.ts +31 -0
- package/dist/esm/dual-signature-verifier.d.ts.map +1 -0
- package/dist/esm/dual-signature-verifier.js +132 -0
- package/dist/esm/dual-signature-verifier.js.map +1 -0
- package/dist/esm/integration/better-sqlite3.d.ts.map +1 -1
- package/dist/esm/integration/better-sqlite3.js +35 -11
- package/dist/esm/integration/better-sqlite3.js.map +1 -1
- package/dist/esm/integration/bun-sqlite.d.ts.map +1 -1
- package/dist/esm/integration/bun-sqlite.js +40 -10
- package/dist/esm/integration/bun-sqlite.js.map +1 -1
- package/dist/esm/integration/cloudflare-kv.d.ts.map +1 -1
- package/dist/esm/integration/cloudflare-kv.js +24 -1
- package/dist/esm/integration/cloudflare-kv.js.map +1 -1
- package/dist/esm/integration/deno-kv.d.ts.map +1 -1
- package/dist/esm/integration/deno-kv.js +18 -0
- package/dist/esm/integration/deno-kv.js.map +1 -1
- package/dist/esm/integration/dynamodb.d.ts.map +1 -1
- package/dist/esm/integration/dynamodb.js +31 -1
- package/dist/esm/integration/dynamodb.js.map +1 -1
- package/dist/esm/integration/hono.d.ts +6 -0
- package/dist/esm/integration/hono.d.ts.map +1 -1
- package/dist/esm/integration/hono.js +1 -0
- package/dist/esm/integration/hono.js.map +1 -1
- package/dist/esm/mod.d.ts +2 -0
- package/dist/esm/mod.d.ts.map +1 -1
- package/dist/esm/mod.js +1 -0
- package/dist/esm/mod.js.map +1 -1
- package/dist/esm/registration.d.ts +4 -0
- package/dist/esm/registration.d.ts.map +1 -1
- package/dist/esm/registration.js +55 -11
- package/dist/esm/registration.js.map +1 -1
- package/dist/esm/repository.d.ts +53 -1
- package/dist/esm/repository.d.ts.map +1 -1
- package/dist/esm/repository.js +64 -1
- package/dist/esm/repository.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloudflare-kv.js","sourceRoot":"","sources":["../../../src/integration/cloudflare-kv.ts"],"names":[],"mappings":";;;AAAA,mDAAmD;AACnD,oDAA8C;AAI9C;;;GAGG;AACH,MAAa,wBAAwB;IAGhB;IAApB,YAAoB,OAAoB;QAApB,YAAO,GAAP,OAAO,CAAa;QACvC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAU,EAAE,GAAW,EAAE,MAAc;QACvD,MAAM,OAAO,CAAC,GAAG,CAAC;
|
|
1
|
+
{"version":3,"file":"cloudflare-kv.js","sourceRoot":"","sources":["../../../src/integration/cloudflare-kv.ts"],"names":[],"mappings":"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","sourcesContent":["/// <reference types=\"@cloudflare/workers-types\" />\nimport { SimpleShop } from \"../repository.js\";\nimport type { ShopRepositoryInterface } from \"../repository.js\";\nimport type { HttpClientTokenCacheInterface, HttpClientTokenCacheItem } from \"../http-client.js\";\n\n/**\n * Cloudflare KV integration\n * @module\n */\nexport class CloudflareShopRepository\n\timplements ShopRepositoryInterface<SimpleShop>\n{\n\tconstructor(private storage: KVNamespace) {\n\t\tthis.storage = storage;\n\t}\n\n\tasync createShop(id: string, url: string, secret: string): Promise<void> {\n\t\tawait Promise.all([\n\t\t\tthis.storage.put(id, this.serializeShop(new SimpleShop(id, url, secret))),\n\t\t\tthis.storage.put(`${id}_active`, JSON.stringify(false)),\n\t\t])\n\t}\n\n\tasync deleteShop(id: string): Promise<void> {\n\t\tawait Promise.all([\n\t\t\tthis.storage.delete(id),\n\t\t\tthis.storage.delete(`${id}_active`),\n\t\t\tthis.storage.delete(`${id}_credentials`)\n\t\t])\n\t}\n\n\tasync getShopById(id: string): Promise<SimpleShop | null> {\n\t\tconst kvValues = await Promise.all([\n\t\t\tthis.storage.get(id),\n\t\t\tthis.storage.get(`${id}_active`),\n\t\t\tthis.storage.get(`${id}_credentials`)\n\t\t]);\n\n\t\tif (kvValues[0] === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn this.deserializeShop(kvValues);\n\t}\n\n\tasync updateShop(shop: SimpleShop): Promise<void> {\n\t\tawait Promise.all([\n\t\t\tthis.storage.put(shop.getShopId(), this.serializeShop(shop)),\n\t\t\tthis.storage.put(`${shop.getShopId()}_active`, JSON.stringify(shop.getShopActive())),\n\t\t\tthis.storage.put(`${shop.getShopId()}_credentials`, JSON.stringify({ clientId: shop.getShopClientId(), clientSecret: shop.getShopClientSecret() }))\n\t\t])\n\t}\n\n\tprotected serializeShop(shop: SimpleShop): string {\n\t\treturn JSON.stringify({\n\t\t\t...shop,\n\t\t\tsecretsRotatedAt: shop.getSecretsRotatedAt()\n\t\t\t\t? shop.getSecretsRotatedAt()!.getTime()\n\t\t\t\t: null,\n\t\t});\n\t}\n\n\tprotected deserializeShop(data: (string | null)[]): SimpleShop {\n\t\tconst obj = JSON.parse(data[0]!);\n\n\t\tconst shop = new SimpleShop(\n\t\t\tobj.shopId || \"\",\n\t\t\tobj.shopUrl || \"\",\n\t\t\tobj.shopSecret || \"\",\n\t\t);\n\n\t\tshop.setShopCredentials(obj.shopClientId || \"\", obj.shopClientSecret || \"\");\n\n\t\tif (obj.shopActive === undefined) {\n\t\t\tobj.shopActive = true;\n\t\t}\n\n\t\tshop.setShopActive(obj.shopActive);\n\n\t\tif (obj.pendingShopUrl) {\n\t\t\tshop.setPendingShopUrl(obj.pendingShopUrl);\n\t\t}\n\n\t\tif (obj.pendingShopSecret) {\n\t\t\tshop.setPendingShopSecret(obj.pendingShopSecret);\n\t\t}\n\n\t\tif (obj.previousShopSecret) {\n\t\t\tshop.setPreviousShopSecret(obj.previousShopSecret);\n\t\t}\n\n\t\tif (obj.secretsRotatedAt) {\n\t\t\tshop.setSecretsRotatedAt(new Date(Number(obj.secretsRotatedAt)));\n\t\t}\n\n\t\tif (data[1] !== null) {\n\t\t\tshop.setShopActive(JSON.parse(data[1]!));\n\t\t}\n\n\t\tif (data[2] !== null) {\n\t\t\tconst credentials = JSON.parse(data[2]!);\n\t\t\tshop.setShopCredentials(credentials.clientId || \"\", credentials.clientSecret || \"\");\n\t\t}\n\n\t\tif (obj.verified_with_double_signatures === 1) {\n\t\t\tshop.setVerifiedWithDoubleSignature();\n\t\t}\n\n\t\tif (obj.registrationConfirmed === 1) {\n\t\t\tshop.setRegistrationConfirmed();\n\t\t}\n\n\t\treturn shop;\n\t}\n}\n\n/**\n * Cloudflare KV implementation for HttpClientTokenCacheInterface\n * @module\n */\nexport class CloudflareHttpClientTokenCache implements HttpClientTokenCacheInterface {\n\tconstructor(private storage: KVNamespace) {\n\t\tthis.storage = storage;\n\t}\n\n\t/**\n\t * Get a token from KV storage for the given shop ID\n\t */\n\tasync getToken(shopId: string): Promise<HttpClientTokenCacheItem | null> {\n\t\tconst tokenData = await this.storage.get(`token_${shopId}`);\n\t\t\n\t\tif (tokenData === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\ttry {\n\t\t\tconst parsedToken = JSON.parse(tokenData);\n\t\t\t// Convert the ISO string back to a Date object\n\t\t\treturn {\n\t\t\t\ttoken: parsedToken.token,\n\t\t\t\texpiresIn: new Date(parsedToken.expiresIn)\n\t\t\t};\n\t\t} catch (error) {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Store a token in KV storage for the given shop ID\n\t */\n\tasync setToken(shopId: string, token: HttpClientTokenCacheItem): Promise<void> {\n\t\t// Convert the Date object to an ISO string for storage\n\t\tconst tokenData = {\n\t\t\ttoken: token.token,\n\t\t\texpiresIn: token.expiresIn.toISOString()\n\t\t};\n\t\t\n\t\tawait this.storage.put(`token_${shopId}`, JSON.stringify(tokenData));\n\t}\n\n\t/**\n\t * Remove a token from KV storage for the given shop ID\n\t */\n\tasync clearToken(shopId: string): Promise<void> {\n\t\tawait this.storage.delete(`token_${shopId}`);\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deno-kv.d.ts","sourceRoot":"","sources":["../../../src/integration/deno-kv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAEhE;;;GAGG;AAEH;;GAEG;AACH,qBAAa,gBAAiB,YAAW,uBAAuB,CAAC,UAAU,CAAC;IAC/D,OAAO,CAAC,SAAS;gBAAT,SAAS,SAAU;IAEjC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOlE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"deno-kv.d.ts","sourceRoot":"","sources":["../../../src/integration/deno-kv.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAEhE;;;GAGG;AAEH;;GAEG;AACH,qBAAa,gBAAiB,YAAW,uBAAuB,CAAC,UAAU,CAAC;IAC/D,OAAO,CAAC,SAAS;gBAAT,SAAS,SAAU;IAEjC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOlE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IA+DnD,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAO3C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAM3C"}
|
|
@@ -35,6 +35,24 @@ class DenoKVRepository {
|
|
|
35
35
|
if (data.shopClientId && data.shopClientSecret) {
|
|
36
36
|
shop.setShopCredentials(data.shopClientId, data.shopClientSecret);
|
|
37
37
|
}
|
|
38
|
+
if (data.pendingShopUrl) {
|
|
39
|
+
shop.setPendingShopUrl(data.pendingShopUrl);
|
|
40
|
+
}
|
|
41
|
+
if (data.pendingShopSecret) {
|
|
42
|
+
shop.setPendingShopSecret(data.pendingShopSecret);
|
|
43
|
+
}
|
|
44
|
+
if (data.previousShopSecret) {
|
|
45
|
+
shop.setPreviousShopSecret(data.previousShopSecret);
|
|
46
|
+
}
|
|
47
|
+
if (data.secretsRotatedAt) {
|
|
48
|
+
shop.setSecretsRotatedAt(new Date(Number(data.secretsRotatedAt)));
|
|
49
|
+
}
|
|
50
|
+
if (data.verifiedWithDoubleSignature) {
|
|
51
|
+
shop.setVerifiedWithDoubleSignature();
|
|
52
|
+
}
|
|
53
|
+
if (data.registrationConfirmed) {
|
|
54
|
+
shop.setRegistrationConfirmed();
|
|
55
|
+
}
|
|
38
56
|
return shop;
|
|
39
57
|
}
|
|
40
58
|
async updateShop(shop) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deno-kv.js","sourceRoot":"","sources":["../../../src/integration/deno-kv.ts"],"names":[],"mappings":";;;AAAA,oDAA8C;AAG9C;;;GAGG;AAEH;;GAEG;AACH,MAAa,gBAAgB;IACR;IAApB,YAAoB,YAAY,OAAO;QAAnB,cAAS,GAAT,SAAS,CAAU;IAAG,CAAC;IAE3C,KAAK,CAAC,UAAU,CAAC,EAAU,EAAE,GAAW,EAAE,MAAc;QACvD,aAAa;QACb,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAE/B,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,IAAI,0BAAU,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,EAAU;QAC3B,aAAa;QACb,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;QAE/B,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;QAElD,IAAI,MAAM,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;YACzB,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"deno-kv.js","sourceRoot":"","sources":["../../../src/integration/deno-kv.ts"],"names":[],"mappings":"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","sourcesContent":["import { SimpleShop } from \"../repository.js\";\nimport type { ShopRepositoryInterface } from \"../repository.js\";\n\n/**\n * Deno KV integration\n * @module\n */\n\n/**\n * DenoKVRepository is a ShopRepositoryInterface implementation that uses the Deno KV storage to save the shop data\n */\nexport class DenoKVRepository implements ShopRepositoryInterface<SimpleShop> {\n\tconstructor(private namespace = \"shops\") {}\n\n\tasync createShop(id: string, url: string, secret: string): Promise<void> {\n\t\t// @ts-ignore\n\t\tconst kv = await Deno.openKv();\n\n\t\tawait kv.set([this.namespace, id], new SimpleShop(id, url, secret));\n\t}\n\n\tasync getShopById(id: string): Promise<SimpleShop | null> {\n\t\t// @ts-ignore\n\t\tconst kv = await Deno.openKv();\n\n\t\tconst result = await kv.get([this.namespace, id]);\n\n\t\tif (result.key === null) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst data = result.value as {\n\t\t\tshopId: string;\n\t\t\tshopActive: boolean | undefined;\n\t\t\tshopUrl: string;\n\t\t\tshopSecret: string;\n\t\t\tshopClientId: string | null;\n\t\t\tshopClientSecret: string | null;\n\t\t\tpendingShopUrl: string | null;\n\t\t\tpendingShopSecret: string | null;\n\t\t\tpreviousShopSecret: string | null;\n\t\t\tsecretsRotatedAt: number | null;\n\t\t\tverifiedWithDoubleSignature: boolean | undefined;\n\t\t\tregistrationConfirmed: boolean | undefined;\n\t\t};\n\n\t\tif (data.shopActive === undefined) {\n\t\t\tdata.shopActive = true;\n\t\t}\n\n\t\tconst shop = new SimpleShop(data.shopId, data.shopUrl, data.shopSecret);\n\t\tshop.setShopActive(data.shopActive);\n\n\t\tif (data.shopClientId && data.shopClientSecret) {\n\t\t\tshop.setShopCredentials(data.shopClientId, data.shopClientSecret);\n\t\t}\n\n\t\tif (data.pendingShopUrl) {\n\t\t\tshop.setPendingShopUrl(data.pendingShopUrl);\n\t\t}\n\n\t\tif (data.pendingShopSecret) {\n\t\t\tshop.setPendingShopSecret(data.pendingShopSecret);\n\t\t}\n\n\t\tif (data.previousShopSecret) {\n\t\t\tshop.setPreviousShopSecret(data.previousShopSecret);\n\t\t}\n\n\t\tif (data.secretsRotatedAt) {\n\t\t\tshop.setSecretsRotatedAt(new Date(Number(data.secretsRotatedAt)));\n\t\t}\n\n\t\tif (data.verifiedWithDoubleSignature) {\n\t\t\tshop.setVerifiedWithDoubleSignature();\n\t\t}\n\n\t\tif (data.registrationConfirmed) {\n\t\t\tshop.setRegistrationConfirmed();\n\t\t}\n\n\t\treturn shop;\n\t}\n\n\tasync updateShop(shop: SimpleShop): Promise<void> {\n\t\t// @ts-ignore\n\t\tconst kv = await Deno.openKv();\n\n\t\tawait kv.set([this.namespace, shop.getShopId()], shop);\n\t}\n\n\tasync deleteShop(id: string): Promise<void> {\n\t\t// @ts-ignore\n\t\tconst kv = await Deno.openKv();\n\n\t\tawait kv.delete([this.namespace, id]);\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamodb.d.ts","sourceRoot":"","sources":["../../../src/integration/dynamodb.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAEN,sBAAsB,EAItB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,uBAAuB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE5E,qBAAa,kBAAmB,YAAW,uBAAuB,CAAC,UAAU,CAAC;IAC7E,SAAS,EAAE,sBAAsB,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;gBAEN,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM;IAK/C,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"dynamodb.d.ts","sourceRoot":"","sources":["../../../src/integration/dynamodb.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAEN,sBAAsB,EAItB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,uBAAuB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE5E,qBAAa,kBAAmB,YAAW,uBAAuB,CAAC,UAAU,CAAC;IAC7E,SAAS,EAAE,sBAAsB,CAAC;IAClC,SAAS,EAAE,MAAM,CAAC;gBAEN,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM;IAK/C,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBlE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IA4DnD,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B3C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAU3C"}
|
|
@@ -20,6 +20,12 @@ class DynamoDBRepository {
|
|
|
20
20
|
secret: secret,
|
|
21
21
|
clientId: null,
|
|
22
22
|
clientSecret: null,
|
|
23
|
+
pendingShopUrl: null,
|
|
24
|
+
pendingShopSecret: null,
|
|
25
|
+
previousShopSecret: null,
|
|
26
|
+
secretsRotatedAt: null,
|
|
27
|
+
verifiedWithDoubleSignature: null,
|
|
28
|
+
registrationConfirmed: false,
|
|
23
29
|
},
|
|
24
30
|
});
|
|
25
31
|
await this.docClient.send(cmd);
|
|
@@ -43,13 +49,31 @@ class DynamoDBRepository {
|
|
|
43
49
|
if (response.Item.clientId) {
|
|
44
50
|
shop.setShopCredentials(response.Item.clientId, response.Item.clientSecret);
|
|
45
51
|
}
|
|
52
|
+
if (response.Item.pendingShopUrl) {
|
|
53
|
+
shop.setPendingShopUrl(response.Item.pendingShopUrl);
|
|
54
|
+
}
|
|
55
|
+
if (response.Item.pendingShopSecret) {
|
|
56
|
+
shop.setPendingShopSecret(response.Item.pendingShopSecret);
|
|
57
|
+
}
|
|
58
|
+
if (response.Item.previousShopSecret) {
|
|
59
|
+
shop.setPreviousShopSecret(response.Item.previousShopSecret);
|
|
60
|
+
}
|
|
61
|
+
if (response.Item.secretsRotatedAt) {
|
|
62
|
+
shop.setSecretsRotatedAt(new Date(Number(response.Item.secretsRotatedAt)));
|
|
63
|
+
}
|
|
64
|
+
if (response.Item.verifiedWithDoubleSignature) {
|
|
65
|
+
shop.setVerifiedWithDoubleSignature();
|
|
66
|
+
}
|
|
67
|
+
if (response.Item.registrationConfirmed) {
|
|
68
|
+
shop.setRegistrationConfirmed();
|
|
69
|
+
}
|
|
46
70
|
return shop;
|
|
47
71
|
}
|
|
48
72
|
async updateShop(shop) {
|
|
49
73
|
const cmd = new lib_dynamodb_1.UpdateCommand({
|
|
50
74
|
TableName: this.tableName,
|
|
51
75
|
Key: { id: shop.getShopId() },
|
|
52
|
-
UpdateExpression: "SET active = :active, #u = :url, secret = :secret, clientId = :clientId, clientSecret = :clientSecret",
|
|
76
|
+
UpdateExpression: "SET active = :active, #u = :url, secret = :secret, clientId = :clientId, clientSecret = :clientSecret, pendingShopUrl = :pendingShopUrl, pendingShopSecret = :pendingShopSecret, previousShopSecret = :previousShopSecret, secretsRotatedAt = :secretsRotatedAt, verifiedWithDoubleSignature = :verifiedWithDoubleSignature, registrationConfirmed = :registrationConfirmed",
|
|
53
77
|
ExpressionAttributeNames: {
|
|
54
78
|
"#u": "url",
|
|
55
79
|
},
|
|
@@ -59,6 +83,12 @@ class DynamoDBRepository {
|
|
|
59
83
|
":secret": shop.getShopSecret(),
|
|
60
84
|
":clientId": shop.getShopClientId(),
|
|
61
85
|
":clientSecret": shop.getShopClientSecret(),
|
|
86
|
+
":pendingShopUrl": shop.getPendingShopUrl(),
|
|
87
|
+
":pendingShopSecret": shop.getPendingShopSecret(),
|
|
88
|
+
":previousShopSecret": shop.getPreviousShopSecret(),
|
|
89
|
+
":secretsRotatedAt": shop.getSecretsRotatedAt()?.getTime() ?? null,
|
|
90
|
+
":verifiedWithDoubleSignature": shop.hasVerifiedWithDoubleSignature(),
|
|
91
|
+
":registrationConfirmed": shop.isRegistrationConfirmed(),
|
|
62
92
|
},
|
|
63
93
|
});
|
|
64
94
|
await this.docClient.send(cmd);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dynamodb.js","sourceRoot":"","sources":["../../../src/integration/dynamodb.ts"],"names":[],"mappings":";;;AACA,wDAM+B;AAC/B,oDAA4E;AAE5E,MAAa,kBAAkB;IAC9B,SAAS,CAAyB;IAClC,SAAS,CAAS;IAElB,YAAY,MAAsB,EAAE,SAAiB;QACpD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,qCAAsB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtD,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAU,EAAE,GAAW,EAAE,MAAc;QACvD,MAAM,GAAG,GAAG,IAAI,yBAAU,CAAC;YAC1B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,IAAI,EAAE;gBACL,EAAE,EAAE,EAAE;gBACN,MAAM,EAAE,KAAK;gBACb,GAAG,EAAE,GAAG;gBACR,MAAM,EAAE,MAAM;gBACd,QAAQ,EAAE,IAAI;gBACd,YAAY,EAAE,IAAI;
|
|
1
|
+
{"version":3,"file":"dynamodb.js","sourceRoot":"","sources":["../../../src/integration/dynamodb.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DynamoDBClient } from \"@aws-sdk/client-dynamodb\";\nimport {\n\tDeleteCommand,\n\tDynamoDBDocumentClient,\n\tGetCommand,\n\tPutCommand,\n\tUpdateCommand,\n} from \"@aws-sdk/lib-dynamodb\";\nimport { type ShopRepositoryInterface, SimpleShop } from \"../repository.js\";\n\nexport class DynamoDBRepository implements ShopRepositoryInterface<SimpleShop> {\n\tdocClient: DynamoDBDocumentClient;\n\ttableName: string;\n\n\tconstructor(client: DynamoDBClient, tableName: string) {\n\t\tthis.tableName = tableName;\n\t\tthis.docClient = DynamoDBDocumentClient.from(client);\n\t}\n\n\tasync createShop(id: string, url: string, secret: string): Promise<void> {\n\t\tconst cmd = new PutCommand({\n\t\t\tTableName: this.tableName,\n\t\t\tItem: {\n\t\t\t\tid: id,\n\t\t\t\tactive: false,\n\t\t\t\turl: url,\n\t\t\t\tsecret: secret,\n\t\t\t\tclientId: null,\n\t\t\t\tclientSecret: null,\n\t\t\t\tpendingShopUrl: null,\n\t\t\t\tpendingShopSecret: null,\n\t\t\t\tpreviousShopSecret: null,\n\t\t\t\tsecretsRotatedAt: null,\n\t\t\t\tverifiedWithDoubleSignature: null,\n\t\t\t\tregistrationConfirmed: false,\n\t\t\t},\n\t\t});\n\n\t\tawait this.docClient.send(cmd);\n\t}\n\n\tasync getShopById(id: string): Promise<SimpleShop | null> {\n\t\tconst cmd = new GetCommand({\n\t\t\tTableName: this.tableName,\n\t\t\tKey: {\n\t\t\t\tid: id,\n\t\t\t},\n\t\t});\n\n\t\tconst response = await this.docClient.send(cmd);\n\n\t\tif (!response.Item) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst shop = new SimpleShop(\n\t\t\tresponse.Item.id,\n\t\t\tresponse.Item.url,\n\t\t\tresponse.Item.secret,\n\t\t);\n\n\t\tif (response.Item.active === undefined) {\n\t\t\tresponse.Item.active = true;\n\t\t}\n\n\t\tshop.setShopActive(response.Item.active);\n\n\t\tif (response.Item.clientId) {\n\t\t\tshop.setShopCredentials(\n\t\t\t\tresponse.Item.clientId,\n\t\t\t\tresponse.Item.clientSecret,\n\t\t\t);\n\t\t}\n\n\t\tif (response.Item.pendingShopUrl) {\n\t\t\tshop.setPendingShopUrl(response.Item.pendingShopUrl);\n\t\t}\n\n\t\tif (response.Item.pendingShopSecret) {\n\t\t\tshop.setPendingShopSecret(response.Item.pendingShopSecret);\n\t\t}\n\n\t\tif (response.Item.previousShopSecret) {\n\t\t\tshop.setPreviousShopSecret(response.Item.previousShopSecret);\n\t\t}\n\n\t\tif (response.Item.secretsRotatedAt) {\n\t\t\tshop.setSecretsRotatedAt(new Date(Number(response.Item.secretsRotatedAt)));\n\t\t}\n\n\t\tif (response.Item.verifiedWithDoubleSignature) {\n\t\t\tshop.setVerifiedWithDoubleSignature();\n\t\t}\n\n\t\tif (response.Item.registrationConfirmed) {\n\t\t\tshop.setRegistrationConfirmed();\n\t\t}\n\n\t\treturn shop;\n\t}\n\n\tasync updateShop(shop: SimpleShop): Promise<void> {\n\t\tconst cmd = new UpdateCommand({\n\t\t\tTableName: this.tableName,\n\t\t\tKey: { id: shop.getShopId() },\n\t\t\tUpdateExpression:\n\t\t\t\t\"SET active = :active, #u = :url, secret = :secret, clientId = :clientId, clientSecret = :clientSecret, pendingShopUrl = :pendingShopUrl, pendingShopSecret = :pendingShopSecret, previousShopSecret = :previousShopSecret, secretsRotatedAt = :secretsRotatedAt, verifiedWithDoubleSignature = :verifiedWithDoubleSignature, registrationConfirmed = :registrationConfirmed\",\n\t\t\tExpressionAttributeNames: {\n\t\t\t\t\"#u\": \"url\",\n\t\t\t},\n\t\t\tExpressionAttributeValues: {\n\t\t\t\t\":active\": shop.getShopActive(),\n\t\t\t\t\":url\": shop.getShopUrl(),\n\t\t\t\t\":secret\": shop.getShopSecret(),\n\t\t\t\t\":clientId\": shop.getShopClientId(),\n\t\t\t\t\":clientSecret\": shop.getShopClientSecret(),\n\t\t\t\t\":pendingShopUrl\": shop.getPendingShopUrl(),\n\t\t\t\t\":pendingShopSecret\": shop.getPendingShopSecret(),\n\t\t\t\t\":previousShopSecret\": shop.getPreviousShopSecret(),\n\t\t\t\t\":secretsRotatedAt\": shop.getSecretsRotatedAt()?.getTime() ?? null,\n\t\t\t\t\":verifiedWithDoubleSignature\": shop.hasVerifiedWithDoubleSignature(),\n\t\t\t\t\":registrationConfirmed\": shop.isRegistrationConfirmed(),\n\t\t\t},\n\t\t});\n\n\t\tawait this.docClient.send(cmd);\n\t}\n\n\tasync deleteShop(id: string): Promise<void> {\n\t\tconst cmd = new DeleteCommand({\n\t\t\tTableName: this.tableName,\n\t\t\tKey: {\n\t\t\t\tid: id,\n\t\t\t},\n\t\t});\n\n\t\tawait this.docClient.send(cmd);\n\t}\n}\n"]}
|
|
@@ -27,6 +27,12 @@ interface MiddlewareConfigBase {
|
|
|
27
27
|
* @default "/app/register/confirm"
|
|
28
28
|
*/
|
|
29
29
|
registerConfirmationUrl?: string | null;
|
|
30
|
+
/**
|
|
31
|
+
* When true, registration requires both app and shop signatures during re-registration and confirmation.
|
|
32
|
+
*
|
|
33
|
+
* @default true
|
|
34
|
+
*/
|
|
35
|
+
enforceDoubleSignature?: boolean;
|
|
30
36
|
/**
|
|
31
37
|
* The relative url of the app installation lifecycle endpoint
|
|
32
38
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hono.d.ts","sourceRoot":"","sources":["../../../src/integration/hono.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAE/E,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,MAAM,CAAC;AACzD,OAAO,EAAc,KAAK,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAEnF,OAAO,QAAQ,MAAM,CAAC;IACrB,UAAU,kBAAkB;QAE3B,GAAG,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;QAC9B,IAAI,EAAE,aAAa,CAAC;QAEpB,OAAO,EAAE,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;KACzC;CACD;AAGD,UAAU,oBAAoB;IAC7B;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhC;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAExC;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE9B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE/B;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEjC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAExB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE9B;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAGD,UAAU,eAAe;IACxB;;OAEG;IACH,SAAS,EAAE,SAAS,CAAC;CACrB;AAED,UAAU,gBAAgB;IACzB;;OAEG;IACH,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,WAAW,KAAK,MAAM,CAAC,CAAC;IAC/C;;OAEG;IACH,SAAS,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,WAAW,KAAK,MAAM,CAAC,CAAC;IACjD;;OAEG;IACH,cAAc,EACX,uBAAuB,GACvB,CAAC,CAAC,CAAC,EAAE,WAAW,KAAK,uBAAuB,CAAC,CAAC;IAEjD;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB;;OAEG;IACH,oBAAoB,CAAC,EAAE,6BAA6B,GAAG,CAAC,CAAC,CAAC,EAAE,WAAW,KAAK,6BAA6B,CAAC,CAAC;IAE3G;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;CACjC;AAGD,KAAK,gBAAgB,GAClB,CAAC,oBAAoB,GAAG,eAAe,CAAC,GACxC,CAAC,oBAAoB,GAAG,gBAAgB,CAAC,CAAC;AAE7C;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"hono.d.ts","sourceRoot":"","sources":["../../../src/integration/hono.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAE/E,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,MAAM,CAAC;AACzD,OAAO,EAAc,KAAK,6BAA6B,EAAE,MAAM,mBAAmB,CAAC;AAEnF,OAAO,QAAQ,MAAM,CAAC;IACrB,UAAU,kBAAkB;QAE3B,GAAG,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;QAC9B,IAAI,EAAE,aAAa,CAAC;QAEpB,OAAO,EAAE,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;KACzC;CACD;AAGD,UAAU,oBAAoB;IAC7B;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEvB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhC;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAExC;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE9B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE/B;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAEjC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE7B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAExB;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE9B;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAGD,UAAU,eAAe;IACxB;;OAEG;IACH,SAAS,EAAE,SAAS,CAAC;CACrB;AAED,UAAU,gBAAgB;IACzB;;OAEG;IACH,OAAO,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,WAAW,KAAK,MAAM,CAAC,CAAC;IAC/C;;OAEG;IACH,SAAS,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,WAAW,KAAK,MAAM,CAAC,CAAC;IACjD;;OAEG;IACH,cAAc,EACX,uBAAuB,GACvB,CAAC,CAAC,CAAC,EAAE,WAAW,KAAK,uBAAuB,CAAC,CAAC;IAEjD;;OAEG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB;;OAEG;IACH,oBAAoB,CAAC,EAAE,6BAA6B,GAAG,CAAC,CAAC,CAAC,EAAE,WAAW,KAAK,6BAA6B,CAAC,CAAC;IAE3G;;OAEG;IACH,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,KAAK,IAAI,CAAC;CACjC;AAGD,KAAK,gBAAgB,GAClB,CAAC,oBAAoB,GAAG,eAAe,CAAC,GACxC,CAAC,oBAAoB,GAAG,gBAAgB,CAAC,CAAC;AAE7C;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,gBAAgB,QAyMnE"}
|
|
@@ -43,6 +43,7 @@ function configureAppServer(hono, cfg) {
|
|
|
43
43
|
appName: cfg.appName,
|
|
44
44
|
appSecret: cfg.appSecret,
|
|
45
45
|
authorizeCallbackUrl: appUrl + cfg.registerConfirmationUrl,
|
|
46
|
+
enforceDoubleSignature: cfg.enforceDoubleSignature ?? false,
|
|
46
47
|
}, cfg.shopRepository, cfg.httpClientTokenCache);
|
|
47
48
|
if (cfg.setup) {
|
|
48
49
|
cfg.setup(app);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hono.js","sourceRoot":"","sources":["../../../src/integration/hono.ts"],"names":[],"mappings":"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","sourcesContent":["import { getSignedCookie, setSignedCookie } from \"hono/cookie\";\nimport { AppServer } from \"../app.js\";\nimport { Context } from \"../context-resolver.js\";\nimport type { ShopInterface, ShopRepositoryInterface } from \"../repository.js\";\n\nimport type { Hono, Context as HonoContext } from \"hono\";\nimport { HttpClient, type HttpClientTokenCacheInterface } from \"../http-client.js\";\n\ndeclare module \"hono\" {\n\tinterface ContextVariableMap {\n\t\t// @ts-ignore\n\t\tapp: AppServer<ShopInterface>;\n\t\tshop: ShopInterface;\n\t\t// @ts-ignore\n\t\tcontext: Context<ShopInterface, unknown>;\n\t}\n}\n\n// Define a base interface with common parameters\ninterface MiddlewareConfigBase {\n\t/**\n\t * The URL of the app. This is the base URL of the app. This will automatically determined by default\n\t */\n\tappUrl?: string | null;\n\n\t/**\n\t * The relative url of the app registration endpoint\n\t *\n\t * @default \"/app/register\"\n\t */\n\tregistrationUrl?: string | null;\n\n\t/**\n\t * The relative url of the app registration confirmation endpoint\n\t *\n\t * @default \"/app/register/confirm\"\n\t */\n\tregisterConfirmationUrl?: string | null;\n\n\t/**\n\t * The relative url of the app installation lifecycle endpoint\n\t *\n\t * @default \"/app/install\"\n\t */\n\tappInstallUrl?: string | null;\n\n\t/**\n\t * The relative url of the app activation lifecycle endpoint\n\t *\n\t * @default \"/app/activate\"\n\t */\n\tappActivateUrl?: string | null;\n\n\t/**\n\t * The relative url of the app update lifecycle endpoint\n\t *\n\t * @default \"/app/update\"\n\t */\n\tappUpdateUrl?: string | null;\n\n\t/**\n\t * The relative url of the app deactivation lifecycle endpoint\n\t *\n\t * @default \"/app/deactivate\"\n\t */\n\tappDeactivateUrl?: string | null;\n\n\t/**\n\t * The relative url of the app deletion lifecycle endpoint\n\t *\n\t * @default \"/app/delete\"\n\t */\n\tappDeleteUrl?: string | null;\n\n\t/**\n\t * The relative url of the app scope. All requests matching this will be the signature automatically validated and the response will be signed\n\t *\n\t * @default \"/app/*\"\n\t */\n\tappPath?: string | null;\n\n\t/**\n\t * 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\n\t */\n\tappIframeEnable?: boolean;\n\n\t/**\n\t * 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\n\t *\n\t * @default \"/client-api/*\"\n\t */\n\tappIframePath?: string | null;\n\n\t/**\n\t * 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.\n\t *\n\t * @default {\n\t * \"/app/module\": \"https://my-static-client-side-app.com\"\n\t * }\n\t */\n\tappIframeRedirects?: Record<string, string>;\n}\n\n// Define specific interfaces for each configuration option\ninterface AppServerConfig {\n\t/**\n\t * An already constructed AppServer instance. When provided, other parameters like appName and appSecret are not required.\n\t */\n\tappServer: AppServer;\n}\n\ninterface ParametersConfig {\n\t/**\n\t * The name of the app\n\t */\n\tappName: string | ((c: HonoContext) => string);\n\t/**\n\t * The secret of the app. When the app is published in the Shopware Store, the Shopware Store provides this value.\n\t */\n\tappSecret: string | ((c: HonoContext) => string);\n\t/**\n\t * The repository to fetch and store the shop data\n\t */\n\tshopRepository:\n\t\t| ShopRepositoryInterface\n\t\t| ((c: HonoContext) => ShopRepositoryInterface);\n\t\n\t/**\n\t * An already constructed AppServer instance. When provided, other parameters like appName and appSecret are not required.\n\t */\n\tappServer?: undefined;\n\n\t/**\n\t * The token cache to use for the HttpClient. This is used to cache the access token for the shopware shop. If you don't provide a token cache, the HttpClient will use an in-memory cache.\n\t */\n\thttpClientTokenCache?: HttpClientTokenCacheInterface | ((c: HonoContext) => HttpClientTokenCacheInterface);\n\n\t/**\n\t * A callback to setup the app server. It will be called after the app server is created and before the first request is handled\n\t */\n\tsetup?: (app: AppServer) => void;\n}\n\n// Create a discriminated union type using intersection types\ntype MiddlewareConfig = \n\t| (MiddlewareConfigBase & AppServerConfig)\n\t| (MiddlewareConfigBase & ParametersConfig);\n\n/**\n * Configure the Hono server to handle the app registration and context resolution\n */\nexport function configureAppServer(hono: Hono, cfg: MiddlewareConfig) {\n\tlet app: AppServer | null = null;\n\n\tcfg.registrationUrl = cfg.registrationUrl || \"/app/register\";\n\tcfg.registerConfirmationUrl =\n\t\tcfg.registerConfirmationUrl || \"/app/register/confirm\";\n\tcfg.appActivateUrl = cfg.appActivateUrl || \"/app/activate\";\n\tcfg.appDeactivateUrl = cfg.appDeactivateUrl || \"/app/deactivate\";\n\tcfg.appDeleteUrl = cfg.appDeleteUrl || \"/app/delete\";\n\tcfg.appPath = cfg.appPath || \"/app/*\";\n\tcfg.appInstallUrl = cfg.appInstallUrl || \"/app/install\";\n\tcfg.appUpdateUrl = cfg.appUpdateUrl || \"/app/update\";\n\n\tcfg.appIframePath = cfg.appIframePath || \"/client-api/*\";\n\n\thono.use(\"*\", async (ctx, next) => {\n\t\tif (app === null) {\n\t\t\tif (cfg.appServer) {\n\t\t\t\tapp = cfg.appServer;\n\t\t\t} else {\n\t\t\t\tconst appUrl = cfg.appUrl || buildBaseUrl(ctx.req.url);\n\n\t\t\t\tif (typeof cfg.shopRepository === \"function\") {\n\t\t\t\t\tcfg.shopRepository = cfg.shopRepository(ctx);\n\t\t\t\t}\n\n\t\t\t\tif (typeof cfg.appName === \"function\") {\n\t\t\t\t\tcfg.appName = cfg.appName(ctx);\n\t\t\t\t}\n\n\t\t\t\tif (typeof cfg.appSecret === \"function\") {\n\t\t\t\t\tcfg.appSecret = cfg.appSecret(ctx);\n\t\t\t\t}\n\n\t\t\t\tif (typeof cfg.httpClientTokenCache === \"function\") {\n\t\t\t\t\tcfg.httpClientTokenCache = cfg.httpClientTokenCache(ctx);\n\t\t\t\t}\n\n\t\t\t\tapp = new AppServer(\n\t\t\t\t\t{\n\t\t\t\t\t\tappName: cfg.appName,\n\t\t\t\t\t\tappSecret: cfg.appSecret,\n\t\t\t\t\t\tauthorizeCallbackUrl: appUrl + cfg.registerConfirmationUrl,\n\t\t\t\t\t},\n\t\t\t\t\tcfg.shopRepository,\n\t\t\t\t\tcfg.httpClientTokenCache,\n\t\t\t\t);\n\n\t\t\t\tif (cfg.setup) {\n\t\t\t\t\tcfg.setup(app);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// @ts-ignore\n\t\tctx.set(\"app\", app);\n\n\t\tawait next();\n\t});\n\n\thono.use(cfg.appPath, async (ctx, next) => {\n\t\t// @ts-ignore\n\t\tconst app = ctx.get(\"app\") as AppServer;\n\n\t\t// Don't validate signature for registration\n\t\tif (\n\t\t\tctx.req.path === cfg.registrationUrl ||\n\t\t\tctx.req.path === cfg.registerConfirmationUrl ||\n\t\t\tctx.req.path === cfg.appActivateUrl ||\n\t\t\tctx.req.path === cfg.appDeactivateUrl ||\n\t\t\tctx.req.path === cfg.appDeleteUrl\n\t\t) {\n\t\t\tawait next();\n\t\t\treturn;\n\t\t}\n\n\t\tlet context: Context<ShopInterface, unknown>;\n\t\ttry {\n\t\t\tcontext =\n\t\t\t\tctx.req.method === \"GET\"\n\t\t\t\t\t? await app.contextResolver.fromBrowser(ctx.req.raw)\n\t\t\t\t\t: await app.contextResolver.fromAPI(ctx.req.raw);\n\t\t} catch (_e) {\n\t\t\treturn jsonResponse({ message: \"Invalid request\" }, 400);\n\t\t}\n\n\t\t// @ts-ignore\n\t\tctx.set(\"shop\", context.shop);\n\t\t// @ts-ignore\n\t\tctx.set(\"context\", context);\n\n\t\tawait next();\n\n\t\tconst cloned = ctx.res.clone();\n\n\t\tawait ctx\n\t\t\t.get(\"app\")\n\t\t\t.signer.signResponse(cloned, ctx.get(\"shop\").getShopSecret());\n\n\t\tctx.header(\n\t\t\t\"shopware-app-signature\",\n\t\t\tcloned.headers.get(\"shopware-app-signature\") as string,\n\t\t);\n\t});\n\n\thono.get(cfg.registrationUrl, async (ctx) => {\n\t\tconst app = ctx.get(\"app\");\n\n\t\treturn await app.registration.authorize(ctx.req.raw);\n\t});\n\n\thono.post(cfg.registerConfirmationUrl, async (ctx) => {\n\t\tconst app = ctx.get(\"app\");\n\n\t\treturn await app.registration.authorizeCallback(ctx.req.raw);\n\t});\n\n\thono.post(cfg.appInstallUrl, async (ctx) => {\n\t\tconst app = ctx.get(\"app\");\n\n\t\treturn await app.registration.install(ctx.req.raw);\n\t});\n\n\thono.post(cfg.appActivateUrl, async (ctx) => {\n\t\tconst app = ctx.get(\"app\");\n\n\t\treturn await app.registration.activate(ctx.req.raw);\n\t});\n\n\thono.post(cfg.appUpdateUrl, async (ctx) => {\n\t\tconst app = ctx.get(\"app\");\n\n\t\treturn await app.registration.update(ctx.req.raw);\n\t});\n\n\thono.post(cfg.appDeactivateUrl, async (ctx) => {\n\t\tconst app = ctx.get(\"app\");\n\n\t\treturn await app.registration.deactivate(ctx.req.raw);\n\t});\n\n\thono.post(cfg.appDeleteUrl, async (ctx) => {\n\t\tconst app = ctx.get(\"app\");\n\n\t\treturn await app.registration.delete(ctx.req.raw);\n\t});\n\n\tif (cfg.appIframeEnable) {\n\t\thono.use(cfg.appIframePath, async (ctx, next) => {\n\t\t\tconst shopId = await getSignedCookie(\n\t\t\t\tctx,\n\t\t\t\tctx.get(\"app\").cfg.appSecret,\n\t\t\t\t\"shop\",\n\t\t\t);\n\n\t\t\tif (!shopId) {\n\t\t\t\treturn ctx.json({ message: \"Shop not found\" }, { status: 400 });\n\t\t\t}\n\n\t\t\tconst shop = await ctx.get(\"app\").repository.getShopById(shopId);\n\n\t\t\tif (!shop) {\n\t\t\t\treturn ctx.json({ message: \"Shop not found\" }, { status: 400 });\n\t\t\t}\n\n\t\t\tctx.set(\"shop\", shop);\n\t\t\t// @ts-ignore\n\t\t\tctx.set(\"context\", new Context(shop, {}, new HttpClient(shop, ctx.get('app').httpClientTokenCache)));\n\n\t\t\tawait next();\n\t\t});\n\n\t\tfor (let [path, redirect] of Object.entries(cfg.appIframeRedirects || {})) {\n\t\t\thono.get(path, async (ctx) => {\n\t\t\t\tconst url = new URL(ctx.req.url);\n\n\t\t\t\tif (redirect.startsWith(\"/\")) {\n\t\t\t\t\turl.pathname = redirect;\n\t\t\t\t\tredirect = url.toString();\n\t\t\t\t} else {\n\t\t\t\t\tconst newUrl = new URL(redirect);\n\n\t\t\t\t\tfor (const [key, value] of url.searchParams) {\n\t\t\t\t\t\tnewUrl.searchParams.set(key, value);\n\t\t\t\t\t}\n\n\t\t\t\t\tredirect = newUrl.toString();\n\t\t\t\t}\n\n\t\t\t\tawait setSignedCookie(\n\t\t\t\t\tctx,\n\t\t\t\t\t\"shop\",\n\t\t\t\t\tctx.get(\"shop\").getShopId(),\n\t\t\t\t\tctx.get(\"app\").cfg.appSecret,\n\t\t\t\t);\n\n\t\t\t\treturn ctx.redirect(redirect);\n\t\t\t});\n\t\t}\n\t}\n}\n\nfunction jsonResponse(body: object, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t},\n\t});\n}\n\nfunction buildBaseUrl(url: string): string {\n\tconst u = new URL(url);\n\n\tlet protocol = u.protocol;\n\n\tif (typeof process !== \"undefined\" && process.env?.SHOPWARE_APP_SDK_FORCE_HTTPS) {\n\t\tprotocol = \"https:\";\n\t}\n\n\treturn `${protocol}//${u.host}`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"hono.js","sourceRoot":"","sources":["../../../src/integration/hono.ts"],"names":[],"mappings":"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","sourcesContent":["import { getSignedCookie, setSignedCookie } from \"hono/cookie\";\nimport { AppServer } from \"../app.js\";\nimport { Context } from \"../context-resolver.js\";\nimport type { ShopInterface, ShopRepositoryInterface } from \"../repository.js\";\n\nimport type { Hono, Context as HonoContext } from \"hono\";\nimport { HttpClient, type HttpClientTokenCacheInterface } from \"../http-client.js\";\n\ndeclare module \"hono\" {\n\tinterface ContextVariableMap {\n\t\t// @ts-ignore\n\t\tapp: AppServer<ShopInterface>;\n\t\tshop: ShopInterface;\n\t\t// @ts-ignore\n\t\tcontext: Context<ShopInterface, unknown>;\n\t}\n}\n\n// Define a base interface with common parameters\ninterface MiddlewareConfigBase {\n\t/**\n\t * The URL of the app. This is the base URL of the app. This will automatically determined by default\n\t */\n\tappUrl?: string | null;\n\n\t/**\n\t * The relative url of the app registration endpoint\n\t *\n\t * @default \"/app/register\"\n\t */\n\tregistrationUrl?: string | null;\n\n\t/**\n\t * The relative url of the app registration confirmation endpoint\n\t *\n\t * @default \"/app/register/confirm\"\n\t */\n\tregisterConfirmationUrl?: string | null;\n\n\t/**\n\t * When true, registration requires both app and shop signatures during re-registration and confirmation.\n\t *\n\t * @default true\n\t */\n\tenforceDoubleSignature?: boolean;\n\n\t/**\n\t * The relative url of the app installation lifecycle endpoint\n\t *\n\t * @default \"/app/install\"\n\t */\n\tappInstallUrl?: string | null;\n\n\t/**\n\t * The relative url of the app activation lifecycle endpoint\n\t *\n\t * @default \"/app/activate\"\n\t */\n\tappActivateUrl?: string | null;\n\n\t/**\n\t * The relative url of the app update lifecycle endpoint\n\t *\n\t * @default \"/app/update\"\n\t */\n\tappUpdateUrl?: string | null;\n\n\t/**\n\t * The relative url of the app deactivation lifecycle endpoint\n\t *\n\t * @default \"/app/deactivate\"\n\t */\n\tappDeactivateUrl?: string | null;\n\n\t/**\n\t * The relative url of the app deletion lifecycle endpoint\n\t *\n\t * @default \"/app/delete\"\n\t */\n\tappDeleteUrl?: string | null;\n\n\t/**\n\t * The relative url of the app scope. All requests matching this will be the signature automatically validated and the response will be signed\n\t *\n\t * @default \"/app/*\"\n\t */\n\tappPath?: string | null;\n\n\t/**\n\t * 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\n\t */\n\tappIframeEnable?: boolean;\n\n\t/**\n\t * 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\n\t *\n\t * @default \"/client-api/*\"\n\t */\n\tappIframePath?: string | null;\n\n\t/**\n\t * 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.\n\t *\n\t * @default {\n\t * \"/app/module\": \"https://my-static-client-side-app.com\"\n\t * }\n\t */\n\tappIframeRedirects?: Record<string, string>;\n}\n\n// Define specific interfaces for each configuration option\ninterface AppServerConfig {\n\t/**\n\t * An already constructed AppServer instance. When provided, other parameters like appName and appSecret are not required.\n\t */\n\tappServer: AppServer;\n}\n\ninterface ParametersConfig {\n\t/**\n\t * The name of the app\n\t */\n\tappName: string | ((c: HonoContext) => string);\n\t/**\n\t * The secret of the app. When the app is published in the Shopware Store, the Shopware Store provides this value.\n\t */\n\tappSecret: string | ((c: HonoContext) => string);\n\t/**\n\t * The repository to fetch and store the shop data\n\t */\n\tshopRepository:\n\t\t| ShopRepositoryInterface\n\t\t| ((c: HonoContext) => ShopRepositoryInterface);\n\t\n\t/**\n\t * An already constructed AppServer instance. When provided, other parameters like appName and appSecret are not required.\n\t */\n\tappServer?: undefined;\n\n\t/**\n\t * The token cache to use for the HttpClient. This is used to cache the access token for the shopware shop. If you don't provide a token cache, the HttpClient will use an in-memory cache.\n\t */\n\thttpClientTokenCache?: HttpClientTokenCacheInterface | ((c: HonoContext) => HttpClientTokenCacheInterface);\n\n\t/**\n\t * A callback to setup the app server. It will be called after the app server is created and before the first request is handled\n\t */\n\tsetup?: (app: AppServer) => void;\n}\n\n// Create a discriminated union type using intersection types\ntype MiddlewareConfig = \n\t| (MiddlewareConfigBase & AppServerConfig)\n\t| (MiddlewareConfigBase & ParametersConfig);\n\n/**\n * Configure the Hono server to handle the app registration and context resolution\n */\nexport function configureAppServer(hono: Hono, cfg: MiddlewareConfig) {\n\tlet app: AppServer | null = null;\n\n\tcfg.registrationUrl = cfg.registrationUrl || \"/app/register\";\n\tcfg.registerConfirmationUrl =\n\t\tcfg.registerConfirmationUrl || \"/app/register/confirm\";\n\tcfg.appActivateUrl = cfg.appActivateUrl || \"/app/activate\";\n\tcfg.appDeactivateUrl = cfg.appDeactivateUrl || \"/app/deactivate\";\n\tcfg.appDeleteUrl = cfg.appDeleteUrl || \"/app/delete\";\n\tcfg.appPath = cfg.appPath || \"/app/*\";\n\tcfg.appInstallUrl = cfg.appInstallUrl || \"/app/install\";\n\tcfg.appUpdateUrl = cfg.appUpdateUrl || \"/app/update\";\n\n\tcfg.appIframePath = cfg.appIframePath || \"/client-api/*\";\n\n\thono.use(\"*\", async (ctx, next) => {\n\t\tif (app === null) {\n\t\t\tif (cfg.appServer) {\n\t\t\t\tapp = cfg.appServer;\n\t\t\t} else {\n\t\t\t\tconst appUrl = cfg.appUrl || buildBaseUrl(ctx.req.url);\n\n\t\t\t\tif (typeof cfg.shopRepository === \"function\") {\n\t\t\t\t\tcfg.shopRepository = cfg.shopRepository(ctx);\n\t\t\t\t}\n\n\t\t\t\tif (typeof cfg.appName === \"function\") {\n\t\t\t\t\tcfg.appName = cfg.appName(ctx);\n\t\t\t\t}\n\n\t\t\t\tif (typeof cfg.appSecret === \"function\") {\n\t\t\t\t\tcfg.appSecret = cfg.appSecret(ctx);\n\t\t\t\t}\n\n\t\t\t\tif (typeof cfg.httpClientTokenCache === \"function\") {\n\t\t\t\t\tcfg.httpClientTokenCache = cfg.httpClientTokenCache(ctx);\n\t\t\t\t}\n\n\t\t\t\tapp = new AppServer(\n\t\t\t\t\t{\n\t\t\t\t\t\tappName: cfg.appName,\n\t\t\t\t\t\tappSecret: cfg.appSecret,\n\t\t\t\t\t\tauthorizeCallbackUrl: appUrl + cfg.registerConfirmationUrl,\n\t\t\t\t\t\tenforceDoubleSignature: cfg.enforceDoubleSignature ?? false,\n\t\t\t\t\t},\n\t\t\t\t\tcfg.shopRepository,\n\t\t\t\t\tcfg.httpClientTokenCache,\n\t\t\t\t);\n\n\t\t\t\tif (cfg.setup) {\n\t\t\t\t\tcfg.setup(app);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// @ts-ignore\n\t\tctx.set(\"app\", app);\n\n\t\tawait next();\n\t});\n\n\thono.use(cfg.appPath, async (ctx, next) => {\n\t\t// @ts-ignore\n\t\tconst app = ctx.get(\"app\") as AppServer;\n\n\t\t// Don't validate signature for registration\n\t\tif (\n\t\t\tctx.req.path === cfg.registrationUrl ||\n\t\t\tctx.req.path === cfg.registerConfirmationUrl ||\n\t\t\tctx.req.path === cfg.appActivateUrl ||\n\t\t\tctx.req.path === cfg.appDeactivateUrl ||\n\t\t\tctx.req.path === cfg.appDeleteUrl\n\t\t) {\n\t\t\tawait next();\n\t\t\treturn;\n\t\t}\n\n\t\tlet context: Context<ShopInterface, unknown>;\n\t\ttry {\n\t\t\tcontext =\n\t\t\t\tctx.req.method === \"GET\"\n\t\t\t\t\t? await app.contextResolver.fromBrowser(ctx.req.raw)\n\t\t\t\t\t: await app.contextResolver.fromAPI(ctx.req.raw);\n\t\t} catch (_e) {\n\t\t\treturn jsonResponse({ message: \"Invalid request\" }, 400);\n\t\t}\n\n\t\t// @ts-ignore\n\t\tctx.set(\"shop\", context.shop);\n\t\t// @ts-ignore\n\t\tctx.set(\"context\", context);\n\n\t\tawait next();\n\n\t\tconst cloned = ctx.res.clone();\n\n\t\tawait ctx\n\t\t\t.get(\"app\")\n\t\t\t.signer.signResponse(cloned, ctx.get(\"shop\").getShopSecret());\n\n\t\tctx.header(\n\t\t\t\"shopware-app-signature\",\n\t\t\tcloned.headers.get(\"shopware-app-signature\") as string,\n\t\t);\n\t});\n\n\thono.get(cfg.registrationUrl, async (ctx) => {\n\t\tconst app = ctx.get(\"app\");\n\n\t\treturn await app.registration.authorize(ctx.req.raw);\n\t});\n\n\thono.post(cfg.registerConfirmationUrl, async (ctx) => {\n\t\tconst app = ctx.get(\"app\");\n\n\t\treturn await app.registration.authorizeCallback(ctx.req.raw);\n\t});\n\n\thono.post(cfg.appInstallUrl, async (ctx) => {\n\t\tconst app = ctx.get(\"app\");\n\n\t\treturn await app.registration.install(ctx.req.raw);\n\t});\n\n\thono.post(cfg.appActivateUrl, async (ctx) => {\n\t\tconst app = ctx.get(\"app\");\n\n\t\treturn await app.registration.activate(ctx.req.raw);\n\t});\n\n\thono.post(cfg.appUpdateUrl, async (ctx) => {\n\t\tconst app = ctx.get(\"app\");\n\n\t\treturn await app.registration.update(ctx.req.raw);\n\t});\n\n\thono.post(cfg.appDeactivateUrl, async (ctx) => {\n\t\tconst app = ctx.get(\"app\");\n\n\t\treturn await app.registration.deactivate(ctx.req.raw);\n\t});\n\n\thono.post(cfg.appDeleteUrl, async (ctx) => {\n\t\tconst app = ctx.get(\"app\");\n\n\t\treturn await app.registration.delete(ctx.req.raw);\n\t});\n\n\tif (cfg.appIframeEnable) {\n\t\thono.use(cfg.appIframePath, async (ctx, next) => {\n\t\t\tconst shopId = await getSignedCookie(\n\t\t\t\tctx,\n\t\t\t\tctx.get(\"app\").cfg.appSecret,\n\t\t\t\t\"shop\",\n\t\t\t);\n\n\t\t\tif (!shopId) {\n\t\t\t\treturn ctx.json({ message: \"Shop not found\" }, { status: 400 });\n\t\t\t}\n\n\t\t\tconst shop = await ctx.get(\"app\").repository.getShopById(shopId);\n\n\t\t\tif (!shop) {\n\t\t\t\treturn ctx.json({ message: \"Shop not found\" }, { status: 400 });\n\t\t\t}\n\n\t\t\tctx.set(\"shop\", shop);\n\t\t\t// @ts-ignore\n\t\t\tctx.set(\"context\", new Context(shop, {}, new HttpClient(shop, ctx.get('app').httpClientTokenCache)));\n\n\t\t\tawait next();\n\t\t});\n\n\t\tfor (let [path, redirect] of Object.entries(cfg.appIframeRedirects || {})) {\n\t\t\thono.get(path, async (ctx) => {\n\t\t\t\tconst url = new URL(ctx.req.url);\n\n\t\t\t\tif (redirect.startsWith(\"/\")) {\n\t\t\t\t\turl.pathname = redirect;\n\t\t\t\t\tredirect = url.toString();\n\t\t\t\t} else {\n\t\t\t\t\tconst newUrl = new URL(redirect);\n\n\t\t\t\t\tfor (const [key, value] of url.searchParams) {\n\t\t\t\t\t\tnewUrl.searchParams.set(key, value);\n\t\t\t\t\t}\n\n\t\t\t\t\tredirect = newUrl.toString();\n\t\t\t\t}\n\n\t\t\t\tawait setSignedCookie(\n\t\t\t\t\tctx,\n\t\t\t\t\t\"shop\",\n\t\t\t\t\tctx.get(\"shop\").getShopId(),\n\t\t\t\t\tctx.get(\"app\").cfg.appSecret,\n\t\t\t\t);\n\n\t\t\t\treturn ctx.redirect(redirect);\n\t\t\t});\n\t\t}\n\t}\n}\n\nfunction jsonResponse(body: object, status = 200): Response {\n\treturn new Response(JSON.stringify(body), {\n\t\tstatus,\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t},\n\t});\n}\n\nfunction buildBaseUrl(url: string): string {\n\tconst u = new URL(url);\n\n\tlet protocol = u.protocol;\n\n\tif (typeof process !== \"undefined\" && process.env?.SHOPWARE_APP_SDK_FORCE_HTTPS) {\n\t\tprotocol = \"https:\";\n\t}\n\n\treturn `${protocol}//${u.host}`;\n}\n"]}
|
package/dist/commonjs/mod.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export { AppServer } from "./app.js";
|
|
2
|
+
export type { Configuration } from "./app.js";
|
|
2
3
|
export { InMemoryShopRepository, SimpleShop } from "./repository.js";
|
|
3
4
|
export type { ShopInterface, ShopRepositoryInterface } from "./repository.js";
|
|
4
5
|
export { HttpClient, HttpClientResponse, ApiClientAuthenticationFailed, ApiClientRequestFailed, InMemoryHttpClientTokenCache, HttpClientTokenCacheInterface } from "./http-client.js";
|
|
6
|
+
export { DualSignatureVerifier } from "./dual-signature-verifier.js";
|
|
5
7
|
export { Context } from "./context-resolver.js";
|
|
6
8
|
export { ShopAuthorizeEvent, AppInstallEvent, AppActivateEvent, AppDeactivateEvent, AppUpdateEvent, AppUninstallEvent, BeforeRegistrationEvent, } from "./registration.js";
|
|
7
9
|
//# sourceMappingURL=mod.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACrE,YAAY,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EACN,UAAU,EACV,kBAAkB,EAClB,6BAA6B,EAC7B,sBAAsB,EACtB,4BAA4B,EAC5B,6BAA6B,EAC7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EACN,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,uBAAuB,GACvB,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/mod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACrE,YAAY,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EACN,UAAU,EACV,kBAAkB,EAClB,6BAA6B,EAC7B,sBAAsB,EACtB,4BAA4B,EAC5B,6BAA6B,EAC7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EACN,kBAAkB,EAClB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,uBAAuB,GACvB,MAAM,mBAAmB,CAAC"}
|
package/dist/commonjs/mod.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BeforeRegistrationEvent = exports.AppUninstallEvent = exports.AppUpdateEvent = exports.AppDeactivateEvent = exports.AppActivateEvent = exports.AppInstallEvent = exports.ShopAuthorizeEvent = exports.Context = exports.InMemoryHttpClientTokenCache = exports.ApiClientRequestFailed = exports.ApiClientAuthenticationFailed = exports.HttpClientResponse = exports.HttpClient = exports.SimpleShop = exports.InMemoryShopRepository = exports.AppServer = void 0;
|
|
3
|
+
exports.BeforeRegistrationEvent = exports.AppUninstallEvent = exports.AppUpdateEvent = exports.AppDeactivateEvent = exports.AppActivateEvent = exports.AppInstallEvent = exports.ShopAuthorizeEvent = exports.Context = exports.DualSignatureVerifier = exports.InMemoryHttpClientTokenCache = exports.ApiClientRequestFailed = exports.ApiClientAuthenticationFailed = exports.HttpClientResponse = exports.HttpClient = exports.SimpleShop = exports.InMemoryShopRepository = exports.AppServer = void 0;
|
|
4
4
|
var app_js_1 = require("./app.js");
|
|
5
5
|
Object.defineProperty(exports, "AppServer", { enumerable: true, get: function () { return app_js_1.AppServer; } });
|
|
6
6
|
var repository_js_1 = require("./repository.js");
|
|
@@ -12,6 +12,8 @@ Object.defineProperty(exports, "HttpClientResponse", { enumerable: true, get: fu
|
|
|
12
12
|
Object.defineProperty(exports, "ApiClientAuthenticationFailed", { enumerable: true, get: function () { return http_client_js_1.ApiClientAuthenticationFailed; } });
|
|
13
13
|
Object.defineProperty(exports, "ApiClientRequestFailed", { enumerable: true, get: function () { return http_client_js_1.ApiClientRequestFailed; } });
|
|
14
14
|
Object.defineProperty(exports, "InMemoryHttpClientTokenCache", { enumerable: true, get: function () { return http_client_js_1.InMemoryHttpClientTokenCache; } });
|
|
15
|
+
var dual_signature_verifier_js_1 = require("./dual-signature-verifier.js");
|
|
16
|
+
Object.defineProperty(exports, "DualSignatureVerifier", { enumerable: true, get: function () { return dual_signature_verifier_js_1.DualSignatureVerifier; } });
|
|
15
17
|
var context_resolver_js_1 = require("./context-resolver.js");
|
|
16
18
|
Object.defineProperty(exports, "Context", { enumerable: true, get: function () { return context_resolver_js_1.Context; } });
|
|
17
19
|
var registration_js_1 = require("./registration.js");
|
package/dist/commonjs/mod.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/mod.ts"],"names":[],"mappings":";;;AAAA,mCAAqC;AAA5B,mGAAA,SAAS,OAAA;
|
|
1
|
+
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/mod.ts"],"names":[],"mappings":";;;AAAA,mCAAqC;AAA5B,mGAAA,SAAS,OAAA;AAElB,iDAAqE;AAA5D,uHAAA,sBAAsB,OAAA;AAAE,2GAAA,UAAU,OAAA;AAE3C,mDAO0B;AANzB,4GAAA,UAAU,OAAA;AACV,oHAAA,kBAAkB,OAAA;AAClB,+HAAA,6BAA6B,OAAA;AAC7B,wHAAA,sBAAsB,OAAA;AACtB,8HAAA,4BAA4B,OAAA;AAG7B,2EAAqE;AAA5D,mIAAA,qBAAqB,OAAA;AAC9B,6DAAgD;AAAvC,8GAAA,OAAO,OAAA;AAChB,qDAQ2B;AAP1B,qHAAA,kBAAkB,OAAA;AAClB,kHAAA,eAAe,OAAA;AACf,mHAAA,gBAAgB,OAAA;AAChB,qHAAA,kBAAkB,OAAA;AAClB,iHAAA,cAAc,OAAA;AACd,oHAAA,iBAAiB,OAAA;AACjB,0HAAA,uBAAuB,OAAA","sourcesContent":["export { AppServer } from \"./app.js\";\nexport type { Configuration } from \"./app.js\";\nexport { InMemoryShopRepository, SimpleShop } from \"./repository.js\";\nexport type { ShopInterface, ShopRepositoryInterface } from \"./repository.js\";\nexport {\n\tHttpClient,\n\tHttpClientResponse,\n\tApiClientAuthenticationFailed,\n\tApiClientRequestFailed,\n\tInMemoryHttpClientTokenCache,\n\tHttpClientTokenCacheInterface\n} from \"./http-client.js\";\nexport { DualSignatureVerifier } from \"./dual-signature-verifier.js\";\nexport { Context } from \"./context-resolver.js\";\nexport {\n\tShopAuthorizeEvent,\n\tAppInstallEvent,\n\tAppActivateEvent,\n\tAppDeactivateEvent,\n\tAppUpdateEvent,\n\tAppUninstallEvent,\n\tBeforeRegistrationEvent,\n} from \"./registration.js\";\n"]}
|
|
@@ -54,6 +54,10 @@ export declare class Registration<Shop extends ShopInterface = ShopInterface> {
|
|
|
54
54
|
* </webhooks>
|
|
55
55
|
*/
|
|
56
56
|
delete(req: Request): Promise<Response>;
|
|
57
|
+
/**
|
|
58
|
+
* @deprecated tag:v6.0.0 - Will be removed. Double signature verification will always be enforced.
|
|
59
|
+
*/
|
|
60
|
+
private setVerifiedWithDoubleSignature;
|
|
57
61
|
}
|
|
58
62
|
export declare function randomString(length?: number): string;
|
|
59
63
|
export declare class ShopAuthorizeEvent<Shop extends ShopInterface = ShopInterface> {
|
|
@@ -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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"}
|
|
@@ -22,21 +22,39 @@ class Registration {
|
|
|
22
22
|
}
|
|
23
23
|
const shopId = url.searchParams.get("shop-id");
|
|
24
24
|
const shopUrl = url.searchParams.get("shop-url");
|
|
25
|
-
const
|
|
25
|
+
const sanitizedShopUrl = shopUrl
|
|
26
|
+
.replace(/([^:])(\/\/+)/g, "$1/")
|
|
27
|
+
.replace(/\/+$/, "");
|
|
26
28
|
const beforeRegistrationEvent = new BeforeRegistrationEvent(req, shopId, shopUrl);
|
|
27
29
|
this.app.hooks.publish('onBeforeRegistrationEvent', beforeRegistrationEvent);
|
|
28
30
|
if (beforeRegistrationEvent.reason) {
|
|
29
31
|
return new InvalidRequestResponse(beforeRegistrationEvent.reason, 400);
|
|
30
32
|
}
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
+
const shop = await this.app.repository.getShopById(shopId);
|
|
34
|
+
try {
|
|
35
|
+
await this.app.requestVerifier.authenticateRegistrationRequest(req, {
|
|
36
|
+
appSecret: this.app.cfg.appSecret,
|
|
37
|
+
enforceDoubleSignature: this.app.cfg.enforceDoubleSignature ?? false,
|
|
38
|
+
}, shop);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
33
41
|
return new InvalidRequestResponse("Cannot validate app signature");
|
|
34
42
|
}
|
|
35
43
|
const shopSecret = randomString();
|
|
36
|
-
|
|
37
|
-
.
|
|
38
|
-
.
|
|
39
|
-
|
|
44
|
+
if (shop === null) {
|
|
45
|
+
await this.app.repository.createShop(shopId, sanitizedShopUrl, shopSecret);
|
|
46
|
+
const shop = (await this.app.repository.getShopById(shopId));
|
|
47
|
+
shop.setPendingShopSecret(shopSecret);
|
|
48
|
+
shop.setPendingShopUrl(sanitizedShopUrl);
|
|
49
|
+
this.setVerifiedWithDoubleSignature(shop, req);
|
|
50
|
+
await this.app.repository.updateShop(shop);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
shop.setPendingShopSecret(shopSecret);
|
|
54
|
+
shop.setPendingShopUrl(sanitizedShopUrl);
|
|
55
|
+
this.setVerifiedWithDoubleSignature(shop, req);
|
|
56
|
+
await this.app.repository.updateShop(shop);
|
|
57
|
+
}
|
|
40
58
|
return new Response(JSON.stringify({
|
|
41
59
|
proof: await this.app.signer.sign(shopId + shopUrl + this.app.cfg.appName, this.app.cfg.appSecret),
|
|
42
60
|
secret: shopSecret,
|
|
@@ -64,12 +82,29 @@ class Registration {
|
|
|
64
82
|
if (shop === null) {
|
|
65
83
|
return new InvalidRequestResponse("Invalid shop given");
|
|
66
84
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
85
|
+
try {
|
|
86
|
+
await this.app.requestVerifier.authenticateRegistrationConfirmation(req, bodyContent, shop, {
|
|
87
|
+
appSecret: this.app.cfg.appSecret,
|
|
88
|
+
enforceDoubleSignature: this.app.cfg.enforceDoubleSignature ?? false,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
71
92
|
return new InvalidRequestResponse("Cannot validate app signature");
|
|
72
93
|
}
|
|
94
|
+
const pendingSecret = shop.getPendingShopSecret();
|
|
95
|
+
const pendingUrl = shop.getPendingShopUrl();
|
|
96
|
+
if (pendingSecret === null || pendingUrl === null) {
|
|
97
|
+
return new InvalidRequestResponse("Invalid Request", 400);
|
|
98
|
+
}
|
|
99
|
+
const previousSecret = shop.getShopSecret();
|
|
100
|
+
if (pendingSecret !== previousSecret) {
|
|
101
|
+
shop.setPreviousShopSecret(previousSecret);
|
|
102
|
+
shop.setShopSecret(pendingSecret);
|
|
103
|
+
shop.setSecretsRotatedAt(new Date());
|
|
104
|
+
}
|
|
105
|
+
shop.setPendingShopSecret(null);
|
|
106
|
+
shop.setShopUrl(pendingUrl);
|
|
107
|
+
shop.setPendingShopUrl(null);
|
|
73
108
|
shop.setShopCredentials(body.apiKey, body.secretKey);
|
|
74
109
|
const event = new ShopAuthorizeEvent(req, shop);
|
|
75
110
|
await this.app.hooks.publish("onAuthorize", event);
|
|
@@ -77,6 +112,7 @@ class Registration {
|
|
|
77
112
|
await this.app.repository.deleteShop(shop.getShopId());
|
|
78
113
|
return new InvalidRequestResponse(event.reason, 403);
|
|
79
114
|
}
|
|
115
|
+
shop.setRegistrationConfirmed();
|
|
80
116
|
await this.app.repository.updateShop(shop);
|
|
81
117
|
return new Response(null, { status: 204 });
|
|
82
118
|
}
|
|
@@ -152,6 +188,14 @@ class Registration {
|
|
|
152
188
|
}
|
|
153
189
|
return new Response(null, { status: 204 });
|
|
154
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* @deprecated tag:v6.0.0 - Will be removed. Double signature verification will always be enforced.
|
|
193
|
+
*/
|
|
194
|
+
setVerifiedWithDoubleSignature(shop, req) {
|
|
195
|
+
if (this.app.cfg.enforceDoubleSignature || req.headers.has('shopware-shop-signature')) {
|
|
196
|
+
shop.setVerifiedWithDoubleSignature();
|
|
197
|
+
}
|
|
198
|
+
}
|
|
155
199
|
}
|
|
156
200
|
exports.Registration = Registration;
|
|
157
201
|
function randomString(length = 120) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registration.js","sourceRoot":"","sources":["../../src/registration.ts"],"names":[],"mappings":";;;AAwOA,oCAUC;AA/OD,MAAa,YAAY;IACJ;IAApB,YAAoB,GAAoB;QAApB,QAAG,GAAH,GAAG,CAAiB;IAAG,CAAC;IAE5C;;;;OAIG;IACI,KAAK,CAAC,SAAS,CAAC,GAAY;QAClC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAE7B,IACC,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC;YACjC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;YAC1C,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC;YAChC,CAAC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,EACjC,CAAC;YACF,OAAO,IAAI,sBAAsB,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;QAC3D,CAAC;QAED,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAW,CAAC;QACzD,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAW,CAAC;QAC3D,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,WAAW,CAAW,CAAC;QAE9D,MAAM,uBAAuB,GAAG,IAAI,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAClF,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,2BAA2B,EAAE,uBAAuB,CAAC,CAAC;QAE7E,IAAI,uBAAuB,CAAC,MAAM,EAAE,CAAC;YACpC,OAAO,IAAI,sBAAsB,CAAC,uBAAuB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACxE,CAAC;QAED,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CACrC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAW,EACnD,WAAW,MAAM,aAAa,OAAO,cAAc,SAAS,EAAE,EAC9D,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CACtB,CAAC;QAEF,IAAI,CAAC,CAAC,EAAE,CAAC;YACR,OAAO,IAAI,sBAAsB,CAAC,+BAA+B,CAAC,CAAC;QACpE,CAAC;QAED,MAAM,UAAU,GAAG,YAAY,EAAE,CAAC;QAClC,MAAM,gBAAgB,GAAG,OAAO;aAC9B,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC;aAChC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAEtB,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,EAAE,gBAAgB,EAAE,UAAU,CAAC,CAAC;QAE3E,OAAO,IAAI,QAAQ,CAClB,IAAI,CAAC,SAAS,CAAC;YACd,KAAK,EAAE,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAChC,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,EACvC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CACtB;YACD,MAAM,EAAE,UAAU;YAClB,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,oBAAoB;SACnD,CAAC,EACF;YACC,OAAO,EAAE;gBACR,cAAc,EAAE,kBAAkB;aAClC;SACD,CACD,CAAC;IACH,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,iBAAiB,CAAC,GAAY;QAC1C,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAErC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QAErC,IACC,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ;YAC/B,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ;YAC/B,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ;YAClC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,EAC1C,CAAC;YACF,OAAO,IAAI,sBAAsB,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;QAC3D,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,MAAgB,CAAC,CAAC;QAE1E,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,IAAI,sBAAsB,CAAC,oBAAoB,CAAC,CAAC;QACzD,CAAC;QAED,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CACrC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAW,EACpD,WAAW,EACX,IAAI,CAAC,aAAa,EAAE,CACpB,CAAC;QAEF,IAAI,CAAC,CAAC,EAAE,CAAC;YACR,2DAA2D;YAC3D,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;YAEvD,OAAO,IAAI,sBAAsB,CAAC,+BAA+B,CAAC,CAAC;QACpE,CAAC;QAED,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAErD,MAAM,KAAK,GAAG,IAAI,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAChD,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;QAEnD,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;YAClB,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;YAEvD,OAAO,IAAI,sBAAsB,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACtD,CAAC;QAED,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAE3C,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,QAAQ,CAAC,GAAY;QACjC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAExD,MAAM,KAAK,GAAG,IAAI,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;QAErD,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAE7B,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAE/C,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,OAAO,CAAC,GAAY;QAChC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,OAAO,CAE/C,GAAG,CAAC,CAAC;QAER,MAAM,KAAK,GAAG,IAAI,eAAe,CAChC,GAAG,EACH,GAAG,CAAC,IAAI,EACR,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,IAAI,IAAI,CAC9C,CAAC;QACF,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QAEpD,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,UAAU,CAAC,GAAY;QACnC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAExD,MAAM,KAAK,GAAG,IAAI,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;QACpD,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;QAEvD,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAE9B,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAE/C,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,MAAM,CAAC,GAAY;QAC/B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,OAAO,CAE/C,GAAG,CAAC,CAAC;QAER,MAAM,KAAK,GAAG,IAAI,cAAc,CAC/B,GAAG,EACH,GAAG,CAAC,IAAI,EACR,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,IAAI,IAAI,CAC9C,CAAC;QACF,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;QAEnD,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,MAAM,CAAC,GAAY;QAC/B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,OAAO,CAE/C,GAAG,CAAC,CAAC;QAER,MAAM,KAAK,GAAG,IAAI,iBAAiB,CAClC,GAAG,EACH,GAAG,CAAC,IAAI,EACR,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,IAAI,IAAI,CAChD,CAAC;QACF,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;QAEtD,IAAI,KAAK,CAAC,YAAY,KAAK,KAAK,EAAE,CAAC;YAClC,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;QAC5D,CAAC;QAED,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5C,CAAC;CACD;AAnOD,oCAmOC;AAED,SAAgB,YAAY,CAAC,MAAM,GAAG,GAAG;IACxC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,MAAM,UAAU,GACf,gEAAgE,CAAC;IAClE,MAAM,gBAAgB,GAAG,UAAU,CAAC,MAAM,CAAC;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACjC,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,gBAAgB,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,OAAO,MAAM,CAAC;AACf,CAAC;AAED,MAAM,sBAAuB,SAAQ,QAAQ;IAC5C,YAAY,KAAa,EAAE,MAAM,GAAG,GAAG;QACtC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;YAChC,MAAM;YACN,OAAO,EAAE;gBACR,cAAc,EAAE,kBAAkB;aAClC;SACD,CAAC,CAAC;IACJ,CAAC;CACD;AAED,MAAa,kBAAkB;IAItB;IACA;IAJA,MAAM,GAAkB,IAAI,CAAC;IAErC,YACQ,OAAgB,EAChB,IAAU;QADV,YAAO,GAAP,OAAO,CAAS;QAChB,SAAI,GAAJ,IAAI,CAAM;IACf,CAAC;IAEG,kBAAkB,CAAC,MAAc;QACvC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACtB,CAAC;IAED,IAAW,MAAM;QAChB,OAAO,IAAI,CAAC,MAAM,CAAC;IACpB,CAAC;CACD;AAfD,gDAeC;AAED,MAAa,eAAe;IAEnB;IACA;IACA;IAHR,YACQ,OAAgB,EAChB,IAAU,EACV,aAA4B,IAAI;QAFhC,YAAO,GAAP,OAAO,CAAS;QAChB,SAAI,GAAJ,IAAI,CAAM;QACV,eAAU,GAAV,UAAU,CAAsB;IACrC,CAAC;CACJ;AAND,0CAMC;AAED,MAAa,gBAAgB;IAEpB;IACA;IAFR,YACQ,OAAgB,EAChB,IAAU;QADV,YAAO,GAAP,OAAO,CAAS;QAChB,SAAI,GAAJ,IAAI,CAAM;IACf,CAAC;CACJ;AALD,4CAKC;AAED,MAAa,kBAAkB;IAEtB;IACA;IAFR,YACQ,OAAgB,EAChB,IAAU;QADV,YAAO,GAAP,OAAO,CAAS;QAChB,SAAI,GAAJ,IAAI,CAAM;IACf,CAAC;CACJ;AALD,gDAKC;AAED,MAAa,cAAc;IAElB;IACA;IACA;IAHR,YACQ,OAAgB,EAChB,IAAU,EACV,aAA4B,IAAI;QAFhC,YAAO,GAAP,OAAO,CAAS;QAChB,SAAI,GAAJ,IAAI,CAAM;QACV,eAAU,GAAV,UAAU,CAAsB;IACrC,CAAC;CACJ;AAND,wCAMC;AAED,MAAa,iBAAiB;IAErB;IACA;IACA;IAHR,YACQ,OAAgB,EAChB,IAAU,EACV,eAA+B,IAAI;QAFnC,YAAO,GAAP,OAAO,CAAS;QAChB,SAAI,GAAJ,IAAI,CAAM;QACV,iBAAY,GAAZ,YAAY,CAAuB;IACxC,CAAC;CACJ;AAND,8CAMC;AAED,MAAa,uBAAuB;IAI3B;IACA;IACA;IALA,kBAAkB,GAAkB,IAAI,CAAC;IAEjD,YACQ,OAAgB,EAChB,MAAc,EACd,OAAe;QAFf,YAAO,GAAP,OAAO,CAAS;QAChB,WAAM,GAAN,MAAM,CAAQ;QACd,YAAO,GAAP,OAAO,CAAQ;IACpB,CAAC;IAEG,kBAAkB,CAAC,MAAc;QACvC,IAAI,CAAC,kBAAkB,GAAG,MAAM,CAAC;IAClC,CAAC;IAED,IAAW,MAAM;QAChB,OAAO,IAAI,CAAC,kBAAkB,CAAC;IAChC,CAAC;CACD;AAhBD,0DAgBC","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(error: string, status = 401) {\n\t\tsuper(JSON.stringify({ error }), {\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"]}
|
|
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 sanitizedShopUrl = shopUrl\n\t\t\t.replace(/([^:])(\\/\\/+)/g, \"$1/\")\n\t\t\t.replace(/\\/+$/, \"\");\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 shop = await this.app.repository.getShopById(shopId);\n\n\t\ttry {\n\t\t\tawait this.app.requestVerifier.authenticateRegistrationRequest(req, {\n\t\t\t\t\tappSecret: this.app.cfg.appSecret,\n\t\t\t\t\tenforceDoubleSignature: this.app.cfg.enforceDoubleSignature ?? false,\n\t\t\t\t},\n\t\t\t\tshop,\n\t\t\t);\n\t\t} catch {\n\t\t\treturn new InvalidRequestResponse(\"Cannot validate app signature\");\n\t\t}\n\n\t\tconst shopSecret = randomString();\n\n\t\tif (shop === null) {\n\t\t\tawait this.app.repository.createShop(shopId, sanitizedShopUrl, shopSecret);\n\t\t\tconst shop = (await this.app.repository.getShopById(shopId))!;\n\t\t\tshop.setPendingShopSecret(shopSecret);\n\t\t\tshop.setPendingShopUrl(sanitizedShopUrl);\n\t\t\tthis.setVerifiedWithDoubleSignature(shop, req);\n\t\t\tawait this.app.repository.updateShop(shop);\n\t\t} else {\n\t\t\tshop.setPendingShopSecret(shopSecret);\n\t\t\tshop.setPendingShopUrl(sanitizedShopUrl);\n\t\t\tthis.setVerifiedWithDoubleSignature(shop, req);\n\t\t\tawait this.app.repository.updateShop(shop);\n\t\t}\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\ttry {\n\t\t\tawait this.app.requestVerifier.authenticateRegistrationConfirmation(\n\t\t\t\treq,\n\t\t\t\tbodyContent,\n\t\t\t\tshop,\n\t\t\t\t{\n\t\t\t\t\tappSecret: this.app.cfg.appSecret,\n\t\t\t\t\tenforceDoubleSignature: this.app.cfg.enforceDoubleSignature ?? false,\n\t\t\t\t},\n\t\t\t);\n\t\t} catch {\n\t\t\treturn new InvalidRequestResponse(\"Cannot validate app signature\");\n\t\t}\n\n\t\tconst pendingSecret = shop.getPendingShopSecret();\n\t\tconst pendingUrl = shop.getPendingShopUrl();\n\t\tif (pendingSecret === null || pendingUrl === null) {\n\t\t\treturn new InvalidRequestResponse(\"Invalid Request\", 400);\n\t\t}\n\n\t\tconst previousSecret = shop.getShopSecret();\n\t\tif (pendingSecret !== previousSecret) {\n\t\t\tshop.setPreviousShopSecret(previousSecret);\n\t\t\tshop.setShopSecret(pendingSecret);\n\t\t\tshop.setSecretsRotatedAt(new Date());\n\t\t}\n\n\t\tshop.setPendingShopSecret(null);\n\t\tshop.setShopUrl(pendingUrl);\n\t\tshop.setPendingShopUrl(null);\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\tshop.setRegistrationConfirmed();\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\t/**\n\t * @deprecated tag:v6.0.0 - Will be removed. Double signature verification will always be enforced.\n\t */\n\tprivate setVerifiedWithDoubleSignature(shop: Shop, req: Request): void\n\t{\n\t\tif (this.app.cfg.enforceDoubleSignature || req.headers.has('shopware-shop-signature')) {\n\t\t\tshop.setVerifiedWithDoubleSignature();\n\t\t}\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(error: string, status = 401) {\n\t\tsuper(JSON.stringify({ error }), {\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"]}
|