@unchainedshop/plugins 4.0.0-rc.16 → 4.0.0-rc.17
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/lib/accounts/google-oauth.d.ts +4 -0
- package/lib/accounts/google-oauth.d.ts.map +1 -0
- package/lib/accounts/google-oauth.js +145 -0
- package/lib/accounts/google-oauth.js.map +1 -0
- package/lib/accounts/linkedin-oauth.d.ts +4 -0
- package/lib/accounts/linkedin-oauth.d.ts.map +1 -0
- package/lib/accounts/linkedin-oauth.js +82 -0
- package/lib/accounts/linkedin-oauth.js.map +1 -0
- package/lib/delivery/send-message.js.map +1 -1
- package/lib/enrollments/licensed.js +15 -2
- package/lib/enrollments/licensed.js.map +1 -1
- package/lib/files/gridfs/adapter.js +1 -1
- package/lib/files/gridfs/adapter.js.map +1 -1
- package/lib/files/gridfs/gridfs-adapter.d.ts +3 -0
- package/lib/files/gridfs/gridfs-adapter.d.ts.map +1 -0
- package/lib/files/gridfs/gridfs-adapter.js +97 -0
- package/lib/files/gridfs/gridfs-adapter.js.map +1 -0
- package/lib/files/gridfs/gridfs-webhook.d.ts +11 -0
- package/lib/files/gridfs/gridfs-webhook.d.ts.map +1 -0
- package/lib/files/gridfs/gridfs-webhook.js +84 -0
- package/lib/files/gridfs/gridfs-webhook.js.map +1 -0
- package/lib/files/gridfs/handler-express.d.ts.map +1 -1
- package/lib/files/gridfs/handler-express.js +6 -2
- package/lib/files/gridfs/handler-express.js.map +1 -1
- package/lib/files/gridfs/handler-fastify.d.ts.map +1 -1
- package/lib/files/gridfs/handler-fastify.js +11 -2
- package/lib/files/gridfs/handler-fastify.js.map +1 -1
- package/lib/files/gridfs/module.d.ts +2 -2
- package/lib/files/minio/handler-express.js +1 -1
- package/lib/files/minio/handler-express.js.map +1 -1
- package/lib/files/minio/handler-fastify.js +1 -1
- package/lib/files/minio/handler-fastify.js.map +1 -1
- package/lib/files/minio/index.d.ts +1 -1
- package/lib/files/minio/index.d.ts.map +1 -1
- package/lib/files/minio/index.js +3 -3
- package/lib/files/minio/index.js.map +1 -1
- package/lib/files/minio/minio-adapter.d.ts +6 -0
- package/lib/files/minio/minio-adapter.d.ts.map +1 -0
- package/lib/files/minio/minio-adapter.js +181 -0
- package/lib/files/minio/minio-adapter.js.map +1 -0
- package/lib/files/minio/minio-webhook.d.ts +2 -0
- package/lib/files/minio/minio-webhook.d.ts.map +1 -0
- package/lib/files/minio/minio-webhook.js +33 -0
- package/lib/files/minio/minio-webhook.js.map +1 -0
- package/lib/filters/local-search.js +1 -1
- package/lib/filters/local-search.js.map +1 -1
- package/lib/payment/apple-iap/adapter.js +12 -10
- package/lib/payment/apple-iap/adapter.js.map +1 -1
- package/lib/payment/apple-iap/db/AppleTransactionsCollection.d.ts +1 -1
- package/lib/payment/apple-iap/db/AppleTransactionsCollection.d.ts.map +1 -1
- package/lib/payment/apple-iap/handler-express.d.ts.map +1 -1
- package/lib/payment/apple-iap/handler-express.js +11 -4
- package/lib/payment/apple-iap/handler-express.js.map +1 -1
- package/lib/payment/apple-iap/handler-fastify.d.ts.map +1 -1
- package/lib/payment/apple-iap/handler-fastify.js +13 -6
- package/lib/payment/apple-iap/handler-fastify.js.map +1 -1
- package/lib/payment/apple-iap/module/configureAppleTransactionsModule.d.ts +9 -0
- package/lib/payment/apple-iap/module/configureAppleTransactionsModule.d.ts.map +1 -0
- package/lib/payment/apple-iap/module/configureAppleTransactionsModule.js +17 -0
- package/lib/payment/apple-iap/module/configureAppleTransactionsModule.js.map +1 -0
- package/lib/payment/apple-iap/module.d.ts +4 -4
- package/lib/payment/apple-iap/module.d.ts.map +1 -1
- package/lib/payment/apple-iap/module.js +4 -2
- package/lib/payment/apple-iap/module.js.map +1 -1
- package/lib/payment/braintree.js +3 -1
- package/lib/payment/braintree.js.map +1 -1
- package/lib/payment/cryptopay/db/CryptopayTransactions.d.ts +1 -1
- package/lib/payment/cryptopay/db/CryptopayTransactions.d.ts.map +1 -1
- package/lib/payment/cryptopay/derive-btc-address.d.ts.map +1 -1
- package/lib/payment/cryptopay/derive-btc-address.js +2 -3
- package/lib/payment/cryptopay/derive-btc-address.js.map +1 -1
- package/lib/payment/cryptopay/derive-eth-address.d.ts.map +1 -1
- package/lib/payment/cryptopay/derive-eth-address.js +2 -0
- package/lib/payment/cryptopay/derive-eth-address.js.map +1 -1
- package/lib/payment/cryptopay/handle-webhook.js +2 -2
- package/lib/payment/cryptopay/handle-webhook.js.map +1 -1
- package/lib/payment/cryptopay/handler-express.js +1 -1
- package/lib/payment/cryptopay/handler-express.js.map +1 -1
- package/lib/payment/cryptopay/handler-fastify.js +1 -1
- package/lib/payment/cryptopay/handler-fastify.js.map +1 -1
- package/lib/payment/cryptopay/middleware.d.ts +2 -0
- package/lib/payment/cryptopay/middleware.d.ts.map +1 -0
- package/lib/payment/cryptopay/middleware.js +75 -0
- package/lib/payment/cryptopay/middleware.js.map +1 -0
- package/lib/payment/cryptopay/module/configureCryptopayModule.d.ts +25 -0
- package/lib/payment/cryptopay/module/configureCryptopayModule.d.ts.map +1 -0
- package/lib/payment/cryptopay/module/configureCryptopayModule.js +75 -0
- package/lib/payment/cryptopay/module/configureCryptopayModule.js.map +1 -0
- package/lib/payment/cryptopay/module.d.ts +2 -2
- package/lib/payment/cryptopay/module.d.ts.map +1 -1
- package/lib/payment/cryptopay/module.js +4 -4
- package/lib/payment/cryptopay/module.js.map +1 -1
- package/lib/payment/cryptopay/plugin.d.ts.map +1 -1
- package/lib/payment/cryptopay/plugin.js +18 -4
- package/lib/payment/cryptopay/plugin.js.map +1 -1
- package/lib/payment/datatrans-v2/handler-express.d.ts.map +1 -1
- package/lib/payment/datatrans-v2/handler-express.js +8 -1
- package/lib/payment/datatrans-v2/handler-express.js.map +1 -1
- package/lib/payment/datatrans-v2/handler-fastify.d.ts.map +1 -1
- package/lib/payment/datatrans-v2/handler-fastify.js +7 -1
- package/lib/payment/datatrans-v2/handler-fastify.js.map +1 -1
- package/lib/payment/datatrans-v2/index.js +63 -37
- package/lib/payment/datatrans-v2/index.js.map +1 -1
- package/lib/payment/datatrans-v2/middleware.d.ts +2 -0
- package/lib/payment/datatrans-v2/middleware.d.ts.map +1 -0
- package/lib/payment/datatrans-v2/middleware.js +68 -0
- package/lib/payment/datatrans-v2/middleware.js.map +1 -0
- package/lib/payment/datatrans-v2/parseRegistrationData.d.ts +1 -1
- package/lib/payment/datatrans-v2/parseRegistrationData.d.ts.map +1 -1
- package/lib/payment/paypal-checkout.js +4 -2
- package/lib/payment/paypal-checkout.js.map +1 -1
- package/lib/payment/payrexx/api/index.d.ts +1 -1
- package/lib/payment/payrexx/api/index.d.ts.map +1 -1
- package/lib/payment/payrexx/api/makeFetcher.d.ts +1 -1
- package/lib/payment/payrexx/api/makeFetcher.d.ts.map +1 -1
- package/lib/payment/payrexx/api/makeFetcher.js +1 -1
- package/lib/payment/payrexx/api/makeFetcher.js.map +1 -1
- package/lib/payment/payrexx/handler-express.d.ts.map +1 -1
- package/lib/payment/payrexx/handler-express.js +3 -1
- package/lib/payment/payrexx/handler-express.js.map +1 -1
- package/lib/payment/payrexx/handler-fastify.d.ts.map +1 -1
- package/lib/payment/payrexx/handler-fastify.js +3 -1
- package/lib/payment/payrexx/handler-fastify.js.map +1 -1
- package/lib/payment/payrexx/index.js +21 -15
- package/lib/payment/payrexx/index.js.map +1 -1
- package/lib/payment/payrexx/middleware.d.ts +2 -0
- package/lib/payment/payrexx/middleware.d.ts.map +1 -0
- package/lib/payment/payrexx/middleware.js +86 -0
- package/lib/payment/payrexx/middleware.js.map +1 -0
- package/lib/payment/postfinance-checkout/handler-express.d.ts.map +1 -1
- package/lib/payment/postfinance-checkout/handler-express.js +4 -2
- package/lib/payment/postfinance-checkout/handler-express.js.map +1 -1
- package/lib/payment/postfinance-checkout/handler-fastify.d.ts.map +1 -1
- package/lib/payment/postfinance-checkout/handler-fastify.js +4 -2
- package/lib/payment/postfinance-checkout/handler-fastify.js.map +1 -1
- package/lib/payment/postfinance-checkout/index.d.ts.map +1 -1
- package/lib/payment/postfinance-checkout/index.js +20 -7
- package/lib/payment/postfinance-checkout/index.js.map +1 -1
- package/lib/payment/postfinance-checkout/middleware.d.ts +2 -0
- package/lib/payment/postfinance-checkout/middleware.d.ts.map +1 -0
- package/lib/payment/postfinance-checkout/middleware.js +38 -0
- package/lib/payment/postfinance-checkout/middleware.js.map +1 -0
- package/lib/payment/saferpay/adapter.d.ts.map +1 -1
- package/lib/payment/saferpay/adapter.js +9 -0
- package/lib/payment/saferpay/adapter.js.map +1 -1
- package/lib/payment/saferpay/handler-express.d.ts.map +1 -1
- package/lib/payment/saferpay/handler-express.js +3 -1
- package/lib/payment/saferpay/handler-express.js.map +1 -1
- package/lib/payment/saferpay/handler-fastify.d.ts.map +1 -1
- package/lib/payment/saferpay/handler-fastify.js +3 -1
- package/lib/payment/saferpay/handler-fastify.js.map +1 -1
- package/lib/payment/saferpay/middleware.d.ts +2 -0
- package/lib/payment/saferpay/middleware.d.ts.map +1 -0
- package/lib/payment/saferpay/middleware.js +57 -0
- package/lib/payment/saferpay/middleware.js.map +1 -0
- package/lib/payment/saferpay/module/configureSaferpayTransactionsModule.d.ts +10 -0
- package/lib/payment/saferpay/module/configureSaferpayTransactionsModule.d.ts.map +1 -0
- package/lib/payment/saferpay/module/configureSaferpayTransactionsModule.js +24 -0
- package/lib/payment/saferpay/module/configureSaferpayTransactionsModule.js.map +1 -0
- package/lib/payment/saferpay/module.d.ts +2 -2
- package/lib/payment/stripe/handler-express.d.ts.map +1 -1
- package/lib/payment/stripe/handler-express.js +9 -1
- package/lib/payment/stripe/handler-express.js.map +1 -1
- package/lib/payment/stripe/handler-fastify.d.ts.map +1 -1
- package/lib/payment/stripe/handler-fastify.js +9 -1
- package/lib/payment/stripe/handler-fastify.js.map +1 -1
- package/lib/payment/stripe/index.js +19 -13
- package/lib/payment/stripe/index.js.map +1 -1
- package/lib/payment/stripe/middleware.d.ts +6 -0
- package/lib/payment/stripe/middleware.d.ts.map +1 -0
- package/lib/payment/stripe/middleware.js +114 -0
- package/lib/payment/stripe/middleware.js.map +1 -0
- package/lib/payment/stripe/stripe.d.ts +2 -2
- package/lib/payment/stripe/stripe.d.ts.map +1 -1
- package/lib/payment/stripe/stripe.js +14 -11
- package/lib/payment/stripe/stripe.js.map +1 -1
- package/lib/plugins-index.d.ts +48 -0
- package/lib/plugins-index.d.ts.map +1 -0
- package/lib/plugins-index.js +107 -0
- package/lib/plugins-index.js.map +1 -0
- package/lib/presets/all.d.ts +5 -5
- package/lib/presets/all.d.ts.map +1 -1
- package/lib/pricing/delivery-swiss-tax.d.ts.map +1 -1
- package/lib/pricing/delivery-swiss-tax.js +13 -11
- package/lib/pricing/delivery-swiss-tax.js.map +1 -1
- package/lib/pricing/order-discount.d.ts.map +1 -1
- package/lib/pricing/order-discount.js +5 -3
- package/lib/pricing/order-discount.js.map +1 -1
- package/lib/pricing/order-round.d.ts.map +1 -1
- package/lib/pricing/order-round.js +4 -3
- package/lib/pricing/order-round.js.map +1 -1
- package/lib/pricing/product-catalog-price.js +4 -4
- package/lib/pricing/product-catalog-price.js.map +1 -1
- package/lib/pricing/product-price-rateconversion.js +3 -3
- package/lib/pricing/product-price-rateconversion.js.map +1 -1
- package/lib/pricing/product-swiss-tax.d.ts +1 -4
- package/lib/pricing/product-swiss-tax.d.ts.map +1 -1
- package/lib/pricing/product-swiss-tax.js +9 -15
- package/lib/pricing/product-swiss-tax.js.map +1 -1
- package/lib/pricing/tax/ch.d.ts +6 -0
- package/lib/pricing/tax/ch.d.ts.map +1 -1
- package/lib/pricing/tax/ch.js +10 -0
- package/lib/pricing/tax/ch.js.map +1 -1
- package/lib/warehousing/eth-minter.js +23 -11
- package/lib/warehousing/eth-minter.js.map +1 -1
- package/lib/worker/BaseWorker.d.ts +30 -0
- package/lib/worker/BaseWorker.d.ts.map +1 -0
- package/lib/worker/BaseWorker.js +79 -0
- package/lib/worker/BaseWorker.js.map +1 -0
- package/lib/worker/EventListenerWorker.d.ts +6 -0
- package/lib/worker/EventListenerWorker.d.ts.map +1 -0
- package/lib/worker/EventListenerWorker.js +46 -0
- package/lib/worker/EventListenerWorker.js.map +1 -0
- package/lib/worker/FailedRescheduler.d.ts +15 -0
- package/lib/worker/FailedRescheduler.d.ts.map +1 -0
- package/lib/worker/FailedRescheduler.js +45 -0
- package/lib/worker/FailedRescheduler.js.map +1 -0
- package/lib/worker/IntervalWorker.d.ts +10 -0
- package/lib/worker/IntervalWorker.d.ts.map +1 -0
- package/lib/worker/IntervalWorker.js +37 -0
- package/lib/worker/IntervalWorker.js.map +1 -0
- package/lib/worker/bulk-import.d.ts +1 -1
- package/lib/worker/bulk-import.d.ts.map +1 -1
- package/lib/worker/bulk-import.js +5 -4
- package/lib/worker/bulk-import.js.map +1 -1
- package/lib/worker/enrollment-order-generator.d.ts.map +1 -1
- package/lib/worker/enrollment-order-generator.js +7 -49
- package/lib/worker/enrollment-order-generator.js.map +1 -1
- package/lib/worker/error-notifications.js +1 -1
- package/lib/worker/error-notifications.js.map +1 -1
- package/lib/worker/export-token.d.ts.map +1 -1
- package/lib/worker/export-token.js +0 -1
- package/lib/worker/export-token.js.map +1 -1
- package/lib/worker/message.d.ts +1 -1
- package/lib/worker/message.d.ts.map +1 -1
- package/lib/worker/message.js +4 -2
- package/lib/worker/message.js.map +1 -1
- package/lib/worker/sms.d.ts +2 -0
- package/lib/worker/sms.d.ts.map +1 -0
- package/lib/worker/sms.js +73 -0
- package/lib/worker/sms.js.map +1 -0
- package/lib/worker/twilio.js +4 -0
- package/lib/worker/twilio.js.map +1 -1
- package/package.json +15 -15
- package/src/delivery/send-message.ts +1 -1
- package/src/enrollments/licensed.ts +15 -2
- package/src/files/gridfs/adapter.ts +1 -1
- package/src/files/gridfs/handler-express.ts +8 -2
- package/src/files/gridfs/handler-fastify.ts +13 -2
- package/src/files/minio/handler-express.ts +1 -1
- package/src/files/minio/handler-fastify.ts +1 -1
- package/src/files/minio/index.ts +12 -12
- package/src/filters/local-search.ts +1 -1
- package/src/payment/apple-iap/adapter.ts +12 -14
- package/src/payment/apple-iap/db/AppleTransactionsCollection.ts +1 -1
- package/src/payment/apple-iap/handler-express.ts +14 -5
- package/src/payment/apple-iap/handler-fastify.ts +17 -7
- package/src/payment/apple-iap/module.ts +9 -4
- package/src/payment/braintree.ts +4 -1
- package/src/payment/cryptopay/db/CryptopayTransactions.ts +1 -1
- package/src/payment/cryptopay/derive-btc-address.ts +1 -3
- package/src/payment/cryptopay/derive-eth-address.ts +2 -0
- package/src/payment/cryptopay/handle-webhook.ts +6 -6
- package/src/payment/cryptopay/handler-express.ts +1 -1
- package/src/payment/cryptopay/handler-fastify.ts +1 -1
- package/src/payment/cryptopay/module.ts +8 -5
- package/src/payment/cryptopay/plugin.ts +21 -4
- package/src/payment/datatrans-v2/handler-express.ts +12 -2
- package/src/payment/datatrans-v2/handler-fastify.ts +11 -2
- package/src/payment/datatrans-v2/index.ts +82 -50
- package/src/payment/paypal-checkout.ts +4 -2
- package/src/payment/payrexx/api/index.ts +1 -1
- package/src/payment/payrexx/api/makeFetcher.ts +2 -2
- package/src/payment/payrexx/handler-express.ts +3 -1
- package/src/payment/payrexx/handler-fastify.ts +5 -4
- package/src/payment/payrexx/index.ts +26 -16
- package/src/payment/postfinance-checkout/handler-express.ts +5 -2
- package/src/payment/postfinance-checkout/handler-fastify.ts +5 -2
- package/src/payment/postfinance-checkout/index.ts +20 -8
- package/src/payment/saferpay/adapter.ts +14 -2
- package/src/payment/saferpay/handler-express.ts +4 -1
- package/src/payment/saferpay/handler-fastify.ts +4 -1
- package/src/payment/stripe/handler-express.ts +9 -1
- package/src/payment/stripe/handler-fastify.ts +9 -1
- package/src/payment/stripe/index.ts +17 -13
- package/src/payment/stripe/stripe.ts +17 -12
- package/src/pricing/delivery-swiss-tax.ts +11 -19
- package/src/pricing/order-discount.ts +6 -4
- package/src/pricing/order-round.ts +5 -4
- package/src/pricing/product-catalog-price.ts +4 -4
- package/src/pricing/product-price-rateconversion.ts +3 -3
- package/src/pricing/product-swiss-tax.test.ts +1 -86
- package/src/pricing/product-swiss-tax.ts +11 -24
- package/src/pricing/tax/ch.test.ts +86 -1
- package/src/pricing/tax/ch.ts +23 -0
- package/src/warehousing/eth-minter.ts +30 -11
- package/src/worker/budgetsms.ts +1 -1
- package/src/worker/bulk-import.ts +6 -7
- package/src/worker/enrollment-order-generator.ts +14 -72
- package/src/worker/error-notifications.ts +2 -2
- package/src/worker/export-token.ts +0 -1
- package/src/worker/message.ts +5 -3
- package/src/worker/twilio.ts +10 -3
|
@@ -10,7 +10,7 @@ import { getFileAdapter } from '@unchainedshop/core-files';
|
|
|
10
10
|
|
|
11
11
|
const { ROOT_URL } = process.env;
|
|
12
12
|
|
|
13
|
-
const logger = createLogger('unchained:
|
|
13
|
+
const logger = createLogger('unchained:gridfs');
|
|
14
14
|
|
|
15
15
|
const gridfsHandler = async (
|
|
16
16
|
req: express.Request & {
|
|
@@ -44,6 +44,12 @@ const gridfsHandler = async (
|
|
|
44
44
|
const fileId = await buildHashedFilename(directoryName, fileName, expiryDate);
|
|
45
45
|
if ((await sign(directoryName, fileId, expiryDate.getTime())) === signature) {
|
|
46
46
|
const file = await modules.files.findFile({ fileId });
|
|
47
|
+
|
|
48
|
+
if (!file) {
|
|
49
|
+
res.status(404).send('File not found');
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
47
53
|
if (file.expires === null) {
|
|
48
54
|
res.status(400).send('File already linked');
|
|
49
55
|
return;
|
|
@@ -97,7 +103,7 @@ const gridfsHandler = async (
|
|
|
97
103
|
const fileUploadAdapter = getFileAdapter();
|
|
98
104
|
const signedUrl = await fileUploadAdapter.createDownloadURL(fileDocument, expiry);
|
|
99
105
|
|
|
100
|
-
if (new URL(signedUrl, 'file://').searchParams.get('s') !== signature) {
|
|
106
|
+
if (!signedUrl || new URL(signedUrl, 'file://').searchParams.get('s') !== signature) {
|
|
101
107
|
res.status(403).send('Access restricted: Invalid signature.');
|
|
102
108
|
return;
|
|
103
109
|
}
|
|
@@ -8,7 +8,7 @@ import { Context } from '@unchainedshop/api';
|
|
|
8
8
|
import { createLogger } from '@unchainedshop/logger';
|
|
9
9
|
import { getFileAdapter } from '@unchainedshop/core-files';
|
|
10
10
|
|
|
11
|
-
const logger = createLogger('unchained:
|
|
11
|
+
const logger = createLogger('unchained:gridfs');
|
|
12
12
|
|
|
13
13
|
const gridfsHandler: RouteHandlerMethod = async (
|
|
14
14
|
req: FastifyRequest & {
|
|
@@ -39,6 +39,17 @@ const gridfsHandler: RouteHandlerMethod = async (
|
|
|
39
39
|
const fileId = await buildHashedFilename(directoryName, fileName, expiryDate);
|
|
40
40
|
if ((await sign(directoryName, fileId, expiryDate.getTime())) === signature) {
|
|
41
41
|
const file = await modules.files.findFile({ fileId });
|
|
42
|
+
|
|
43
|
+
if (!file) {
|
|
44
|
+
reply.status(404);
|
|
45
|
+
logger.error('File not found', { fileId });
|
|
46
|
+
return reply.send({
|
|
47
|
+
success: false,
|
|
48
|
+
message: 'File not found',
|
|
49
|
+
name: 'FILE_NOT_FOUND',
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
42
53
|
if (file.expires === null) {
|
|
43
54
|
reply.status(400);
|
|
44
55
|
logger.error('File already linked', { fileId });
|
|
@@ -113,7 +124,7 @@ const gridfsHandler: RouteHandlerMethod = async (
|
|
|
113
124
|
const fileUploadAdapter = getFileAdapter();
|
|
114
125
|
const signedUrl = await fileUploadAdapter.createDownloadURL(fileDocument, expiry);
|
|
115
126
|
|
|
116
|
-
if (new URL(signedUrl, 'file://').searchParams.get('s') !== signature) {
|
|
127
|
+
if (!signedUrl || new URL(signedUrl, 'file://').searchParams.get('s') !== signature) {
|
|
117
128
|
reply.status(403);
|
|
118
129
|
logger.error('Invalid signature', { fileId, expiry });
|
|
119
130
|
return reply.send({
|
|
@@ -2,7 +2,7 @@ import { Context } from '@unchainedshop/api';
|
|
|
2
2
|
import { createLogger } from '@unchainedshop/logger';
|
|
3
3
|
import { FastifyRequest, RouteHandlerMethod } from 'fastify';
|
|
4
4
|
|
|
5
|
-
const logger = createLogger('unchained:
|
|
5
|
+
const logger = createLogger('unchained:minio');
|
|
6
6
|
|
|
7
7
|
const { MINIO_WEBHOOK_AUTH_TOKEN } = process.env;
|
|
8
8
|
|
package/src/files/minio/index.ts
CHANGED
|
@@ -14,7 +14,7 @@ import { AssumeRoleProvider } from 'minio/dist/esm/AssumeRoleProvider.mjs';
|
|
|
14
14
|
import { expiryOffsetInMs } from '@unchainedshop/file-upload/lib/put-expiration.js';
|
|
15
15
|
import { createLogger } from '@unchainedshop/logger';
|
|
16
16
|
|
|
17
|
-
const logger = createLogger('unchained:
|
|
17
|
+
const logger = createLogger('unchained:minio');
|
|
18
18
|
|
|
19
19
|
const {
|
|
20
20
|
MINIO_ACCESS_KEY,
|
|
@@ -28,7 +28,7 @@ const {
|
|
|
28
28
|
AMAZON_S3_SESSION_TOKEN,
|
|
29
29
|
} = process.env;
|
|
30
30
|
|
|
31
|
-
let client: Client;
|
|
31
|
+
let client: Client | null = null;
|
|
32
32
|
|
|
33
33
|
export async function connectToMinio() {
|
|
34
34
|
if (!MINIO_ENDPOINT || !MINIO_BUCKET_NAME) {
|
|
@@ -56,8 +56,8 @@ export async function connectToMinio() {
|
|
|
56
56
|
if (MINIO_STS_ENDPOINT) {
|
|
57
57
|
const ap = new AssumeRoleProvider({
|
|
58
58
|
stsEndpoint: MINIO_STS_ENDPOINT,
|
|
59
|
-
accessKey: MINIO_ACCESS_KEY
|
|
60
|
-
secretKey: MINIO_SECRET_KEY
|
|
59
|
+
accessKey: MINIO_ACCESS_KEY!,
|
|
60
|
+
secretKey: MINIO_SECRET_KEY!,
|
|
61
61
|
});
|
|
62
62
|
// eslint-disable-next-line
|
|
63
63
|
// @ts-ignore
|
|
@@ -76,17 +76,17 @@ const generateMinioPath = (directoryName: string, fileName: string) => {
|
|
|
76
76
|
};
|
|
77
77
|
|
|
78
78
|
const generateMinioUrl = (directoryName: string, hashedFilename: string) => {
|
|
79
|
-
return `${MINIO_ENDPOINT}/${MINIO_BUCKET_NAME}/${generateMinioPath(directoryName, hashedFilename)}`;
|
|
79
|
+
return `${MINIO_ENDPOINT}/${MINIO_BUCKET_NAME!}/${generateMinioPath(directoryName, hashedFilename)}`;
|
|
80
80
|
};
|
|
81
81
|
|
|
82
82
|
connectToMinio().then(function setClient(c) {
|
|
83
|
-
client = c;
|
|
83
|
+
client = c || client;
|
|
84
84
|
});
|
|
85
85
|
|
|
86
86
|
const getObjectStats = async (fileName: string) => {
|
|
87
87
|
if (!client) throw new Error('Minio not connected, check env variables');
|
|
88
88
|
|
|
89
|
-
return client.statObject(MINIO_BUCKET_NAME
|
|
89
|
+
return client.statObject(MINIO_BUCKET_NAME!, fileName);
|
|
90
90
|
};
|
|
91
91
|
|
|
92
92
|
const bufferToStream = (buffer: any) => {
|
|
@@ -116,7 +116,7 @@ export const MinioAdapter: IFileAdapter = {
|
|
|
116
116
|
const _id = await buildHashedFilename(directoryName, fileName, expiryDate);
|
|
117
117
|
|
|
118
118
|
const url = await client.presignedPutObject(
|
|
119
|
-
MINIO_BUCKET_NAME
|
|
119
|
+
MINIO_BUCKET_NAME!,
|
|
120
120
|
generateMinioPath(directoryName, _id),
|
|
121
121
|
expiryOffsetInMs() / 1000,
|
|
122
122
|
);
|
|
@@ -139,7 +139,7 @@ export const MinioAdapter: IFileAdapter = {
|
|
|
139
139
|
return `${path}/${_id}`;
|
|
140
140
|
});
|
|
141
141
|
|
|
142
|
-
await client.removeObjects(MINIO_BUCKET_NAME
|
|
142
|
+
await client.removeObjects(MINIO_BUCKET_NAME!, fileIds);
|
|
143
143
|
},
|
|
144
144
|
|
|
145
145
|
async uploadFileFromStream(directoryName: string, rawFile: any) {
|
|
@@ -164,7 +164,7 @@ export const MinioAdapter: IFileAdapter = {
|
|
|
164
164
|
};
|
|
165
165
|
|
|
166
166
|
await client.putObject(
|
|
167
|
-
MINIO_BUCKET_NAME
|
|
167
|
+
MINIO_BUCKET_NAME!,
|
|
168
168
|
generateMinioPath(directoryName, _id),
|
|
169
169
|
stream,
|
|
170
170
|
undefined,
|
|
@@ -200,7 +200,7 @@ export const MinioAdapter: IFileAdapter = {
|
|
|
200
200
|
};
|
|
201
201
|
|
|
202
202
|
await client.putObject(
|
|
203
|
-
MINIO_BUCKET_NAME
|
|
203
|
+
MINIO_BUCKET_NAME!,
|
|
204
204
|
generateMinioPath(directoryName, hashedFilename),
|
|
205
205
|
readable,
|
|
206
206
|
undefined,
|
|
@@ -222,7 +222,7 @@ export const MinioAdapter: IFileAdapter = {
|
|
|
222
222
|
async createDownloadStream(file) {
|
|
223
223
|
if (!client) throw new Error('Minio not connected, check env variables');
|
|
224
224
|
|
|
225
|
-
const stream = await client.getObject(MINIO_BUCKET_NAME
|
|
225
|
+
const stream = await client.getObject(MINIO_BUCKET_NAME!, generateMinioPath(file.path, file._id));
|
|
226
226
|
return stream;
|
|
227
227
|
},
|
|
228
228
|
};
|
|
@@ -5,7 +5,7 @@ import { FilterDirector, FilterAdapter, IFilterAdapter } from '@unchainedshop/co
|
|
|
5
5
|
import { createLogger } from '@unchainedshop/logger';
|
|
6
6
|
import { isDocumentDBCompatModeEnabled } from '@unchainedshop/mongodb';
|
|
7
7
|
|
|
8
|
-
const logger = createLogger('unchained:
|
|
8
|
+
const logger = createLogger('unchained:local-search');
|
|
9
9
|
|
|
10
10
|
const LocalSearch: IFilterAdapter = {
|
|
11
11
|
...FilterAdapter,
|
|
@@ -3,7 +3,7 @@ import { createLogger } from '@unchainedshop/logger';
|
|
|
3
3
|
import { AppleTransactionsModule } from './module.js';
|
|
4
4
|
import { verifyReceipt } from './verify-receipt.js';
|
|
5
5
|
|
|
6
|
-
const logger = createLogger('unchained:
|
|
6
|
+
const logger = createLogger('unchained:apple-iap');
|
|
7
7
|
|
|
8
8
|
const { APPLE_IAP_SHARED_SECRET } = process.env;
|
|
9
9
|
|
|
@@ -42,7 +42,7 @@ const AppleIAP: IPaymentAdapter = {
|
|
|
42
42
|
},
|
|
43
43
|
|
|
44
44
|
async sign() {
|
|
45
|
-
throw new Error('
|
|
45
|
+
throw new Error('Payment signing not supported');
|
|
46
46
|
},
|
|
47
47
|
|
|
48
48
|
async validate() {
|
|
@@ -60,7 +60,7 @@ const AppleIAP: IPaymentAdapter = {
|
|
|
60
60
|
const { status, latest_receipt_info: latestReceiptInfo } = response;
|
|
61
61
|
|
|
62
62
|
if (status === 0) {
|
|
63
|
-
logger.debug('
|
|
63
|
+
logger.debug('Receipt validated and updated for the user');
|
|
64
64
|
const latestTransaction = latestReceiptInfo[latestReceiptInfo.length - 1];
|
|
65
65
|
return {
|
|
66
66
|
token: latestTransaction.web_order_line_item_id,
|
|
@@ -68,7 +68,7 @@ const AppleIAP: IPaymentAdapter = {
|
|
|
68
68
|
};
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
logger.warn('
|
|
71
|
+
logger.warn('Receipt invalid', {
|
|
72
72
|
status: response.status,
|
|
73
73
|
});
|
|
74
74
|
return null;
|
|
@@ -79,9 +79,11 @@ const AppleIAP: IPaymentAdapter = {
|
|
|
79
79
|
const { transactionIdentifier } = meta || {};
|
|
80
80
|
|
|
81
81
|
if (!transactionIdentifier) {
|
|
82
|
-
throw new Error('
|
|
82
|
+
throw new Error('You have to set the transaction id on the order payment');
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
if (!order) throw new Error('Order not found');
|
|
86
|
+
|
|
85
87
|
const receiptResponse =
|
|
86
88
|
receiptData &&
|
|
87
89
|
(await verifyReceipt({
|
|
@@ -90,7 +92,7 @@ const AppleIAP: IPaymentAdapter = {
|
|
|
90
92
|
}));
|
|
91
93
|
|
|
92
94
|
if (receiptResponse && receiptResponse.status !== 0) {
|
|
93
|
-
throw new Error('
|
|
95
|
+
throw new Error('Receipt invalid');
|
|
94
96
|
}
|
|
95
97
|
|
|
96
98
|
const transactions =
|
|
@@ -99,9 +101,7 @@ const AppleIAP: IPaymentAdapter = {
|
|
|
99
101
|
(transaction) => transaction?.transaction_id === transactionIdentifier,
|
|
100
102
|
);
|
|
101
103
|
if (!matchedTransaction) {
|
|
102
|
-
throw new Error(
|
|
103
|
-
`Apple IAP Plugin: Cannot match transaction with identifier ${transactionIdentifier}`,
|
|
104
|
-
);
|
|
104
|
+
throw new Error(`Cannot match transaction with identifier ${transactionIdentifier}`);
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
const orderPositions = await modules.orders.positions.findOrderPositions({
|
|
@@ -117,7 +117,7 @@ const AppleIAP: IPaymentAdapter = {
|
|
|
117
117
|
);
|
|
118
118
|
|
|
119
119
|
if (items.length !== 1) {
|
|
120
|
-
throw new Error('
|
|
120
|
+
throw new Error('You can only checkout 1 unique product at once');
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
const [[productId, quantity]] = items;
|
|
@@ -126,14 +126,12 @@ const AppleIAP: IPaymentAdapter = {
|
|
|
126
126
|
parseInt(matchedTransaction.quantity, 10) === quantity &&
|
|
127
127
|
matchedTransaction.product_id === productId;
|
|
128
128
|
|
|
129
|
-
if (!isMatchesTransaction)
|
|
130
|
-
throw new Error('Apple IAP Plugin: Product in order does not match transaction');
|
|
129
|
+
if (!isMatchesTransaction) throw new Error('Product in order does not match transaction');
|
|
131
130
|
|
|
132
131
|
const alreadyProcessedTransaction =
|
|
133
132
|
await modules.appleTransactions.findTransactionById(transactionIdentifier);
|
|
134
133
|
|
|
135
|
-
if (alreadyProcessedTransaction)
|
|
136
|
-
throw new Error('Apple IAP Plugin: Transaction already processed');
|
|
134
|
+
if (alreadyProcessedTransaction) throw new Error('Transaction already processed');
|
|
137
135
|
|
|
138
136
|
// All good
|
|
139
137
|
await modules.appleTransactions.createTransaction({
|
|
@@ -3,7 +3,7 @@ import { EnrollmentStatus } from '@unchainedshop/core-enrollments';
|
|
|
3
3
|
import { createLogger } from '@unchainedshop/logger';
|
|
4
4
|
import { fixPeriods } from './fix-periods.js';
|
|
5
5
|
|
|
6
|
-
const logger = createLogger('unchained:
|
|
6
|
+
const logger = createLogger('unchained:apple-iap:handler');
|
|
7
7
|
|
|
8
8
|
const { APPLE_IAP_SHARED_SECRET } = process.env;
|
|
9
9
|
|
|
@@ -43,10 +43,16 @@ export const appleIAPHandler = async (req, res) => {
|
|
|
43
43
|
receiptData: responseBody?.unified_receipt?.latest_receipt,
|
|
44
44
|
},
|
|
45
45
|
});
|
|
46
|
+
|
|
47
|
+
if (!order) throw new Error(`Order with id ${orderPayment.orderId} not found`);
|
|
48
|
+
|
|
46
49
|
const orderId = order._id;
|
|
47
50
|
const enrollment = await modules.enrollments.findEnrollment({
|
|
48
51
|
orderId,
|
|
49
52
|
});
|
|
53
|
+
|
|
54
|
+
if (!enrollment) throw new Error('Could not find any matching enrollment');
|
|
55
|
+
|
|
50
56
|
await fixPeriods(
|
|
51
57
|
{
|
|
52
58
|
transactionId: latestTransaction.original_transaction_id,
|
|
@@ -72,9 +78,12 @@ export const appleIAPHandler = async (req, res) => {
|
|
|
72
78
|
const originalOrder = await modules.orders.findOrder({
|
|
73
79
|
orderId: originalOrderPayment.orderId,
|
|
74
80
|
});
|
|
75
|
-
const enrollment =
|
|
76
|
-
|
|
77
|
-
|
|
81
|
+
const enrollment =
|
|
82
|
+
originalOrder &&
|
|
83
|
+
(await modules.enrollments.findEnrollment({
|
|
84
|
+
orderId: originalOrder._id,
|
|
85
|
+
}));
|
|
86
|
+
if (!enrollment?.payment) throw new Error('Could not find a valid enrollment payment method');
|
|
78
87
|
|
|
79
88
|
await services.orders.registerPaymentCredentials(enrollment.payment.paymentProviderId, {
|
|
80
89
|
transactionContext: {
|
|
@@ -88,7 +97,7 @@ export const appleIAPHandler = async (req, res) => {
|
|
|
88
97
|
transactionId: latestTransaction.original_transaction_id,
|
|
89
98
|
transactions,
|
|
90
99
|
enrollmentId: enrollment._id,
|
|
91
|
-
orderId: originalOrder
|
|
100
|
+
orderId: originalOrder!._id,
|
|
92
101
|
},
|
|
93
102
|
resolvedContext,
|
|
94
103
|
);
|
|
@@ -5,7 +5,7 @@ import { fixPeriods } from './fix-periods.js';
|
|
|
5
5
|
import { FastifyRequest, RouteHandlerMethod } from 'fastify';
|
|
6
6
|
import { AppleTransactionsModule } from './module.js';
|
|
7
7
|
|
|
8
|
-
const logger = createLogger('unchained:
|
|
8
|
+
const logger = createLogger('unchained:apple-iap:handler');
|
|
9
9
|
|
|
10
10
|
const { APPLE_IAP_SHARED_SECRET } = process.env;
|
|
11
11
|
|
|
@@ -51,10 +51,16 @@ export const appleIAPHandler: RouteHandlerMethod = async (
|
|
|
51
51
|
receiptData: responseBody?.unified_receipt?.latest_receipt,
|
|
52
52
|
},
|
|
53
53
|
});
|
|
54
|
+
|
|
55
|
+
if (!order) throw new Error(`Order with id ${orderPayment.orderId} not found`);
|
|
56
|
+
|
|
54
57
|
const orderId = order._id;
|
|
55
58
|
const enrollment = await modules.enrollments.findEnrollment({
|
|
56
59
|
orderId,
|
|
57
60
|
});
|
|
61
|
+
|
|
62
|
+
if (!enrollment) throw new Error('Enrollent not found');
|
|
63
|
+
|
|
58
64
|
await fixPeriods(
|
|
59
65
|
{
|
|
60
66
|
transactionId: latestTransaction.original_transaction_id,
|
|
@@ -65,7 +71,7 @@ export const appleIAPHandler: RouteHandlerMethod = async (
|
|
|
65
71
|
resolvedContext,
|
|
66
72
|
);
|
|
67
73
|
|
|
68
|
-
logger.info(`
|
|
74
|
+
logger.info(`Webhook confirmed checkout for order ${order.orderNumber}`, {
|
|
69
75
|
orderId: order._id,
|
|
70
76
|
});
|
|
71
77
|
} else {
|
|
@@ -80,9 +86,13 @@ export const appleIAPHandler: RouteHandlerMethod = async (
|
|
|
80
86
|
const originalOrder = await modules.orders.findOrder({
|
|
81
87
|
orderId: originalOrderPayment.orderId,
|
|
82
88
|
});
|
|
83
|
-
const enrollment =
|
|
84
|
-
|
|
85
|
-
|
|
89
|
+
const enrollment =
|
|
90
|
+
originalOrder &&
|
|
91
|
+
(await modules.enrollments.findEnrollment({
|
|
92
|
+
orderId: originalOrder._id,
|
|
93
|
+
}));
|
|
94
|
+
|
|
95
|
+
if (!enrollment?.payment) throw new Error('Could not find a valid enrollment payment method');
|
|
86
96
|
|
|
87
97
|
await services.orders.registerPaymentCredentials(enrollment.payment.paymentProviderId, {
|
|
88
98
|
transactionContext: {
|
|
@@ -96,13 +106,13 @@ export const appleIAPHandler: RouteHandlerMethod = async (
|
|
|
96
106
|
transactionId: latestTransaction.original_transaction_id,
|
|
97
107
|
transactions,
|
|
98
108
|
enrollmentId: enrollment._id,
|
|
99
|
-
orderId: originalOrder
|
|
109
|
+
orderId: originalOrder!._id,
|
|
100
110
|
},
|
|
101
111
|
resolvedContext,
|
|
102
112
|
);
|
|
103
113
|
|
|
104
114
|
logger.info(
|
|
105
|
-
`
|
|
115
|
+
`Webhook rocessed notification for ${latestTransaction.original_transaction_id} and type ${responseBody.notification_type}`,
|
|
106
116
|
);
|
|
107
117
|
|
|
108
118
|
if (responseBody.notification_type === AppleNotificationTypes.DID_RECOVER) {
|
|
@@ -1,19 +1,24 @@
|
|
|
1
|
+
import { generateDbObjectId } from '@unchainedshop/mongodb';
|
|
1
2
|
import { AppleTransaction, AppleTransactionsCollection } from './db/AppleTransactionsCollection.js';
|
|
2
3
|
|
|
3
4
|
export const configureAppleTransactionsModule = async ({ db }) => {
|
|
4
5
|
const AppleTransactions = await AppleTransactionsCollection(db);
|
|
5
6
|
|
|
6
7
|
return {
|
|
7
|
-
findTransactionById: async (transactionIdentifier: string): Promise<AppleTransaction> => {
|
|
8
|
+
findTransactionById: async (transactionIdentifier: string): Promise<AppleTransaction | null> => {
|
|
8
9
|
return AppleTransactions.findOne({ _id: transactionIdentifier });
|
|
9
10
|
},
|
|
10
11
|
|
|
11
|
-
createTransaction: async (
|
|
12
|
-
|
|
12
|
+
createTransaction: async (
|
|
13
|
+
doc: Omit<AppleTransaction, '_id' | 'created'> &
|
|
14
|
+
Pick<Partial<AppleTransaction>, '_id' | 'created'>,
|
|
15
|
+
) => {
|
|
16
|
+
const { insertedId } = await AppleTransactions.insertOne({
|
|
17
|
+
_id: generateDbObjectId(),
|
|
13
18
|
...doc,
|
|
14
19
|
created: new Date(),
|
|
15
20
|
});
|
|
16
|
-
return
|
|
21
|
+
return insertedId;
|
|
17
22
|
},
|
|
18
23
|
};
|
|
19
24
|
};
|
package/src/payment/braintree.ts
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
OrderPricingSheet,
|
|
8
8
|
} from '@unchainedshop/core';
|
|
9
9
|
|
|
10
|
-
const logger = createLogger('unchained:
|
|
10
|
+
const logger = createLogger('unchained:braintree');
|
|
11
11
|
|
|
12
12
|
const { BRAINTREE_SANDBOX_TOKEN, BRAINTREE_PRIVATE_KEY } = process.env;
|
|
13
13
|
|
|
@@ -108,6 +108,9 @@ const BraintreeDirect: IPaymentAdapter = {
|
|
|
108
108
|
|
|
109
109
|
charge: async ({ paypalPaymentMethodNonce }) => {
|
|
110
110
|
const { order } = context;
|
|
111
|
+
|
|
112
|
+
if (!order) throw new Error('Order is missing in payment context');
|
|
113
|
+
|
|
111
114
|
if (!paypalPaymentMethodNonce)
|
|
112
115
|
throw new Error('You have to provide paypalPaymentMethodNonce in paymentContext');
|
|
113
116
|
|
|
@@ -37,9 +37,7 @@ export default (xpub, index) => {
|
|
|
37
37
|
|
|
38
38
|
const child = hardenedMaster.deriveChild(0).deriveChild(index);
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
// const derivationPath = resolvePath(prefix);
|
|
42
|
-
// const child = hardenedMaster.derive(`${derivationPath}/0/${btcDerivationNumber}`);
|
|
40
|
+
if (!child.publicKey) throw new Error('Cannot derive public key from extended public key');
|
|
43
41
|
|
|
44
42
|
const network = resolveNetwork(prefix);
|
|
45
43
|
const pubKey = p2wpkh(child.publicKey /* hex.decode( as string)*/, network);
|
|
@@ -28,6 +28,8 @@ export default (xpub, index) => {
|
|
|
28
28
|
|
|
29
29
|
const child = hardenedMaster.deriveChild(0).deriveChild(index);
|
|
30
30
|
|
|
31
|
+
if (!child.publicKey) throw new Error('Could not derive child key from extended public key');
|
|
32
|
+
|
|
31
33
|
// ETH Address (secp256k1 + keccak_256 + checksum)
|
|
32
34
|
const childSigningKey = secp256k1.Point.fromBytes(child.publicKey).toBytes(false);
|
|
33
35
|
const address = Buffer.from(keccak_256(childSigningKey.slice(1)))
|
|
@@ -6,7 +6,7 @@ import { ProductPriceRate } from '@unchainedshop/core-products';
|
|
|
6
6
|
|
|
7
7
|
const { CRYPTOPAY_SECRET, CRYPTOPAY_MAX_RATE_AGE = '360' } = process.env;
|
|
8
8
|
|
|
9
|
-
const logger = createLogger('unchained:
|
|
9
|
+
const logger = createLogger('unchained:cryptopay:handler');
|
|
10
10
|
|
|
11
11
|
export default async function handleWebhook(
|
|
12
12
|
{
|
|
@@ -54,7 +54,7 @@ export default async function handleWebhook(
|
|
|
54
54
|
blockHeight,
|
|
55
55
|
amount,
|
|
56
56
|
contract,
|
|
57
|
-
decimals,
|
|
57
|
+
decimals: decimals ?? 0,
|
|
58
58
|
currencyCode,
|
|
59
59
|
});
|
|
60
60
|
|
|
@@ -68,10 +68,10 @@ export default async function handleWebhook(
|
|
|
68
68
|
// Try to process order to next status
|
|
69
69
|
// TODO: Not sure if it's correct to use processOrder here if status is PENDING!
|
|
70
70
|
const order = await modules.orders.findOrder({ orderId: orderPayment.orderId });
|
|
71
|
-
if (order
|
|
72
|
-
await services.orders.checkoutOrder(order
|
|
73
|
-
} else if (order
|
|
74
|
-
await services.orders.processOrder(order
|
|
71
|
+
if (order!.status === null) {
|
|
72
|
+
await services.orders.checkoutOrder(order!._id, {});
|
|
73
|
+
} else if (order!.status === OrderStatus.PENDING) {
|
|
74
|
+
await services.orders.processOrder(order!, {});
|
|
75
75
|
} else {
|
|
76
76
|
throw new Error('Already processed');
|
|
77
77
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createLogger } from '@unchainedshop/logger';
|
|
2
2
|
import handleWebhook from './handle-webhook.js';
|
|
3
3
|
|
|
4
|
-
const logger = createLogger('unchained:
|
|
4
|
+
const logger = createLogger('unchained:cryptopay:handler');
|
|
5
5
|
|
|
6
6
|
const cryptopayHandler = async (req, res) => {
|
|
7
7
|
if (req.method === 'POST') {
|
|
@@ -2,7 +2,7 @@ import { createLogger } from '@unchainedshop/logger';
|
|
|
2
2
|
import handleWebhook from './handle-webhook.js';
|
|
3
3
|
import { FastifyRequest, RouteHandlerMethod } from 'fastify';
|
|
4
4
|
|
|
5
|
-
const logger = createLogger('unchained:
|
|
5
|
+
const logger = createLogger('unchained:cryptopay:handler');
|
|
6
6
|
|
|
7
7
|
const cryptopayHandler: RouteHandlerMethod = async (
|
|
8
8
|
req: FastifyRequest & {
|
|
@@ -4,7 +4,10 @@ import { CryptopayTransaction, CryptopayTransactionsCollection } from './db/Cryp
|
|
|
4
4
|
const configureCryptopayModule = ({ db }) => {
|
|
5
5
|
const CryptoTransactions = CryptopayTransactionsCollection(db);
|
|
6
6
|
|
|
7
|
-
const getWalletAddress = async (
|
|
7
|
+
const getWalletAddress = async (
|
|
8
|
+
address: string,
|
|
9
|
+
contract?: string,
|
|
10
|
+
): Promise<CryptopayTransaction | null> => {
|
|
8
11
|
const addressId = [address, contract].filter(Boolean).join(':');
|
|
9
12
|
return CryptoTransactions.findOne({ _id: addressId });
|
|
10
13
|
};
|
|
@@ -35,7 +38,7 @@ const configureCryptopayModule = ({ db }) => {
|
|
|
35
38
|
}): Promise<CryptopayTransaction> => {
|
|
36
39
|
const addressId = [address, contract].filter(Boolean).join(':');
|
|
37
40
|
|
|
38
|
-
return CryptoTransactions.findOneAndUpdate(
|
|
41
|
+
return (await CryptoTransactions.findOneAndUpdate(
|
|
39
42
|
{
|
|
40
43
|
_id: addressId,
|
|
41
44
|
},
|
|
@@ -54,7 +57,7 @@ const configureCryptopayModule = ({ db }) => {
|
|
|
54
57
|
},
|
|
55
58
|
},
|
|
56
59
|
{ upsert: true, returnDocument: 'after' },
|
|
57
|
-
);
|
|
60
|
+
)) as CryptopayTransaction;
|
|
58
61
|
};
|
|
59
62
|
|
|
60
63
|
const getNextDerivationNumber = async (currencyCode: string): Promise<number> => {
|
|
@@ -92,7 +95,7 @@ const configureCryptopayModule = ({ db }) => {
|
|
|
92
95
|
decimals: number;
|
|
93
96
|
}): Promise<CryptopayTransaction> => {
|
|
94
97
|
const addressId = [address, contract].filter(Boolean).join(':');
|
|
95
|
-
return CryptoTransactions.findOneAndUpdate(
|
|
98
|
+
return (await CryptoTransactions.findOneAndUpdate(
|
|
96
99
|
{
|
|
97
100
|
_id: addressId,
|
|
98
101
|
},
|
|
@@ -111,7 +114,7 @@ const configureCryptopayModule = ({ db }) => {
|
|
|
111
114
|
},
|
|
112
115
|
},
|
|
113
116
|
{ upsert: true, returnDocument: 'after' },
|
|
114
|
-
);
|
|
117
|
+
)) as CryptopayTransaction;
|
|
115
118
|
};
|
|
116
119
|
|
|
117
120
|
return {
|
|
@@ -12,7 +12,7 @@ import deriveBtcAddress from './derive-btc-address.js';
|
|
|
12
12
|
import deriveEthAddress from './derive-eth-address.js';
|
|
13
13
|
import denoteAmount from './denote-amount.js';
|
|
14
14
|
|
|
15
|
-
const logger = createLogger('unchained:
|
|
15
|
+
const logger = createLogger('unchained:cryptopay');
|
|
16
16
|
|
|
17
17
|
const { CRYPTOPAY_SECRET, CRYPTOPAY_BTC_XPUB, CRYPTOPAY_ETH_XPUB } = process.env;
|
|
18
18
|
|
|
@@ -44,6 +44,9 @@ const Cryptopay: IPaymentAdapter = {
|
|
|
44
44
|
|
|
45
45
|
const setConversionRates = async (currencyCode: string, existingAddresses: any[]) => {
|
|
46
46
|
const originCurrencyObj = await modules.currencies.findCurrency({ isoCode: currencyCode });
|
|
47
|
+
|
|
48
|
+
if (!originCurrencyObj?.isActive) throw new Error('Origin currency is not supported');
|
|
49
|
+
|
|
47
50
|
const updatedAddresses = await Promise.all(
|
|
48
51
|
existingAddresses.map(async (addressData) => {
|
|
49
52
|
const targetCurrencyObj = await modules.currencies.findCurrency({
|
|
@@ -113,6 +116,8 @@ const Cryptopay: IPaymentAdapter = {
|
|
|
113
116
|
if (!orderPayment)
|
|
114
117
|
throw new Error('Payment Credential Registration is not yet supported for Cryptopay');
|
|
115
118
|
|
|
119
|
+
if (!order) throw new Error('Order context is required for signing with Cryptopay');
|
|
120
|
+
|
|
116
121
|
const existingAddresses = await modules.cryptopay.getWalletAddressesByOrderPaymentId(
|
|
117
122
|
orderPayment._id,
|
|
118
123
|
);
|
|
@@ -166,6 +171,11 @@ const Cryptopay: IPaymentAdapter = {
|
|
|
166
171
|
charge: async () => {
|
|
167
172
|
const { order, orderPayment } = context;
|
|
168
173
|
|
|
174
|
+
if (!orderPayment)
|
|
175
|
+
throw new Error('Order Payment context is required for charging with Cryptopay');
|
|
176
|
+
|
|
177
|
+
if (!order) throw new Error('Order context is required for charging with Cryptopay');
|
|
178
|
+
|
|
169
179
|
const foundWalletsWithBalances = await modules.cryptopay.getWalletAddressesByOrderPaymentId(
|
|
170
180
|
orderPayment._id,
|
|
171
181
|
);
|
|
@@ -180,18 +190,25 @@ const Cryptopay: IPaymentAdapter = {
|
|
|
180
190
|
});
|
|
181
191
|
const totalAmount = BigInt(pricing?.total({ useNetPrice: false }).amount);
|
|
182
192
|
|
|
183
|
-
if (walletForOrderPayment.currencyCode !== order.currencyCode) {
|
|
193
|
+
if (walletForOrderPayment && walletForOrderPayment.currencyCode !== order.currencyCode) {
|
|
184
194
|
const baseCurrency = await modules.currencies.findCurrency({
|
|
185
195
|
isoCode: walletForOrderPayment.currencyCode,
|
|
186
196
|
});
|
|
197
|
+
|
|
198
|
+
if (!baseCurrency) throw new Error('Base currency not found');
|
|
199
|
+
|
|
187
200
|
const quoteCurrency = await modules.currencies.findCurrency({ isoCode: order.currencyCode });
|
|
188
201
|
|
|
189
|
-
|
|
202
|
+
if (!quoteCurrency) throw new Error('Quote currency not found');
|
|
203
|
+
|
|
204
|
+
const rate = await modules.products.prices.rates.getRateRange(
|
|
190
205
|
baseCurrency,
|
|
191
206
|
quoteCurrency,
|
|
192
207
|
order.confirmed || new Date(),
|
|
193
208
|
);
|
|
194
209
|
|
|
210
|
+
if (!rate) throw new Error('No conversion rate found');
|
|
211
|
+
|
|
195
212
|
const convertedAmount = denoteAmount(
|
|
196
213
|
walletForOrderPayment.amount.toString(),
|
|
197
214
|
walletForOrderPayment.decimals,
|
|
@@ -199,7 +216,7 @@ const Cryptopay: IPaymentAdapter = {
|
|
|
199
216
|
|
|
200
217
|
// Add a Promille 🍻
|
|
201
218
|
// const minAmount = parseFloat(convertedAmount.toString()) * min * 0.999;
|
|
202
|
-
const maxAmount = parseFloat(convertedAmount.toString()) * max * 1.001;
|
|
219
|
+
const maxAmount = parseFloat(convertedAmount.toString()) * rate.max * 1.001;
|
|
203
220
|
|
|
204
221
|
if (maxAmount && maxAmount >= totalAmount) {
|
|
205
222
|
// Enough sent
|