@unchainedshop/api 2.12.2 → 2.13.1
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/createBulkImportMiddleware.d.ts.map +1 -1
- package/lib/express/createBulkImportMiddleware.js +1 -0
- package/lib/express/createBulkImportMiddleware.js.map +1 -1
- package/lib/locale-context.d.ts +1 -0
- package/lib/locale-context.d.ts.map +1 -1
- package/lib/locale-context.js +23 -22
- package/lib/locale-context.js.map +1 -1
- package/lib/resolvers/mutations/accounts/logout.js +1 -1
- package/lib/resolvers/mutations/accounts/logout.js.map +1 -1
- package/lib/resolvers/mutations/accounts/logoutAllSessions.js +1 -1
- package/lib/resolvers/mutations/accounts/logoutAllSessions.js.map +1 -1
- package/lib/resolvers/mutations/countries/updateCountry.d.ts +3 -1
- package/lib/resolvers/mutations/countries/updateCountry.d.ts.map +1 -1
- package/lib/resolvers/mutations/countries/updateCountry.js +5 -1
- package/lib/resolvers/mutations/countries/updateCountry.js.map +1 -1
- package/lib/resolvers/mutations/enrollments/createEnrollment.d.ts.map +1 -1
- package/lib/resolvers/mutations/enrollments/createEnrollment.js +2 -1
- package/lib/resolvers/mutations/enrollments/createEnrollment.js.map +1 -1
- package/lib/resolvers/mutations/orders/confirmOrder.d.ts +1 -0
- package/lib/resolvers/mutations/orders/confirmOrder.d.ts.map +1 -1
- package/lib/resolvers/mutations/orders/confirmOrder.js.map +1 -1
- package/lib/resolvers/mutations/orders/rejectOrder.d.ts +1 -0
- package/lib/resolvers/mutations/orders/rejectOrder.d.ts.map +1 -1
- package/lib/resolvers/mutations/orders/rejectOrder.js.map +1 -1
- package/lib/resolvers/type/country-types.js +2 -2
- package/lib/resolvers/type/country-types.js.map +1 -1
- package/lib/resolvers/type/delivery-provider-types.d.ts.map +1 -1
- package/lib/resolvers/type/delivery-provider-types.js +2 -5
- package/lib/resolvers/type/delivery-provider-types.js.map +1 -1
- package/lib/resolvers/type/index.d.ts +1 -1
- package/lib/resolvers/type/index.d.ts.map +1 -1
- package/lib/resolvers/type/login-method-response-types.d.ts +1 -1
- package/lib/resolvers/type/login-method-response-types.d.ts.map +1 -1
- package/lib/resolvers/type/login-method-response-types.js +2 -2
- package/lib/resolvers/type/login-method-response-types.js.map +1 -1
- package/lib/resolvers/type/payment/payment-provider-types.d.ts.map +1 -1
- package/lib/resolvers/type/payment/payment-provider-types.js +2 -5
- package/lib/resolvers/type/payment/payment-provider-types.js.map +1 -1
- package/lib/resolvers/type/product/product-configurable-types.d.ts.map +1 -1
- package/lib/resolvers/type/product/product-configurable-types.js +2 -8
- package/lib/resolvers/type/product/product-configurable-types.js.map +1 -1
- package/lib/resolvers/type/product/product-plan-types.d.ts.map +1 -1
- package/lib/resolvers/type/product/product-plan-types.js +4 -13
- package/lib/resolvers/type/product/product-plan-types.js.map +1 -1
- package/lib/resolvers/type/product/product-simple-types.d.ts.map +1 -1
- package/lib/resolvers/type/product/product-tokenized-types.d.ts.map +1 -1
- package/lib/schema/inputTypes.d.ts.map +1 -1
- package/lib/schema/inputTypes.js +2 -1
- package/lib/schema/inputTypes.js.map +1 -1
- package/lib/schema/mutation.js +2 -2
- package/lib/user-context.d.ts.map +1 -1
- package/lib/user-context.js +20 -16
- package/lib/user-context.js.map +1 -1
- package/package.json +13 -13
- package/src/express/createBulkImportMiddleware.ts +1 -0
- package/src/locale-context.ts +53 -49
- package/src/resolvers/mutations/accounts/logout.ts +1 -1
- package/src/resolvers/mutations/accounts/logoutAllSessions.ts +1 -1
- package/src/resolvers/mutations/countries/updateCountry.ts +7 -2
- package/src/resolvers/mutations/enrollments/createEnrollment.ts +2 -1
- package/src/resolvers/mutations/orders/confirmOrder.ts +1 -0
- package/src/resolvers/mutations/orders/rejectOrder.ts +2 -0
- package/src/resolvers/type/country-types.ts +2 -2
- package/src/resolvers/type/delivery-provider-types.ts +2 -10
- package/src/resolvers/type/login-method-response-types.ts +2 -2
- package/src/resolvers/type/payment/payment-provider-types.ts +2 -9
- package/src/resolvers/type/product/product-configurable-types.ts +3 -16
- package/src/resolvers/type/product/product-plan-types.ts +5 -25
- package/src/schema/inputTypes.ts +2 -1
- package/src/schema/mutation.ts +2 -2
- package/src/user-context.ts +24 -17
package/lib/schema/mutation.js
CHANGED
|
@@ -304,12 +304,12 @@ export default [
|
|
|
304
304
|
"""
|
|
305
305
|
Manually confirm an order which is in progress
|
|
306
306
|
"""
|
|
307
|
-
confirmOrder(orderId: ID!, paymentContext: JSON, deliveryContext: JSON): Order!
|
|
307
|
+
confirmOrder(orderId: ID!, paymentContext: JSON, deliveryContext: JSON, comment: String): Order!
|
|
308
308
|
|
|
309
309
|
"""
|
|
310
310
|
Manually reject an order which is in progress
|
|
311
311
|
"""
|
|
312
|
-
rejectOrder(orderId: ID!, paymentContext: JSON, deliveryContext: JSON): Order!
|
|
312
|
+
rejectOrder(orderId: ID!, paymentContext: JSON, deliveryContext: JSON, comment: String): Order!
|
|
313
313
|
|
|
314
314
|
"""
|
|
315
315
|
Manually mark an unpaid/partially paid order as fully paid
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-context.d.ts","sourceRoot":"","sources":["../src/user-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"user-context.d.ts","sourceRoot":"","sources":["../src/user-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAiC7D,eAAO,MAAM,cAAc,QACpB,eAAe,GAAG;IAAE,OAAO,CAAC,EAAE,GAAG,CAAA;CAAE,OACnC,eAAe,gBACN,aAAa,KAC1B,OAAO,CAAC,oBAAoB,CAsD9B,CAAC"}
|
package/lib/user-context.js
CHANGED
|
@@ -3,26 +3,27 @@ function isString(input) {
|
|
|
3
3
|
return typeof input === 'string' && Object.prototype.toString.call(input) === '[object String]';
|
|
4
4
|
}
|
|
5
5
|
const { UNCHAINED_COOKIE_NAME = 'unchained_token', UNCHAINED_COOKIE_PATH = '/', UNCHAINED_COOKIE_DOMAIN, NODE_ENV, } = process.env;
|
|
6
|
-
|
|
7
|
-
// there is a possible current user connected!
|
|
6
|
+
function setLoginToken(res, token, expires) {
|
|
8
7
|
const cookieName = UNCHAINED_COOKIE_NAME;
|
|
9
8
|
const domain = UNCHAINED_COOKIE_DOMAIN;
|
|
10
9
|
const path = UNCHAINED_COOKIE_PATH;
|
|
10
|
+
if (!domain)
|
|
11
|
+
return;
|
|
12
|
+
const authCookie = cookie.serialize(cookieName, token || null, {
|
|
13
|
+
domain,
|
|
14
|
+
httpOnly: true,
|
|
15
|
+
path,
|
|
16
|
+
expires: token && expires ? expires : undefined,
|
|
17
|
+
maxAge: token ? undefined : -1,
|
|
18
|
+
sameSite: 'lax',
|
|
19
|
+
secure: NODE_ENV === 'production',
|
|
20
|
+
});
|
|
21
|
+
res.setHeader('Set-Cookie', authCookie);
|
|
22
|
+
}
|
|
23
|
+
export const getUserContext = async (req, res, unchainedAPI) => {
|
|
24
|
+
// there is a possible current user connected!
|
|
25
|
+
const cookieName = UNCHAINED_COOKIE_NAME;
|
|
11
26
|
let loginToken = req.cookies?.[cookieName];
|
|
12
|
-
function setLoginToken(token, expires) {
|
|
13
|
-
if (!domain)
|
|
14
|
-
return;
|
|
15
|
-
const authCookie = cookie.serialize(cookieName, token || null, {
|
|
16
|
-
domain,
|
|
17
|
-
httpOnly: true,
|
|
18
|
-
path,
|
|
19
|
-
expires: token ? expires : undefined,
|
|
20
|
-
maxAge: token ? undefined : -1,
|
|
21
|
-
sameSite: 'lax',
|
|
22
|
-
secure: NODE_ENV === 'production',
|
|
23
|
-
});
|
|
24
|
-
res.setHeader('Set-Cookie', authCookie);
|
|
25
|
-
}
|
|
26
27
|
if (req.headers.authorization) {
|
|
27
28
|
const [type, token] = req.headers.authorization.split(' ');
|
|
28
29
|
if (type === 'Bearer') {
|
|
@@ -57,6 +58,9 @@ export const getUserContext = async (req, res, unchainedAPI) => {
|
|
|
57
58
|
};
|
|
58
59
|
}
|
|
59
60
|
}
|
|
61
|
+
// If there is no user with this token or the token is expires/invalid,
|
|
62
|
+
// we should remove that cookie from the client
|
|
63
|
+
setLoginToken(res, null);
|
|
60
64
|
return { loginToken: loginToken, setLoginToken };
|
|
61
65
|
}
|
|
62
66
|
return { setLoginToken };
|
package/lib/user-context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-context.js","sourceRoot":"","sources":["../src/user-context.ts"],"names":[],"mappings":"AAGA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,SAAS,QAAQ,CAAC,KAAK;IACrB,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,iBAAiB,CAAC;AAClG,CAAC;AAED,MAAM,EACJ,qBAAqB,GAAG,iBAAiB,EACzC,qBAAqB,GAAG,GAAG,EAC3B,uBAAuB,EACvB,QAAQ,GACT,GAAG,OAAO,CAAC,GAAG,CAAC;AAEhB,
|
|
1
|
+
{"version":3,"file":"user-context.js","sourceRoot":"","sources":["../src/user-context.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unchainedshop/api",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.1",
|
|
4
4
|
"main": "lib/api-index.js",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./lib/api-index.js",
|
|
@@ -40,35 +40,35 @@
|
|
|
40
40
|
},
|
|
41
41
|
"homepage": "https://github.com/unchainedshop/unchained#readme",
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@apollo/server": "^4.10.
|
|
43
|
+
"@apollo/server": "^4.10.5",
|
|
44
44
|
"cookie": "~0.6"
|
|
45
45
|
},
|
|
46
46
|
"optionalDependencies": {
|
|
47
47
|
"express": "~4"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@metamask/eth-sig-util": "^7.0.
|
|
51
|
-
"@unchainedshop/core": "^2.
|
|
52
|
-
"@unchainedshop/events": "^2.
|
|
53
|
-
"@unchainedshop/logger": "^2.
|
|
54
|
-
"@unchainedshop/roles": "^2.
|
|
55
|
-
"@unchainedshop/utils": "^2.
|
|
50
|
+
"@metamask/eth-sig-util": "^7.0.3",
|
|
51
|
+
"@unchainedshop/core": "^2.13.0",
|
|
52
|
+
"@unchainedshop/events": "^2.13.0",
|
|
53
|
+
"@unchainedshop/logger": "^2.13.0",
|
|
54
|
+
"@unchainedshop/roles": "^2.13.0",
|
|
55
|
+
"@unchainedshop/utils": "^2.13.0",
|
|
56
56
|
"accounting": "0.4.1",
|
|
57
57
|
"dataloader": "^2.2.2",
|
|
58
58
|
"graphql-scalars": "^1.23.0",
|
|
59
59
|
"graphql-upload": "^16.0.2",
|
|
60
60
|
"locale": "0.1.0",
|
|
61
61
|
"lodash.isnumber": "3.0.3",
|
|
62
|
-
"
|
|
62
|
+
"memoizee": "^0.4.17"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
65
|
"@types/graphql-upload": "^16.0.7",
|
|
66
66
|
"@types/locale": "^0.1.4",
|
|
67
|
-
"@types/node": "^20.14.
|
|
68
|
-
"@unchainedshop/types": "^2.
|
|
67
|
+
"@types/node": "^20.14.12",
|
|
68
|
+
"@unchainedshop/types": "^2.13.0",
|
|
69
69
|
"express": "^4.19.2",
|
|
70
70
|
"jest": "^29.7.0",
|
|
71
|
-
"ts-jest": "^29.2.
|
|
72
|
-
"typescript": "^5.5.
|
|
71
|
+
"ts-jest": "^29.2.3",
|
|
72
|
+
"typescript": "^5.5.4"
|
|
73
73
|
}
|
|
74
74
|
}
|
|
@@ -30,6 +30,7 @@ export default async function bulkImportMiddleware(req, res) {
|
|
|
30
30
|
|
|
31
31
|
const input: any = {
|
|
32
32
|
createShouldUpsertIfIDExists: !!req.query?.createShouldUpsertIfIDExists,
|
|
33
|
+
updateShouldUpsertIfIDNotExists: !!req.query?.updateShouldUpsertIfIDNotExists,
|
|
33
34
|
skipCacheInvalidation: !!req.query?.skipCacheInvalidation,
|
|
34
35
|
remoteAddress: context.remoteAddress,
|
|
35
36
|
};
|
package/src/locale-context.ts
CHANGED
|
@@ -6,73 +6,77 @@ import { log, LogLevel } from '@unchainedshop/logger';
|
|
|
6
6
|
import {
|
|
7
7
|
resolveBestCountry,
|
|
8
8
|
resolveBestSupported,
|
|
9
|
+
resolveBestCurrency,
|
|
9
10
|
resolveUserRemoteAddress,
|
|
10
11
|
systemLocale,
|
|
11
12
|
} from '@unchainedshop/utils';
|
|
12
13
|
import { UnchainedCore } from '@unchainedshop/types/core.js';
|
|
13
|
-
import
|
|
14
|
+
import memoizee from 'memoizee';
|
|
14
15
|
|
|
15
16
|
const { Locales } = localePkg;
|
|
16
17
|
|
|
17
18
|
const { NODE_ENV } = process.env;
|
|
18
19
|
|
|
19
|
-
const
|
|
20
|
+
export const resolveDefaultContext = memoizee(
|
|
21
|
+
async ({ acceptLang, acceptCountry }, unchainedAPI) => {
|
|
22
|
+
const languages = await unchainedAPI.modules.languages.findLanguages(
|
|
23
|
+
{ includeInactive: false },
|
|
24
|
+
{ projection: { isoCode: 1, isActive: 1 } },
|
|
25
|
+
);
|
|
20
26
|
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
27
|
+
const countries = await unchainedAPI.modules.countries.findCountries(
|
|
28
|
+
{ includeInactive: false },
|
|
29
|
+
{ projection: { isoCode: 1, isActive: 1 } },
|
|
30
|
+
);
|
|
25
31
|
|
|
26
|
-
|
|
27
|
-
req: IncomingMessage,
|
|
28
|
-
res: OutgoingMessage,
|
|
29
|
-
unchainedAPI: UnchainedCore,
|
|
30
|
-
): Promise<UnchainedLocaleContext> => {
|
|
31
|
-
const cacheKey = `${req.headers['accept-language']}:${req.headers['x-shop-country']}`;
|
|
32
|
-
const cachedContext = localeContextCache.get(cacheKey) as UnchainedLocaleContext;
|
|
32
|
+
const currencies = await unchainedAPI.modules.currencies.findCurrencies({ includeInactive: false });
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
const supportedLocaleStrings = languages.reduce((accumulator, language) => {
|
|
35
|
+
const added = countries.map((country) => {
|
|
36
|
+
return `${language.isoCode}-${country.isoCode}`;
|
|
37
|
+
});
|
|
38
|
+
return accumulator.concat(added);
|
|
39
|
+
}, []);
|
|
36
40
|
|
|
37
|
-
|
|
41
|
+
const supportedLocales = new Locales(supportedLocaleStrings, systemLocale.code);
|
|
38
42
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// else fallback to base language & base country
|
|
43
|
+
const localeContext = resolveBestSupported(acceptLang, supportedLocales);
|
|
44
|
+
const countryContext = resolveBestCountry(localeContext.country, acceptCountry, countries);
|
|
42
45
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
{ projection: { isoCode: 1, isActive: 1 } },
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
const countries = await unchainedAPI.modules.countries.findCountries(
|
|
49
|
-
{ includeInactive: false },
|
|
50
|
-
{ projection: { isoCode: 1, isActive: 1 } },
|
|
51
|
-
);
|
|
46
|
+
const countryObject = countries.find((country) => country.isoCode === countryContext);
|
|
47
|
+
const currencyContext = resolveBestCurrency(countryObject.defaultCurrencyCode, currencies);
|
|
52
48
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return `${language.isoCode}-${country.isoCode}`;
|
|
49
|
+
log(`Locale Context: Resolved ${localeContext.normalized} ${countryContext} ${currencyContext}`, {
|
|
50
|
+
level: LogLevel.Debug,
|
|
56
51
|
});
|
|
57
|
-
return accumulator.concat(added);
|
|
58
|
-
}, []);
|
|
59
52
|
|
|
60
|
-
|
|
53
|
+
const newContext: UnchainedLocaleContext = {
|
|
54
|
+
localeContext,
|
|
55
|
+
countryContext,
|
|
56
|
+
currencyContext,
|
|
57
|
+
};
|
|
61
58
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
localeContext,
|
|
73
|
-
countryContext,
|
|
74
|
-
};
|
|
75
|
-
localeContextCache.set(cacheKey, newContext);
|
|
59
|
+
return newContext;
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
maxAge: NODE_ENV === 'production' ? 1000 * 60 : 100, // minute or 100ms
|
|
63
|
+
promise: true,
|
|
64
|
+
normalizer(args) {
|
|
65
|
+
return `${args[0].acceptLang}-${args[0].acceptCountry}`;
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
);
|
|
76
69
|
|
|
77
|
-
|
|
70
|
+
export const getLocaleContext = async (
|
|
71
|
+
req: IncomingMessage,
|
|
72
|
+
res: OutgoingMessage,
|
|
73
|
+
unchainedAPI: UnchainedCore,
|
|
74
|
+
): Promise<UnchainedLocaleContext> => {
|
|
75
|
+
const userAgent = req.headers['user-agent'];
|
|
76
|
+
const { remoteAddress, remotePort } = resolveUserRemoteAddress(req);
|
|
77
|
+
const context = await resolveDefaultContext(
|
|
78
|
+
{ acceptLang: req.headers['accept-language'], acceptCountry: req.headers['x-shop-country'] },
|
|
79
|
+
unchainedAPI,
|
|
80
|
+
);
|
|
81
|
+
return { remoteAddress, remotePort, userAgent, ...context };
|
|
78
82
|
};
|
|
@@ -5,7 +5,7 @@ import { CountryNotFoundError, InvalidIdError } from '../../../errors.js';
|
|
|
5
5
|
|
|
6
6
|
export default async function updateCountry(
|
|
7
7
|
root: Root,
|
|
8
|
-
{ country, countryId }: { country: Country; countryId: string },
|
|
8
|
+
{ country, countryId }: { country: Country & { defaultCurrencyId: string }; countryId: string },
|
|
9
9
|
{ userId, modules }: Context,
|
|
10
10
|
) {
|
|
11
11
|
log(`mutation updateCountry ${countryId}`, { userId });
|
|
@@ -15,7 +15,12 @@ export default async function updateCountry(
|
|
|
15
15
|
if (!(await modules.countries.countryExists({ countryId })))
|
|
16
16
|
throw new CountryNotFoundError({ countryId });
|
|
17
17
|
|
|
18
|
-
await modules.
|
|
18
|
+
const currencyObject = await modules.currencies.findCurrency({
|
|
19
|
+
currencyId: country.defaultCurrencyId,
|
|
20
|
+
});
|
|
21
|
+
const defaultCurrencyCode = country?.defaultCurrencyCode || currencyObject?.isoCode;
|
|
22
|
+
|
|
23
|
+
await modules.countries.update(countryId, { ...country, defaultCurrencyCode });
|
|
19
24
|
|
|
20
25
|
return modules.countries.findCountry({ countryId });
|
|
21
26
|
}
|
|
@@ -13,7 +13,7 @@ export default async function createEnrollment(
|
|
|
13
13
|
{ contact, plan, billingAddress, payment, delivery, meta },
|
|
14
14
|
context: Context,
|
|
15
15
|
) {
|
|
16
|
-
const { countryContext, modules, userId } = context;
|
|
16
|
+
const { countryContext, currencyContext, modules, userId } = context;
|
|
17
17
|
|
|
18
18
|
log('mutation createEnrollment', { userId });
|
|
19
19
|
|
|
@@ -40,6 +40,7 @@ export default async function createEnrollment(
|
|
|
40
40
|
configuration,
|
|
41
41
|
contact,
|
|
42
42
|
countryCode: countryContext,
|
|
43
|
+
currencyCode: currencyContext,
|
|
43
44
|
delivery,
|
|
44
45
|
meta,
|
|
45
46
|
payment,
|
|
@@ -9,6 +9,7 @@ export default async function rejectOrder(
|
|
|
9
9
|
orderId: string;
|
|
10
10
|
paymentContext?: any;
|
|
11
11
|
deliveryContext?: any;
|
|
12
|
+
comment?: string;
|
|
12
13
|
},
|
|
13
14
|
context: Context,
|
|
14
15
|
) {
|
|
@@ -16,6 +17,7 @@ export default async function rejectOrder(
|
|
|
16
17
|
const { orderId, ...transactionContext } = params;
|
|
17
18
|
|
|
18
19
|
log('mutation rejectOrder', { orderId, userId });
|
|
20
|
+
|
|
19
21
|
if (!orderId) throw new InvalidIdError({ orderId });
|
|
20
22
|
|
|
21
23
|
const order = await modules.orders.findOrder({ orderId });
|
|
@@ -13,9 +13,9 @@ export interface CountryHelperTypes {
|
|
|
13
13
|
|
|
14
14
|
export const Country: CountryHelperTypes = {
|
|
15
15
|
defaultCurrency: async (country, _, { modules }) => {
|
|
16
|
-
if (country.
|
|
16
|
+
if (country.defaultCurrencyCode) {
|
|
17
17
|
return modules.currencies.findCurrency({
|
|
18
|
-
|
|
18
|
+
isoCode: country.defaultCurrencyCode,
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
return null;
|
|
@@ -59,17 +59,9 @@ export const DeliveryProvider: DeliveryProviderHelperTypes = {
|
|
|
59
59
|
{ currency: currencyCode, orderId, useNetPrice, context: providerContext },
|
|
60
60
|
requestContext,
|
|
61
61
|
) {
|
|
62
|
-
const { modules,
|
|
62
|
+
const { modules, countryContext: country, user } = requestContext;
|
|
63
63
|
const order = await modules.orders.findOrder({ orderId });
|
|
64
|
-
|
|
65
|
-
const currency =
|
|
66
|
-
currencyCode ||
|
|
67
|
-
(await services.countries.resolveDefaultCurrencyCode(
|
|
68
|
-
{
|
|
69
|
-
isoCode: country,
|
|
70
|
-
},
|
|
71
|
-
requestContext,
|
|
72
|
-
));
|
|
64
|
+
const currency = currencyCode || requestContext.currencyContext;
|
|
73
65
|
|
|
74
66
|
const pricingDirector = await DeliveryPricingDirector.actions(
|
|
75
67
|
{
|
|
@@ -10,8 +10,8 @@ export const LoginMethodResponse = {
|
|
|
10
10
|
|
|
11
11
|
return user;
|
|
12
12
|
},
|
|
13
|
-
token({ token, tokenExpires }, _, { setLoginToken }: Context) {
|
|
14
|
-
setLoginToken(token, tokenExpires);
|
|
13
|
+
token({ token, tokenExpires }, _, { res, setLoginToken }: Context) {
|
|
14
|
+
setLoginToken(res, token, tokenExpires);
|
|
15
15
|
return token;
|
|
16
16
|
},
|
|
17
17
|
};
|
|
@@ -59,17 +59,10 @@ export const PaymentProvider: PaymentProviderHelperTypes = {
|
|
|
59
59
|
{ currency: currencyCode, orderId, useNetPrice, context: providerContext },
|
|
60
60
|
requestContext,
|
|
61
61
|
) {
|
|
62
|
-
const { modules,
|
|
62
|
+
const { modules, countryContext: country, user } = requestContext;
|
|
63
63
|
const order = await modules.orders.findOrder({ orderId });
|
|
64
64
|
|
|
65
|
-
const currency =
|
|
66
|
-
currencyCode ||
|
|
67
|
-
(await services.countries.resolveDefaultCurrencyCode(
|
|
68
|
-
{
|
|
69
|
-
isoCode: country,
|
|
70
|
-
},
|
|
71
|
-
requestContext,
|
|
72
|
-
));
|
|
65
|
+
const currency = currencyCode || requestContext.currencyContext;
|
|
73
66
|
|
|
74
67
|
const pricingDirector = await PaymentPricingDirector.actions(
|
|
75
68
|
{
|
|
@@ -58,14 +58,7 @@ export const ConfigurableProduct = {
|
|
|
58
58
|
requestContext: Context,
|
|
59
59
|
): Promise<ProductPriceRange> {
|
|
60
60
|
const { countryContext, modules } = requestContext;
|
|
61
|
-
const currencyCode =
|
|
62
|
-
forcedCurrencyCode ||
|
|
63
|
-
(await requestContext.services.countries.resolveDefaultCurrencyCode(
|
|
64
|
-
{
|
|
65
|
-
isoCode: countryContext,
|
|
66
|
-
},
|
|
67
|
-
requestContext,
|
|
68
|
-
));
|
|
61
|
+
const currencyCode = forcedCurrencyCode || requestContext.currencyContext;
|
|
69
62
|
return modules.products.prices.catalogPriceRange(product, {
|
|
70
63
|
quantity,
|
|
71
64
|
vectors,
|
|
@@ -111,14 +104,8 @@ export const ConfigurableProduct = {
|
|
|
111
104
|
requestContext: Context,
|
|
112
105
|
): Promise<ProductPriceRange> {
|
|
113
106
|
const { countryContext, modules } = requestContext;
|
|
114
|
-
const currency =
|
|
115
|
-
|
|
116
|
-
(await requestContext.services.countries.resolveDefaultCurrencyCode(
|
|
117
|
-
{
|
|
118
|
-
isoCode: countryContext,
|
|
119
|
-
},
|
|
120
|
-
requestContext,
|
|
121
|
-
));
|
|
107
|
+
const currency = forcedCurrencyCode || requestContext.currencyContext;
|
|
108
|
+
|
|
122
109
|
return modules.products.prices.simulatedPriceRange(
|
|
123
110
|
product,
|
|
124
111
|
{
|
|
@@ -11,17 +11,10 @@ export const PlanProduct = {
|
|
|
11
11
|
requestContext: Context,
|
|
12
12
|
): Promise<ProductPrice> {
|
|
13
13
|
const { modules, countryContext } = requestContext;
|
|
14
|
-
const
|
|
15
|
-
forcedCurrencyCode ||
|
|
16
|
-
(await requestContext.services.countries.resolveDefaultCurrencyCode(
|
|
17
|
-
{
|
|
18
|
-
isoCode: countryContext,
|
|
19
|
-
},
|
|
20
|
-
requestContext,
|
|
21
|
-
));
|
|
14
|
+
const currency = forcedCurrencyCode || requestContext.currencyContext;
|
|
22
15
|
return modules.products.prices.price(product, {
|
|
23
16
|
country: countryContext,
|
|
24
|
-
currency
|
|
17
|
+
currency,
|
|
25
18
|
quantity,
|
|
26
19
|
});
|
|
27
20
|
},
|
|
@@ -36,14 +29,8 @@ export const PlanProduct = {
|
|
|
36
29
|
requestContext: Context,
|
|
37
30
|
): Promise<ProductPrice> {
|
|
38
31
|
const { countryContext, modules } = requestContext;
|
|
39
|
-
const currency =
|
|
40
|
-
|
|
41
|
-
(await requestContext.services.countries.resolveDefaultCurrencyCode(
|
|
42
|
-
{
|
|
43
|
-
isoCode: countryContext,
|
|
44
|
-
},
|
|
45
|
-
requestContext,
|
|
46
|
-
));
|
|
32
|
+
const currency = forcedCurrencyCode || requestContext.currencyContext;
|
|
33
|
+
|
|
47
34
|
return modules.products.prices.userPrice(
|
|
48
35
|
obj,
|
|
49
36
|
{ quantity, userId: requestContext.userId, currency, country: countryContext, useNetPrice },
|
|
@@ -63,14 +50,7 @@ export const PlanProduct = {
|
|
|
63
50
|
}>
|
|
64
51
|
> {
|
|
65
52
|
const { countryContext, modules } = requestContext;
|
|
66
|
-
const currency =
|
|
67
|
-
forcedCurrencyCode ||
|
|
68
|
-
(await requestContext.services.countries.resolveDefaultCurrencyCode(
|
|
69
|
-
{
|
|
70
|
-
isoCode: countryContext,
|
|
71
|
-
},
|
|
72
|
-
requestContext,
|
|
73
|
-
));
|
|
53
|
+
const currency = forcedCurrencyCode || requestContext.currencyContext;
|
|
74
54
|
return modules.products.prices.catalogPricesLeveled(obj, { currency, country: countryContext });
|
|
75
55
|
},
|
|
76
56
|
|
package/src/schema/inputTypes.ts
CHANGED
|
@@ -44,7 +44,8 @@ export default [
|
|
|
44
44
|
input UpdateCountryInput {
|
|
45
45
|
isoCode: String!
|
|
46
46
|
isActive: Boolean
|
|
47
|
-
|
|
47
|
+
defaultCurrencyCode: String
|
|
48
|
+
defaultCurrencyId: String @deprecated(reason: "Use defaultCurrencyCode instead")
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
input CreateCurrencyInput {
|
package/src/schema/mutation.ts
CHANGED
|
@@ -304,12 +304,12 @@ export default [
|
|
|
304
304
|
"""
|
|
305
305
|
Manually confirm an order which is in progress
|
|
306
306
|
"""
|
|
307
|
-
confirmOrder(orderId: ID!, paymentContext: JSON, deliveryContext: JSON): Order!
|
|
307
|
+
confirmOrder(orderId: ID!, paymentContext: JSON, deliveryContext: JSON, comment: String): Order!
|
|
308
308
|
|
|
309
309
|
"""
|
|
310
310
|
Manually reject an order which is in progress
|
|
311
311
|
"""
|
|
312
|
-
rejectOrder(orderId: ID!, paymentContext: JSON, deliveryContext: JSON): Order!
|
|
312
|
+
rejectOrder(orderId: ID!, paymentContext: JSON, deliveryContext: JSON, comment: String): Order!
|
|
313
313
|
|
|
314
314
|
"""
|
|
315
315
|
Manually mark an unpaid/partially paid order as fully paid
|
package/src/user-context.ts
CHANGED
|
@@ -14,6 +14,25 @@ const {
|
|
|
14
14
|
NODE_ENV,
|
|
15
15
|
} = process.env;
|
|
16
16
|
|
|
17
|
+
function setLoginToken(res: OutgoingMessage, token: string | null, expires?: Date) {
|
|
18
|
+
const cookieName = UNCHAINED_COOKIE_NAME;
|
|
19
|
+
const domain = UNCHAINED_COOKIE_DOMAIN;
|
|
20
|
+
const path = UNCHAINED_COOKIE_PATH;
|
|
21
|
+
|
|
22
|
+
if (!domain) return;
|
|
23
|
+
|
|
24
|
+
const authCookie = cookie.serialize(cookieName, token || null, {
|
|
25
|
+
domain,
|
|
26
|
+
httpOnly: true,
|
|
27
|
+
path,
|
|
28
|
+
expires: token && expires ? expires : undefined,
|
|
29
|
+
maxAge: token ? undefined : -1,
|
|
30
|
+
sameSite: 'lax',
|
|
31
|
+
secure: NODE_ENV === 'production',
|
|
32
|
+
});
|
|
33
|
+
res.setHeader('Set-Cookie', authCookie);
|
|
34
|
+
}
|
|
35
|
+
|
|
17
36
|
export const getUserContext = async (
|
|
18
37
|
req: IncomingMessage & { cookies?: any },
|
|
19
38
|
res: OutgoingMessage,
|
|
@@ -21,25 +40,8 @@ export const getUserContext = async (
|
|
|
21
40
|
): Promise<UnchainedUserContext> => {
|
|
22
41
|
// there is a possible current user connected!
|
|
23
42
|
const cookieName = UNCHAINED_COOKIE_NAME;
|
|
24
|
-
const domain = UNCHAINED_COOKIE_DOMAIN;
|
|
25
|
-
const path = UNCHAINED_COOKIE_PATH;
|
|
26
|
-
|
|
27
43
|
let loginToken = req.cookies?.[cookieName];
|
|
28
44
|
|
|
29
|
-
function setLoginToken(token: string, expires: Date) {
|
|
30
|
-
if (!domain) return;
|
|
31
|
-
const authCookie = cookie.serialize(cookieName, token || null, {
|
|
32
|
-
domain,
|
|
33
|
-
httpOnly: true,
|
|
34
|
-
path,
|
|
35
|
-
expires: token ? expires : undefined,
|
|
36
|
-
maxAge: token ? undefined : -1,
|
|
37
|
-
sameSite: 'lax',
|
|
38
|
-
secure: NODE_ENV === 'production',
|
|
39
|
-
});
|
|
40
|
-
res.setHeader('Set-Cookie', authCookie);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
45
|
if (req.headers.authorization) {
|
|
44
46
|
const [type, token] = req.headers.authorization.split(' ');
|
|
45
47
|
if (type === 'Bearer') {
|
|
@@ -80,6 +82,11 @@ export const getUserContext = async (
|
|
|
80
82
|
};
|
|
81
83
|
}
|
|
82
84
|
}
|
|
85
|
+
|
|
86
|
+
// If there is no user with this token or the token is expires/invalid,
|
|
87
|
+
// we should remove that cookie from the client
|
|
88
|
+
setLoginToken(res, null);
|
|
89
|
+
|
|
83
90
|
return { loginToken: loginToken as string, setLoginToken };
|
|
84
91
|
}
|
|
85
92
|
|