@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.
Files changed (85) hide show
  1. package/dist/commonjs/app.d.ts +8 -2
  2. package/dist/commonjs/app.d.ts.map +1 -1
  3. package/dist/commonjs/app.js +3 -0
  4. package/dist/commonjs/app.js.map +1 -1
  5. package/dist/commonjs/context-resolver.d.ts.map +1 -1
  6. package/dist/commonjs/context-resolver.js +2 -8
  7. package/dist/commonjs/context-resolver.js.map +1 -1
  8. package/dist/commonjs/dual-signature-verifier.d.ts +31 -0
  9. package/dist/commonjs/dual-signature-verifier.d.ts.map +1 -0
  10. package/dist/commonjs/dual-signature-verifier.js +136 -0
  11. package/dist/commonjs/dual-signature-verifier.js.map +1 -0
  12. package/dist/commonjs/integration/better-sqlite3.d.ts.map +1 -1
  13. package/dist/commonjs/integration/better-sqlite3.js +35 -11
  14. package/dist/commonjs/integration/better-sqlite3.js.map +1 -1
  15. package/dist/commonjs/integration/bun-sqlite.d.ts.map +1 -1
  16. package/dist/commonjs/integration/bun-sqlite.js +40 -10
  17. package/dist/commonjs/integration/bun-sqlite.js.map +1 -1
  18. package/dist/commonjs/integration/cloudflare-kv.d.ts.map +1 -1
  19. package/dist/commonjs/integration/cloudflare-kv.js +24 -1
  20. package/dist/commonjs/integration/cloudflare-kv.js.map +1 -1
  21. package/dist/commonjs/integration/deno-kv.d.ts.map +1 -1
  22. package/dist/commonjs/integration/deno-kv.js +18 -0
  23. package/dist/commonjs/integration/deno-kv.js.map +1 -1
  24. package/dist/commonjs/integration/dynamodb.d.ts.map +1 -1
  25. package/dist/commonjs/integration/dynamodb.js +31 -1
  26. package/dist/commonjs/integration/dynamodb.js.map +1 -1
  27. package/dist/commonjs/integration/hono.d.ts +6 -0
  28. package/dist/commonjs/integration/hono.d.ts.map +1 -1
  29. package/dist/commonjs/integration/hono.js +1 -0
  30. package/dist/commonjs/integration/hono.js.map +1 -1
  31. package/dist/commonjs/mod.d.ts +2 -0
  32. package/dist/commonjs/mod.d.ts.map +1 -1
  33. package/dist/commonjs/mod.js +3 -1
  34. package/dist/commonjs/mod.js.map +1 -1
  35. package/dist/commonjs/registration.d.ts +4 -0
  36. package/dist/commonjs/registration.d.ts.map +1 -1
  37. package/dist/commonjs/registration.js +55 -11
  38. package/dist/commonjs/registration.js.map +1 -1
  39. package/dist/commonjs/repository.d.ts +53 -1
  40. package/dist/commonjs/repository.d.ts.map +1 -1
  41. package/dist/commonjs/repository.js +64 -1
  42. package/dist/commonjs/repository.js.map +1 -1
  43. package/dist/esm/app.d.ts +8 -2
  44. package/dist/esm/app.d.ts.map +1 -1
  45. package/dist/esm/app.js +3 -0
  46. package/dist/esm/app.js.map +1 -1
  47. package/dist/esm/context-resolver.d.ts.map +1 -1
  48. package/dist/esm/context-resolver.js +2 -8
  49. package/dist/esm/context-resolver.js.map +1 -1
  50. package/dist/esm/dual-signature-verifier.d.ts +31 -0
  51. package/dist/esm/dual-signature-verifier.d.ts.map +1 -0
  52. package/dist/esm/dual-signature-verifier.js +132 -0
  53. package/dist/esm/dual-signature-verifier.js.map +1 -0
  54. package/dist/esm/integration/better-sqlite3.d.ts.map +1 -1
  55. package/dist/esm/integration/better-sqlite3.js +35 -11
  56. package/dist/esm/integration/better-sqlite3.js.map +1 -1
  57. package/dist/esm/integration/bun-sqlite.d.ts.map +1 -1
  58. package/dist/esm/integration/bun-sqlite.js +40 -10
  59. package/dist/esm/integration/bun-sqlite.js.map +1 -1
  60. package/dist/esm/integration/cloudflare-kv.d.ts.map +1 -1
  61. package/dist/esm/integration/cloudflare-kv.js +24 -1
  62. package/dist/esm/integration/cloudflare-kv.js.map +1 -1
  63. package/dist/esm/integration/deno-kv.d.ts.map +1 -1
  64. package/dist/esm/integration/deno-kv.js +18 -0
  65. package/dist/esm/integration/deno-kv.js.map +1 -1
  66. package/dist/esm/integration/dynamodb.d.ts.map +1 -1
  67. package/dist/esm/integration/dynamodb.js +31 -1
  68. package/dist/esm/integration/dynamodb.js.map +1 -1
  69. package/dist/esm/integration/hono.d.ts +6 -0
  70. package/dist/esm/integration/hono.d.ts.map +1 -1
  71. package/dist/esm/integration/hono.js +1 -0
  72. package/dist/esm/integration/hono.js.map +1 -1
  73. package/dist/esm/mod.d.ts +2 -0
  74. package/dist/esm/mod.d.ts.map +1 -1
  75. package/dist/esm/mod.js +1 -0
  76. package/dist/esm/mod.js.map +1 -1
  77. package/dist/esm/registration.d.ts +4 -0
  78. package/dist/esm/registration.d.ts.map +1 -1
  79. package/dist/esm/registration.js +55 -11
  80. package/dist/esm/registration.js.map +1 -1
  81. package/dist/esm/repository.d.ts +53 -1
  82. package/dist/esm/repository.d.ts.map +1 -1
  83. package/dist/esm/repository.js +64 -1
  84. package/dist/esm/repository.js.map +1 -1
  85. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
1
  import { ContextResolver } from "./context-resolver.js";
2
+ import { DualSignatureVerifier } from "./dual-signature-verifier.js";
2
3
  import { Hooks } from "./hooks.js";
3
4
  import { HttpClientTokenCacheInterface } from "./http-client.js";
4
5
  import { Registration } from "./registration.js";
@@ -14,10 +15,11 @@ export declare class AppServer<Shop extends ShopInterface = ShopInterface> {
14
15
  registration: Registration<Shop>;
15
16
  contextResolver: ContextResolver<Shop>;
16
17
  signer: WebCryptoHmacSigner;
18
+ requestVerifier: DualSignatureVerifier<Shop>;
17
19
  hooks: Hooks<Shop>;
18
20
  constructor(cfg: Configuration, repository: ShopRepositoryInterface<Shop>, httpClientTokenCache?: HttpClientTokenCacheInterface);
19
21
  }
