@unchainedshop/api 1.2.40 → 2.0.0-beta2
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/api-index.d.ts +1 -0
- package/lib/api-index.js +3 -0
- package/lib/api-index.js.map +1 -1
- package/lib/context.js +3 -3
- package/lib/context.js.map +1 -1
- package/lib/createBulkImportServer.js +1 -1
- package/lib/createBulkImportServer.js.map +1 -1
- package/lib/createERCMetadataServer.d.ts +2 -0
- package/lib/createERCMetadataServer.js +53 -0
- package/lib/createERCMetadataServer.js.map +1 -0
- package/lib/errors.d.ts +4 -0
- package/lib/errors.js +4 -0
- package/lib/errors.js.map +1 -1
- package/lib/loaders/index.d.ts +2 -2
- package/lib/loaders/index.js +1 -1
- package/lib/loaders/index.js.map +1 -1
- package/lib/locale-context.d.ts +2 -2
- package/lib/locale-context.js +1 -1
- package/lib/locale-context.js.map +1 -1
- package/lib/resolvers/index.js +2 -0
- package/lib/resolvers/index.js.map +1 -1
- package/lib/resolvers/mutations/accounts/addWeb3Address.d.ts +4 -0
- package/lib/resolvers/mutations/accounts/addWeb3Address.js +21 -0
- package/lib/resolvers/mutations/accounts/addWeb3Address.js.map +1 -0
- package/lib/resolvers/mutations/accounts/addWebAuthnCredentials.d.ts +4 -0
- package/lib/resolvers/mutations/accounts/addWebAuthnCredentials.js +14 -0
- package/lib/resolvers/mutations/accounts/addWebAuthnCredentials.js.map +1 -0
- package/lib/resolvers/mutations/accounts/createUser.js +18 -6
- package/lib/resolvers/mutations/accounts/createUser.js.map +1 -1
- package/lib/resolvers/mutations/accounts/createWebAuthnCredentialCreationOptions.d.ts +5 -0
- package/lib/resolvers/mutations/accounts/createWebAuthnCredentialCreationOptions.js +9 -0
- package/lib/resolvers/mutations/accounts/createWebAuthnCredentialCreationOptions.js.map +1 -0
- package/lib/resolvers/mutations/accounts/createWebAuthnCredentialRequestOptions.d.ts +5 -0
- package/lib/resolvers/mutations/accounts/createWebAuthnCredentialRequestOptions.js +16 -0
- package/lib/resolvers/mutations/accounts/createWebAuthnCredentialRequestOptions.js.map +1 -0
- package/lib/resolvers/mutations/accounts/loginWithWebAuthn.d.ts +8 -0
- package/lib/resolvers/mutations/accounts/loginWithWebAuthn.js +7 -0
- package/lib/resolvers/mutations/accounts/loginWithWebAuthn.js.map +1 -0
- package/lib/resolvers/mutations/accounts/logout.js +6 -2
- package/lib/resolvers/mutations/accounts/logout.js.map +1 -1
- package/lib/resolvers/mutations/accounts/logoutAllSessions.js +6 -2
- package/lib/resolvers/mutations/accounts/logoutAllSessions.js.map +1 -1
- package/lib/resolvers/mutations/accounts/removeWeb3Address.d.ts +4 -0
- package/lib/resolvers/mutations/accounts/removeWeb3Address.js +18 -0
- package/lib/resolvers/mutations/accounts/removeWeb3Address.js.map +1 -0
- package/lib/resolvers/mutations/accounts/removeWebAuthnCredentials.d.ts +4 -0
- package/lib/resolvers/mutations/accounts/removeWebAuthnCredentials.js +18 -0
- package/lib/resolvers/mutations/accounts/removeWebAuthnCredentials.js.map +1 -0
- package/lib/resolvers/mutations/accounts/verifyWeb3Address.d.ts +5 -0
- package/lib/resolvers/mutations/accounts/verifyWeb3Address.js +40 -0
- package/lib/resolvers/mutations/accounts/verifyWeb3Address.js.map +1 -0
- package/lib/resolvers/mutations/index.d.ts +174 -157
- package/lib/resolvers/mutations/index.js +20 -0
- package/lib/resolvers/mutations/index.js.map +1 -1
- package/lib/resolvers/mutations/orders/signPaymentProviderForCheckout.js +7 -1
- package/lib/resolvers/mutations/orders/signPaymentProviderForCheckout.js.map +1 -1
- package/lib/resolvers/mutations/pageView.d.ts +2 -2
- package/lib/resolvers/mutations/pageView.js.map +1 -1
- package/lib/resolvers/mutations/products/updateProductTokenization.d.ts +6 -0
- package/lib/resolvers/mutations/products/updateProductTokenization.js +19 -0
- package/lib/resolvers/mutations/products/updateProductTokenization.js.map +1 -0
- package/lib/resolvers/mutations/warehousing/exportToken.d.ts +6 -0
- package/lib/resolvers/mutations/warehousing/exportToken.js +21 -0
- package/lib/resolvers/mutations/warehousing/exportToken.js.map +1 -0
- package/lib/resolvers/queries/index.d.ts +67 -66
- package/lib/resolvers/queries/index.js +2 -0
- package/lib/resolvers/queries/index.js.map +1 -1
- package/lib/resolvers/queries/warehousing/token.d.ts +4 -0
- package/lib/resolvers/queries/warehousing/token.js +11 -0
- package/lib/resolvers/queries/warehousing/token.js.map +1 -0
- package/lib/resolvers/scalars/LowerCaseString.d.ts +3 -0
- package/lib/resolvers/scalars/LowerCaseString.js +17 -0
- package/lib/resolvers/scalars/LowerCaseString.js.map +1 -0
- package/lib/resolvers/scalars/index.d.ts +4 -0
- package/lib/resolvers/scalars/index.js +5 -0
- package/lib/resolvers/scalars/index.js.map +1 -0
- package/lib/resolvers/type/assortment/assortment-filter-types.d.ts +1 -1
- package/lib/resolvers/type/assortment/assortment-link-types.d.ts +1 -1
- package/lib/resolvers/type/assortment/assortment-product-types.d.ts +1 -1
- package/lib/resolvers/type/currency-types.d.ts +3 -0
- package/lib/resolvers/type/currency-types.js +6 -0
- package/lib/resolvers/type/currency-types.js.map +1 -0
- package/lib/resolvers/type/index.d.ts +246 -130
- package/lib/resolvers/type/index.js +8 -0
- package/lib/resolvers/type/index.js.map +1 -1
- package/lib/resolvers/type/login-method-response-types.d.ts +4 -0
- package/lib/resolvers/type/login-method-response-types.js +4 -0
- package/lib/resolvers/type/login-method-response-types.js.map +1 -1
- package/lib/resolvers/type/order/order-delivery-discount-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-delivery-shipping-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-discount-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-discountable-types.d.ts +6 -0
- package/lib/resolvers/type/order/order-discountable-types.js +1 -1
- package/lib/resolvers/type/order/order-discountable-types.js.map +1 -1
- package/lib/resolvers/type/order/order-global-discount-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-item-discount-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-item-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-payment-card-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-payment-discount-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-payment-generic-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-payment-invoice-types.d.ts +1 -1
- package/lib/resolvers/type/order/order-types.d.ts +2 -6
- package/lib/resolvers/type/order/order-types.js +0 -1
- package/lib/resolvers/type/order/order-types.js.map +1 -1
- package/lib/resolvers/type/product/product-tokenized-types.d.ts +2 -0
- package/lib/resolvers/type/product/product-tokenized-types.js +28 -0
- package/lib/resolvers/type/product/product-tokenized-types.js.map +1 -0
- package/lib/resolvers/type/quotation-types.d.ts +0 -4
- package/lib/resolvers/type/quotation-types.js +0 -10
- package/lib/resolvers/type/quotation-types.js.map +1 -1
- package/lib/resolvers/type/shop-types.d.ts +1 -1
- package/lib/resolvers/type/token-types.d.ts +17 -0
- package/lib/resolvers/type/token-types.js +30 -0
- package/lib/resolvers/type/token-types.js.map +1 -0
- package/lib/resolvers/type/user-types.d.ts +5 -1
- package/lib/resolvers/type/user-types.js +12 -0
- package/lib/resolvers/type/user-types.js.map +1 -1
- package/lib/resolvers/type/webauthn-credentials-types.d.ts +10 -0
- package/lib/resolvers/type/webauthn-credentials-types.js +13 -0
- package/lib/resolvers/type/webauthn-credentials-types.js.map +1 -0
- package/lib/roles/admin.js +3 -0
- package/lib/roles/admin.js.map +1 -1
- package/lib/roles/all.js +3 -0
- package/lib/roles/all.js.map +1 -1
- package/lib/roles/index.d.ts +1 -1
- package/lib/roles/index.js +3 -0
- package/lib/roles/index.js.map +1 -1
- package/lib/roles/loggedIn.js +9 -0
- package/lib/roles/loggedIn.js.map +1 -1
- package/lib/schema/inputTypes.js +6 -4
- package/lib/schema/inputTypes.js.map +1 -1
- package/lib/schema/mutation.js +57 -4
- package/lib/schema/mutation.js.map +1 -1
- package/lib/schema/query.js +9 -4
- package/lib/schema/query.js.map +1 -1
- package/lib/schema/scalars.js +1 -0
- package/lib/schema/scalars.js.map +1 -1
- package/lib/schema/types/assortment.js +6 -6
- package/lib/schema/types/currency.js +1 -0
- package/lib/schema/types/currency.js.map +1 -1
- package/lib/schema/types/order/order.js +0 -33
- package/lib/schema/types/order/order.js.map +1 -1
- package/lib/schema/types/payment.js +1 -1
- package/lib/schema/types/product/bundle-product.js +2 -2
- package/lib/schema/types/product/configurable-product.js +2 -2
- package/lib/schema/types/product/index.js +9 -1
- package/lib/schema/types/product/index.js.map +1 -1
- package/lib/schema/types/product/plan-product.js +2 -2
- package/lib/schema/types/product/product.js +4 -4
- package/lib/schema/types/product/simple-product.js +2 -2
- package/lib/schema/types/product/tokenized-product.d.ts +2 -0
- package/lib/schema/types/product/tokenized-product.js +57 -0
- package/lib/schema/types/product/tokenized-product.js.map +1 -0
- package/lib/schema/types/quotation.js +0 -1
- package/lib/schema/types/quotation.js.map +1 -1
- package/lib/schema/types/user.js +39 -1
- package/lib/schema/types/user.js.map +1 -1
- package/lib/schema/types/warehousing.js +23 -1
- package/lib/schema/types/warehousing.js.map +1 -1
- package/lib/user-context.d.ts +2 -2
- package/lib/user-context.js +20 -9
- package/lib/user-context.js.map +1 -1
- package/package.json +11 -9
- package/src/api-index.ts +4 -0
- package/src/context.ts +3 -3
- package/src/createBulkImportServer.ts +1 -1
- package/src/createERCMetadataServer.ts +71 -0
- package/src/errors.ts +20 -0
- package/src/loaders/index.ts +2 -1
- package/src/locale-context.ts +2 -1
- package/src/resolvers/index.ts +2 -0
- package/src/resolvers/mutations/accounts/addWeb3Address.ts +33 -0
- package/src/resolvers/mutations/accounts/addWebAuthnCredentials.ts +29 -0
- package/src/resolvers/mutations/accounts/createUser.ts +28 -6
- package/src/resolvers/mutations/accounts/createWebAuthnCredentialCreationOptions.ts +20 -0
- package/src/resolvers/mutations/accounts/createWebAuthnCredentialRequestOptions.ts +28 -0
- package/src/resolvers/mutations/accounts/loginWithWebAuthn.ts +16 -0
- package/src/resolvers/mutations/accounts/logout.ts +5 -2
- package/src/resolvers/mutations/accounts/logoutAllSessions.ts +5 -2
- package/src/resolvers/mutations/accounts/removeWeb3Address.ts +32 -0
- package/src/resolvers/mutations/accounts/removeWebAuthnCredentials.ts +30 -0
- package/src/resolvers/mutations/accounts/verifyWeb3Address.ts +60 -0
- package/src/resolvers/mutations/{index.js → index.ts} +20 -0
- package/src/resolvers/mutations/orders/signPaymentProviderForCheckout.ts +8 -1
- package/src/resolvers/mutations/{pageView.js → pageView.ts} +0 -0
- package/src/resolvers/mutations/products/updateProductTokenization.ts +28 -0
- package/src/resolvers/mutations/warehousing/exportToken.ts +33 -0
- package/src/resolvers/queries/{index.js → index.ts} +2 -0
- package/src/resolvers/queries/warehousing/token.ts +17 -0
- package/src/resolvers/scalars/LowerCaseString.ts +19 -0
- package/src/resolvers/scalars/index.ts +5 -0
- package/src/resolvers/type/assortment/assortment-filter-types.ts +1 -1
- package/src/resolvers/type/assortment/assortment-link-types.ts +1 -1
- package/src/resolvers/type/assortment/assortment-product-types.ts +1 -1
- package/src/resolvers/type/currency-types.ts +5 -0
- package/src/resolvers/type/{index.js → index.ts} +8 -0
- package/src/resolvers/type/login-method-response-types.ts +4 -0
- package/src/resolvers/type/order/order-delivery-discount-types.ts +1 -1
- package/src/resolvers/type/order/order-delivery-shipping-types.ts +1 -1
- package/src/resolvers/type/order/order-discount-types.ts +1 -1
- package/src/resolvers/type/order/order-discountable-types.ts +1 -1
- package/src/resolvers/type/order/order-global-discount-types.ts +1 -1
- package/src/resolvers/type/order/order-item-discount-types.ts +1 -1
- package/src/resolvers/type/order/order-item-types.ts +1 -1
- package/src/resolvers/type/order/order-payment-card-types.ts +1 -1
- package/src/resolvers/type/order/order-payment-discount-types.ts +1 -1
- package/src/resolvers/type/order/order-payment-generic-types.ts +1 -1
- package/src/resolvers/type/order/order-payment-invoice-types.ts +1 -1
- package/src/resolvers/type/order/order-types.ts +2 -10
- package/src/resolvers/type/product/product-tokenized-types.ts +34 -0
- package/src/resolvers/type/quotation-types.ts +0 -17
- package/src/resolvers/type/shop-types.ts +1 -1
- package/src/resolvers/type/token-types.ts +43 -0
- package/src/resolvers/type/user-types.ts +26 -1
- package/src/resolvers/type/webauthn-credentials-types.ts +27 -0
- package/src/roles/admin.ts +3 -0
- package/src/roles/all.ts +3 -0
- package/src/roles/index.ts +4 -1
- package/src/roles/loggedIn.ts +13 -0
- package/src/schema/inputTypes.js +6 -4
- package/src/schema/mutation.js +57 -4
- package/src/schema/query.js +9 -4
- package/src/schema/scalars.js +1 -0
- package/src/schema/types/assortment.js +6 -6
- package/src/schema/types/currency.js +1 -0
- package/src/schema/types/order/order.js +0 -33
- package/src/schema/types/payment.js +1 -1
- package/src/schema/types/product/bundle-product.js +2 -2
- package/src/schema/types/product/configurable-product.js +2 -2
- package/src/schema/types/product/index.js +9 -1
- package/src/schema/types/product/plan-product.js +2 -2
- package/src/schema/types/product/product.js +4 -4
- package/src/schema/types/product/simple-product.js +2 -2
- package/src/schema/types/product/tokenized-product.js +56 -0
- package/src/schema/types/quotation.js +0 -1
- package/src/schema/types/user.js +39 -1
- package/src/schema/types/warehousing.js +23 -1
- package/src/user-context.ts +23 -9
package/lib/user-context.js
CHANGED
|
@@ -1,14 +1,24 @@
|
|
|
1
|
+
import cookie from 'cookie';
|
|
1
2
|
function isString(input) {
|
|
2
3
|
return typeof input === 'string' && Object.prototype.toString.call(input) === '[object String]';
|
|
3
4
|
}
|
|
4
|
-
export const getUserContext = async (req, unchainedAPI) => {
|
|
5
|
+
export const getUserContext = async (req, res, unchainedAPI) => {
|
|
5
6
|
// there is a possible current user connected!
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
const cookieName = process.env.UNCHAINED_COOKIE_NAME || 'unchained_token';
|
|
8
|
+
const domain = process.env.UNCHAINED_COOKIE_DOMAIN;
|
|
9
|
+
let loginToken = req.cookies?.[cookieName];
|
|
10
|
+
function setLoginToken(token, expires) {
|
|
11
|
+
if (!domain)
|
|
12
|
+
return;
|
|
13
|
+
const authCookie = cookie.serialize(cookieName, token || null, {
|
|
14
|
+
domain,
|
|
15
|
+
httpOnly: true,
|
|
16
|
+
expires: token ? expires : undefined,
|
|
17
|
+
maxAge: token ? undefined : -1,
|
|
18
|
+
sameSite: 'lax',
|
|
19
|
+
secure: process.env.NODE_ENV === 'production',
|
|
20
|
+
});
|
|
21
|
+
res.setHeader('Set-Cookie', authCookie);
|
|
12
22
|
}
|
|
13
23
|
if (req.headers.authorization) {
|
|
14
24
|
const [type, token] = req.headers.authorization.split(' ');
|
|
@@ -40,11 +50,12 @@ export const getUserContext = async (req, unchainedAPI) => {
|
|
|
40
50
|
user: currentUser,
|
|
41
51
|
userId: currentUser._id,
|
|
42
52
|
loginToken: loginToken,
|
|
53
|
+
setLoginToken,
|
|
43
54
|
};
|
|
44
55
|
}
|
|
45
56
|
}
|
|
46
|
-
return { loginToken: loginToken };
|
|
57
|
+
return { loginToken: loginToken, setLoginToken };
|
|
47
58
|
}
|
|
48
|
-
return {};
|
|
59
|
+
return { setLoginToken };
|
|
49
60
|
};
|
|
50
61
|
//# sourceMappingURL=user-context.js.map
|
package/lib/user-context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-context.js","sourceRoot":"","sources":["../src/user-context.ts"],"names":[],"mappings":"
|
|
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,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,GAAwC,EACxC,GAAoB,EACpB,YAA2B,EACI,EAAE;IACjC,8CAA8C;IAC9C,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,iBAAiB,CAAC;IAC1E,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC;IAEnD,IAAI,UAAU,GAAG,GAAG,CAAC,OAAO,EAAE,CAAC,UAAU,CAAC,CAAC;IAE3C,SAAS,aAAa,CAAC,KAAa,EAAE,OAAa;QACjD,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,KAAK,IAAI,IAAI,EAAE;YAC7D,MAAM;YACN,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;YACpC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9B,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY;SAC9C,CAAC,CAAC;QACH,GAAG,CAAC,SAAS,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;IAC1C,CAAC;IAED,IAAI,GAAG,CAAC,OAAO,CAAC,aAAa,EAAE;QAC7B,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3D,IAAI,IAAI,KAAK,QAAQ,EAAE;YACrB,UAAU,GAAG,KAAK,CAAC;SACpB;KACF;IACD,IAAI,UAAU,EAAE;QACd,8CAA8C;QAC9C,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAE3E,0EAA0E;QAC1E,MAAM,WAAW,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,UAAoB,CAAC,CAAC;QAE7F,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC;YACnE,WAAW;SACZ,CAAC,CAAC;QAEH,0BAA0B;QAC1B,IAAI,WAAW,EAAE;YACf,sEAAsE;YACtE,4DAA4D;YAC5D,MAAM,gBAAgB,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,CACnE,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,WAAW,KAAK,WAAW,CACrD,CAAC,CAAC,sBAAsB;YAEzB,+BAA+B;YAC/B,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;YAE/D,+DAA+D;YAC/D,uCAAuC;YACvC,IAAI,CAAC,SAAS,EAAE;gBACd,6DAA6D;gBAC7D,OAAO;oBACL,IAAI,EAAE,WAAW;oBACjB,MAAM,EAAE,WAAW,CAAC,GAAG;oBACvB,UAAU,EAAE,UAAoB;oBAChC,aAAa;iBACd,CAAC;aACH;SACF;QACD,OAAO,EAAE,UAAU,EAAE,UAAoB,EAAE,aAAa,EAAE,CAAC;KAC5D;IAED,OAAO,EAAE,aAAa,EAAE,CAAC;AAC3B,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@unchainedshop/api",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-beta2",
|
|
4
4
|
"main": "lib/api-index.js",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": "./lib/api-index.js",
|
|
@@ -31,14 +31,16 @@
|
|
|
31
31
|
"homepage": "https://github.com/unchainedshop/unchained#readme",
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"apollo-server-express": "2.x",
|
|
34
|
+
"cookie": "^0.5.0",
|
|
34
35
|
"graphql": "^15.x"
|
|
35
36
|
},
|
|
36
37
|
"dependencies": {
|
|
37
|
-
"@
|
|
38
|
-
"@unchainedshop/
|
|
39
|
-
"@unchainedshop/
|
|
40
|
-
"@unchainedshop/
|
|
41
|
-
"@unchainedshop/
|
|
38
|
+
"@metamask/eth-sig-util": "^5.0.0",
|
|
39
|
+
"@unchainedshop/core": "^2.0.0-beta2",
|
|
40
|
+
"@unchainedshop/events": "^2.0.0-beta2",
|
|
41
|
+
"@unchainedshop/logger": "^2.0.0-beta2",
|
|
42
|
+
"@unchainedshop/roles": "^2.0.0-beta2",
|
|
43
|
+
"@unchainedshop/utils": "^2.0.0-beta2",
|
|
42
44
|
"accounting": "0.4.1",
|
|
43
45
|
"dataloader": "^2.1.0",
|
|
44
46
|
"graphql-scalars": "^1.19.0",
|
|
@@ -50,11 +52,11 @@
|
|
|
50
52
|
"devDependencies": {
|
|
51
53
|
"@types/graphql-upload": "^8.0.11",
|
|
52
54
|
"@types/locale": "^0.1.1",
|
|
53
|
-
"@types/node": "^16.11.
|
|
54
|
-
"@unchainedshop/types": "^
|
|
55
|
+
"@types/node": "^16.11.68",
|
|
56
|
+
"@unchainedshop/types": "^2.0.0-beta2",
|
|
55
57
|
"apollo-server-express": "^2.26.0",
|
|
56
58
|
"graphql": "^15.8.0",
|
|
57
|
-
"jest": "^29.2.
|
|
59
|
+
"jest": "^29.2.1",
|
|
58
60
|
"ts-jest": "^29.0.3",
|
|
59
61
|
"typescript": "^4.8.4"
|
|
60
62
|
}
|
package/src/api-index.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { ApolloServer } from 'apollo-server-express';
|
|
|
3
3
|
import createBulkImportServer from './createBulkImportServer';
|
|
4
4
|
import createGraphQLServer from './createGraphQLServer';
|
|
5
5
|
import { createContextResolver, getCurrentContextResolver, setCurrentContextResolver } from './context';
|
|
6
|
+
import createERCMetadataServer from './createERCMetadataServer';
|
|
6
7
|
|
|
7
8
|
export * from './context';
|
|
8
9
|
export * as acl from './acl';
|
|
@@ -19,6 +20,7 @@ export const startAPIServer = (
|
|
|
19
20
|
): {
|
|
20
21
|
apolloGraphQLServer: ApolloServer;
|
|
21
22
|
bulkImportServer: any;
|
|
23
|
+
ercMetadataServer: any;
|
|
22
24
|
} => {
|
|
23
25
|
const {
|
|
24
26
|
unchainedAPI,
|
|
@@ -40,9 +42,11 @@ export const startAPIServer = (
|
|
|
40
42
|
|
|
41
43
|
const apolloGraphQLServer = createGraphQLServer(expressApp, apolloServerOptions);
|
|
42
44
|
const bulkImportServer = createBulkImportServer(expressApp);
|
|
45
|
+
const ercMetadataServer = createERCMetadataServer(expressApp);
|
|
43
46
|
|
|
44
47
|
return {
|
|
45
48
|
apolloGraphQLServer,
|
|
46
49
|
bulkImportServer,
|
|
50
|
+
ercMetadataServer,
|
|
47
51
|
};
|
|
48
52
|
};
|
package/src/context.ts
CHANGED
|
@@ -16,9 +16,9 @@ export const setCurrentContextResolver = (newContext: UnchainedContextResolver)
|
|
|
16
16
|
export const createContextResolver =
|
|
17
17
|
(unchainedAPI: UnchainedCore, roles: any, version: string): UnchainedContextResolver =>
|
|
18
18
|
async ({ req, res, ...apolloContext }) => {
|
|
19
|
-
const loaders = await instantiateLoaders(req, unchainedAPI);
|
|
20
|
-
const userContext = await getUserContext(req, unchainedAPI);
|
|
21
|
-
const localeContext = await getLocaleContext(req, unchainedAPI);
|
|
19
|
+
const loaders = await instantiateLoaders(req, res, unchainedAPI);
|
|
20
|
+
const userContext = await getUserContext(req, res, unchainedAPI);
|
|
21
|
+
const localeContext = await getLocaleContext(req, res, unchainedAPI);
|
|
22
22
|
|
|
23
23
|
return {
|
|
24
24
|
req,
|
|
@@ -14,7 +14,7 @@ const { BULK_IMPORT_API_PATH = '/bulk-import', BULK_IMPORT_PAYLOAD_CACHE_DIRECTO
|
|
|
14
14
|
const errorHandler = (res) => (e) => {
|
|
15
15
|
logger.error(e.message);
|
|
16
16
|
res.writeHead(503);
|
|
17
|
-
res.end(JSON.stringify(e));
|
|
17
|
+
res.end(JSON.stringify({ name: e.name, code: e.code, message: e.message }));
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
const methodWrongHandler = (res) => () => {
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { createLogger } from '@unchainedshop/logger';
|
|
2
|
+
import { UnchainedCore } from '@unchainedshop/types/core';
|
|
3
|
+
import { systemLocale } from '@unchainedshop/utils';
|
|
4
|
+
import { IncomingMessage } from 'http';
|
|
5
|
+
import localePkg from 'locale';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
import { useMiddlewareWithCurrentContext } from './context';
|
|
8
|
+
|
|
9
|
+
const { Locale } = localePkg;
|
|
10
|
+
|
|
11
|
+
const logger = createLogger('unchained:erc-metadata');
|
|
12
|
+
|
|
13
|
+
const { ERC_METADATA_API_PATH = '/erc-metadata' } = process.env;
|
|
14
|
+
|
|
15
|
+
const errorHandler = (res) => (e) => {
|
|
16
|
+
logger.error(e.message);
|
|
17
|
+
res.writeHead(503);
|
|
18
|
+
res.end(JSON.stringify({ name: e.name, code: e.code, message: e.message }));
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const methodWrongHandler = (res) => () => {
|
|
22
|
+
logger.error('Method not supported, return 404');
|
|
23
|
+
res.writeHead(404);
|
|
24
|
+
res.end();
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const ercMetadataMiddleware = async (
|
|
28
|
+
req: IncomingMessage & { unchainedContext?: UnchainedCore },
|
|
29
|
+
res,
|
|
30
|
+
) => {
|
|
31
|
+
try {
|
|
32
|
+
if (req.method !== 'GET') {
|
|
33
|
+
methodWrongHandler(res)();
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const resolvedContext = req.unchainedContext;
|
|
38
|
+
|
|
39
|
+
const url = new URL(req.url, process.env.ROOT_URL);
|
|
40
|
+
const parsedPath = path.parse(url.pathname);
|
|
41
|
+
|
|
42
|
+
if (parsedPath.ext !== '.json') throw new Error('Invalid ERC Metadata URI');
|
|
43
|
+
|
|
44
|
+
const locale = parsedPath.dir === '/' ? systemLocale.language : parsedPath.name;
|
|
45
|
+
const tokenId = parsedPath.dir === '/' ? parsedPath.name : parsedPath.dir.substring(1);
|
|
46
|
+
|
|
47
|
+
const [product] = await resolvedContext.modules.products.findProducts({
|
|
48
|
+
productSelector: { 'tokenization.tokenId': tokenId },
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const ercMetadata = await resolvedContext.services.products.ercMetadata(
|
|
52
|
+
{
|
|
53
|
+
product,
|
|
54
|
+
locale: new Locale(locale),
|
|
55
|
+
},
|
|
56
|
+
resolvedContext,
|
|
57
|
+
);
|
|
58
|
+
const body = JSON.stringify(ercMetadata);
|
|
59
|
+
res.writeHead(200, {
|
|
60
|
+
'Content-Length': Buffer.byteLength(body),
|
|
61
|
+
'Content-Type': 'text/plain',
|
|
62
|
+
});
|
|
63
|
+
res.end(body);
|
|
64
|
+
} catch (e) {
|
|
65
|
+
errorHandler(res)(e);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export default (expressApp) => {
|
|
70
|
+
useMiddlewareWithCurrentContext(expressApp, ERC_METADATA_API_PATH, ercMetadataMiddleware);
|
|
71
|
+
};
|
package/src/errors.ts
CHANGED
|
@@ -69,6 +69,26 @@ export const DeliverProviderNotFoundError = createError(
|
|
|
69
69
|
export const LanguageNotFoundError = createError('LanguageNotFoundError', 'Language not found');
|
|
70
70
|
|
|
71
71
|
export const UserNotFoundError = createError('UserNotFoundError', 'User not found');
|
|
72
|
+
export const UserWebAuthnCredentialsNotFoundError = createError(
|
|
73
|
+
'UserWebAuthnCredentialsNotFoundError',
|
|
74
|
+
'User WebAuth Credentials not found',
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
export const UserWeb3AddressNotFoundError = createError(
|
|
78
|
+
'UserWeb3AddressNotFoundError',
|
|
79
|
+
'Web3 Account not found for User',
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
export const UserWeb3InvalidAddressError = createError(
|
|
83
|
+
'UserWeb3InvalidAddressError',
|
|
84
|
+
'Invalid address provided',
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
export const UserWeb3AddressSignatureError = createError(
|
|
88
|
+
'UserWeb3AddressSignatureError',
|
|
89
|
+
'Signature does not match web3 account / is invalid',
|
|
90
|
+
);
|
|
91
|
+
|
|
72
92
|
export const UserNoCartError = createError('UserNoCartError', 'No open cart available to checkout');
|
|
73
93
|
export const OrderItemNotFoundError = createError('OrderItemNotFoundError', 'Order Item not found');
|
|
74
94
|
export const OrderNotFoundError = createError('OrderNotFoundError', 'Order not found');
|
package/src/loaders/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { UnchainedLoaders } from '@unchainedshop/types/api';
|
|
2
2
|
import DataLoader from 'dataloader';
|
|
3
|
-
import { IncomingMessage } from 'http';
|
|
3
|
+
import { IncomingMessage, OutgoingMessage } from 'http';
|
|
4
4
|
import { systemLocale } from '@unchainedshop/utils';
|
|
5
5
|
import localePkg from 'locale';
|
|
6
6
|
import { AssortmentText } from '@unchainedshop/types/assortments';
|
|
@@ -12,6 +12,7 @@ const { Locale } = localePkg;
|
|
|
12
12
|
|
|
13
13
|
export default async (
|
|
14
14
|
req: IncomingMessage,
|
|
15
|
+
res: OutgoingMessage,
|
|
15
16
|
unchainedAPI: UnchainedCore,
|
|
16
17
|
): Promise<UnchainedLoaders['loaders']> => {
|
|
17
18
|
return {
|
package/src/locale-context.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { UnchainedLocaleContext } from '@unchainedshop/types/api';
|
|
2
|
-
import { IncomingMessage } from 'http';
|
|
2
|
+
import { IncomingMessage, OutgoingMessage } from 'http';
|
|
3
3
|
import localePkg from 'locale';
|
|
4
4
|
import 'abort-controller/polyfill';
|
|
5
5
|
import LRU from 'lru-cache';
|
|
@@ -25,6 +25,7 @@ const localeContextCache = new LRU({
|
|
|
25
25
|
|
|
26
26
|
export const getLocaleContext = async (
|
|
27
27
|
req: IncomingMessage,
|
|
28
|
+
res: OutgoingMessage,
|
|
28
29
|
unchainedAPI: UnchainedCore,
|
|
29
30
|
): Promise<UnchainedLocaleContext> => {
|
|
30
31
|
const cacheKey = `${req.headers['accept-language']}:${req.headers['x-shop-country']}`;
|
package/src/resolvers/index.ts
CHANGED
|
@@ -3,9 +3,11 @@ import { JSONResolver, TimestampResolver, DateTimeResolver, DateResolver } from
|
|
|
3
3
|
import Query from './queries';
|
|
4
4
|
import Mutation from './mutations';
|
|
5
5
|
import Types from './type';
|
|
6
|
+
import CustomScalars from './scalars';
|
|
6
7
|
|
|
7
8
|
export default {
|
|
8
9
|
...Types,
|
|
10
|
+
...CustomScalars,
|
|
9
11
|
Upload: GraphQLUpload,
|
|
10
12
|
JSON: JSONResolver,
|
|
11
13
|
Query,
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { log } from '@unchainedshop/logger';
|
|
2
|
+
import { Context, Root } from '@unchainedshop/types/api';
|
|
3
|
+
import { UserWeb3InvalidAddressError } from '../../../errors';
|
|
4
|
+
|
|
5
|
+
export default async function addWeb3Address(
|
|
6
|
+
root: Root,
|
|
7
|
+
{ address }: { address: any },
|
|
8
|
+
{ modules, userId, user }: Context,
|
|
9
|
+
) {
|
|
10
|
+
log(`mutation addWeb3Address ${user.username}`, {
|
|
11
|
+
userId,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
if (!address) {
|
|
15
|
+
throw new UserWeb3InvalidAddressError({ userId, address });
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const nonce = Math.floor(Math.random() * 1000000).toString();
|
|
19
|
+
await modules.users.updateUser(
|
|
20
|
+
{ _id: userId },
|
|
21
|
+
{
|
|
22
|
+
$push: {
|
|
23
|
+
'services.web3': {
|
|
24
|
+
address,
|
|
25
|
+
nonce,
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
{},
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
return modules.users.findUserById(userId);
|
|
33
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { log } from '@unchainedshop/logger';
|
|
2
|
+
import { Context, Root } from '@unchainedshop/types/api';
|
|
3
|
+
|
|
4
|
+
export default async function addWebAuthnCredentials(
|
|
5
|
+
root: Root,
|
|
6
|
+
{ credentials }: { credentials: any },
|
|
7
|
+
{ modules, userId, user }: Context,
|
|
8
|
+
) {
|
|
9
|
+
log(`mutation addWebAuthnCredentials ${user.username}`, {
|
|
10
|
+
userId,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const webAuthnService = await modules.accounts.webAuthn.verifyCredentialCreation(
|
|
14
|
+
user.username,
|
|
15
|
+
credentials,
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
await modules.users.updateUser(
|
|
19
|
+
{ _id: userId },
|
|
20
|
+
{
|
|
21
|
+
$push: {
|
|
22
|
+
'services.webAuthn': webAuthnService,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
{},
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
return modules.users.findUserById(userId);
|
|
29
|
+
}
|
|
@@ -6,19 +6,41 @@ import { hashPassword } from '../../../hashPassword';
|
|
|
6
6
|
export default async function createUser(root: Root, params: UserData, context: Context) {
|
|
7
7
|
const { modules, userId } = context;
|
|
8
8
|
|
|
9
|
-
log('mutation createUser', { email: params.email, userId });
|
|
9
|
+
log('mutation createUser', { email: params.email, username: params.username, userId });
|
|
10
10
|
|
|
11
|
-
if (!params.password && !params.plainPassword) {
|
|
12
|
-
throw new Error('Password is required');
|
|
11
|
+
if (!params.password && !params.plainPassword && !params.webAuthnPublicKeyCredentials) {
|
|
12
|
+
throw new Error('Password or Public Key is required');
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
const mappedUser = params;
|
|
16
|
-
if (!mappedUser.password) {
|
|
15
|
+
const mappedUser = { ...params };
|
|
16
|
+
if (!mappedUser.password && mappedUser.plainPassword) {
|
|
17
17
|
mappedUser.password = hashPassword(mappedUser.plainPassword);
|
|
18
18
|
}
|
|
19
19
|
delete mappedUser.plainPassword;
|
|
20
|
+
delete mappedUser.webAuthnPublicKeyCredentials;
|
|
20
21
|
|
|
21
|
-
const
|
|
22
|
+
const webAuthnService =
|
|
23
|
+
params.webAuthnPublicKeyCredentials &&
|
|
24
|
+
(await modules.accounts.webAuthn.verifyCredentialCreation(
|
|
25
|
+
params.username,
|
|
26
|
+
params.webAuthnPublicKeyCredentials,
|
|
27
|
+
));
|
|
28
|
+
|
|
29
|
+
const newUserId = await modules.accounts.createUser(mappedUser, {
|
|
30
|
+
skipPasswordEnrollment: !!webAuthnService,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if (newUserId && webAuthnService) {
|
|
34
|
+
await modules.users.updateUser(
|
|
35
|
+
{ _id: newUserId },
|
|
36
|
+
{
|
|
37
|
+
$push: {
|
|
38
|
+
'services.webAuthn': webAuthnService,
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
{},
|
|
42
|
+
);
|
|
43
|
+
}
|
|
22
44
|
|
|
23
45
|
return modules.accounts.createLoginToken(newUserId, context);
|
|
24
46
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { log } from '@unchainedshop/logger';
|
|
2
|
+
import { Context, Root } from '@unchainedshop/types/api';
|
|
3
|
+
|
|
4
|
+
export default async function createWebAuthnCredentialCreationOptions(
|
|
5
|
+
root: Root,
|
|
6
|
+
{ extensionOptions, username }: { username: string; extensionOptions: any },
|
|
7
|
+
{ modules, userId, req }: Context,
|
|
8
|
+
) {
|
|
9
|
+
log(`mutation createWebAuthnCredentialCreationOptions ${username}`, {
|
|
10
|
+
userId,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const options = await modules.accounts.webAuthn.createCredentialCreationOptions(
|
|
14
|
+
req.headers.origin,
|
|
15
|
+
username,
|
|
16
|
+
extensionOptions,
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
return options;
|
|
20
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { log } from '@unchainedshop/logger';
|
|
2
|
+
import { Context, Root } from '@unchainedshop/types/api';
|
|
3
|
+
|
|
4
|
+
export default async function createWebAuthnCredentialRequestOptions(
|
|
5
|
+
root: Root,
|
|
6
|
+
{ extensionOptions, username }: { username: string; extensionOptions: any },
|
|
7
|
+
{ modules, userId, req }: Context,
|
|
8
|
+
) {
|
|
9
|
+
log(`mutation createWebAuthnCredentialRequestOptions ${username}`, {
|
|
10
|
+
userId,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const options = await modules.accounts.webAuthn.createCredentialRequestOptions(
|
|
14
|
+
req.headers.origin,
|
|
15
|
+
username,
|
|
16
|
+
extensionOptions,
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
if (username) {
|
|
20
|
+
const user = await modules.users.findUser({ username });
|
|
21
|
+
options.allowCredentials = user?.services?.webAuthn?.map(({ id, type }) => ({
|
|
22
|
+
id,
|
|
23
|
+
type: type || options.type || 'public-key',
|
|
24
|
+
}));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return options;
|
|
28
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { log } from '@unchainedshop/logger';
|
|
2
|
+
import { Context, Root } from '@unchainedshop/types/api';
|
|
3
|
+
|
|
4
|
+
export default async function loginWithWebAuthn(
|
|
5
|
+
root: Root,
|
|
6
|
+
params: {
|
|
7
|
+
webAuthnPublicKeyCredentials?: any;
|
|
8
|
+
},
|
|
9
|
+
context: Context,
|
|
10
|
+
) {
|
|
11
|
+
const { modules } = context;
|
|
12
|
+
|
|
13
|
+
log('mutation loginWithWebAuthn');
|
|
14
|
+
|
|
15
|
+
return modules.accounts.loginWithService({ service: 'webAuthn', ...params }, context);
|
|
16
|
+
}
|
|
@@ -2,17 +2,20 @@ import { Context, Root } from '@unchainedshop/types/api';
|
|
|
2
2
|
import { log, LogLevel } from '@unchainedshop/logger';
|
|
3
3
|
|
|
4
4
|
export default async function logout(root: Root, params: { token: string }, context: Context) {
|
|
5
|
-
const { modules, userId } = context;
|
|
5
|
+
const { modules, userId, setLoginToken } = context;
|
|
6
6
|
|
|
7
7
|
log('mutation logout', { userId });
|
|
8
8
|
|
|
9
9
|
const loggedOut = await modules.accounts.logout(params, context);
|
|
10
10
|
|
|
11
|
-
if (loggedOut.error)
|
|
11
|
+
if (loggedOut.error) {
|
|
12
12
|
log('Error while logging out', {
|
|
13
13
|
logLevel: LogLevel.Error,
|
|
14
14
|
...loggedOut.error,
|
|
15
15
|
});
|
|
16
|
+
} else {
|
|
17
|
+
setLoginToken(null);
|
|
18
|
+
}
|
|
16
19
|
|
|
17
20
|
return { success: loggedOut.success };
|
|
18
21
|
}
|
|
@@ -2,17 +2,20 @@ import { Context, Root } from '@unchainedshop/types/api';
|
|
|
2
2
|
import { log, LogLevel } from '@unchainedshop/logger';
|
|
3
3
|
|
|
4
4
|
export default async function logoutAllSessions(root: Root, _: any, context: Context) {
|
|
5
|
-
const { modules, userId } = context;
|
|
5
|
+
const { modules, userId, setLoginToken } = context;
|
|
6
6
|
|
|
7
7
|
log('mutation logoutAllSessions', { userId });
|
|
8
8
|
|
|
9
9
|
const loggedOut = await modules.accounts.logout({}, context);
|
|
10
10
|
|
|
11
|
-
if (loggedOut.error)
|
|
11
|
+
if (loggedOut.error) {
|
|
12
12
|
log('Error while logging out', {
|
|
13
13
|
logLevel: LogLevel.Error,
|
|
14
14
|
...loggedOut.error,
|
|
15
15
|
});
|
|
16
|
+
} else {
|
|
17
|
+
setLoginToken(null);
|
|
18
|
+
}
|
|
16
19
|
|
|
17
20
|
return { success: loggedOut.success };
|
|
18
21
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { log } from '@unchainedshop/logger';
|
|
2
|
+
import { Context, Root } from '@unchainedshop/types/api';
|
|
3
|
+
import { UserWeb3AddressNotFoundError } from '../../../errors';
|
|
4
|
+
|
|
5
|
+
export default async function removeWeb3Address(
|
|
6
|
+
root: Root,
|
|
7
|
+
{ address }: { address: string },
|
|
8
|
+
{ modules, userId, user }: Context,
|
|
9
|
+
) {
|
|
10
|
+
log(`mutation removeWeb3Address ${address} ${user.username}`, {
|
|
11
|
+
userId,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const foundCredentials = user.services?.web3?.find(
|
|
15
|
+
(service) => service.address.toLowerCase() === address.toLowerCase(),
|
|
16
|
+
);
|
|
17
|
+
if (!foundCredentials) {
|
|
18
|
+
throw new UserWeb3AddressNotFoundError({ userId, address });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
await modules.users.updateUser(
|
|
22
|
+
{ _id: userId },
|
|
23
|
+
{
|
|
24
|
+
$pull: {
|
|
25
|
+
'services.web3': { address: foundCredentials.address },
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{},
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
return modules.users.findUserById(userId);
|
|
32
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { log } from '@unchainedshop/logger';
|
|
2
|
+
import { Context, Root } from '@unchainedshop/types/api';
|
|
3
|
+
import { UserWebAuthnCredentialsNotFoundError } from '../../../errors';
|
|
4
|
+
|
|
5
|
+
export default async function removeWebAuthnCredentials(
|
|
6
|
+
root: Root,
|
|
7
|
+
{ credentialsId }: { credentialsId: string },
|
|
8
|
+
{ modules, userId, user }: Context,
|
|
9
|
+
) {
|
|
10
|
+
log(`mutation removeWebAuthnCredentials ${credentialsId} ${user.username}`, {
|
|
11
|
+
userId,
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
const foundCredentials = user.services?.webAuthn?.find((service) => service.id === credentialsId);
|
|
15
|
+
if (!foundCredentials) {
|
|
16
|
+
throw new UserWebAuthnCredentialsNotFoundError({ userId, credentialsId });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
await modules.users.updateUser(
|
|
20
|
+
{ _id: userId },
|
|
21
|
+
{
|
|
22
|
+
$pull: {
|
|
23
|
+
'services.webAuthn': { id: credentialsId },
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
{},
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
return modules.users.findUserById(userId);
|
|
30
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { log } from '@unchainedshop/logger';
|
|
2
|
+
import { Context, Root } from '@unchainedshop/types/api';
|
|
3
|
+
import { recoverPersonalSignature } from '@metamask/eth-sig-util';
|
|
4
|
+
import { UserWeb3AddressNotFoundError, UserWeb3AddressSignatureError } from '../../../errors';
|
|
5
|
+
|
|
6
|
+
export default async function verifyWeb3Address(
|
|
7
|
+
root: Root,
|
|
8
|
+
{ address, hash }: { address: string; hash: string },
|
|
9
|
+
{ modules, userId, user }: Context,
|
|
10
|
+
) {
|
|
11
|
+
log(`mutation verifyWeb3Address ${address} ${user.username}`, {
|
|
12
|
+
userId,
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const foundCredentials = user.services?.web3?.find(
|
|
16
|
+
(service) => service.address.toLowerCase() === address.toLowerCase(),
|
|
17
|
+
);
|
|
18
|
+
if (!foundCredentials) {
|
|
19
|
+
throw new UserWeb3AddressNotFoundError({ userId, address });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const msg = `0x${Buffer.from(foundCredentials.nonce, 'utf8').toString('hex')}`;
|
|
23
|
+
|
|
24
|
+
const recoveredAddr = recoverPersonalSignature({
|
|
25
|
+
data: msg,
|
|
26
|
+
signature: hash,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const signatureCorrectForAddress =
|
|
30
|
+
recoveredAddr.toLowerCase() === foundCredentials.address.toLowerCase();
|
|
31
|
+
|
|
32
|
+
if (!signatureCorrectForAddress) {
|
|
33
|
+
throw new UserWeb3AddressSignatureError({ userId, address: foundCredentials.address });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const web3Services: any[] = user.services.web3.map((service) => {
|
|
37
|
+
if (foundCredentials.address === service.address) {
|
|
38
|
+
return {
|
|
39
|
+
...service,
|
|
40
|
+
nonce: undefined,
|
|
41
|
+
verified: true,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return service;
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
await modules.users.updateUser(
|
|
48
|
+
{ _id: userId },
|
|
49
|
+
{
|
|
50
|
+
$set: {
|
|
51
|
+
// eslint-disable-next-line
|
|
52
|
+
// @ts-ignore
|
|
53
|
+
'services.web3': web3Services,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
{},
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
return modules.users.findUserById(userId);
|
|
60
|
+
}
|