@unchainedshop/api 4.0.0-rc.13 → 4.0.0-rc.15
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/express/createERCMetadataMiddleware.d.ts.map +1 -1
- package/lib/express/createERCMetadataMiddleware.js +10 -9
- package/lib/express/createERCMetadataMiddleware.js.map +1 -1
- package/lib/fastify/bulkImportHandler.js +1 -1
- package/lib/fastify/bulkImportHandler.js.map +1 -1
- package/lib/fastify/ercMetadataHandler.js +1 -1
- package/lib/fastify/ercMetadataHandler.js.map +1 -1
- package/lib/fastify/tempUploadHandler.js +1 -1
- package/lib/fastify/tempUploadHandler.js.map +1 -1
- package/lib/mcp/tools/order/schemas.d.ts +2 -2
- package/lib/mcp/tools/product/schemas.d.ts +62 -62
- package/lib/mcp/tools/system/schemas.d.ts +36 -6
- package/lib/mcp/tools/system/schemas.d.ts.map +1 -1
- package/lib/mcp/tools/system/schemas.js +4 -6
- package/lib/mcp/tools/system/schemas.js.map +1 -1
- package/lib/mcp/tools/system/types.d.ts +8 -2
- package/lib/mcp/tools/system/types.d.ts.map +1 -1
- package/lib/mcp/tools/users/schemas.d.ts +2 -2
- package/lib/resolvers/mutations/accounts/verifyWeb3Address.d.ts.map +1 -1
- package/lib/resolvers/mutations/accounts/verifyWeb3Address.js +78 -5
- package/lib/resolvers/mutations/accounts/verifyWeb3Address.js.map +1 -1
- package/lib/resolvers/mutations/index.d.ts +4 -1
- package/lib/resolvers/mutations/index.d.ts.map +1 -1
- package/lib/resolvers/mutations/index.js +8 -2
- package/lib/resolvers/mutations/index.js.map +1 -1
- package/lib/resolvers/mutations/orders/updateCart.js +6 -6
- package/lib/resolvers/mutations/orders/updateCart.js.map +1 -1
- package/lib/resolvers/mutations/orders/updateCartDeliveryPickUp.d.ts +8 -0
- package/lib/resolvers/mutations/orders/updateCartDeliveryPickUp.d.ts.map +1 -0
- package/lib/resolvers/mutations/orders/updateCartDeliveryPickUp.js +38 -0
- package/lib/resolvers/mutations/orders/updateCartDeliveryPickUp.js.map +1 -0
- package/lib/resolvers/mutations/orders/updateCartDeliveryShipping.d.ts +8 -0
- package/lib/resolvers/mutations/orders/updateCartDeliveryShipping.d.ts.map +1 -0
- package/lib/resolvers/mutations/orders/updateCartDeliveryShipping.js +38 -0
- package/lib/resolvers/mutations/orders/updateCartDeliveryShipping.js.map +1 -0
- package/lib/resolvers/mutations/orders/updateCartPaymentGeneric.d.ts +7 -0
- package/lib/resolvers/mutations/orders/updateCartPaymentGeneric.d.ts.map +1 -0
- package/lib/resolvers/mutations/orders/updateCartPaymentGeneric.js +37 -0
- package/lib/resolvers/mutations/orders/updateCartPaymentGeneric.js.map +1 -0
- package/lib/resolvers/mutations/orders/updateCartPaymentInvoice.d.ts +7 -0
- package/lib/resolvers/mutations/orders/updateCartPaymentInvoice.d.ts.map +1 -0
- package/lib/resolvers/mutations/orders/updateCartPaymentInvoice.js +37 -0
- package/lib/resolvers/mutations/orders/updateCartPaymentInvoice.js.map +1 -0
- package/lib/resolvers/mutations/products/updateProductCommerce.d.ts.map +1 -1
- package/lib/resolvers/mutations/products/updateProductCommerce.js +11 -2
- package/lib/resolvers/mutations/products/updateProductCommerce.js.map +1 -1
- package/lib/resolvers/queries/orders/orderStatistics.d.ts +3 -1
- package/lib/resolvers/queries/orders/orderStatistics.d.ts.map +1 -1
- package/lib/resolvers/queries/orders/orderStatistics.js +3 -2
- package/lib/resolvers/queries/orders/orderStatistics.js.map +1 -1
- package/lib/resolvers/type/index.d.ts +52 -0
- package/lib/resolvers/type/index.d.ts.map +1 -1
- package/lib/resolvers/type/index.js +2 -0
- package/lib/resolvers/type/index.js.map +1 -1
- package/lib/resolvers/type/order/order-payment-types.d.ts.map +1 -1
- package/lib/resolvers/type/order/order-payment-types.js +0 -1
- package/lib/resolvers/type/order/order-payment-types.js.map +1 -1
- package/lib/resolvers/type/order/order-statistics-types.d.ts +34 -0
- package/lib/resolvers/type/order/order-statistics-types.d.ts.map +1 -0
- package/lib/resolvers/type/order/order-statistics-types.js +68 -0
- package/lib/resolvers/type/order/order-statistics-types.js.map +1 -0
- package/lib/resolvers/type/product/product-bundle-types.d.ts +20 -0
- package/lib/resolvers/type/product/product-bundle-types.d.ts.map +1 -1
- package/lib/resolvers/type/product/product-bundle-types.js +2 -2
- package/lib/resolvers/type/product/product-bundle-types.js.map +1 -1
- package/lib/schema/mutation.d.ts.map +1 -1
- package/lib/schema/mutation.js +36 -7
- package/lib/schema/mutation.js.map +1 -1
- package/lib/schema/query.js +2 -2
- package/lib/schema/types/events.d.ts.map +1 -1
- package/lib/schema/types/events.js +7 -1
- package/lib/schema/types/events.js.map +1 -1
- package/lib/schema/types/order/order.d.ts.map +1 -1
- package/lib/schema/types/order/order.js +9 -1
- package/lib/schema/types/order/order.js.map +1 -1
- package/lib/schema/types/payment.d.ts.map +1 -1
- package/lib/schema/types/payment.js +0 -5
- package/lib/schema/types/payment.js.map +1 -1
- package/lib/schema/types/product/bundle-product.d.ts.map +1 -1
- package/lib/schema/types/product/bundle-product.js +18 -7
- package/lib/schema/types/product/bundle-product.js.map +1 -1
- package/package.json +17 -12
- package/src/express/createERCMetadataMiddleware.ts +11 -9
- package/src/fastify/bulkImportHandler.ts +1 -1
- package/src/fastify/ercMetadataHandler.ts +1 -1
- package/src/fastify/tempUploadHandler.ts +1 -1
- package/src/mcp/tools/system/schemas.ts +4 -6
- package/src/mcp/tools/system/types.ts +8 -2
- package/src/resolvers/mutations/accounts/verifyWeb3Address.ts +100 -7
- package/src/resolvers/mutations/index.ts +8 -2
- package/src/resolvers/mutations/orders/updateCart.ts +6 -6
- package/src/resolvers/mutations/orders/updateCartDeliveryPickUp.ts +51 -0
- package/src/resolvers/mutations/orders/updateCartDeliveryShipping.ts +51 -0
- package/src/resolvers/mutations/orders/updateCartPaymentGeneric.ts +50 -0
- package/src/resolvers/mutations/orders/updateCartPaymentInvoice.ts +50 -0
- package/src/resolvers/mutations/products/updateProductCommerce.ts +12 -4
- package/src/resolvers/queries/orders/orderStatistics.ts +3 -3
- package/src/resolvers/type/index.ts +2 -0
- package/src/resolvers/type/order/order-payment-types.ts +0 -1
- package/src/resolvers/type/order/order-statistics-types.ts +99 -0
- package/src/resolvers/type/product/product-bundle-types.ts +2 -2
- package/src/schema/mutation.ts +36 -7
- package/src/schema/query.ts +2 -2
- package/src/schema/types/events.ts +7 -1
- package/src/schema/types/order/order.ts +9 -1
- package/src/schema/types/payment.ts +0 -5
- package/src/schema/types/product/bundle-product.ts +18 -7
- package/src/resolvers/mutations/orders/updateOrderPaymentCard.ts +0 -37
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unchainedshop/api",
|
|
3
|
-
"version": "4.0.0-rc.
|
|
3
|
+
"version": "4.0.0-rc.15",
|
|
4
4
|
"main": "lib/api-index.js",
|
|
5
5
|
"types": "lib/api-index.d.ts",
|
|
6
6
|
"type": "module",
|
|
@@ -31,7 +31,6 @@
|
|
|
31
31
|
},
|
|
32
32
|
"homepage": "https://github.com/unchainedshop/unchained#readme",
|
|
33
33
|
"peerDependencies": {
|
|
34
|
-
"@ethereumjs/util": ">= 10 < 11",
|
|
35
34
|
"fastify": ">= 5.2 < 6",
|
|
36
35
|
"@fastify/cookie": ">= 11 < 12",
|
|
37
36
|
"@fastify/session": ">= 11 < 12",
|
|
@@ -42,7 +41,9 @@
|
|
|
42
41
|
"express-session": ">= 1.18 < 2",
|
|
43
42
|
"multer": ">= 2 < 3",
|
|
44
43
|
"graphql-yoga": ">= 5.9 < 6",
|
|
45
|
-
"passport": ">= 0.7 < 1"
|
|
44
|
+
"passport": ">= 0.7 < 1",
|
|
45
|
+
"@noble/curves": "^2.0.0",
|
|
46
|
+
"@noble/hashes": "^2.0.0"
|
|
46
47
|
},
|
|
47
48
|
"peerDependenciesMeta": {
|
|
48
49
|
"@modelcontextprotocol/sdk": {
|
|
@@ -54,9 +55,6 @@
|
|
|
54
55
|
"connect-mongo": {
|
|
55
56
|
"optional": false
|
|
56
57
|
},
|
|
57
|
-
"@ethereumjs/util": {
|
|
58
|
-
"optional": true
|
|
59
|
-
},
|
|
60
58
|
"fastify": {
|
|
61
59
|
"optional": true
|
|
62
60
|
},
|
|
@@ -80,14 +78,20 @@
|
|
|
80
78
|
},
|
|
81
79
|
"passport": {
|
|
82
80
|
"optional": true
|
|
81
|
+
},
|
|
82
|
+
"@noble/curves": {
|
|
83
|
+
"optional": true
|
|
84
|
+
},
|
|
85
|
+
"@noble/hashes": {
|
|
86
|
+
"optional": true
|
|
83
87
|
}
|
|
84
88
|
},
|
|
85
89
|
"dependencies": {
|
|
86
|
-
"@unchainedshop/core": "^4.0.0-rc.
|
|
87
|
-
"@unchainedshop/events": "^4.0.0-rc.
|
|
88
|
-
"@unchainedshop/logger": "^4.0.0-rc.
|
|
89
|
-
"@unchainedshop/roles": "^4.0.0-rc.
|
|
90
|
-
"@unchainedshop/utils": "^4.0.0-rc.
|
|
90
|
+
"@unchainedshop/core": "^4.0.0-rc.15",
|
|
91
|
+
"@unchainedshop/events": "^4.0.0-rc.15",
|
|
92
|
+
"@unchainedshop/logger": "^4.0.0-rc.15",
|
|
93
|
+
"@unchainedshop/roles": "^4.0.0-rc.15",
|
|
94
|
+
"@unchainedshop/utils": "^4.0.0-rc.15",
|
|
91
95
|
"accounting": "0.4.1",
|
|
92
96
|
"dataloader": "^2.2.3",
|
|
93
97
|
"expiry-map": "^2.0.0",
|
|
@@ -97,7 +101,8 @@
|
|
|
97
101
|
"zod": "^3.25.76"
|
|
98
102
|
},
|
|
99
103
|
"devDependencies": {
|
|
100
|
-
"@
|
|
104
|
+
"@noble/curves": "^2.0.0",
|
|
105
|
+
"@noble/hashes": "^2.0.0",
|
|
101
106
|
"@fastify/cookie": "^11.0.2",
|
|
102
107
|
"@fastify/multipart": "^9.0.3",
|
|
103
108
|
"@fastify/session": "^11.1.0",
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
1
|
import { createLogger } from '@unchainedshop/logger';
|
|
3
2
|
import { Context } from '../context.js';
|
|
4
3
|
import { Request, RequestHandler } from 'express';
|
|
@@ -25,16 +24,20 @@ const ercMetadataMiddleware: RequestHandler = async (
|
|
|
25
24
|
|
|
26
25
|
const { services, modules, loaders, locale } = req.unchainedContext;
|
|
27
26
|
const url = new URL(req.url, ROOT_URL);
|
|
28
|
-
const parsedPath = path.parse(url.pathname);
|
|
29
27
|
|
|
30
|
-
|
|
28
|
+
// Replace path.parse with URL/string methods
|
|
29
|
+
const pathname = url.pathname;
|
|
30
|
+
if (!pathname.toLowerCase().endsWith('.json')) throw new Error('Invalid ERC Metadata URI');
|
|
31
|
+
|
|
32
|
+
const fileName = pathname.split('/').pop();
|
|
33
|
+
const chainTokenId = fileName.slice(0, fileName.lastIndexOf('.'));
|
|
31
34
|
|
|
32
35
|
const [, productId, localeOrTokenFilename, tokenFileName] = url.pathname.split('/');
|
|
33
36
|
|
|
34
37
|
const product = await loaders.productLoader.load({ productId });
|
|
35
38
|
|
|
36
39
|
const [token] = await modules.warehousing.findTokens({
|
|
37
|
-
chainTokenId
|
|
40
|
+
chainTokenId,
|
|
38
41
|
contractAddress: product?.tokenization?.contractAddress,
|
|
39
42
|
});
|
|
40
43
|
|
|
@@ -49,11 +52,10 @@ const ercMetadataMiddleware: RequestHandler = async (
|
|
|
49
52
|
}
|
|
50
53
|
|
|
51
54
|
const body = JSON.stringify(ercMetadata);
|
|
52
|
-
res.
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
res.end(body);
|
|
55
|
+
res.status(200);
|
|
56
|
+
res.setHeader('Content-Type', 'application/json');
|
|
57
|
+
res.setHeader('Content-Length', new TextEncoder().encode(body).length);
|
|
58
|
+
return res.send(body);
|
|
57
59
|
} catch (e) {
|
|
58
60
|
logger.error(e.message);
|
|
59
61
|
res.writeHead(503);
|
|
@@ -46,7 +46,7 @@ const bulkImportHandler: RouteHandlerMethod = async (
|
|
|
46
46
|
|
|
47
47
|
const body = JSON.stringify(work);
|
|
48
48
|
res.status(200);
|
|
49
|
-
res.header('Content-Length',
|
|
49
|
+
res.header('Content-Length', new TextEncoder().encode(body).length);
|
|
50
50
|
res.header('Content-Type', 'application/json');
|
|
51
51
|
return res.send(body);
|
|
52
52
|
} catch (e) {
|
|
@@ -41,7 +41,7 @@ const ercMetadataHandler: RouteHandlerMethod = async (
|
|
|
41
41
|
|
|
42
42
|
const body = JSON.stringify(ercMetadata);
|
|
43
43
|
res.status(200);
|
|
44
|
-
res.header('Content-Length',
|
|
44
|
+
res.header('Content-Length', new TextEncoder().encode(body).length);
|
|
45
45
|
res.header('Content-Type', 'application/json');
|
|
46
46
|
return res.send(body);
|
|
47
47
|
} catch (e) {
|
|
@@ -39,7 +39,7 @@ const tempUploadHandler: RouteHandlerMethod = async (
|
|
|
39
39
|
const url = context.modules.files.normalizeUrl(rawUrl, {});
|
|
40
40
|
const body = JSON.stringify({ fileId: file._id, url, expires: expires.toISOString() });
|
|
41
41
|
res.status(200);
|
|
42
|
-
res.header('Content-Length',
|
|
42
|
+
res.header('Content-Length', new TextEncoder().encode(body).length);
|
|
43
43
|
res.header('Content-Type', 'application/json');
|
|
44
44
|
return res.send(body);
|
|
45
45
|
} catch (e) {
|
|
@@ -183,10 +183,9 @@ export const actionValidators = {
|
|
|
183
183
|
.optional()
|
|
184
184
|
.describe('Filter events by specific event types (e.g., USER_CREATED, ORDER_PLACED)'),
|
|
185
185
|
created: z
|
|
186
|
-
.
|
|
187
|
-
.datetime()
|
|
186
|
+
.object(DateRangeSchema)
|
|
188
187
|
.optional()
|
|
189
|
-
.describe('
|
|
188
|
+
.describe('Date range filter for when events are emitted/created'),
|
|
190
189
|
}),
|
|
191
190
|
|
|
192
191
|
EVENT_COUNT: z.object({
|
|
@@ -196,10 +195,9 @@ export const actionValidators = {
|
|
|
196
195
|
.optional()
|
|
197
196
|
.describe('Filter events by specific event types (e.g., USER_CREATED, ORDER_PLACED)'),
|
|
198
197
|
created: z
|
|
199
|
-
.
|
|
200
|
-
.datetime()
|
|
198
|
+
.object(DateRangeSchema)
|
|
201
199
|
.optional()
|
|
202
|
-
.describe('
|
|
200
|
+
.describe('Date range filter for when events are emitted/created'),
|
|
203
201
|
}),
|
|
204
202
|
|
|
205
203
|
EVENT_STATISTICS: z.object({
|
|
@@ -30,11 +30,17 @@ export interface EventListOptions {
|
|
|
30
30
|
queryString?: string;
|
|
31
31
|
types?: string[];
|
|
32
32
|
sort?: SortOption[];
|
|
33
|
-
created?:
|
|
33
|
+
created?: {
|
|
34
|
+
start?: Date;
|
|
35
|
+
end?: Date;
|
|
36
|
+
};
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
export interface EventCountOptions {
|
|
37
40
|
queryString?: string;
|
|
38
|
-
created?:
|
|
41
|
+
created?: {
|
|
42
|
+
start?: Date;
|
|
43
|
+
end?: Date;
|
|
44
|
+
};
|
|
39
45
|
types?: string[];
|
|
40
46
|
}
|
|
@@ -2,6 +2,93 @@ import { log } from '@unchainedshop/logger';
|
|
|
2
2
|
import { UserWeb3AddressNotFoundError, UserWeb3AddressSignatureError } from '../../../errors.js';
|
|
3
3
|
import { Context } from '../../../context.js';
|
|
4
4
|
|
|
5
|
+
import type { keccak_256 as Keccak256Type } from '@noble/hashes/sha3.js';
|
|
6
|
+
import type { bytesToHex as BytesToHex, hexToBytes as HexToBytes } from '@noble/hashes/utils.js';
|
|
7
|
+
import type { secp256k1 as Secp256k1Type } from '@noble/curves/secp256k1.js';
|
|
8
|
+
|
|
9
|
+
// Dynamic imports for optional peer dependencies
|
|
10
|
+
let secp256k1: typeof Secp256k1Type;
|
|
11
|
+
let keccak_256: typeof Keccak256Type;
|
|
12
|
+
let bytesToHex: typeof BytesToHex;
|
|
13
|
+
let hexToBytes: typeof HexToBytes;
|
|
14
|
+
|
|
15
|
+
async function loadNoblePackages() {
|
|
16
|
+
try {
|
|
17
|
+
// eslint-disable-next-line
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
const curves = await import('@noble/curves/secp256k1.js');
|
|
20
|
+
|
|
21
|
+
// eslint-disable-next-line
|
|
22
|
+
// @ts-ignore
|
|
23
|
+
const hashes = await import('@noble/hashes/sha3.js');
|
|
24
|
+
|
|
25
|
+
// eslint-disable-next-line
|
|
26
|
+
// @ts-ignore
|
|
27
|
+
const utils = await import('@noble/hashes/utils.js');
|
|
28
|
+
|
|
29
|
+
if (!curves || !hashes || !utils) {
|
|
30
|
+
throw new Error('Missing required @noble packages for Web3 signature verification');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
secp256k1 = curves.secp256k1;
|
|
34
|
+
keccak_256 = hashes.keccak_256;
|
|
35
|
+
bytesToHex = utils.bytesToHex;
|
|
36
|
+
hexToBytes = utils.hexToBytes;
|
|
37
|
+
|
|
38
|
+
return true;
|
|
39
|
+
} catch (error) {
|
|
40
|
+
log('Failed to load @noble packages for Web3 verification', { error: error.message });
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Inline utility functions to replace @ethereumjs/util
|
|
46
|
+
function fromRPCSig(sig: string): { v: bigint; r: Uint8Array; s: Uint8Array } {
|
|
47
|
+
const bytes = hexToBytes(sig.startsWith('0x') ? sig.slice(2) : sig);
|
|
48
|
+
if (bytes.length !== 65) throw new Error('Invalid signature length');
|
|
49
|
+
|
|
50
|
+
const r = bytes.slice(0, 32);
|
|
51
|
+
const s = bytes.slice(32, 64);
|
|
52
|
+
let v = BigInt(bytes[64]);
|
|
53
|
+
|
|
54
|
+
// Handle EIP-155 encoding
|
|
55
|
+
if (v >= 35n) {
|
|
56
|
+
v = v - 35n - 2n * 1n; // chainId = 1 for mainnet, adjust if needed
|
|
57
|
+
} else if (v >= 27n) {
|
|
58
|
+
v = v - 27n;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return { v, r, s };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function hashPersonalMessage(message: Uint8Array): Uint8Array {
|
|
65
|
+
const prefix = new TextEncoder().encode('\x19Ethereum Signed Message:\n');
|
|
66
|
+
const lengthBytes = new TextEncoder().encode(message.length.toString());
|
|
67
|
+
const combined = new Uint8Array(prefix.length + lengthBytes.length + message.length);
|
|
68
|
+
combined.set(prefix, 0);
|
|
69
|
+
combined.set(lengthBytes, prefix.length);
|
|
70
|
+
combined.set(message, prefix.length + lengthBytes.length);
|
|
71
|
+
return keccak_256(combined);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function ecrecover(msgHash: Uint8Array, v: bigint, r: Uint8Array, s: Uint8Array): Uint8Array {
|
|
75
|
+
const recovery = Number(v);
|
|
76
|
+
const signature = new Uint8Array(64);
|
|
77
|
+
signature.set(r, 0);
|
|
78
|
+
signature.set(s, 32);
|
|
79
|
+
|
|
80
|
+
const publicKey = secp256k1.Signature.fromBytes(signature)
|
|
81
|
+
.addRecoveryBit(recovery)
|
|
82
|
+
.recoverPublicKey(msgHash);
|
|
83
|
+
|
|
84
|
+
return publicKey.toBytes(false).slice(1); // Remove the 0x04 prefix for uncompressed key
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function publicToAddress(publicKey: Uint8Array): Uint8Array {
|
|
88
|
+
const hash = keccak_256(publicKey);
|
|
89
|
+
return hash.slice(-20); // Take last 20 bytes
|
|
90
|
+
}
|
|
91
|
+
|
|
5
92
|
export default async function verifyWeb3Address(
|
|
6
93
|
root: never,
|
|
7
94
|
{ address, hash }: { address: string; hash: `0x${string}` },
|
|
@@ -11,6 +98,14 @@ export default async function verifyWeb3Address(
|
|
|
11
98
|
userId,
|
|
12
99
|
});
|
|
13
100
|
|
|
101
|
+
// Load noble packages dynamically
|
|
102
|
+
const packagesLoaded = await loadNoblePackages();
|
|
103
|
+
if (!packagesLoaded) {
|
|
104
|
+
throw new Error(
|
|
105
|
+
'Web3 signature verification is not available. Please install the required @noble packages: @noble/curves, @noble/hashes',
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
14
109
|
const foundCredentials = user.services?.web3?.find(
|
|
15
110
|
(service) => service.address.toLowerCase() === address.toLowerCase(),
|
|
16
111
|
);
|
|
@@ -20,17 +115,15 @@ export default async function verifyWeb3Address(
|
|
|
20
115
|
|
|
21
116
|
// eslint-disable-next-line
|
|
22
117
|
// @ts-ignore
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const message = `0x${Buffer.from(foundCredentials.nonce, 'utf8').toString('hex')}`;
|
|
27
|
-
const messageHash = hashPersonalMessage(toBuffer(message));
|
|
118
|
+
const messageHash = hashPersonalMessage(
|
|
119
|
+
hexToBytes(`0x${Buffer.from(foundCredentials.nonce, 'utf8').toString('hex')}`),
|
|
120
|
+
);
|
|
28
121
|
|
|
29
|
-
const sigParams =
|
|
122
|
+
const sigParams = fromRPCSig(hash);
|
|
30
123
|
const publicKey = ecrecover(messageHash, sigParams.v, sigParams.r, sigParams.s);
|
|
31
124
|
|
|
32
125
|
const sender = publicToAddress(publicKey);
|
|
33
|
-
const recoveredAddr =
|
|
126
|
+
const recoveredAddr = `0x${bytesToHex(sender)}`;
|
|
34
127
|
|
|
35
128
|
const isSignatureCorrectForAddress =
|
|
36
129
|
recoveredAddr.toLowerCase() === foundCredentials.address.toLowerCase();
|
|
@@ -138,7 +138,6 @@ import removePaymentCredentials from './payment/removePaymentCredentials.js';
|
|
|
138
138
|
import updateOrderDeliveryShipping from './orders/updateOrderDeliveryShipping.js';
|
|
139
139
|
import updateOrderDeliveryPickUp from './orders/updateOrderDeliveryPickUp.js';
|
|
140
140
|
import updateOrderPaymentGeneric from './orders/updateOrderPaymentGeneric.js';
|
|
141
|
-
import updateOrderPaymentCard from './orders/updateOrderPaymentCard.js';
|
|
142
141
|
import updateOrderPaymentInvoice from './orders/updateOrderPaymentInvoice.js';
|
|
143
142
|
import signPaymentProviderForCredentialRegistration from './payment/signPaymentProviderForCredentialRegistration.js';
|
|
144
143
|
import signPaymentProviderForCheckout from './orders/signPaymentProviderForCheckout.js';
|
|
@@ -153,6 +152,10 @@ import rejectOrder from './orders/rejectOrder.js';
|
|
|
153
152
|
import removePushSubscription from './users/removePushSubscription.js';
|
|
154
153
|
import addPushSubscription from './users/addPushSubscription.js';
|
|
155
154
|
import removeUserProductReviews from './users/removeUserProductReviews.js';
|
|
155
|
+
import updateCartDeliveryPickUp from './orders/updateCartDeliveryPickUp.js';
|
|
156
|
+
import updateCartDeliveryShipping from './orders/updateCartDeliveryShipping.js';
|
|
157
|
+
import updateCartPaymentGeneric from './orders/updateCartPaymentGeneric.js';
|
|
158
|
+
import updateCartPaymentInvoice from './orders/updateCartPaymentInvoice.js';
|
|
156
159
|
|
|
157
160
|
export default {
|
|
158
161
|
logout: acl(actions.logout)(logout),
|
|
@@ -244,12 +247,15 @@ export default {
|
|
|
244
247
|
updateCartItem: acl(actions.updateOrderItem)(updateCartItem),
|
|
245
248
|
removeCartItem: acl(actions.updateOrderItem)(removeCartItem),
|
|
246
249
|
removeCartDiscount: acl(actions.updateOrderDiscount)(removeCartDiscount),
|
|
250
|
+
updateCartDeliveryPickUp: acl(actions.updateCart)(updateCartDeliveryPickUp),
|
|
251
|
+
updateCartDeliveryShipping: acl(actions.updateCart)(updateCartDeliveryShipping),
|
|
252
|
+
updateCartPaymentGeneric: acl(actions.updateCart)(updateCartPaymentGeneric),
|
|
253
|
+
updateCartPaymentInvoice: acl(actions.updateCart)(updateCartPaymentInvoice),
|
|
247
254
|
setOrderPaymentProvider: acl(actions.updateOrder)(setOrderPaymentProvider),
|
|
248
255
|
setOrderDeliveryProvider: acl(actions.updateOrder)(setOrderDeliveryProvider),
|
|
249
256
|
updateOrderDeliveryShipping: acl(actions.updateOrderDelivery)(updateOrderDeliveryShipping),
|
|
250
257
|
updateOrderDeliveryPickUp: acl(actions.updateOrderDelivery)(updateOrderDeliveryPickUp),
|
|
251
258
|
updateOrderPaymentGeneric: acl(actions.updateOrderPayment)(updateOrderPaymentGeneric),
|
|
252
|
-
updateOrderPaymentCard: acl(actions.updateOrderPayment)(updateOrderPaymentCard),
|
|
253
259
|
updateOrderPaymentInvoice: acl(actions.updateOrderPayment)(updateOrderPaymentInvoice),
|
|
254
260
|
removeOrder: acl(actions.updateOrder)(removeOrder),
|
|
255
261
|
confirmOrder: acl(actions.markOrderConfirmed)(confirmOrder),
|
|
@@ -19,7 +19,7 @@ export default async function updateCart(root: never, params: UpdateCartParams,
|
|
|
19
19
|
|
|
20
20
|
log('mutation updateCart', { userId });
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
const order = await services.orders.findOrInitCart({
|
|
23
23
|
orderId,
|
|
24
24
|
user,
|
|
25
25
|
countryCode: context.countryCode,
|
|
@@ -28,23 +28,23 @@ export default async function updateCart(root: never, params: UpdateCartParams,
|
|
|
28
28
|
if (!modules.orders.isCart(order)) throw new OrderWrongStatusError({ status: order.status });
|
|
29
29
|
|
|
30
30
|
if (meta) {
|
|
31
|
-
|
|
31
|
+
await modules.orders.updateContext(order._id, meta);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
if (billingAddress) {
|
|
35
|
-
|
|
35
|
+
await modules.orders.updateBillingAddress(order._id, billingAddress);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
if (contact) {
|
|
39
|
-
|
|
39
|
+
await modules.orders.updateContact(order._id, contact);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
if (paymentProviderId) {
|
|
43
|
-
|
|
43
|
+
await modules.orders.setPaymentProvider(order._id, paymentProviderId);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
if (deliveryProviderId) {
|
|
47
|
-
|
|
47
|
+
await modules.orders.setDeliveryProvider(order._id, deliveryProviderId);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
// Recalculate, then return
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Context } from '../../../context.js';
|
|
2
|
+
import { DeliveryProviderType } from '@unchainedshop/core-delivery';
|
|
3
|
+
import { log } from '@unchainedshop/logger';
|
|
4
|
+
import {
|
|
5
|
+
InvalidIdError,
|
|
6
|
+
OrderDeliveryTypeError,
|
|
7
|
+
OrderNotFoundError,
|
|
8
|
+
OrderWrongStatusError,
|
|
9
|
+
} from '../../../errors.js';
|
|
10
|
+
|
|
11
|
+
export default async function updateCartDeliveryPickUp(
|
|
12
|
+
root: never,
|
|
13
|
+
params: { orderId: string; deliveryProviderId: string; orderPickUpLocationId: string; meta: any },
|
|
14
|
+
context: Context,
|
|
15
|
+
) {
|
|
16
|
+
const { modules, services, userId, user } = context;
|
|
17
|
+
const { orderId, deliveryProviderId, orderPickUpLocationId, meta } = params;
|
|
18
|
+
log(`mutation updateCartDeliveryPickUp provider ${deliveryProviderId}`, {
|
|
19
|
+
userId,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (!deliveryProviderId) throw new InvalidIdError({ deliveryProviderId });
|
|
23
|
+
|
|
24
|
+
let order = await services.orders.findOrInitCart({
|
|
25
|
+
orderId,
|
|
26
|
+
user,
|
|
27
|
+
countryCode: context.countryCode,
|
|
28
|
+
});
|
|
29
|
+
if (!order) throw new OrderNotFoundError({ orderId });
|
|
30
|
+
if (!modules.orders.isCart(order)) throw new OrderWrongStatusError({ status: order.status });
|
|
31
|
+
|
|
32
|
+
const provider = await modules.delivery.findProvider({
|
|
33
|
+
deliveryProviderId,
|
|
34
|
+
});
|
|
35
|
+
const deliveryProviderType = provider?.type;
|
|
36
|
+
|
|
37
|
+
if (deliveryProviderType !== DeliveryProviderType.PICKUP)
|
|
38
|
+
throw new OrderDeliveryTypeError({
|
|
39
|
+
orderId: order._id,
|
|
40
|
+
received: deliveryProviderType,
|
|
41
|
+
required: DeliveryProviderType.PICKUP,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
order = (await modules.orders.setDeliveryProvider(order._id, deliveryProviderId)) || order;
|
|
45
|
+
|
|
46
|
+
await modules.orders.deliveries.updateContext(order.deliveryId, {
|
|
47
|
+
orderPickUpLocationId,
|
|
48
|
+
meta,
|
|
49
|
+
});
|
|
50
|
+
return services.orders.updateCalculation(order._id);
|
|
51
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Context } from '../../../context.js';
|
|
2
|
+
import { DeliveryProviderType } from '@unchainedshop/core-delivery';
|
|
3
|
+
import { log } from '@unchainedshop/logger';
|
|
4
|
+
import {
|
|
5
|
+
InvalidIdError,
|
|
6
|
+
OrderDeliveryTypeError,
|
|
7
|
+
OrderNotFoundError,
|
|
8
|
+
OrderWrongStatusError,
|
|
9
|
+
} from '../../../errors.js';
|
|
10
|
+
|
|
11
|
+
export default async function updateCartDeliveryShipping(
|
|
12
|
+
root: never,
|
|
13
|
+
params: { orderId: string; deliveryProviderId: string; address: any; meta: any },
|
|
14
|
+
context: Context,
|
|
15
|
+
) {
|
|
16
|
+
const { modules, services, userId, user } = context;
|
|
17
|
+
const { orderId, deliveryProviderId, address, meta } = params;
|
|
18
|
+
log(`mutation updateCartDeliveryShipping provider ${deliveryProviderId}`, {
|
|
19
|
+
userId,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (!deliveryProviderId) throw new InvalidIdError({ deliveryProviderId });
|
|
23
|
+
|
|
24
|
+
let order = await services.orders.findOrInitCart({
|
|
25
|
+
orderId,
|
|
26
|
+
user,
|
|
27
|
+
countryCode: context.countryCode,
|
|
28
|
+
});
|
|
29
|
+
if (!order) throw new OrderNotFoundError({ orderId });
|
|
30
|
+
if (!modules.orders.isCart(order)) throw new OrderWrongStatusError({ status: order.status });
|
|
31
|
+
|
|
32
|
+
const provider = await modules.delivery.findProvider({
|
|
33
|
+
deliveryProviderId,
|
|
34
|
+
});
|
|
35
|
+
const deliveryProviderType = provider?.type;
|
|
36
|
+
|
|
37
|
+
if (deliveryProviderType !== DeliveryProviderType.SHIPPING)
|
|
38
|
+
throw new OrderDeliveryTypeError({
|
|
39
|
+
orderId: order._id,
|
|
40
|
+
received: deliveryProviderType,
|
|
41
|
+
required: DeliveryProviderType.SHIPPING,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
order = (await modules.orders.setDeliveryProvider(order._id, deliveryProviderId)) || order;
|
|
45
|
+
|
|
46
|
+
await modules.orders.deliveries.updateContext(order.deliveryId, {
|
|
47
|
+
address,
|
|
48
|
+
meta,
|
|
49
|
+
});
|
|
50
|
+
return services.orders.updateCalculation(order._id);
|
|
51
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Context } from '../../../context.js';
|
|
2
|
+
import { PaymentProviderType } from '@unchainedshop/core-payment';
|
|
3
|
+
import { log } from '@unchainedshop/logger';
|
|
4
|
+
import {
|
|
5
|
+
InvalidIdError,
|
|
6
|
+
OrderNotFoundError,
|
|
7
|
+
OrderPaymentTypeError,
|
|
8
|
+
OrderWrongStatusError,
|
|
9
|
+
} from '../../../errors.js';
|
|
10
|
+
|
|
11
|
+
export default async function updateCartPaymentGeneric(
|
|
12
|
+
root: never,
|
|
13
|
+
params: { orderId: string; paymentProviderId: string; meta?: any },
|
|
14
|
+
context: Context,
|
|
15
|
+
) {
|
|
16
|
+
const { modules, services, userId, user } = context;
|
|
17
|
+
const { orderId, paymentProviderId, meta } = params;
|
|
18
|
+
log(`mutation updateCartPaymentGeneric provider ${paymentProviderId}`, {
|
|
19
|
+
userId,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (!paymentProviderId) throw new InvalidIdError({ paymentProviderId });
|
|
23
|
+
|
|
24
|
+
let order = await services.orders.findOrInitCart({
|
|
25
|
+
orderId,
|
|
26
|
+
user,
|
|
27
|
+
countryCode: context.countryCode,
|
|
28
|
+
});
|
|
29
|
+
if (!order) throw new OrderNotFoundError({ orderId });
|
|
30
|
+
if (!modules.orders.isCart(order)) throw new OrderWrongStatusError({ status: order.status });
|
|
31
|
+
|
|
32
|
+
const provider = await modules.payment.paymentProviders.findProvider({
|
|
33
|
+
paymentProviderId,
|
|
34
|
+
});
|
|
35
|
+
const paymentProviderType = provider?.type;
|
|
36
|
+
|
|
37
|
+
if (paymentProviderType !== PaymentProviderType.GENERIC)
|
|
38
|
+
throw new OrderPaymentTypeError({
|
|
39
|
+
orderId: order._id,
|
|
40
|
+
received: paymentProviderType,
|
|
41
|
+
required: PaymentProviderType.GENERIC,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
order = (await modules.orders.setPaymentProvider(order._id, paymentProviderId)) || order;
|
|
45
|
+
|
|
46
|
+
await modules.orders.payments.updateContext(order.paymentId, {
|
|
47
|
+
meta,
|
|
48
|
+
});
|
|
49
|
+
return services.orders.updateCalculation(order._id);
|
|
50
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Context } from '../../../context.js';
|
|
2
|
+
import { PaymentProviderType } from '@unchainedshop/core-payment';
|
|
3
|
+
import { log } from '@unchainedshop/logger';
|
|
4
|
+
import {
|
|
5
|
+
InvalidIdError,
|
|
6
|
+
OrderNotFoundError,
|
|
7
|
+
OrderPaymentTypeError,
|
|
8
|
+
OrderWrongStatusError,
|
|
9
|
+
} from '../../../errors.js';
|
|
10
|
+
|
|
11
|
+
export default async function updateCartPaymentInvoice(
|
|
12
|
+
root: never,
|
|
13
|
+
params: { orderId: string; paymentProviderId: string; meta?: any },
|
|
14
|
+
context: Context,
|
|
15
|
+
) {
|
|
16
|
+
const { modules, services, userId, user } = context;
|
|
17
|
+
const { orderId, paymentProviderId, meta } = params;
|
|
18
|
+
log(`mutation updateCartPaymentInvoice provider ${paymentProviderId}`, {
|
|
19
|
+
userId,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (!paymentProviderId) throw new InvalidIdError({ paymentProviderId });
|
|
23
|
+
|
|
24
|
+
let order = await services.orders.findOrInitCart({
|
|
25
|
+
orderId,
|
|
26
|
+
user,
|
|
27
|
+
countryCode: context.countryCode,
|
|
28
|
+
});
|
|
29
|
+
if (!order) throw new OrderNotFoundError({ orderId });
|
|
30
|
+
if (!modules.orders.isCart(order)) throw new OrderWrongStatusError({ status: order.status });
|
|
31
|
+
|
|
32
|
+
const provider = await modules.payment.paymentProviders.findProvider({
|
|
33
|
+
paymentProviderId,
|
|
34
|
+
});
|
|
35
|
+
const paymentProviderType = provider?.type;
|
|
36
|
+
|
|
37
|
+
if (paymentProviderType !== PaymentProviderType.INVOICE)
|
|
38
|
+
throw new OrderPaymentTypeError({
|
|
39
|
+
orderId: order._id,
|
|
40
|
+
received: paymentProviderType,
|
|
41
|
+
required: PaymentProviderType.INVOICE,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
order = (await modules.orders.setPaymentProvider(order._id, paymentProviderId)) || order;
|
|
45
|
+
|
|
46
|
+
await modules.orders.payments.updateContext(order.paymentId, {
|
|
47
|
+
meta,
|
|
48
|
+
});
|
|
49
|
+
return services.orders.updateCalculation(order._id);
|
|
50
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { log } from '@unchainedshop/logger';
|
|
2
|
-
import { ProductCommerce } from '@unchainedshop/core-products';
|
|
3
|
-
import { ProductNotFoundError, InvalidIdError } from '../../../errors.js';
|
|
2
|
+
import { ProductCommerce, ProductTypes } from '@unchainedshop/core-products';
|
|
3
|
+
import { ProductNotFoundError, InvalidIdError, ProductWrongTypeError } from '../../../errors.js';
|
|
4
4
|
import { Context } from '../../../context.js';
|
|
5
5
|
|
|
6
6
|
export default async function updateProductCommerce(
|
|
@@ -12,8 +12,16 @@ export default async function updateProductCommerce(
|
|
|
12
12
|
|
|
13
13
|
if (!productId) throw new InvalidIdError({ productId });
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
const product = await modules.products.findProduct({ productId });
|
|
16
|
+
if (!product) throw new ProductNotFoundError({ productId });
|
|
17
|
+
|
|
18
|
+
if (product.type === ProductTypes.ConfigurableProduct) {
|
|
19
|
+
throw new ProductWrongTypeError({
|
|
20
|
+
productId: productId,
|
|
21
|
+
received: product.type,
|
|
22
|
+
required: { not: ProductTypes.ConfigurableProduct },
|
|
23
|
+
});
|
|
24
|
+
}
|
|
17
25
|
|
|
18
26
|
await modules.products.update(productId, { commerce });
|
|
19
27
|
|
|
@@ -5,12 +5,12 @@ import { DateFilterInput } from '@unchainedshop/utils';
|
|
|
5
5
|
export default async function orderStatistics(
|
|
6
6
|
root: never,
|
|
7
7
|
params: { dateRange?: DateFilterInput },
|
|
8
|
-
{
|
|
8
|
+
{ userId }: Context,
|
|
9
9
|
) {
|
|
10
|
+
const { dateRange } = params || {};
|
|
10
11
|
log(`query orderStatistics `, {
|
|
11
12
|
userId,
|
|
12
13
|
...(params?.dateRange || {}),
|
|
13
14
|
});
|
|
14
|
-
|
|
15
|
-
return modules.orders.getReport(params);
|
|
15
|
+
return { dateRange };
|
|
16
16
|
}
|
|
@@ -67,6 +67,7 @@ import { Token } from './token-types.js';
|
|
|
67
67
|
import { Web3Address } from './web3-address.js';
|
|
68
68
|
import { LoginMethodResponse } from './login-method-response-types.js';
|
|
69
69
|
import { ProductSearchResult } from './product-search-result-types.js';
|
|
70
|
+
import { OrderStatistics } from './order/order-statistics-types.js';
|
|
70
71
|
|
|
71
72
|
const types = {
|
|
72
73
|
Assortment,
|
|
@@ -138,6 +139,7 @@ const types = {
|
|
|
138
139
|
Media,
|
|
139
140
|
Web3Address,
|
|
140
141
|
LoginMethodResponse,
|
|
142
|
+
OrderStatistics,
|
|
141
143
|
};
|
|
142
144
|
|
|
143
145
|
export default types;
|