20
- interface Configuration {
22
+ export interface Configuration {
21
23
  /**
22
24
  * Your app name
23
25
  */
@@ -30,6 +32,10 @@ interface Configuration {
30
32
  * URL to authorize callback url
31
33
  */
32
34
  authorizeCallbackUrl: string;
35
+ /**
36
+ * When true, registration requires both app and shop signatures during re-registration and confirmation.
37
+ * Defaults to false.
38
+ */
39
+ enforceDoubleSignature?: boolean;
33
40
  }
34
- export {};
35
41
  //# sourceMappingURL=app.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,6BAA6B,EAAgC,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD;;GAEG;AACH,qBAAa,SAAS,CAAC,IAAI,SAAS,aAAa,GAAG,aAAa;IAOxD,GAAG,EAAE,aAAa;IAClB,UAAU,EAAE,uBAAuB,CAAC,IAAI,CAAC;IACzC,oBAAoB,EAAE,6BAA6B;IARpD,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;IACjC,eAAe,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAGlB,GAAG,EAAE,aAAa,EAClB,UAAU,EAAE,uBAAuB,CAAC,IAAI,CAAC,EACzC,oBAAoB,GAAE,6BAAkE;CAOhG;AAED,UAAU,aAAa;IACtB;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,oBAAoB,EAAE,MAAM,CAAC;CAC7B"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,6BAA6B,EAAgC,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC9E,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD;;GAEG;AACH,qBAAa,SAAS,CAAC,IAAI,SAAS,aAAa,GAAG,aAAa;IAQxD,GAAG,EAAE,aAAa;IAClB,UAAU,EAAE,uBAAuB,CAAC,IAAI,CAAC;IACzC,oBAAoB,EAAE,6BAA6B;IATpD,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC;IACjC,eAAe,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,EAAE,mBAAmB,CAAC;IAC5B,eAAe,EAAE,qBAAqB,CAAC,IAAI,CAAC,CAAC;IAC7C,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAGlB,GAAG,EAAE,aAAa,EAClB,UAAU,EAAE,uBAAuB,CAAC,IAAI,CAAC,EACzC,oBAAoB,GAAE,6BAAkE;CAQhG;AAED,MAAM,WAAW,aAAa;IAC7B;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAE7B;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;CACjC"}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AppServer = void 0;
4
4
  const context_resolver_js_1 = require("./context-resolver.js");
5
+ const dual_signature_verifier_js_1 = require("./dual-signature-verifier.js");
5
6
  const hooks_js_1 = require("./hooks.js");
6
7
  const http_client_js_1 = require("./http-client.js");
7
8
  const registration_js_1 = require("./registration.js");
@@ -16,6 +17,7 @@ class AppServer {
16
17
  registration;
17
18
  contextResolver;
18
19
  signer;
20
+ requestVerifier;
19
21
  hooks;
20
22
  constructor(cfg, repository, httpClientTokenCache = new http_client_js_1.InMemoryHttpClientTokenCache()) {
21
23
  this.cfg = cfg;
@@ -24,6 +26,7 @@ class AppServer {
24
26
  this.registration = new registration_js_1.Registration(this);
25
27
  this.contextResolver = new context_resolver_js_1.ContextResolver(this, httpClientTokenCache);
26
28
  this.signer = new signer_js_1.WebCryptoHmacSigner();
29
+ this.requestVerifier = new dual_signature_verifier_js_1.DualSignatureVerifier(this.signer);
27
30
  this.hooks = new hooks_js_1.Hooks();
28
31
  }
29
32
  }
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/app.ts"],"names":[],"mappings":";;;AAAA,+DAAwD;AACxD,yCAAmC;AACnC,qDAA+F;AAC/F,uDAAiD;AAEjD,2CAAkD;AAElD;;GAEG;AACH,MAAa,SAAS;IAOb;IACA;IACA;IARD,YAAY,CAAqB;IACjC,eAAe,CAAwB;IACvC,MAAM,CAAsB;IAC5B,KAAK,CAAc;IAE1B,YACQ,GAAkB,EAClB,UAAyC,EACzC,uBAAsD,IAAI,6CAA4B,EAAE;QAFxF,QAAG,GAAH,GAAG,CAAe;QAClB,eAAU,GAAV,UAAU,CAA+B;QACzC,yBAAoB,GAApB,oBAAoB,CAAoE;QAE/F,IAAI,CAAC,YAAY,GAAG,IAAI,8BAAY,CAAO,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,eAAe,GAAG,IAAI,qCAAe,CAAO,IAAI,EAAE,oBAAoB,CAAC,CAAC;QAC7E,IAAI,CAAC,MAAM,GAAG,IAAI,+BAAmB,EAAE,CAAC;QACxC,IAAI,CAAC,KAAK,GAAG,IAAI,gBAAK,EAAQ,CAAC;IAChC,CAAC;CACD;AAhBD,8BAgBC","sourcesContent":["import { ContextResolver } from \"./context-resolver.js\";\nimport { Hooks } from \"./hooks.js\";\nimport { HttpClientTokenCacheInterface, InMemoryHttpClientTokenCache } from \"./http-client.js\";\nimport { Registration } from \"./registration.js\";\nimport type { ShopInterface, ShopRepositoryInterface } from \"./repository.js\";\nimport { WebCryptoHmacSigner } from \"./signer.js\";\n\n/**\n * AppServer is the main class, this is where you start your app\n */\nexport class AppServer<Shop extends ShopInterface = ShopInterface> {\n\tpublic registration: Registration<Shop>;\n\tpublic contextResolver: ContextResolver<Shop>;\n\tpublic signer: WebCryptoHmacSigner;\n\tpublic hooks: Hooks<Shop>;\n\n\tconstructor(\n\t\tpublic cfg: Configuration,\n\t\tpublic repository: ShopRepositoryInterface<Shop>,\n\t\tpublic httpClientTokenCache: HttpClientTokenCacheInterface = new InMemoryHttpClientTokenCache()\n\t) {\n\t\tthis.registration = new Registration<Shop>(this);\n\t\tthis.contextResolver = new ContextResolver<Shop>(this, httpClientTokenCache);\n\t\tthis.signer = new WebCryptoHmacSigner();\n\t\tthis.hooks = new Hooks<Shop>();\n\t}\n}\n\ninterface Configuration {\n\t/**\n\t * Your app name\n\t */\n\tappName: string;\n\n\t/**\n\t * Your app secret\n\t */\n\tappSecret: string;\n\n\t/**\n\t * URL to authorize callback url\n\t */\n\tauthorizeCallbackUrl: string;\n}\n"]}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/app.ts"],"names":[],"mappings":";;;AAAA,+DAAwD;AACxD,6EAAqE;AACrE,yCAAmC;AACnC,qDAA+F;AAC/F,uDAAiD;AAEjD,2CAAkD;AAElD;;GAEG;AACH,MAAa,SAAS;IAQb;IACA;IACA;IATD,YAAY,CAAqB;IACjC,eAAe,CAAwB;IACvC,MAAM,CAAsB;IAC5B,eAAe,CAA8B;IAC7C,KAAK,CAAc;IAE1B,YACQ,GAAkB,EAClB,UAAyC,EACzC,uBAAsD,IAAI,6CAA4B,EAAE;QAFxF,QAAG,GAAH,GAAG,CAAe;QAClB,eAAU,GAAV,UAAU,CAA+B;QACzC,yBAAoB,GAApB,oBAAoB,CAAoE;QAE/F,IAAI,CAAC,YAAY,GAAG,IAAI,8BAAY,CAAO,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,eAAe,GAAG,IAAI,qCAAe,CAAO,IAAI,EAAE,oBAAoB,CAAC,CAAC;QAC7E,IAAI,CAAC,MAAM,GAAG,IAAI,+BAAmB,EAAE,CAAC;QACxC,IAAI,CAAC,eAAe,GAAG,IAAI,kDAAqB,CAAO,IAAI,CAAC,MAAM,CAAC,CAAC;QACpE,IAAI,CAAC,KAAK,GAAG,IAAI,gBAAK,EAAQ,CAAC;IAChC,CAAC;CACD;AAlBD,8BAkBC","sourcesContent":["import { ContextResolver } from \"./context-resolver.js\";\nimport { DualSignatureVerifier } from \"./dual-signature-verifier.js\";\nimport { Hooks } from \"./hooks.js\";\nimport { HttpClientTokenCacheInterface, InMemoryHttpClientTokenCache } from \"./http-client.js\";\nimport { Registration } from \"./registration.js\";\nimport type { ShopInterface, ShopRepositoryInterface } from \"./repository.js\";\nimport { WebCryptoHmacSigner } from \"./signer.js\";\n\n/**\n * AppServer is the main class, this is where you start your app\n */\nexport class AppServer<Shop extends ShopInterface = ShopInterface> {\n\tpublic registration: Registration<Shop>;\n\tpublic contextResolver: ContextResolver<Shop>;\n\tpublic signer: WebCryptoHmacSigner;\n\tpublic requestVerifier: DualSignatureVerifier<Shop>;\n\tpublic hooks: Hooks<Shop>;\n\n\tconstructor(\n\t\tpublic cfg: Configuration,\n\t\tpublic repository: ShopRepositoryInterface<Shop>,\n\t\tpublic httpClientTokenCache: HttpClientTokenCacheInterface = new InMemoryHttpClientTokenCache()\n\t) {\n\t\tthis.registration = new Registration<Shop>(this);\n\t\tthis.contextResolver = new ContextResolver<Shop>(this, httpClientTokenCache);\n\t\tthis.signer = new WebCryptoHmacSigner();\n\t\tthis.requestVerifier = new DualSignatureVerifier<Shop>(this.signer);\n\t\tthis.hooks = new Hooks<Shop>();\n\t}\n}\n\nexport interface Configuration {\n\t/**\n\t * Your app name\n\t */\n\tappName: string;\n\n\t/**\n\t * Your app secret\n\t */\n\tappSecret: string;\n\n\t/**\n\t * URL to authorize callback url\n\t */\n\tauthorizeCallbackUrl: string;\n\n\t/**\n\t * When true, registration requires both app and shop signatures during re-registration and confirmation.\n\t * Defaults to false.\n\t */\n\tenforceDoubleSignature?: boolean;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"context-resolver.d.ts","sourceRoot":"","sources":["../../src/context-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,KAAK,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD;;;GAGG;AACH,qBAAa,eAAe,CAAC,IAAI,SAAS,aAAa,GAAG,aAAa;IAC1D,OAAO,CAAC,GAAG;IAAmB,OAAO,CAAC,oBAAoB;gBAAlD,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,EAAU,oBAAoB,EAAE,6BAA6B;IAErG;;OAEG;IACU,OAAO,CAAC,OAAO,GAAG,OAAO,EACrC,GAAG,EAAE,OAAO,GACV,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IA0ClC;;;OAGG;IACU,WAAW,CAAC,OAAO,GAAG,OAAO,EACzC,GAAG,EAAE,OAAO,GACV,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;CA6BlC;AAED;;GAEG;AACH,qBAAa,OAAO,CACnB,IAAI,SAAS,aAAa,GAAG,aAAa,EAC1C,OAAO,GAAG,OAAO;IAGT,IAAI,EAAE,IAAI;IACV,OAAO,EAAE,OAAO;IAChB,UAAU,EAAE,UAAU;gBAFtB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,UAAU;CAE9B"}
1
+ {"version":3,"file":"context-resolver.d.ts","sourceRoot":"","sources":["../../src/context-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,KAAK,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD;;;GAGG;AACH,qBAAa,eAAe,CAAC,IAAI,SAAS,aAAa,GAAG,aAAa;IAC1D,OAAO,CAAC,GAAG;IAAmB,OAAO,CAAC,oBAAoB;gBAAlD,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,EAAU,oBAAoB,EAAE,6BAA6B;IAErG;;OAEG;IACU,OAAO,CAAC,OAAO,GAAG,OAAO,EACrC,GAAG,EAAE,OAAO,GACV,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IA4BlC;;;OAGG;IACU,WAAW,CAAC,OAAO,GAAG,OAAO,EACzC,GAAG,EAAE,OAAO,GACV,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;CA6BlC;AAED;;GAEG;AACH,qBAAa,OAAO,CACnB,IAAI,SAAS,aAAa,GAAG,aAAa,EAC1C,OAAO,GAAG,OAAO;IAGT,IAAI,EAAE,IAAI;IACV,OAAO,EAAE,OAAO;IAChB,UAAU,EAAE,UAAU;gBAFtB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,UAAU;CAE9B"}
@@ -27,13 +27,7 @@ class ContextResolver {
27
27
  if (shop === null) {
28
28
  throw new Error(`Cannot find shop by id ${webHookBody.source.shopId}`);
29
29
  }
30
- const signature = req.headers.get("shopware-shop-signature");
31
- if (signature === null) {
32
- throw new Error("Missing shopware-shop-signature header");
33
- }
34
- if (!(await this.app.signer.verify(signature, webHookContent, shop.getShopSecret()))) {
35
- throw new Error("Invalid signature");
36
- }
30
+ await this.app.requestVerifier.authenticatePostRequest(req, webHookContent, shop);
37
31
  return new Context(shop, webHookBody, new http_client_js_1.HttpClient(shop, this.httpClientTokenCache));
38
32
  }
39
33
  /**
@@ -50,7 +44,7 @@ class ContextResolver {
50
44
  if (shop === null) {
51
45
  throw new Error(`Cannot find shop by id ${shopId}`);
52
46
  }
53
- await this.app.signer.verifyGetRequest(req, shop.getShopSecret());
47
+ await this.app.requestVerifier.authenticateGetRequest(req, shop);
54
48
  const paramsObject = {};
55
49
  url.searchParams.forEach((value, key) => {
56
50
  paramsObject[key] = value;
@@ -1 +1 @@
1
- {"version":3,"file":"context-resolver.js","sourceRoot":"","sources":["../../src/context-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AppServer } from \"./app.js\";\nimport { HttpClient, type HttpClientTokenCacheInterface } from \"./http-client.js\";\nimport type { ShopInterface } from \"./repository.js\";\n\n/**\n * ContextResolver is a helper class to create a Context object from a request.\n * The context contains the shop, the payload and an instance of the HttpClient\n */\nexport class ContextResolver<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(private app: AppServer<Shop>, private httpClientTokenCache: HttpClientTokenCacheInterface) {}\n\n\t/**\n\t * Create a context from a request body\n\t */\n\tpublic async fromAPI<Payload = unknown>(\n\t\treq: Request,\n\t): Promise<Context<Shop, Payload>> {\n\t\tconst webHookContent = await req.text();\n\t\tconst webHookBody = JSON.parse(webHookContent);\n\n\t\tif (\n\t\t\twebHookBody.source === undefined ||\n\t\t\twebHookBody.source.shopId === undefined\n\t\t) {\n\t\t\tthrow new Error(\"Invalid request\");\n\t\t}\n\n\t\tconst shop = await this.app.repository.getShopById(\n\t\t\twebHookBody.source.shopId,\n\t\t);\n\n\t\tif (shop === null) {\n\t\t\tthrow new Error(`Cannot find shop by id ${webHookBody.source.shopId}`);\n\t\t}\n\n\t\tconst signature = req.headers.get(\"shopware-shop-signature\");\n\n\t\tif (signature === null) {\n\t\t\tthrow new Error(\"Missing shopware-shop-signature header\");\n\t\t}\n\n\t\tif (\n\t\t\t!(await this.app.signer.verify(\n\t\t\t\tsignature,\n\t\t\t\twebHookContent,\n\t\t\t\tshop.getShopSecret(),\n\t\t\t))\n\t\t) {\n\t\t\tthrow new Error(\"Invalid signature\");\n\t\t}\n\n\t\treturn new Context<Shop, Payload>(\n\t\t\tshop as Shop,\n\t\t\twebHookBody,\n\t\t\tnew HttpClient(shop, this.httpClientTokenCache),\n\t\t);\n\t}\n\n\t/**\n\t * Create a context from a request query parameters\n\t * This is usually a module request from the shopware admin\n\t */\n\tpublic async fromBrowser<Payload = unknown>(\n\t\treq: Request,\n\t): Promise<Context<Shop, Payload>> {\n\t\tconst url = new URL(req.url);\n\n\t\tconst shopId = url.searchParams.get(\"shop-id\");\n\n\t\tif (shopId === null) {\n\t\t\tthrow new Error(\"Missing shop-id query parameter\");\n\t\t}\n\n\t\tconst shop = await this.app.repository.getShopById(shopId);\n\n\t\tif (shop === null) {\n\t\t\tthrow new Error(`Cannot find shop by id ${shopId}`);\n\t\t}\n\n\t\tawait this.app.signer.verifyGetRequest(req, shop.getShopSecret());\n\n\t\tconst paramsObject: Record<string, string> = {};\n\n\t\turl.searchParams.forEach((value, key) => {\n\t\t\tparamsObject[key] = value;\n\t\t});\n\n\t\treturn new Context<Shop, Payload>(\n\t\t\tshop as Shop,\n\t\t\tparamsObject as Payload,\n\t\t\tnew HttpClient(shop, this.httpClientTokenCache),\n\t\t);\n\t}\n}\n\n/**\n * Context is the parsed data from the request\n */\nexport class Context<\n\tShop extends ShopInterface = ShopInterface,\n\tPayload = unknown,\n> {\n\tconstructor(\n\t\tpublic shop: Shop,\n\t\tpublic payload: Payload,\n\t\tpublic httpClient: HttpClient,\n\t) {}\n}\n"]}
1
+ {"version":3,"file":"context-resolver.js","sourceRoot":"","sources":["../../src/context-resolver.ts"],"names":[],"mappings":";;;AACA,qDAAkF;AAGlF;;;GAGG;AACH,MAAa,eAAe;IACP;IAA8B;IAAlD,YAAoB,GAAoB,EAAU,oBAAmD;QAAjF,QAAG,GAAH,GAAG,CAAiB;QAAU,yBAAoB,GAApB,oBAAoB,CAA+B;IAAG,CAAC;IAEzG;;OAEG;IACI,KAAK,CAAC,OAAO,CACnB,GAAY;QAEZ,MAAM,cAAc,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QACxC,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;QAE/C,IACC,WAAW,CAAC,MAAM,KAAK,SAAS;YAChC,WAAW,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,EACtC,CAAC;YACF,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACpC,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,CACjD,WAAW,CAAC,MAAM,CAAC,MAAM,CACzB,CAAC;QAEF,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,0BAA0B,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QACxE,CAAC;QAED,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,uBAAuB,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC;QAElF,OAAO,IAAI,OAAO,CACjB,IAAY,EACZ,WAAW,EACX,IAAI,2BAAU,CAAC,IAAI,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAC/C,CAAC;IACH,CAAC;IAED;;;OAGG;IACI,KAAK,CAAC,WAAW,CACvB,GAAY;QAEZ,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAE7B,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAE/C,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QAE3D,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,0BAA0B,MAAM,EAAE,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,sBAAsB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAEjE,MAAM,YAAY,GAA2B,EAAE,CAAC;QAEhD,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;YACvC,YAAY,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,OAAO,IAAI,OAAO,CACjB,IAAY,EACZ,YAAuB,EACvB,IAAI,2BAAU,CAAC,IAAI,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAC/C,CAAC;IACH,CAAC;CACD;AAvED,0CAuEC;AAED;;GAEG;AACH,MAAa,OAAO;IAKX;IACA;IACA;IAHR,YACQ,IAAU,EACV,OAAgB,EAChB,UAAsB;QAFtB,SAAI,GAAJ,IAAI,CAAM;QACV,YAAO,GAAP,OAAO,CAAS;QAChB,eAAU,GAAV,UAAU,CAAY;IAC3B,CAAC;CACJ;AATD,0BASC","sourcesContent":["import type { AppServer } from \"./app.js\";\nimport { HttpClient, type HttpClientTokenCacheInterface } from \"./http-client.js\";\nimport type { ShopInterface } from \"./repository.js\";\n\n/**\n * ContextResolver is a helper class to create a Context object from a request.\n * The context contains the shop, the payload and an instance of the HttpClient\n */\nexport class ContextResolver<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(private app: AppServer<Shop>, private httpClientTokenCache: HttpClientTokenCacheInterface) {}\n\n\t/**\n\t * Create a context from a request body\n\t */\n\tpublic async fromAPI<Payload = unknown>(\n\t\treq: Request,\n\t): Promise<Context<Shop, Payload>> {\n\t\tconst webHookContent = await req.text();\n\t\tconst webHookBody = JSON.parse(webHookContent);\n\n\t\tif (\n\t\t\twebHookBody.source === undefined ||\n\t\t\twebHookBody.source.shopId === undefined\n\t\t) {\n\t\t\tthrow new Error(\"Invalid request\");\n\t\t}\n\n\t\tconst shop = await this.app.repository.getShopById(\n\t\t\twebHookBody.source.shopId,\n\t\t);\n\n\t\tif (shop === null) {\n\t\t\tthrow new Error(`Cannot find shop by id ${webHookBody.source.shopId}`);\n\t\t}\n\n\t\tawait this.app.requestVerifier.authenticatePostRequest(req, webHookContent, shop);\n\n\t\treturn new Context<Shop, Payload>(\n\t\t\tshop as Shop,\n\t\t\twebHookBody,\n\t\t\tnew HttpClient(shop, this.httpClientTokenCache),\n\t\t);\n\t}\n\n\t/**\n\t * Create a context from a request query parameters\n\t * This is usually a module request from the shopware admin\n\t */\n\tpublic async fromBrowser<Payload = unknown>(\n\t\treq: Request,\n\t): Promise<Context<Shop, Payload>> {\n\t\tconst url = new URL(req.url);\n\n\t\tconst shopId = url.searchParams.get(\"shop-id\");\n\n\t\tif (shopId === null) {\n\t\t\tthrow new Error(\"Missing shop-id query parameter\");\n\t\t}\n\n\t\tconst shop = await this.app.repository.getShopById(shopId);\n\n\t\tif (shop === null) {\n\t\t\tthrow new Error(`Cannot find shop by id ${shopId}`);\n\t\t}\n\n\t\tawait this.app.requestVerifier.authenticateGetRequest(req, shop);\n\n\t\tconst paramsObject: Record<string, string> = {};\n\n\t\turl.searchParams.forEach((value, key) => {\n\t\t\tparamsObject[key] = value;\n\t\t});\n\n\t\treturn new Context<Shop, Payload>(\n\t\t\tshop as Shop,\n\t\t\tparamsObject as Payload,\n\t\t\tnew HttpClient(shop, this.httpClientTokenCache),\n\t\t);\n\t}\n}\n\n/**\n * Context is the parsed data from the request\n */\nexport class Context<\n\tShop extends ShopInterface = ShopInterface,\n\tPayload = unknown,\n> {\n\tconstructor(\n\t\tpublic shop: Shop,\n\t\tpublic payload: Payload,\n\t\tpublic httpClient: HttpClient,\n\t) {}\n}\n"]}
@@ -0,0 +1,31 @@
1
+ import type { ShopInterface } from "./repository.js";
2
+ import { WebCryptoHmacSigner } from "./signer.js";
3
+ export interface DualSignatureConfiguration {
4
+ appSecret: string;
5
+ enforceDoubleSignature: boolean;
6
+ }
7
+ export declare class DualSignatureVerifier<Shop extends ShopInterface = ShopInterface> {
8
+ private readonly signer;
9
+ private readonly now;
10
+ constructor(signer: WebCryptoHmacSigner, now?: () => Date);
11
+ authenticateRegistrationRequest(req: Request, cfg: DualSignatureConfiguration, shop: Shop | null): Promise<void>;
12
+ authenticateRegistrationConfirmation(req: Request, body: string, shop: Shop, cfg: DualSignatureConfiguration): Promise<void>;
13
+ authenticatePostRequest(req: Request, body: string, shop: Shop): Promise<void>;
14
+ authenticateGetRequest(req: Request, shop: Shop): Promise<void>;
15
+ private verifyRegistrationAppSignature;
16
+ private verifyRegistrationShopSignature;
17
+ private verifyPostSignature;
18
+ private getRegistrationSignatureMessage;
19
+ private tryAuthenticateWithPreviousSecret;
20
+ /**
21
+ * @deprecated tag:v6.0.0 - Will be removed. Double signature verification will always be enforced.
22
+ *
23
+ * 1. If the shop has previously verified with a double signature, it must always do so
24
+ * 2. If the shop is sending a double signature, then we should also verify it
25
+ * 3. If the app is configured to enforce double signature, then we should force it
26
+ */
27
+ private shouldEnforceDoubleSignature;
28
+ private shouldEnforceDoubleSignatureForRegister;
29
+ private shouldEnforceDoubleSignatureForRegisterConfirm;
30
+ }
31
+ //# sourceMappingURL=dual-signature-verifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dual-signature-verifier.d.ts","sourceRoot":"","sources":["../../src/dual-signature-verifier.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAOlD,MAAM,WAAW,0BAA0B;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB,EAAE,OAAO,CAAC;CAChC;AAED,qBAAa,qBAAqB,CAAC,IAAI,SAAS,aAAa,GAAG,aAAa;IAE3E,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBADH,MAAM,EAAE,mBAAmB,EAC3B,GAAG,GAAE,MAAM,IAAuB;IAGvC,+BAA+B,CAC3C,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,0BAA0B,EAC/B,IAAI,EAAE,IAAI,GAAG,IAAI,GACf,OAAO,CAAC,IAAI,CAAC;IAgBH,oCAAoC,CAChD,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,0BAA0B,GAC7B,OAAO,CAAC,IAAI,CAAC;IAkBH,uBAAuB,CACnC,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI,GACR,OAAO,CAAC,IAAI,CAAC;IAcH,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;YAc9D,8BAA8B;YAe9B,+BAA+B;YAe/B,mBAAmB;IAmBjC,OAAO,CAAC,+BAA+B;YAazB,iCAAiC;IAqB/C;;;;;;OAMG;IACH,OAAO,CAAC,4BAA4B;IAKpC,OAAO,CAAC,uCAAuC;IAK/C,OAAO,CAAC,8CAA8C;CAItD"}
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DualSignatureVerifier = void 0;
4
+ const SHOPWARE_SHOP_SIGNATURE_HEADER = "shopware-shop-signature";
5
+ const SHOPWARE_SHOP_SIGNATURE_PREVIOUS_HEADER = "shopware-shop-signature-previous";
6
+ const SHOPWARE_APP_SIGNATURE_HEADER = "shopware-app-signature";
7
+ const INFLIGHT_ALLOWANCE_MS = 60_000;
8
+ class DualSignatureVerifier {
9
+ signer;
10
+ now;
11
+ constructor(signer, now = () => new Date()) {
12
+ this.signer = signer;
13
+ this.now = now;
14
+ }
15
+ async authenticateRegistrationRequest(req, cfg, shop) {
16
+ try {
17
+ await this.verifyRegistrationAppSignature(req, cfg.appSecret);
18
+ }
19
+ catch (error) {
20
+ throw new Error("invalid-app-signature", { cause: error });
21
+ }
22
+ if (shop?.isRegistrationConfirmed() && this.shouldEnforceDoubleSignatureForRegister(cfg, shop, req)) {
23
+ try {
24
+ await this.verifyRegistrationShopSignature(req, shop.getShopSecret());
25
+ }
26
+ catch (error) {
27
+ throw new Error("invalid-shop-registration-signature", { cause: error });
28
+ }
29
+ }
30
+ }
31
+ async authenticateRegistrationConfirmation(req, body, shop, cfg) {
32
+ const pendingSecret = shop.getPendingShopSecret();
33
+ if (pendingSecret === null) {
34
+ throw new Error("Signature could not be verified");
35
+ }
36
+ await this.verifyPostSignature(req, body, pendingSecret, SHOPWARE_SHOP_SIGNATURE_HEADER);
37
+ if (!shop.isRegistrationConfirmed()) {
38
+ return;
39
+ }
40
+ if (this.shouldEnforceDoubleSignatureForRegisterConfirm(cfg, shop, req)) {
41
+ await this.verifyPostSignature(req, body, shop.getShopSecret(), SHOPWARE_SHOP_SIGNATURE_PREVIOUS_HEADER);
42
+ }
43
+ }
44
+ async authenticatePostRequest(req, body, shop) {
45
+ try {
46
+ await this.verifyPostSignature(req, body, shop.getShopSecret(), SHOPWARE_SHOP_SIGNATURE_HEADER);
47
+ }
48
+ catch (error) {
49
+ await this.tryAuthenticateWithPreviousSecret(shop, error, async (secret) => {
50
+ await this.verifyPostSignature(req, body, secret, SHOPWARE_SHOP_SIGNATURE_HEADER);
51
+ });
52
+ }
53
+ }
54
+ async authenticateGetRequest(req, shop) {
55
+ try {
56
+ await this.signer.verifyGetRequest(req, shop.getShopSecret());
57
+ }
58
+ catch (error) {
59
+ await this.tryAuthenticateWithPreviousSecret(shop, error, async (secret) => {
60
+ await this.signer.verifyGetRequest(req, secret);
61
+ });
62
+ }
63
+ }
64
+ async verifyRegistrationAppSignature(req, secret) {
65
+ const signature = req.headers.get(SHOPWARE_APP_SIGNATURE_HEADER);
66
+ if (signature === null) {
67
+ throw new Error("Missing shopware-app-signature header");
68
+ }
69
+ const message = this.getRegistrationSignatureMessage(req);
70
+ const valid = await this.signer.verify(signature, message, secret);
71
+ if (!valid) {
72
+ throw new Error("Invalid app signature");
73
+ }
74
+ }
75
+ async verifyRegistrationShopSignature(req, secret) {
76
+ const signature = req.headers.get(SHOPWARE_SHOP_SIGNATURE_HEADER);
77
+ if (signature === null) {
78
+ throw new Error("Missing shopware-shop-signature header");
79
+ }
80
+ const message = this.getRegistrationSignatureMessage(req);
81
+ const valid = await this.signer.verify(signature, message, secret);
82
+ if (!valid) {
83
+ throw new Error("Invalid shop signature");
84
+ }
85
+ }
86
+ async verifyPostSignature(req, body, secret, headerName) {
87
+ const signature = req.headers.get(headerName);
88
+ if (signature === null) {
89
+ throw new Error(`Missing ${headerName} header`);
90
+ }
91
+ const valid = await this.signer.verify(signature, body, secret);
92
+ if (!valid) {
93
+ throw new Error("Invalid signature");
94
+ }
95
+ }
96
+ getRegistrationSignatureMessage(req) {
97
+ const url = new URL(req.url);
98
+ const shopId = url.searchParams.get("shop-id");
99
+ const shopUrl = url.searchParams.get("shop-url");
100
+ const timestamp = url.searchParams.get("timestamp");
101
+ if (!shopId || !shopUrl || !timestamp) {
102
+ throw new Error("Missing required registration parameters");
103
+ }
104
+ return `shop-id=${shopId}&shop-url=${shopUrl}&timestamp=${timestamp}`;
105
+ }
106
+ async tryAuthenticateWithPreviousSecret(shop, error, verify) {
107
+ const previousSecret = shop.getPreviousShopSecret();
108
+ const rotatedAt = shop.getSecretsRotatedAt();
109
+ if (previousSecret === null || rotatedAt === null) {
110
+ throw error instanceof Error ? error : new Error("Invalid signature");
111
+ }
112
+ const allowanceEnd = rotatedAt.getTime() + INFLIGHT_ALLOWANCE_MS;
113
+ if (this.now().getTime() >= allowanceEnd) {
114
+ throw error instanceof Error ? error : new Error("Invalid signature");
115
+ }
116
+ await verify(previousSecret);
117
+ }
118
+ /**
119
+ * @deprecated tag:v6.0.0 - Will be removed. Double signature verification will always be enforced.
120
+ *
121
+ * 1. If the shop has previously verified with a double signature, it must always do so
122
+ * 2. If the shop is sending a double signature, then we should also verify it
123
+ * 3. If the app is configured to enforce double signature, then we should force it
124
+ */
125
+ shouldEnforceDoubleSignature(cfg, shop, req, header) {
126
+ return shop.hasVerifiedWithDoubleSignature() || req.headers.has(header) || cfg.enforceDoubleSignature;
127
+ }
128
+ shouldEnforceDoubleSignatureForRegister(cfg, shop, req) {
129
+ return this.shouldEnforceDoubleSignature(cfg, shop, req, SHOPWARE_SHOP_SIGNATURE_HEADER);
130
+ }
131
+ shouldEnforceDoubleSignatureForRegisterConfirm(cfg, shop, req) {
132
+ return this.shouldEnforceDoubleSignature(cfg, shop, req, SHOPWARE_SHOP_SIGNATURE_PREVIOUS_HEADER);
133
+ }
134
+ }
135
+ exports.DualSignatureVerifier = DualSignatureVerifier;
136
+ //# sourceMappingURL=dual-signature-verifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dual-signature-verifier.js","sourceRoot":"","sources":["../../src/dual-signature-verifier.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ShopInterface } from \"./repository.js\";\nimport { WebCryptoHmacSigner } from \"./signer.js\";\n\nconst SHOPWARE_SHOP_SIGNATURE_HEADER = \"shopware-shop-signature\";\nconst SHOPWARE_SHOP_SIGNATURE_PREVIOUS_HEADER = \"shopware-shop-signature-previous\";\nconst SHOPWARE_APP_SIGNATURE_HEADER = \"shopware-app-signature\";\nconst INFLIGHT_ALLOWANCE_MS = 60_000;\n\nexport interface DualSignatureConfiguration {\n\tappSecret: string;\n\tenforceDoubleSignature: boolean;\n}\n\nexport class DualSignatureVerifier<Shop extends ShopInterface = ShopInterface> {\n\tconstructor(\n\t\tprivate readonly signer: WebCryptoHmacSigner,\n\t\tprivate readonly now: () => Date = () => new Date(),\n\t) {}\n\n\tpublic async authenticateRegistrationRequest(\n\t\treq: Request,\n\t\tcfg: DualSignatureConfiguration,\n\t\tshop: Shop | null,\n\t): Promise<void> {\n\t\ttry {\n\t\t\tawait this.verifyRegistrationAppSignature(req, cfg.appSecret);\n\t\t} catch (error) {\n\t\t\tthrow new Error(\"invalid-app-signature\", { cause: error });\n\t\t}\n\n\t\tif (shop?.isRegistrationConfirmed() && this.shouldEnforceDoubleSignatureForRegister(cfg, shop, req)) {\n\t\t\ttry {\n\t\t\t\tawait this.verifyRegistrationShopSignature(req, shop.getShopSecret());\n\t\t\t} catch (error) {\n\t\t\t\tthrow new Error(\"invalid-shop-registration-signature\", { cause: error });\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic async authenticateRegistrationConfirmation(\n\t\treq: Request,\n\t\tbody: string,\n\t\tshop: Shop,\n\t\tcfg: DualSignatureConfiguration,\n\t): Promise<void> {\n\t\tconst pendingSecret = shop.getPendingShopSecret();\n\n\t\tif (pendingSecret === null) {\n\t\t\tthrow new Error(\"Signature could not be verified\");\n\t\t}\n\n\t\tawait this.verifyPostSignature(req, body, pendingSecret, SHOPWARE_SHOP_SIGNATURE_HEADER);\n\n\t\tif (!shop.isRegistrationConfirmed()) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.shouldEnforceDoubleSignatureForRegisterConfirm(cfg, shop, req)) {\n\t\t\tawait this.verifyPostSignature(req, body, shop.getShopSecret(), SHOPWARE_SHOP_SIGNATURE_PREVIOUS_HEADER);\n\t\t}\n\t}\n\n\tpublic async authenticatePostRequest(\n\t\treq: Request,\n\t\tbody: string,\n\t\tshop: Shop,\n\t): Promise<void> {\n\t\ttry {\n\t\t\tawait this.verifyPostSignature(req, body, shop.getShopSecret(), SHOPWARE_SHOP_SIGNATURE_HEADER);\n\t\t} catch (error) {\n\t\t\tawait this.tryAuthenticateWithPreviousSecret(\n\t\t\t\tshop,\n\t\t\t\terror,\n\t\t\t\tasync (secret) => {\n\t\t\t\t\tawait this.verifyPostSignature(req, body, secret, SHOPWARE_SHOP_SIGNATURE_HEADER);\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\n\tpublic async authenticateGetRequest(req: Request, shop: Shop): Promise<void> {\n\t\ttry {\n\t\t\tawait this.signer.verifyGetRequest(req, shop.getShopSecret());\n\t\t} catch (error) {\n\t\t\tawait this.tryAuthenticateWithPreviousSecret(\n\t\t\t\tshop,\n\t\t\t\terror,\n\t\t\t\tasync (secret) => {\n\t\t\t\t\tawait this.signer.verifyGetRequest(req, secret);\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate async verifyRegistrationAppSignature(req: Request, secret: string): Promise<void> {\n\t\tconst signature = req.headers.get(SHOPWARE_APP_SIGNATURE_HEADER);\n\n\t\tif (signature === null) {\n\t\t\tthrow new Error(\"Missing shopware-app-signature header\");\n\t\t}\n\n\t\tconst message = this.getRegistrationSignatureMessage(req);\n\t\tconst valid = await this.signer.verify(signature, message, secret);\n\n\t\tif (!valid) {\n\t\t\tthrow new Error(\"Invalid app signature\");\n\t\t}\n\t}\n\n\tprivate async verifyRegistrationShopSignature(req: Request, secret: string): Promise<void> {\n\t\tconst signature = req.headers.get(SHOPWARE_SHOP_SIGNATURE_HEADER);\n\n\t\tif (signature === null) {\n\t\t\tthrow new Error(\"Missing shopware-shop-signature header\");\n\t\t}\n\n\t\tconst message = this.getRegistrationSignatureMessage(req);\n\t\tconst valid = await this.signer.verify(signature, message, secret);\n\n\t\tif (!valid) {\n\t\t\tthrow new Error(\"Invalid shop signature\");\n\t\t}\n\t}\n\n\tprivate async verifyPostSignature(\n\t\treq: Request,\n\t\tbody: string,\n\t\tsecret: string,\n\t\theaderName: string,\n\t): Promise<void> {\n\t\tconst signature = req.headers.get(headerName);\n\n\t\tif (signature === null) {\n\t\t\tthrow new Error(`Missing ${headerName} header`);\n\t\t}\n\n\t\tconst valid = await this.signer.verify(signature, body, secret);\n\n\t\tif (!valid) {\n\t\t\tthrow new Error(\"Invalid signature\");\n\t\t}\n\t}\n\n\tprivate getRegistrationSignatureMessage(req: Request): string {\n\t\tconst url = new URL(req.url);\n\t\tconst shopId = url.searchParams.get(\"shop-id\");\n\t\tconst shopUrl = url.searchParams.get(\"shop-url\");\n\t\tconst timestamp = url.searchParams.get(\"timestamp\");\n\n\t\tif (!shopId || !shopUrl || !timestamp) {\n\t\t\tthrow new Error(\"Missing required registration parameters\");\n\t\t}\n\n\t\treturn `shop-id=${shopId}&shop-url=${shopUrl}&timestamp=${timestamp}`;\n\t}\n\n\tprivate async tryAuthenticateWithPreviousSecret(\n\t\tshop: Shop,\n\t\terror: unknown,\n\t\tverify: (secret: string) => Promise<void>,\n\t): Promise<void> {\n\t\tconst previousSecret = shop.getPreviousShopSecret();\n\t\tconst rotatedAt = shop.getSecretsRotatedAt();\n\n\t\tif (previousSecret === null || rotatedAt === null) {\n\t\t\tthrow error instanceof Error ? error : new Error(\"Invalid signature\");\n\t\t}\n\n\t\tconst allowanceEnd = rotatedAt.getTime() + INFLIGHT_ALLOWANCE_MS;\n\n\t\tif (this.now().getTime() >= allowanceEnd) {\n\t\t\tthrow error instanceof Error ? error : new Error(\"Invalid signature\");\n\t\t}\n\n\t\tawait verify(previousSecret);\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\t * 1. If the shop has previously verified with a double signature, it must always do so\n\t * 2. If the shop is sending a double signature, then we should also verify it\n\t * 3. If the app is configured to enforce double signature, then we should force it\n\t */\n\tprivate shouldEnforceDoubleSignature(cfg: DualSignatureConfiguration, shop: Shop, req: Request, header: string): boolean\n\t{\n\t\treturn shop.hasVerifiedWithDoubleSignature() || req.headers.has(header) || cfg.enforceDoubleSignature;\n\t}\n\n\tprivate shouldEnforceDoubleSignatureForRegister(cfg: DualSignatureConfiguration, shop: Shop, req: Request): boolean\n\t{\n\t\treturn this.shouldEnforceDoubleSignature(cfg, shop, req, SHOPWARE_SHOP_SIGNATURE_HEADER);\n\t}\n\n\tprivate shouldEnforceDoubleSignatureForRegisterConfirm(cfg: DualSignatureConfiguration, shop: Shop, req: Request): boolean\n\t{\n\t\treturn this.shouldEnforceDoubleSignature(cfg, shop, req, SHOPWARE_SHOP_SIGNATURE_PREVIOUS_HEADER);\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"better-sqlite3.d.ts","sourceRoot":"","sources":["../../../src/integration/better-sqlite3.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,uBAAuB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE5E,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,qBAAa,uBACZ,YAAW,uBAAuB,CAAC,UAAU,CAAC;IAE9C,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC;gBACV,QAAQ,EAAE,MAAM;IAetB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYlE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IA0BnD,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG3C"}
1
+ {"version":3,"file":"better-sqlite3.d.ts","sourceRoot":"","sources":["../../../src/integration/better-sqlite3.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,uBAAuB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE5E,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,qBAAa,uBACZ,YAAW,uBAAuB,CAAC,UAAU,CAAC;IAE9C,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC;gBACV,QAAQ,EAAE,MAAM;IAqBtB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYlE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAwDnD,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAoB3C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG3C"}
@@ -12,15 +12,21 @@ class BetterSqlite3Repository {
12
12
  this.db = new better_sqlite3_1.default(fileName);
13
13
  this.db.pragma("journal_mode = WAL");
14
14
  this.db.exec(`
15
- CREATE TABLE IF NOT EXISTS shop (
16
- id TEXT PRIMARY KEY,
17
- active BOOLEAN DEFAULT 1,
18
- url TEXT NOT NULL,
19
- secret TEXT NOT NULL,
20
- client_id TEXT NULL,
21
- client_secret TEXT NULL
22
- );
23
- `);
15
+ CREATE TABLE IF NOT EXISTS shop (
16
+ id TEXT PRIMARY KEY,
17
+ active BOOLEAN DEFAULT 1,
18
+ url TEXT NOT NULL,
19
+ secret TEXT NOT NULL,
20
+ client_id TEXT NULL,
21
+ client_secret TEXT NULL,
22
+ pending_shop_url TEXT NULL,
23
+ pending_shop_secret TEXT NULL,
24
+ previous_shop_secret TEXT NULL,
25
+ secrets_rotated_at INTEGER NULL,
26
+ verified_with_double_signatures BOOLEAN DEFAULT 0,
27
+ registration_confirmed BOOLEAN DEFAULT 0
28
+ );
29
+ `);
24
30
  }
25
31
  async createShop(id, url, secret) {
26
32
  const shop = await this.getShopById(id);
@@ -43,12 +49,30 @@ class BetterSqlite3Repository {
43
49
  shop.setShopCredentials(result.client_id, result.client_secret);
44
50
  }
45
51
  shop.setShopActive(result.active === 1);
52
+ if (result.pending_shop_url) {
53
+ shop.setPendingShopUrl(result.pending_shop_url);
54
+ }
55
+ if (result.pending_shop_secret) {
56
+ shop.setPendingShopSecret(result.pending_shop_secret);
57
+ }
58
+ if (result.previous_shop_secret) {
59
+ shop.setPreviousShopSecret(result.previous_shop_secret);
60
+ }
61
+ if (result.secrets_rotated_at) {
62
+ shop.setSecretsRotatedAt(new Date(Number(result.secrets_rotated_at)));
63
+ }
64
+ if (result.verified_with_double_signatures === 1) {
65
+ shop.setVerifiedWithDoubleSignature();
66
+ }
67
+ if (result.registration_confirmed === 1) {
68
+ shop.setRegistrationConfirmed();
69
+ }
46
70
  return shop;
47
71
  }
48
72
  async updateShop(shop) {
49
73
  this.db
50
- .prepare("UPDATE shop SET url = ?, secret = ?, client_id = ?, client_secret = ?, active = ? WHERE id = ?")
51
- .run(shop.getShopUrl(), shop.getShopSecret(), shop.getShopClientId(), shop.getShopClientSecret(), +shop.getShopActive(), shop.getShopId());
74
+ .prepare("UPDATE shop SET url = ?, secret = ?, client_id = ?, client_secret = ?, active = ?, pending_shop_url = ?, pending_shop_secret = ?, previous_shop_secret = ?, secrets_rotated_at = ?, verified_with_double_signatures = ?, registration_confirmed = ? WHERE id = ?")
75
+ .run(shop.getShopUrl(), shop.getShopSecret(), shop.getShopClientId(), shop.getShopClientSecret(), +shop.getShopActive(), shop.getPendingShopUrl(), shop.getPendingShopSecret(), shop.getPreviousShopSecret(), shop.getSecretsRotatedAt()?.getTime() ?? null, +shop.hasVerifiedWithDoubleSignature(), +shop.isRegistrationConfirmed(), shop.getShopId());
52
76
  }
53
77
  async deleteShop(id) {
54
78
  this.db.prepare("DELETE FROM shop where id = ?").run(id);
@@ -1 +1 @@
1
- {"version":3,"file":"better-sqlite3.js","sourceRoot":"","sources":["../../../src/integration/better-sqlite3.ts"],"names":[],"mappings":";;;;;;AAAA,oDAA4E;AAE5E,oEAAsC;AAEtC,MAAa,uBAAuB;IAGnC,EAAE,CAAoB;IACtB,YAAY,QAAgB;QAC3B,IAAI,CAAC,EAAE,GAAG,IAAI,wBAAQ,CAAC,QAAQ,CAAC,CAAC;QACjC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;OASR,CAAC,CAAC;IACR,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAU,EAAE,GAAW,EAAE,MAAc;QACvD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAExC,IAAI,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC3B,CAAC;QAED,IAAI,CAAC,EAAE;aACL,OAAO,CAAC,qDAAqD,CAAC;aAC9D,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,EAAU;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE;aACpB,OAAO,CAAC,iCAAiC,CAAC;aAC1C,GAAG,CAAC,EAAE,CAOP,CAAC;QAEF,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,0BAAU,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAElE,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YAC9C,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;QACjE,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;QAExC,OAAO,IAAI,CAAC;IACb,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,IAAgB;QAChC,IAAI,CAAC,EAAE;aACL,OAAO,CACP,gGAAgG,CAChG;aACA,GAAG,CACH,IAAI,CAAC,UAAU,EAAE,EACjB,IAAI,CAAC,aAAa,EAAE,EACpB,IAAI,CAAC,eAAe,EAAE,EACtB,IAAI,CAAC,mBAAmB,EAAE,EAC1B,CAAC,IAAI,CAAC,aAAa,EAAE,EACrB,IAAI,CAAC,SAAS,EAAE,CAChB,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,EAAU;QAC1B,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC1D,CAAC;CACD;AA1ED,0DA0EC","sourcesContent":["import { type ShopRepositoryInterface, SimpleShop } from \"../repository.js\";\n\nimport Database from \"better-sqlite3\";\n\nexport class BetterSqlite3Repository\n\timplements ShopRepositoryInterface<SimpleShop>\n{\n\tdb: Database.Database;\n\tconstructor(fileName: string) {\n\t\tthis.db = new Database(fileName);\n\t\tthis.db.pragma(\"journal_mode = WAL\");\n\t\tthis.db.exec(`\n CREATE TABLE IF NOT EXISTS shop (\n id TEXT PRIMARY KEY,\n active BOOLEAN DEFAULT 1,\n url TEXT NOT NULL,\n secret TEXT NOT NULL,\n client_id TEXT NULL,\n client_secret TEXT NULL\n );\n `);\n\t}\n\n\tasync createShop(id: string, url: string, secret: string): Promise<void> {\n\t\tconst shop = await this.getShopById(id);\n\n\t\tif (shop) {\n\t\t\tawait this.deleteShop(id);\n\t\t}\n\n\t\tthis.db\n\t\t\t.prepare(\"INSERT INTO shop (id, url, secret) VALUES (?, ?, ?)\")\n\t\t\t.run(id, url, secret);\n\t}\n\n\tasync getShopById(id: string): Promise<SimpleShop | null> {\n\t\tconst result = this.db\n\t\t\t.prepare(\"SELECT * FROM shop WHERE id = ?\")\n\t\t\t.get(id) as null | {\n\t\t\tid: string;\n\t\t\tactive: number;\n\t\t\turl: string;\n\t\t\tsecret: string;\n\t\t\tclient_id?: string;\n\t\t\tclient_secret?: string;\n\t\t};\n\n\t\tif (!result) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst shop = new SimpleShop(result.id, result.url, result.secret);\n\n\t\tif (result.client_id && result.client_secret) {\n\t\t\tshop.setShopCredentials(result.client_id, result.client_secret);\n\t\t}\n\n\t\tshop.setShopActive(result.active === 1);\n\n\t\treturn shop;\n\t}\n\tasync updateShop(shop: SimpleShop): Promise<void> {\n\t\tthis.db\n\t\t\t.prepare(\n\t\t\t\t\"UPDATE shop SET url = ?, secret = ?, client_id = ?, client_secret = ?, active = ? WHERE id = ?\",\n\t\t\t)\n\t\t\t.run(\n\t\t\t\tshop.getShopUrl(),\n\t\t\t\tshop.getShopSecret(),\n\t\t\t\tshop.getShopClientId(),\n\t\t\t\tshop.getShopClientSecret(),\n\t\t\t\t+shop.getShopActive(),\n\t\t\t\tshop.getShopId(),\n\t\t\t);\n\t}\n\tasync deleteShop(id: string): Promise<void> {\n\t\tthis.db.prepare(\"DELETE FROM shop where id = ?\").run(id);\n\t}\n}\n"]}
1
+ {"version":3,"file":"better-sqlite3.js","sourceRoot":"","sources":["../../../src/integration/better-sqlite3.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ShopRepositoryInterface, SimpleShop } from \"../repository.js\";\n\nimport Database from \"better-sqlite3\";\n\nexport class BetterSqlite3Repository\n\timplements ShopRepositoryInterface<SimpleShop>\n{\n\tdb: Database.Database;\n\tconstructor(fileName: string) {\n\t\tthis.db = new Database(fileName);\n\t\tthis.db.pragma(\"journal_mode = WAL\");\n\t\tthis.db.exec(`\n\t\tCREATE TABLE IF NOT EXISTS shop (\n\t\t id TEXT PRIMARY KEY,\n\t\t active BOOLEAN DEFAULT 1,\n\t\t url TEXT NOT NULL,\n\t\t secret TEXT NOT NULL,\n\t\t client_id TEXT NULL,\n\t\t client_secret TEXT NULL,\n\t\t pending_shop_url TEXT NULL,\n\t\t pending_shop_secret TEXT NULL,\n\t\t previous_shop_secret TEXT NULL,\n\t\t secrets_rotated_at INTEGER NULL,\n\t\t verified_with_double_signatures BOOLEAN DEFAULT 0,\n\t\t registration_confirmed BOOLEAN DEFAULT 0\n\t\t);\n\t `);\n\t}\n\n\tasync createShop(id: string, url: string, secret: string): Promise<void> {\n\t\tconst shop = await this.getShopById(id);\n\n\t\tif (shop) {\n\t\t\tawait this.deleteShop(id);\n\t\t}\n\n\t\tthis.db\n\t\t\t.prepare(\"INSERT INTO shop (id, url, secret) VALUES (?, ?, ?)\")\n\t\t\t.run(id, url, secret);\n\t}\n\n\tasync getShopById(id: string): Promise<SimpleShop | null> {\n\t\tconst result = this.db\n\t\t\t.prepare(\"SELECT * FROM shop WHERE id = ?\")\n\t\t\t.get(id) as null | {\n\t\t\tid: string;\n\t\t\tactive: number;\n\t\t\turl: string;\n\t\t\tsecret: string;\n\t\t\tclient_id?: string;\n\t\t\tclient_secret?: string;\n\t\t\tpending_shop_url?: string;\n\t\t\tpending_shop_secret?: string;\n\t\t\tprevious_shop_secret?: string;\n\t\t\tsecrets_rotated_at?: Date;\n\t\t\tverified_with_double_signatures?: number;\n\t\t\tregistration_confirmed?: number;\n\t\t};\n\n\t\tif (!result) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst shop = new SimpleShop(result.id, result.url, result.secret);\n\n\t\tif (result.client_id && result.client_secret) {\n\t\t\tshop.setShopCredentials(result.client_id, result.client_secret);\n\t\t}\n\n\t\tshop.setShopActive(result.active === 1);\n\n\t\tif (result.pending_shop_url) {\n\t\t\tshop.setPendingShopUrl(result.pending_shop_url);\n\t\t}\n\n\t\tif (result.pending_shop_secret) {\n\t\t\tshop.setPendingShopSecret(result.pending_shop_secret);\n\t\t}\n\n\t\tif (result.previous_shop_secret) {\n\t\t\tshop.setPreviousShopSecret(result.previous_shop_secret);\n\t\t}\n\n\t\tif (result.secrets_rotated_at) {\n\t\t\tshop.setSecretsRotatedAt(new Date(Number(result.secrets_rotated_at)));\n\t\t}\n\n\t\tif (result.verified_with_double_signatures === 1) {\n\t\t\tshop.setVerifiedWithDoubleSignature();\n\t\t}\n\n\t\tif (result.registration_confirmed === 1) {\n\t\t\tshop.setRegistrationConfirmed();\n\t\t}\n\n\t\treturn shop;\n\t}\n\tasync updateShop(shop: SimpleShop): Promise<void> {\n\t\tthis.db\n\t\t\t.prepare(\n\t\t\t\t\"UPDATE shop SET url = ?, secret = ?, client_id = ?, client_secret = ?, active = ?, pending_shop_url = ?, pending_shop_secret = ?, previous_shop_secret = ?, secrets_rotated_at = ?, verified_with_double_signatures = ?, registration_confirmed = ? WHERE id = ?\",\n\t\t\t)\n\t\t\t.run(\n\t\t\t\tshop.getShopUrl(),\n\t\t\t\tshop.getShopSecret(),\n\t\t\t\tshop.getShopClientId(),\n\t\t\t\tshop.getShopClientSecret(),\n\t\t\t\t+shop.getShopActive(),\n\t\t\t\tshop.getPendingShopUrl(),\n\t\t\t\tshop.getPendingShopSecret(),\n\t\t\t\tshop.getPreviousShopSecret(),\n\t\t\t\tshop.getSecretsRotatedAt()?.getTime() ?? null,\n\t\t\t\t+shop.hasVerifiedWithDoubleSignature(),\n\t\t\t\t+shop.isRegistrationConfirmed(),\n\t\t\t\tshop.getShopId(),\n\t\t\t);\n\t}\n\tasync deleteShop(id: string): Promise<void> {\n\t\tthis.db.prepare(\"DELETE FROM shop where id = ?\").run(id);\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"bun-sqlite.d.ts","sourceRoot":"","sources":["../../../src/integration/bun-sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,uBAAuB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE5E,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,qBAAa,mBACZ,YAAW,uBAAuB,CAAC,UAAU,CAAC;IAE9C,EAAE,EAAE,QAAQ,CAAC;gBACD,QAAQ,EAAE,MAAM;IAetB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAclE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IA4BnD,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAa3C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG3C"}
1
+ {"version":3,"file":"bun-sqlite.d.ts","sourceRoot":"","sources":["../../../src/integration/bun-sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,uBAAuB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE5E,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,qBAAa,mBACZ,YAAW,uBAAuB,CAAC,UAAU,CAAC;IAE9C,EAAE,EAAE,QAAQ,CAAC;gBACD,QAAQ,EAAE,MAAM;IAqBtB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAclE,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IA0DnD,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB3C,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG3C"}
@@ -9,15 +9,21 @@ class BunSqliteRepository {
9
9
  this.db = new bun_sqlite_1.Database(fileName);
10
10
  this.db.exec("PRAGMA journal_mode = WAL;");
11
11
  this.db.exec(`
12
- CREATE TABLE IF NOT EXISTS shop (
13
- id TEXT PRIMARY KEY,
14
- active BOOLEAN DEFAULT 1,
15
- url TEXT NOT NULL,
16
- secret TEXT NOT NULL,
17
- client_id TEXT NULL,
18
- client_secret TEXT NULL
19
- );
20
- `);
12
+ CREATE TABLE IF NOT EXISTS shop (
13
+ id TEXT PRIMARY KEY,
14
+ active BOOLEAN DEFAULT 1,
15
+ url TEXT NOT NULL,
16
+ secret TEXT NOT NULL,
17
+ client_id TEXT NULL,
18
+ client_secret TEXT NULL,
19
+ pending_shop_url TEXT NULL,
20
+ pending_shop_secret TEXT NULL,
21
+ previous_shop_secret TEXT NULL,
22
+ secrets_rotated_at INTEGER NULL,
23
+ verified_with_double_signatures BOOLEAN DEFAULT 0,
24
+ registration_confirmed BOOLEAN DEFAULT 0
25
+ );
26
+ `);
21
27
  }
22
28
  async createShop(id, url, secret) {
23
29
  const shop = await this.getShopById(id);
@@ -41,15 +47,39 @@ class BunSqliteRepository {
41
47
  shop.setShopCredentials(result.client_id, result.client_secret);
42
48
  }
43
49
  shop.setShopActive(result.active);
50
+ if (result.pending_shop_url) {
51
+ shop.setPendingShopUrl(result.pending_shop_url);
52
+ }
53
+ if (result.pending_shop_secret) {
54
+ shop.setPendingShopSecret(result.pending_shop_secret);
55
+ }
56
+ if (result.previous_shop_secret) {
57
+ shop.setPreviousShopSecret(result.previous_shop_secret);
58
+ }
59
+ if (result.secrets_rotated_at) {
60
+ shop.setSecretsRotatedAt(new Date(Number(result.secrets_rotated_at)));
61
+ }
62
+ if (result.verified_with_double_signatures === 1) {
63
+ shop.setVerifiedWithDoubleSignature();
64
+ }
65
+ if (result.registration_confirmed === 1) {
66
+ shop.setRegistrationConfirmed();
67
+ }
44
68
  return shop;
45
69
  }
46
70
  async updateShop(shop) {
47
- this.db.exec("UPDATE shop SET url = ?, secret = ?, client_id = ?, client_secret = ?, active = ? WHERE id = ?", [
71
+ this.db.exec("UPDATE shop SET url = ?, secret = ?, client_id = ?, client_secret = ?, active = ?, pending_shop_url = ?, pending_shop_secret = ?, previous_shop_secret = ?, secrets_rotated_at = ?, verified_with_double_signatures = ?, registration_confirmed = ? WHERE id = ?", [
48
72
  shop.getShopUrl(),
49
73
  shop.getShopSecret(),
50
74
  shop.getShopClientId(),
51
75
  shop.getShopClientSecret(),
52
76
  shop.getShopActive(),
77
+ shop.getPendingShopUrl(),
78
+ shop.getPendingShopSecret(),
79
+ shop.getPreviousShopSecret(),
80
+ shop.getSecretsRotatedAt()?.getTime() ?? null,
81
+ shop.hasVerifiedWithDoubleSignature(),
82
+ shop.isRegistrationConfirmed(),
53
83
  shop.getShopId(),
54
84
  ]);
55
85
  }
@@ -1 +1 @@
1
- {"version":3,"file":"bun-sqlite.js","sourceRoot":"","sources":["../../../src/integration/bun-sqlite.ts"],"names":[],"mappings":";;;AAAA,oDAA4E;AAE5E,2CAAsC;AAEtC,MAAa,mBAAmB;IAG/B,EAAE,CAAW;IACb,YAAY,QAAgB;QAC3B,IAAI,CAAC,EAAE,GAAG,IAAI,qBAAQ,CAAC,QAAQ,CAAC,CAAC;QACjC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAC3C,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;OASR,CAAC,CAAC;IACR,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,EAAU,EAAE,GAAW,EAAE,MAAc;QACvD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAExC,IAAI,IAAI,EAAE,CAAC;YACV,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC3B,CAAC;QAED,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,qDAAqD,EAAE;YACnE,EAAE;YACF,GAAG;YACH,MAAM;SACN,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,EAAU;QAC3B,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,KAAK,CAUzB,iCAAiC,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAE7B,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACb,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,0BAAU,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;QAElE,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YAC9C,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;QACjE,CAAC;QAED,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAElC,OAAO,IAAI,CAAC;IACb,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,IAAgB;QAChC,IAAI,CAAC,EAAE,CAAC,IAAI,CACX,gGAAgG,EAChG;YACC,IAAI,CAAC,UAAU,EAAE;YACjB,IAAI,CAAC,aAAa,EAAE;YACpB,IAAI,CAAC,eAAe,EAAE;YACtB,IAAI,CAAC,mBAAmB,EAAE;YAC1B,IAAI,CAAC,aAAa,EAAE;YACpB,IAAI,CAAC,SAAS,EAAE;SAChB,CACD,CAAC;IACH,CAAC;IACD,KAAK,CAAC,UAAU,CAAC,EAAU;QAC1B,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,+BAA+B,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACrD,CAAC;CACD;AA7ED,kDA6EC","sourcesContent":["import { type ShopRepositoryInterface, SimpleShop } from \"../repository.js\";\n\nimport { Database } from \"bun:sqlite\";\n\nexport class BunSqliteRepository\n\timplements ShopRepositoryInterface<SimpleShop>\n{\n\tdb: Database;\n\tconstructor(fileName: string) {\n\t\tthis.db = new Database(fileName);\n\t\tthis.db.exec(\"PRAGMA journal_mode = WAL;\");\n\t\tthis.db.exec(`\n CREATE TABLE IF NOT EXISTS shop (\n id TEXT PRIMARY KEY,\n active BOOLEAN DEFAULT 1,\n url TEXT NOT NULL,\n secret TEXT NOT NULL,\n client_id TEXT NULL,\n client_secret TEXT NULL\n );\n `);\n\t}\n\n\tasync createShop(id: string, url: string, secret: string): Promise<void> {\n\t\tconst shop = await this.getShopById(id);\n\n\t\tif (shop) {\n\t\t\tawait this.deleteShop(id);\n\t\t}\n\n\t\tthis.db.exec(\"INSERT INTO shop (id, url, secret) VALUES (?, ?, ?)\", [\n\t\t\tid,\n\t\t\turl,\n\t\t\tsecret,\n\t\t]);\n\t}\n\n\tasync getShopById(id: string): Promise<SimpleShop | null> {\n\t\tconst query = this.db.query<\n\t\t\t{\n\t\t\t\tid: string;\n\t\t\t\tactive: boolean;\n\t\t\t\turl: string;\n\t\t\t\tsecret: string;\n\t\t\t\tclient_id?: string;\n\t\t\t\tclient_secret?: string;\n\t\t\t},\n\t\t\tstring\n\t\t>(\"SELECT * FROM shop WHERE id = ?\");\n\t\tconst result = query.get(id);\n\n\t\tif (!result) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst shop = new SimpleShop(result.id, result.url, result.secret);\n\n\t\tif (result.client_id && result.client_secret) {\n\t\t\tshop.setShopCredentials(result.client_id, result.client_secret);\n\t\t}\n\n\t\tshop.setShopActive(result.active);\n\n\t\treturn shop;\n\t}\n\tasync updateShop(shop: SimpleShop): Promise<void> {\n\t\tthis.db.exec(\n\t\t\t\"UPDATE shop SET url = ?, secret = ?, client_id = ?, client_secret = ?, active = ? WHERE id = ?\",\n\t\t\t[\n\t\t\t\tshop.getShopUrl(),\n\t\t\t\tshop.getShopSecret(),\n\t\t\t\tshop.getShopClientId(),\n\t\t\t\tshop.getShopClientSecret(),\n\t\t\t\tshop.getShopActive(),\n\t\t\t\tshop.getShopId(),\n\t\t\t],\n\t\t);\n\t}\n\tasync deleteShop(id: string): Promise<void> {\n\t\tthis.db.exec(\"DELETE FROM shop where id = ?\", [id]);\n\t}\n}\n"]}
1
+ {"version":3,"file":"bun-sqlite.js","sourceRoot":"","sources":["../../../src/integration/bun-sqlite.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ShopRepositoryInterface, SimpleShop } from \"../repository.js\";\n\nimport { Database } from \"bun:sqlite\";\n\nexport class BunSqliteRepository\n\timplements ShopRepositoryInterface<SimpleShop>\n{\n\tdb: Database;\n\tconstructor(fileName: string) {\n\t\tthis.db = new Database(fileName);\n\t\tthis.db.exec(\"PRAGMA journal_mode = WAL;\");\n\t\tthis.db.exec(`\n\t\tCREATE TABLE IF NOT EXISTS shop (\n\t\t id TEXT PRIMARY KEY,\n\t\t active BOOLEAN DEFAULT 1,\n\t\t url TEXT NOT NULL,\n\t\t secret TEXT NOT NULL,\n\t\t client_id TEXT NULL,\n\t\t client_secret TEXT NULL,\n\t\t pending_shop_url TEXT NULL,\n\t\t pending_shop_secret TEXT NULL,\n\t\t previous_shop_secret TEXT NULL,\n\t\t secrets_rotated_at INTEGER NULL,\n\t\t verified_with_double_signatures BOOLEAN DEFAULT 0,\n\t\t registration_confirmed BOOLEAN DEFAULT 0\n\t\t);\n\t `);\n\t}\n\n\tasync createShop(id: string, url: string, secret: string): Promise<void> {\n\t\tconst shop = await this.getShopById(id);\n\n\t\tif (shop) {\n\t\t\tawait this.deleteShop(id);\n\t\t}\n\n\t\tthis.db.exec(\"INSERT INTO shop (id, url, secret) VALUES (?, ?, ?)\", [\n\t\t\tid,\n\t\t\turl,\n\t\t\tsecret,\n\t\t]);\n\t}\n\n\tasync getShopById(id: string): Promise<SimpleShop | null> {\n\t\tconst query = this.db.query<\n\t\t\t{\n\t\t\t\tid: string;\n\t\t\t\tactive: boolean;\n\t\t\t\turl: string;\n\t\t\t\tsecret: string;\n\t\t\t\tclient_id?: string;\n\t\t\t\tclient_secret?: string;\n\t\t\t\tpending_shop_url?: string;\n\t\t\t\tpending_shop_secret?: string;\n\t\t\t\tprevious_shop_secret?: string;\n\t\t\t\tsecrets_rotated_at?: Date;\n\t\t\t\tverified_with_double_signatures?: number;\n\t\t\t\tregistration_confirmed?: number;\n\t\t\t},\n\t\t\tstring\n\t\t>(\"SELECT * FROM shop WHERE id = ?\");\n\t\tconst result = query.get(id);\n\n\t\tif (!result) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst shop = new SimpleShop(result.id, result.url, result.secret);\n\n\t\tif (result.client_id && result.client_secret) {\n\t\t\tshop.setShopCredentials(result.client_id, result.client_secret);\n\t\t}\n\n\t\tshop.setShopActive(result.active);\n\n\t\tif (result.pending_shop_url) {\n\t\t\tshop.setPendingShopUrl(result.pending_shop_url);\n\t\t}\n\n\t\tif (result.pending_shop_secret) {\n\t\t\tshop.setPendingShopSecret(result.pending_shop_secret);\n\t\t}\n\n\t\tif (result.previous_shop_secret) {\n\t\t\tshop.setPreviousShopSecret(result.previous_shop_secret);\n\t\t}\n\n\t\tif (result.secrets_rotated_at) {\n\t\t\tshop.setSecretsRotatedAt(new Date(Number(result.secrets_rotated_at)));\n\t\t}\n\n\t\tif (result.verified_with_double_signatures === 1) {\n\t\t\tshop.setVerifiedWithDoubleSignature();\n\t\t}\n\n\t\tif (result.registration_confirmed === 1) {\n\t\t\tshop.setRegistrationConfirmed();\n\t\t}\n\n\t\treturn shop;\n\t}\n\tasync updateShop(shop: SimpleShop): Promise<void> {\n\t\tthis.db.exec(\n\t\t\t\"UPDATE shop SET url = ?, secret = ?, client_id = ?, client_secret = ?, active = ?, pending_shop_url = ?, pending_shop_secret = ?, previous_shop_secret = ?, secrets_rotated_at = ?, verified_with_double_signatures = ?, registration_confirmed = ? WHERE id = ?\",\n\t\t\t[\n\t\t\t\tshop.getShopUrl(),\n\t\t\t\tshop.getShopSecret(),\n\t\t\t\tshop.getShopClientId(),\n\t\t\t\tshop.getShopClientSecret(),\n\t\t\t\tshop.getShopActive(),\n\t\t\t\tshop.getPendingShopUrl(),\n\t\t\t\tshop.getPendingShopSecret(),\n\t\t\t\tshop.getPreviousShopSecret(),\n\t\t\t\tshop.getSecretsRotatedAt()?.getTime() ?? null,\n\t\t\t\tshop.hasVerifiedWithDoubleSignature(),\n\t\t\t\tshop.isRegistrationConfirmed(),\n\t\t\t\tshop.getShopId(),\n\t\t\t],\n\t\t);\n\t}\n\tasync deleteShop(id: string): Promise<void> {\n\t\tthis.db.exec(\"DELETE FROM shop where id = ?\", [id]);\n\t}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"cloudflare-kv.d.ts","sourceRoot":"","sources":["../../../src/integration/cloudflare-kv.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,KAAK,EAAE,6BAA6B,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAEjG;;;GAGG;AACH,qBAAa,wBACZ,YAAW,uBAAuB,CAAC,UAAU,CAAC;IAElC,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,WAAW;IAIlC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOlE,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQrC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAcnD,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjD,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM;IAIjD,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,UAAU;CA4B9D;AAED;;;GAGG;AACH,qBAAa,8BAA+B,YAAW,6BAA6B;IACvE,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,WAAW;IAIxC;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC;IAmBxE;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9E;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG/C"}
1
+ {"version":3,"file":"cloudflare-kv.d.ts","sourceRoot":"","sources":["../../../src/integration/cloudflare-kv.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,KAAK,EAAE,6BAA6B,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAEjG;;;GAGG;AACH,qBAAa,wBACZ,YAAW,uBAAuB,CAAC,UAAU,CAAC;IAElC,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,WAAW;IAIlC,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOlE,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQrC,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAcnD,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjD,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM;IASjD,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,UAAU;CAoD9D;AAED;;;GAGG;AACH,qBAAa,8BAA+B,YAAW,6BAA6B;IACvE,OAAO,CAAC,OAAO;gBAAP,OAAO,EAAE,WAAW;IAIxC;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC;IAmBxE;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9E;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAG/C"}
@@ -45,7 +45,12 @@ class CloudflareShopRepository {
45
45
  ]);
46
46
  }
47
47
  serializeShop(shop) {
48
- return JSON.stringify(shop);
48
+ return JSON.stringify({
49
+ ...shop,
50
+ secretsRotatedAt: shop.getSecretsRotatedAt()
51
+ ? shop.getSecretsRotatedAt().getTime()
52
+ : null,
53
+ });
49
54
  }
50
55
  deserializeShop(data) {
51
56
  const obj = JSON.parse(data[0]);
@@ -55,6 +60,18 @@ class CloudflareShopRepository {
55
60
  obj.shopActive = true;
56
61
  }
57
62
  shop.setShopActive(obj.shopActive);
63
+ if (obj.pendingShopUrl) {
64
+ shop.setPendingShopUrl(obj.pendingShopUrl);
65
+ }
66
+ if (obj.pendingShopSecret) {
67
+ shop.setPendingShopSecret(obj.pendingShopSecret);
68
+ }
69
+ if (obj.previousShopSecret) {
70
+ shop.setPreviousShopSecret(obj.previousShopSecret);
71
+ }
72
+ if (obj.secretsRotatedAt) {
73
+ shop.setSecretsRotatedAt(new Date(Number(obj.secretsRotatedAt)));
74
+ }
58
75
  if (data[1] !== null) {
59
76
  shop.setShopActive(JSON.parse(data[1]));
60
77
  }
@@ -62,6 +79,12 @@ class CloudflareShopRepository {
62
79
  const credentials = JSON.parse(data[2]);
63
80
  shop.setShopCredentials(credentials.clientId || "", credentials.clientSecret || "");
64
81
  }
82
+ if (obj.verified_with_double_signatures === 1) {
83
+ shop.setVerifiedWithDoubleSignature();
84
+ }
85
+ if (obj.registrationConfirmed === 1) {
86
+ shop.setRegistrationConfirmed();
87
+ }
65
88
  return shop;
66
89
  }
67
90
  }