@lana-commerce/core 13.1.0-alpha.9 → 14.0.0-alpha.2
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/CHANGELOG.md +6 -0
- package/cjs/graphql/fragments/Customer.js +1 -1
- package/cjs/graphql/fragments/Shop.js +1 -1
- package/cjs/graphql/operations/AddWebauthnMutation.js +3 -0
- package/cjs/graphql/operations/DeleteWebauthnMutation.js +3 -0
- package/cjs/graphql/operations/DisconnectOAuth2Mutation.js +1 -1
- package/cjs/graphql/operations/InitWebauthnMutation.js +3 -0
- package/cjs/modules/customer.js +284 -8
- package/cjs/script.js +1 -0
- package/esm/graphql/fragments/Customer.js +1 -1
- package/esm/graphql/fragments/Shop.js +1 -1
- package/esm/graphql/operations/AddWebauthnMutation.js +1 -0
- package/esm/graphql/operations/DeleteWebauthnMutation.js +1 -0
- package/esm/graphql/operations/DisconnectOAuth2Mutation.js +1 -1
- package/esm/graphql/operations/InitWebauthnMutation.js +1 -0
- package/esm/modules/customer.js +285 -9
- package/esm/script.js +1 -0
- package/package.json +3 -2
- package/types/dataLoader.d.ts +1 -0
- package/types/generated/codes.d.ts +7 -0
- package/types/graphql/fragments/Customer.d.ts +1 -1
- package/types/graphql/fragments/Shop.d.ts +1 -1
- package/types/graphql/operations/AddWebauthnMutation.d.ts +3 -0
- package/types/graphql/operations/DeleteWebauthnMutation.d.ts +3 -0
- package/types/graphql/operations/InitWebauthnMutation.d.ts +3 -0
- package/types/graphql/types.d.ts +57 -1
- package/types/json/commerceTypes.d.ts +246 -4
- package/types/json/storefrontTypes.d.ts +60 -0
- package/types/modules/customer.d.ts +59 -7
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,9 @@ This project adheres to [Semantic Versioning][semantic versioning].
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
9
|
### Major Changes
|
|
10
|
+
|
|
11
|
+
- OAuth APIs of "customer" module were changed in backwards incompatible way. To delete oauth provider you need to specify its type. This is due to the fact that you can connect multiple providers now.
|
|
12
|
+
|
|
10
13
|
### Minor Changes
|
|
11
14
|
|
|
12
15
|
- Add "clear" event to "modules/advancedSearch".
|
|
@@ -14,6 +17,9 @@ This project adheres to [Semantic Versioning][semantic versioning].
|
|
|
14
17
|
- A bunch of internal APIs were removed. While it's a major change, I put it here, because we know for sure that nobody was using those.
|
|
15
18
|
- Add "wrapWebSocket" function to "websocket" lib.
|
|
16
19
|
- Propagate new "meta" field for invoice line item descriptions.
|
|
20
|
+
- Add "webauthn" logic to "customer" module.
|
|
21
|
+
- Add webauthn related fields to customer/shop fragments.
|
|
22
|
+
- "Customer" module: now all signin forms share the custom error type. When custom error happens, it is set on all forms.
|
|
17
23
|
|
|
18
24
|
### Patch Changes
|
|
19
25
|
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.default = "fragment Customer on StorefrontCustomer{id email name display_name mobile mobile_notifications accepts_marketing reminder_messages addresses{...FullAddress}mobile mobile_notifications default_billing_address_id default_shipping_address_id default_payment_source_id is_guest password_defined
|
|
3
|
+
exports.default = "fragment Customer on StorefrontCustomer{id email name display_name mobile mobile_notifications accepts_marketing reminder_messages addresses{...FullAddress}mobile mobile_notifications default_billing_address_id default_shipping_address_id default_payment_source_id is_guest password_defined oauth_providers webauthn_keys{id name created_at}}\n";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.default = "fragment Shop on StorefrontShop{app_domain created_at currency customer_service_email id name product_review_enabled tax_label timezone primary_domain{domain id}customer_oauth_providers{...CustomerOAuthProvider}tips_enabled tips_variant{id}}\n";
|
|
3
|
+
exports.default = "fragment Shop on StorefrontShop{app_domain created_at currency customer_service_email id name product_review_enabled tax_label timezone primary_domain{domain id}customer_oauth_providers{...CustomerOAuthProvider}tips_enabled tips_variant{id}customer_webauthn}\n";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.default = "mutation DisconnectOAuth2($shopID:String!){storefrontCustomersOauthDelete(shop_id:$shopID)}";
|
|
3
|
+
exports.default = "mutation DisconnectOAuth2($shopID:String!$provider:CustomerOAuthProviderKind!){storefrontCustomersOauthDelete(shop_id:$shopID provider:$provider)}";
|
package/cjs/modules/customer.js
CHANGED
|
@@ -4,6 +4,8 @@ exports.createCustomer = exports.isSamePageParam = exports.createVariantMap = vo
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const jwt_decode_1 = tslib_1.__importDefault(require("jwt-decode"));
|
|
6
6
|
const effector_1 = require("effector");
|
|
7
|
+
const browser_1 = require("@simplewebauthn/browser");
|
|
8
|
+
const AddWebauthnMutation_js_1 = tslib_1.__importDefault(require("../graphql/operations/AddWebauthnMutation.js"));
|
|
7
9
|
const ApplyGiftCardMutation_js_1 = tslib_1.__importDefault(require("../graphql/operations/ApplyGiftCardMutation.js"));
|
|
8
10
|
const CancelOrderMutation_js_1 = tslib_1.__importDefault(require("../graphql/operations/CancelOrderMutation.js"));
|
|
9
11
|
const CancelSubscriptionMutation_js_1 = tslib_1.__importDefault(require("../graphql/operations/CancelSubscriptionMutation.js"));
|
|
@@ -13,6 +15,7 @@ const CreatePaymentSourceMutation_js_1 = tslib_1.__importDefault(require("../gra
|
|
|
13
15
|
const CreateReturnMutation_js_1 = tslib_1.__importDefault(require("../graphql/operations/CreateReturnMutation.js"));
|
|
14
16
|
const DeleteFavoriteMutation_js_1 = tslib_1.__importDefault(require("../graphql/operations/DeleteFavoriteMutation.js"));
|
|
15
17
|
const DeletePaymentSourceMutation_js_1 = tslib_1.__importDefault(require("../graphql/operations/DeletePaymentSourceMutation.js"));
|
|
18
|
+
const DeleteWebauthnMutation_js_1 = tslib_1.__importDefault(require("../graphql/operations/DeleteWebauthnMutation.js"));
|
|
16
19
|
const DisconnectOAuth2Mutation_js_1 = tslib_1.__importDefault(require("../graphql/operations/DisconnectOAuth2Mutation.js"));
|
|
17
20
|
const EditSubscriptionMutation_js_1 = tslib_1.__importDefault(require("../graphql/operations/EditSubscriptionMutation.js"));
|
|
18
21
|
const GetCustomerAddressesPageDataQuery_js_1 = tslib_1.__importDefault(require("../graphql/operations/GetCustomerAddressesPageDataQuery.js"));
|
|
@@ -30,6 +33,7 @@ const GetReturnQuery_js_1 = tslib_1.__importDefault(require("../graphql/operatio
|
|
|
30
33
|
const GetReturnsPageQuery_js_1 = tslib_1.__importDefault(require("../graphql/operations/GetReturnsPageQuery.js"));
|
|
31
34
|
const GetSubscriptionQuery_js_1 = tslib_1.__importDefault(require("../graphql/operations/GetSubscriptionQuery.js"));
|
|
32
35
|
const GetSubscriptionsPageQuery_js_1 = tslib_1.__importDefault(require("../graphql/operations/GetSubscriptionsPageQuery.js"));
|
|
36
|
+
const InitWebauthnMutation_js_1 = tslib_1.__importDefault(require("../graphql/operations/InitWebauthnMutation.js"));
|
|
33
37
|
const ModifyCustomerMutation_js_1 = tslib_1.__importDefault(require("../graphql/operations/ModifyCustomerMutation.js"));
|
|
34
38
|
const ModifyFavoriteMutation_js_1 = tslib_1.__importDefault(require("../graphql/operations/ModifyFavoriteMutation.js"));
|
|
35
39
|
const NewPasswordMutation_js_1 = tslib_1.__importDefault(require("../graphql/operations/NewPasswordMutation.js"));
|
|
@@ -61,6 +65,32 @@ const multiResponseToResponse_js_1 = require("../multiResponseToResponse.js");
|
|
|
61
65
|
const nonNull_js_1 = require("../nonNull.js");
|
|
62
66
|
const requestResponse_js_1 = require("../effector/requestResponse.js");
|
|
63
67
|
const split_js_1 = require("../effector/split.js");
|
|
68
|
+
function mapSignInResponseToWrongOAuth(params, result) {
|
|
69
|
+
if (result.kind !== "error")
|
|
70
|
+
return undefined;
|
|
71
|
+
const a = result.error.apiError;
|
|
72
|
+
if (!a || a.code !== codes_js_1.ErrorCode.Unauthorized)
|
|
73
|
+
return undefined;
|
|
74
|
+
const m = a.meta;
|
|
75
|
+
if (!m ||
|
|
76
|
+
m.email === undefined ||
|
|
77
|
+
m.oauth_providers === undefined ||
|
|
78
|
+
m.oauth_session_id === undefined ||
|
|
79
|
+
m.password_defined === undefined ||
|
|
80
|
+
m.webauthn_defined === undefined) {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
params,
|
|
85
|
+
meta: {
|
|
86
|
+
email: m.email,
|
|
87
|
+
oauth_providers: m.oauth_providers,
|
|
88
|
+
oauth_session_id: m.oauth_session_id,
|
|
89
|
+
password_defined: m.password_defined,
|
|
90
|
+
webauthn_defined: m.webauthn_defined,
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
64
94
|
function getCustomerInfo(shopID, id, opts) {
|
|
65
95
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
66
96
|
if (!(opts === null || opts === void 0 ? void 0 : opts.authToken))
|
|
@@ -248,6 +278,7 @@ function splitRequestResponseData(source) {
|
|
|
248
278
|
// pages you're not allowed to be in, while being logged in
|
|
249
279
|
const disallowedAuthPages = {
|
|
250
280
|
signup: true,
|
|
281
|
+
webauthn_signup: true,
|
|
251
282
|
signin: true,
|
|
252
283
|
};
|
|
253
284
|
// it's not allowed to store these pages as lastAuthPage
|
|
@@ -255,6 +286,7 @@ const disallowedLastAuthPages = Object.assign(Object.assign({}, disallowedAuthPa
|
|
|
255
286
|
// only pages you're allowed to be in, while NOT being logged in
|
|
256
287
|
const allowedNoAuthPages = {
|
|
257
288
|
signup: true,
|
|
289
|
+
webauthn_signup: true,
|
|
258
290
|
signin: true,
|
|
259
291
|
confirm: true,
|
|
260
292
|
reset_password: true,
|
|
@@ -355,6 +387,70 @@ function createSignupPageGraph(binding) {
|
|
|
355
387
|
//===================================================================================================================
|
|
356
388
|
//===================================================================================================================
|
|
357
389
|
//===================================================================================================================
|
|
390
|
+
function createWebauthnSignupPageGraph(binding) {
|
|
391
|
+
const init = defineInitBlank(binding);
|
|
392
|
+
const form = (0, form_js_1.createForm)({
|
|
393
|
+
name: (0, form_js_1.createStringField)("name", "", [validator_js_1.validNonEmpty, validator_js_1.validMaxLength250]),
|
|
394
|
+
email: (0, form_js_1.createStringField)("email", "", [validator_js_1.validNonEmpty, validator_js_1.validEmail, validator_js_1.validMaxLength250]),
|
|
395
|
+
accepts_marketing: (0, form_js_1.createBooleanField)("accepts_marketing", false),
|
|
396
|
+
});
|
|
397
|
+
(0, effector_1.forward)({
|
|
398
|
+
from: init.event,
|
|
399
|
+
to: form.reset,
|
|
400
|
+
});
|
|
401
|
+
const signupFx = (0, effector_1.createEffect)((p) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
402
|
+
const { shopID, opts } = p.config;
|
|
403
|
+
const resp = yield (0, request_js_1.request)(InitWebauthnMutation_js_1.default)({
|
|
404
|
+
shopID,
|
|
405
|
+
email: p.data.email,
|
|
406
|
+
name: p.data.name,
|
|
407
|
+
}, opts);
|
|
408
|
+
if (resp.kind !== "data") {
|
|
409
|
+
return resp;
|
|
410
|
+
}
|
|
411
|
+
let sessionID;
|
|
412
|
+
let credential;
|
|
413
|
+
try {
|
|
414
|
+
sessionID = resp.data.session_id;
|
|
415
|
+
credential = yield (0, browser_1.startRegistration)({ optionsJSON: JSON.parse(resp.data.options).publicKey });
|
|
416
|
+
}
|
|
417
|
+
catch (err) {
|
|
418
|
+
console.error(err);
|
|
419
|
+
return { kind: "custom_error", text: "webauthn failure" };
|
|
420
|
+
}
|
|
421
|
+
return (0, request_js_1.request)(SignUpMutation_js_1.default)({
|
|
422
|
+
shopID,
|
|
423
|
+
data: {
|
|
424
|
+
email: p.data.email,
|
|
425
|
+
webauthn_credential: JSON.stringify(credential),
|
|
426
|
+
webauthn_session_id: sessionID,
|
|
427
|
+
accepts_marketing: p.data.accepts_marketing,
|
|
428
|
+
timezone_hint: (0, getTimezone_js_1.getTimezone)(),
|
|
429
|
+
},
|
|
430
|
+
}, opts);
|
|
431
|
+
}));
|
|
432
|
+
(0, effector_1.guard)({
|
|
433
|
+
source: (0, effector_1.sample)(binding.internalConfig, form.submitted, (config, data) => ({ config, data })),
|
|
434
|
+
filter: binding.everythingIdle,
|
|
435
|
+
target: signupFx,
|
|
436
|
+
});
|
|
437
|
+
const { data: signupData, error: signupError } = (0, requestResponse_js_1.requestResponseSplit)(signupFx.doneData);
|
|
438
|
+
// success
|
|
439
|
+
(0, effector_1.forward)({
|
|
440
|
+
from: signupData.filterMap((v) => v[0].token || undefined),
|
|
441
|
+
to: binding.setJWT,
|
|
442
|
+
});
|
|
443
|
+
// failure
|
|
444
|
+
handleFormFailure({ source: signupError, form, unexpectedError: binding.unexpectedError }, { from: "[0]." });
|
|
445
|
+
return {
|
|
446
|
+
init,
|
|
447
|
+
form,
|
|
448
|
+
somethingIsPending: (0, combineSome_js_1.combineSome)(init.pending, signupFx.pending),
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
//===================================================================================================================
|
|
452
|
+
//===================================================================================================================
|
|
453
|
+
//===================================================================================================================
|
|
358
454
|
function createResetPasswordPageGraph(binding) {
|
|
359
455
|
const init = defineInitBlank(binding);
|
|
360
456
|
// forms, we use shared fields here
|
|
@@ -1656,6 +1752,17 @@ function createSigninPageGraph(binding) {
|
|
|
1656
1752
|
const init = defineInitBlank(binding);
|
|
1657
1753
|
const setSignInMode = (0, effector_1.createEvent)();
|
|
1658
1754
|
const signInMode = (0, effector_1.restore)(setSignInMode, "email-otp-init");
|
|
1755
|
+
const setWrongOAuth = (0, effector_1.createEvent)();
|
|
1756
|
+
const wrongOAuth = (0, effector_1.restore)(setWrongOAuth, null);
|
|
1757
|
+
const wrongOAuthInfo = (0, effector_1.createStore)(null);
|
|
1758
|
+
wrongOAuthInfo.on(setWrongOAuth, (_, v) => v
|
|
1759
|
+
? {
|
|
1760
|
+
email: v.meta.email,
|
|
1761
|
+
oauthProviders: v.meta.oauth_providers,
|
|
1762
|
+
passwordDefined: v.meta.password_defined,
|
|
1763
|
+
webauthnDefined: v.meta.webauthn_defined,
|
|
1764
|
+
}
|
|
1765
|
+
: null);
|
|
1659
1766
|
const form = (0, form_js_1.createFormWithCustomError)({
|
|
1660
1767
|
email: (0, form_js_1.createStringField)("email", "", [validator_js_1.validNonEmpty, validator_js_1.validEmail, validator_js_1.validMaxLength250]),
|
|
1661
1768
|
password: (0, form_js_1.createStringField)("password", "", [validator_js_1.validNonEmpty]),
|
|
@@ -1666,6 +1773,11 @@ function createSigninPageGraph(binding) {
|
|
|
1666
1773
|
const formOTPComplete = (0, form_js_1.createFormWithCustomError)({
|
|
1667
1774
|
code: (0, form_js_1.createStringField)("code", "", [validator_js_1.validNonEmpty, validator_js_1.validMaxLength250]),
|
|
1668
1775
|
}, null);
|
|
1776
|
+
const setErrorOnAllForms = (0, effector_1.createEvent)();
|
|
1777
|
+
(0, effector_1.forward)({
|
|
1778
|
+
from: setErrorOnAllForms,
|
|
1779
|
+
to: [form.setError, formOTPInit.setError, formOTPComplete.setError],
|
|
1780
|
+
});
|
|
1669
1781
|
(0, effector_1.forward)({
|
|
1670
1782
|
from: init.event,
|
|
1671
1783
|
to: [form.reset, formOTPInit.reset, formOTPComplete.reset],
|
|
@@ -1701,7 +1813,44 @@ function createSigninPageGraph(binding) {
|
|
|
1701
1813
|
filter: binding.everythingIdle,
|
|
1702
1814
|
target: signInViaEmailCompleteFx,
|
|
1703
1815
|
});
|
|
1704
|
-
|
|
1816
|
+
const signInViaWebauthnFx = (0, effector_1.createEffect)((p) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1817
|
+
const { shopID, opts } = p.config;
|
|
1818
|
+
const resp = yield (0, request_js_1.request)(InitWebauthnMutation_js_1.default)({ shopID }, opts);
|
|
1819
|
+
if (resp.kind !== "data") {
|
|
1820
|
+
return resp;
|
|
1821
|
+
}
|
|
1822
|
+
let sessionID;
|
|
1823
|
+
let credential;
|
|
1824
|
+
try {
|
|
1825
|
+
sessionID = resp.data.session_id;
|
|
1826
|
+
credential = yield (0, browser_1.startAuthentication)({ optionsJSON: JSON.parse(resp.data.options).publicKey });
|
|
1827
|
+
}
|
|
1828
|
+
catch (err) {
|
|
1829
|
+
console.error(err);
|
|
1830
|
+
return { kind: "custom_error", text: "webauthn failure" };
|
|
1831
|
+
}
|
|
1832
|
+
return (0, request_js_1.request)(SignInMutation_js_1.default)({
|
|
1833
|
+
shopID,
|
|
1834
|
+
data: {
|
|
1835
|
+
webauthn_credential: JSON.stringify(credential),
|
|
1836
|
+
webauthn_session_id: sessionID,
|
|
1837
|
+
},
|
|
1838
|
+
}, opts);
|
|
1839
|
+
}));
|
|
1840
|
+
// webauthn
|
|
1841
|
+
{
|
|
1842
|
+
const { data: signinData } = (0, requestResponse_js_1.requestResponseSplit)(signInViaWebauthnFx.doneData);
|
|
1843
|
+
// success
|
|
1844
|
+
(0, effector_1.forward)({
|
|
1845
|
+
from: signinData.filterMap((v) => v.token || undefined),
|
|
1846
|
+
to: binding.setJWT,
|
|
1847
|
+
});
|
|
1848
|
+
// failure
|
|
1849
|
+
(0, split_js_1.splitMap)(signInViaWebauthnFx.done)
|
|
1850
|
+
.map((e) => (e.result.kind !== "system_error" ? "unauthorized_webauthn" : undefined), setErrorOnAllForms)
|
|
1851
|
+
.map((e) => (e.result.kind !== "data" ? e.result : undefined), handleFormFailure({ form, unexpectedError: binding.unexpectedError }));
|
|
1852
|
+
}
|
|
1853
|
+
// email/password form (oauth flow also goes here)
|
|
1705
1854
|
{
|
|
1706
1855
|
const { data: signinData } = (0, requestResponse_js_1.requestResponseSplit)(signinFx.doneData);
|
|
1707
1856
|
// success
|
|
@@ -1710,7 +1859,8 @@ function createSigninPageGraph(binding) {
|
|
|
1710
1859
|
to: binding.setJWT,
|
|
1711
1860
|
});
|
|
1712
1861
|
// failure
|
|
1713
|
-
(0, split_js_1.splitMap)(signinFx.done)
|
|
1862
|
+
(0, split_js_1.splitMap)(signinFx.done) // we use "done" here because we need "e.params.data.email" for logic
|
|
1863
|
+
.map((e) => mapSignInResponseToWrongOAuth(e.params, e.result), setWrongOAuth)
|
|
1714
1864
|
.map((e) => {
|
|
1715
1865
|
var _a;
|
|
1716
1866
|
return e.result.kind === "error" && ((_a = e.result.error.apiError) === null || _a === void 0 ? void 0 : _a.code) === codes_js_1.ErrorCode.Unauthorized
|
|
@@ -1718,7 +1868,7 @@ function createSigninPageGraph(binding) {
|
|
|
1718
1868
|
? "unauthorized"
|
|
1719
1869
|
: "unauthorized_oauth"
|
|
1720
1870
|
: undefined;
|
|
1721
|
-
},
|
|
1871
|
+
}, setErrorOnAllForms)
|
|
1722
1872
|
.map((e) => (e.result.kind !== "data" ? e.result : undefined), handleFormFailure({ form, unexpectedError: binding.unexpectedError }));
|
|
1723
1873
|
}
|
|
1724
1874
|
// OTP init form
|
|
@@ -1731,7 +1881,7 @@ function createSigninPageGraph(binding) {
|
|
|
1731
1881
|
});
|
|
1732
1882
|
// failure
|
|
1733
1883
|
(0, split_js_1.splitMap)(error)
|
|
1734
|
-
.map((e) => { var _a; return e.kind === "error" && ((_a = e.error.apiError) === null || _a === void 0 ? void 0 : _a.code) === codes_js_1.ErrorCode.TryAgainLater ? "try_again_later" : undefined; },
|
|
1884
|
+
.map((e) => { var _a; return e.kind === "error" && ((_a = e.error.apiError) === null || _a === void 0 ? void 0 : _a.code) === codes_js_1.ErrorCode.TryAgainLater ? "try_again_later" : undefined; }, setErrorOnAllForms)
|
|
1735
1885
|
.fallback(handleFormFailure({ form: formOTPInit, unexpectedError: binding.unexpectedError }));
|
|
1736
1886
|
}
|
|
1737
1887
|
// OTP complete form
|
|
@@ -1744,7 +1894,7 @@ function createSigninPageGraph(binding) {
|
|
|
1744
1894
|
});
|
|
1745
1895
|
// failure
|
|
1746
1896
|
(0, split_js_1.splitMap)(error)
|
|
1747
|
-
.map((e) => { var _a; return (e.kind === "error" && ((_a = e.error.apiError) === null || _a === void 0 ? void 0 : _a.code) === codes_js_1.ErrorCode.NotFound ? "unauthorized" : undefined); },
|
|
1897
|
+
.map((e) => { var _a; return (e.kind === "error" && ((_a = e.error.apiError) === null || _a === void 0 ? void 0 : _a.code) === codes_js_1.ErrorCode.NotFound ? "unauthorized" : undefined); }, setErrorOnAllForms)
|
|
1748
1898
|
.fallback(handleFormFailure({ form: formOTPComplete, unexpectedError: binding.unexpectedError }));
|
|
1749
1899
|
}
|
|
1750
1900
|
// oauth flow
|
|
@@ -1768,6 +1918,28 @@ function createSigninPageGraph(binding) {
|
|
|
1768
1918
|
filter: binding.everythingIdle,
|
|
1769
1919
|
target: signinFx,
|
|
1770
1920
|
});
|
|
1921
|
+
const webauthnClick = (0, effector_1.createEvent)();
|
|
1922
|
+
(0, effector_1.guard)({
|
|
1923
|
+
source: (0, effector_1.sample)(binding.internalConfig, webauthnClick, (config, data) => ({ config, data })),
|
|
1924
|
+
filter: binding.everythingIdle,
|
|
1925
|
+
target: signInViaWebauthnFx,
|
|
1926
|
+
});
|
|
1927
|
+
const connectWrongOAuth = (0, effector_1.createEvent)();
|
|
1928
|
+
const cancelWrongOAuth = (0, effector_1.createEvent)();
|
|
1929
|
+
(0, effector_1.guard)({
|
|
1930
|
+
source: (0, effector_1.sample)(wrongOAuth, connectWrongOAuth, (w) => w
|
|
1931
|
+
? {
|
|
1932
|
+
config: w.params.config,
|
|
1933
|
+
data: Object.assign(Object.assign({}, w.params.data), { oauth_session_id: w.meta.oauth_session_id }),
|
|
1934
|
+
}
|
|
1935
|
+
: undefined).filterMap((v) => v),
|
|
1936
|
+
filter: binding.everythingIdle,
|
|
1937
|
+
target: signinFx,
|
|
1938
|
+
});
|
|
1939
|
+
(0, effector_1.forward)({
|
|
1940
|
+
from: cancelWrongOAuth.map(() => null),
|
|
1941
|
+
to: setWrongOAuth,
|
|
1942
|
+
});
|
|
1771
1943
|
return {
|
|
1772
1944
|
init,
|
|
1773
1945
|
form,
|
|
@@ -1776,6 +1948,10 @@ function createSigninPageGraph(binding) {
|
|
|
1776
1948
|
signInMode,
|
|
1777
1949
|
setSignInMode,
|
|
1778
1950
|
oauth2Click,
|
|
1951
|
+
webauthnClick,
|
|
1952
|
+
wrongOAuthInfo,
|
|
1953
|
+
connectWrongOAuth,
|
|
1954
|
+
cancelWrongOAuth,
|
|
1779
1955
|
somethingIsPending: (0, combineSome_js_1.combineSome)(init.pending, signinFx.pending),
|
|
1780
1956
|
};
|
|
1781
1957
|
}
|
|
@@ -1825,7 +2001,7 @@ function createOAuth2UtilsGraph(binding) {
|
|
|
1825
2001
|
}));
|
|
1826
2002
|
const disconnectFx = (0, effector_1.createEffect)((p) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
1827
2003
|
const { shopID, opts } = p.config;
|
|
1828
|
-
return (0, request_js_1.request)(DisconnectOAuth2Mutation_js_1.default)({ shopID }, opts);
|
|
2004
|
+
return (0, request_js_1.request)(DisconnectOAuth2Mutation_js_1.default)({ shopID, provider: p.data }, opts);
|
|
1829
2005
|
}));
|
|
1830
2006
|
// connect flow
|
|
1831
2007
|
{
|
|
@@ -1888,6 +2064,92 @@ function createOAuth2UtilsGraph(binding) {
|
|
|
1888
2064
|
somethingIsPending: (0, combineSome_js_1.combineSome)(connectFx.pending, disconnectFx.pending),
|
|
1889
2065
|
};
|
|
1890
2066
|
}
|
|
2067
|
+
//--------------------------------------------------------------------------------------------------------------------
|
|
2068
|
+
//--------------------------------------------------------------------------------------------------------------------
|
|
2069
|
+
//--------------------------------------------------------------------------------------------------------------------
|
|
2070
|
+
// not really a part of any page, but somewhat follows page graph conventions, except it doesn't have init.
|
|
2071
|
+
function createWebauthnUtilsGraph(binding) {
|
|
2072
|
+
const createWebauthn = (0, effector_1.createEvent)();
|
|
2073
|
+
const deleteWebauthn = (0, effector_1.createEvent)();
|
|
2074
|
+
const createFx = (0, effector_1.createEffect)((p) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2075
|
+
const { shopID, opts } = p.config;
|
|
2076
|
+
if (!p.data) {
|
|
2077
|
+
return { kind: "custom_error", text: "no customer info" };
|
|
2078
|
+
}
|
|
2079
|
+
const email = p.data.customer.email;
|
|
2080
|
+
const name = p.data.customer.name;
|
|
2081
|
+
const resp = yield (0, request_js_1.request)(InitWebauthnMutation_js_1.default)({ shopID, email, name }, opts);
|
|
2082
|
+
if (resp.kind !== "data") {
|
|
2083
|
+
return resp;
|
|
2084
|
+
}
|
|
2085
|
+
let sessionID;
|
|
2086
|
+
let credential;
|
|
2087
|
+
try {
|
|
2088
|
+
sessionID = resp.data.session_id;
|
|
2089
|
+
credential = yield (0, browser_1.startRegistration)({ optionsJSON: JSON.parse(resp.data.options).publicKey });
|
|
2090
|
+
}
|
|
2091
|
+
catch (err) {
|
|
2092
|
+
console.error(err);
|
|
2093
|
+
return { kind: "custom_error", text: "webauthn failure" };
|
|
2094
|
+
}
|
|
2095
|
+
return (0, request_js_1.request)(AddWebauthnMutation_js_1.default)({ shopID, data: { webauthn_credential: JSON.stringify(credential), webauthn_session_id: sessionID } }, opts);
|
|
2096
|
+
}));
|
|
2097
|
+
const deleteFx = (0, effector_1.createEffect)((p) => tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
2098
|
+
const { shopID, opts } = p.config;
|
|
2099
|
+
return (0, request_js_1.request)(DeleteWebauthnMutation_js_1.default)({ shopID, ids: p.data }, opts);
|
|
2100
|
+
}));
|
|
2101
|
+
// create flow
|
|
2102
|
+
{
|
|
2103
|
+
(0, effector_1.guard)({
|
|
2104
|
+
source: (0, effector_1.sample)((0, effector_1.combine)({ config: binding.internalConfig, customerInfo: binding.customerInfo }), createWebauthn, ({ config, customerInfo }, _data) => ({ config, data: customerInfo })),
|
|
2105
|
+
filter: binding.everythingIdle,
|
|
2106
|
+
target: createFx,
|
|
2107
|
+
});
|
|
2108
|
+
const { data: connectData, error: connectError } = (0, requestResponse_js_1.requestResponseSplit)(createFx.doneData);
|
|
2109
|
+
// success
|
|
2110
|
+
(0, effector_1.forward)({
|
|
2111
|
+
from: connectData,
|
|
2112
|
+
to: binding.fetchCustomerInfoNow,
|
|
2113
|
+
});
|
|
2114
|
+
(0, effector_1.forward)({
|
|
2115
|
+
from: connectData.map(() => "webauthn_created"),
|
|
2116
|
+
to: binding.message,
|
|
2117
|
+
});
|
|
2118
|
+
// failure
|
|
2119
|
+
(0, effector_1.forward)({
|
|
2120
|
+
from: connectError,
|
|
2121
|
+
to: binding.unexpectedError,
|
|
2122
|
+
});
|
|
2123
|
+
}
|
|
2124
|
+
// delete flow
|
|
2125
|
+
{
|
|
2126
|
+
(0, effector_1.guard)({
|
|
2127
|
+
source: (0, effector_1.sample)(binding.internalConfig, deleteWebauthn, (config, data) => ({ config, data })),
|
|
2128
|
+
filter: binding.everythingIdle,
|
|
2129
|
+
target: deleteFx,
|
|
2130
|
+
});
|
|
2131
|
+
const { data: disconnectData, error: disconnectError } = (0, requestResponse_js_1.requestResponseSplit)(deleteFx.doneData);
|
|
2132
|
+
// success
|
|
2133
|
+
(0, effector_1.forward)({
|
|
2134
|
+
from: disconnectData,
|
|
2135
|
+
to: binding.fetchCustomerInfoNow,
|
|
2136
|
+
});
|
|
2137
|
+
(0, effector_1.forward)({
|
|
2138
|
+
from: disconnectData.map(() => "webauthn_deleted"),
|
|
2139
|
+
to: binding.message,
|
|
2140
|
+
});
|
|
2141
|
+
// failure
|
|
2142
|
+
(0, effector_1.forward)({
|
|
2143
|
+
from: disconnectError,
|
|
2144
|
+
to: binding.unexpectedError,
|
|
2145
|
+
});
|
|
2146
|
+
}
|
|
2147
|
+
return {
|
|
2148
|
+
createWebauthn,
|
|
2149
|
+
deleteWebauthn,
|
|
2150
|
+
somethingIsPending: (0, combineSome_js_1.combineSome)(createFx.pending, deleteFx.pending),
|
|
2151
|
+
};
|
|
2152
|
+
}
|
|
1891
2153
|
function createCustomer(config, init) {
|
|
1892
2154
|
var _a;
|
|
1893
2155
|
const currency = config.currency || (0, effector_1.createStore)(config.shopCurrency);
|
|
@@ -1957,6 +2219,7 @@ function createCustomer(config, init) {
|
|
|
1957
2219
|
message,
|
|
1958
2220
|
fetchCustomerInfoNow,
|
|
1959
2221
|
oauth2,
|
|
2222
|
+
customerInfo,
|
|
1960
2223
|
};
|
|
1961
2224
|
config.jwt.on(setJWT, (_, v) => v);
|
|
1962
2225
|
customerInfo.on(setFavorites, (pv, favorites) => {
|
|
@@ -1994,6 +2257,7 @@ function createCustomer(config, init) {
|
|
|
1994
2257
|
const pages = {
|
|
1995
2258
|
signin: createSigninPageGraph(binding),
|
|
1996
2259
|
signup: createSignupPageGraph(binding),
|
|
2260
|
+
webauthnSignup: createWebauthnSignupPageGraph(binding),
|
|
1997
2261
|
resetPassword: createResetPasswordPageGraph(binding),
|
|
1998
2262
|
addresses: createAddressesPageGraph(binding),
|
|
1999
2263
|
favorites: createFavoritesPageGraph(binding),
|
|
@@ -2009,6 +2273,7 @@ function createCustomer(config, init) {
|
|
|
2009
2273
|
paymentMethods: createPaymentMethodsPageGraph(binding),
|
|
2010
2274
|
};
|
|
2011
2275
|
const oauth2Utils = createOAuth2UtilsGraph(binding);
|
|
2276
|
+
const webauthnUtils = createWebauthnUtilsGraph(binding);
|
|
2012
2277
|
const currentPage = (0, effector_1.createStore)(null);
|
|
2013
2278
|
const loadPage = (0, effector_1.createEvent)();
|
|
2014
2279
|
const loadPageExt = (0, effector_1.sample)(currentPage, loadPage, (p, param) => ({
|
|
@@ -2017,6 +2282,7 @@ function createCustomer(config, init) {
|
|
|
2017
2282
|
}));
|
|
2018
2283
|
const loadSignin = loadPageExt.filterMap((v) => (v.param.kind === "signin" ? Object.assign(Object.assign({}, v), { param: v.param }) : undefined));
|
|
2019
2284
|
const loadSignup = loadPageExt.filterMap((v) => (v.param.kind === "signup" ? Object.assign(Object.assign({}, v), { param: v.param }) : undefined));
|
|
2285
|
+
const loadWebauthnSignup = loadPageExt.filterMap((v) => v.param.kind === "webauthn_signup" ? Object.assign(Object.assign({}, v), { param: v.param }) : undefined);
|
|
2020
2286
|
const loadResetPassword = loadPageExt.filterMap((v) => v.param.kind === "reset_password" ? Object.assign(Object.assign({}, v), { param: v.param }) : undefined);
|
|
2021
2287
|
const loadAddresses = loadPageExt.filterMap((v) => v.param.kind === "addresses" ? Object.assign(Object.assign({}, v), { param: v.param }) : undefined);
|
|
2022
2288
|
const loadFavorites = loadPageExt.filterMap((v) => v.param.kind === "favorites" ? Object.assign(Object.assign({}, v), { param: v.param }) : undefined);
|
|
@@ -2032,6 +2298,7 @@ function createCustomer(config, init) {
|
|
|
2032
2298
|
const loadPaymentMethods = loadPageExt.filterMap((v) => v.param.kind === "payment_methods" ? Object.assign(Object.assign({}, v), { param: v.param }) : undefined);
|
|
2033
2299
|
(0, effector_1.forward)({ from: loadSignin, to: pages.signin.init.load });
|
|
2034
2300
|
(0, effector_1.forward)({ from: loadSignup, to: pages.signup.init.load });
|
|
2301
|
+
(0, effector_1.forward)({ from: loadWebauthnSignup, to: pages.webauthnSignup.init.load });
|
|
2035
2302
|
(0, effector_1.forward)({ from: loadResetPassword, to: pages.resetPassword.init.load });
|
|
2036
2303
|
(0, effector_1.forward)({ from: loadAddresses, to: pages.addresses.init.load });
|
|
2037
2304
|
(0, effector_1.forward)({ from: loadFavorites, to: pages.favorites.init.load });
|
|
@@ -2053,6 +2320,7 @@ function createCustomer(config, init) {
|
|
|
2053
2320
|
from: [
|
|
2054
2321
|
pages.signin.init.loaded,
|
|
2055
2322
|
pages.signup.init.loaded,
|
|
2323
|
+
pages.webauthnSignup.init.loaded,
|
|
2056
2324
|
pages.resetPassword.init.loaded,
|
|
2057
2325
|
pages.addresses.init.loaded,
|
|
2058
2326
|
pages.favorites.init.loaded,
|
|
@@ -2069,7 +2337,7 @@ function createCustomer(config, init) {
|
|
|
2069
2337
|
],
|
|
2070
2338
|
to: currentPage,
|
|
2071
2339
|
});
|
|
2072
|
-
const somethingPending = (0, combineSome_js_1.combineSome)(pages.signin.somethingIsPending, pages.signup.somethingIsPending, pages.resetPassword.somethingIsPending, pages.addresses.somethingIsPending, pages.favorites.somethingIsPending, pages.orders.somethingIsPending, pages.subscriptions.somethingIsPending, pages.returns.somethingIsPending, pages.order.somethingIsPending, pages.subscription.somethingIsPending, pages.return.somethingIsPending, pages.createReturn.somethingIsPending, pages.storeCredit.somethingIsPending, pages.profile.somethingIsPending, pages.paymentMethods.somethingIsPending, oauth2Utils.somethingIsPending);
|
|
2340
|
+
const somethingPending = (0, combineSome_js_1.combineSome)(pages.signin.somethingIsPending, pages.signup.somethingIsPending, pages.webauthnSignup.somethingIsPending, pages.resetPassword.somethingIsPending, pages.addresses.somethingIsPending, pages.favorites.somethingIsPending, pages.orders.somethingIsPending, pages.subscriptions.somethingIsPending, pages.returns.somethingIsPending, pages.order.somethingIsPending, pages.subscription.somethingIsPending, pages.return.somethingIsPending, pages.createReturn.somethingIsPending, pages.storeCredit.somethingIsPending, pages.profile.somethingIsPending, pages.paymentMethods.somethingIsPending, oauth2Utils.somethingIsPending, webauthnUtils.somethingIsPending);
|
|
2073
2341
|
(0, effector_1.forward)({
|
|
2074
2342
|
from: somethingPending.map((v) => !v),
|
|
2075
2343
|
to: everythingIdle,
|
|
@@ -2150,7 +2418,11 @@ function createCustomer(config, init) {
|
|
|
2150
2418
|
to: internalGoTo,
|
|
2151
2419
|
});
|
|
2152
2420
|
// customerMenuVisible helper
|
|
2153
|
-
const customerLoggedIn = jwtAndCurrentPage.map(([jwt, currentPage]) => jwt !== "" &&
|
|
2421
|
+
const customerLoggedIn = jwtAndCurrentPage.map(([jwt, currentPage]) => jwt !== "" &&
|
|
2422
|
+
currentPage &&
|
|
2423
|
+
currentPage.kind !== "signin" &&
|
|
2424
|
+
currentPage.kind !== "signup" &&
|
|
2425
|
+
currentPage.kind !== "webauthn_signup");
|
|
2154
2426
|
return {
|
|
2155
2427
|
message,
|
|
2156
2428
|
logout,
|
|
@@ -2169,6 +2441,10 @@ function createCustomer(config, init) {
|
|
|
2169
2441
|
connect: oauth2Utils.connectOAuth2,
|
|
2170
2442
|
disconnect: oauth2Utils.disconnectOAuth2,
|
|
2171
2443
|
},
|
|
2444
|
+
webauthn: {
|
|
2445
|
+
create: webauthnUtils.createWebauthn,
|
|
2446
|
+
delete: webauthnUtils.deleteWebauthn,
|
|
2447
|
+
},
|
|
2172
2448
|
};
|
|
2173
2449
|
}
|
|
2174
2450
|
exports.createCustomer = createCustomer;
|
package/cjs/script.js
CHANGED
|
@@ -45,6 +45,7 @@ function embedUI(config) {
|
|
|
45
45
|
shopCurrencies: (0, arrayToDict_js_1.arrayToDict)(config.currencies, (c) => c.currency.code),
|
|
46
46
|
tipsVariantID: config.shop.tips_enabled ? (_b = config.shop.tips_variant) === null || _b === void 0 ? void 0 : _b.id : undefined,
|
|
47
47
|
oauth2Providers: config.shop.customer_oauth_providers,
|
|
48
|
+
customerWebauthn: config.shop.customer_webauthn,
|
|
48
49
|
stripe: stripeGateway
|
|
49
50
|
? {
|
|
50
51
|
accountID: stripeGateway.account_id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export default "fragment Customer on StorefrontCustomer{id email name display_name mobile mobile_notifications accepts_marketing reminder_messages addresses{...FullAddress}mobile mobile_notifications default_billing_address_id default_shipping_address_id default_payment_source_id is_guest password_defined
|
|
1
|
+
export default "fragment Customer on StorefrontCustomer{id email name display_name mobile mobile_notifications accepts_marketing reminder_messages addresses{...FullAddress}mobile mobile_notifications default_billing_address_id default_shipping_address_id default_payment_source_id is_guest password_defined oauth_providers webauthn_keys{id name created_at}}\n";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export default "fragment Shop on StorefrontShop{app_domain created_at currency customer_service_email id name product_review_enabled tax_label timezone primary_domain{domain id}customer_oauth_providers{...CustomerOAuthProvider}tips_enabled tips_variant{id}}\n";
|
|
1
|
+
export default "fragment Shop on StorefrontShop{app_domain created_at currency customer_service_email id name product_review_enabled tax_label timezone primary_domain{domain id}customer_oauth_providers{...CustomerOAuthProvider}tips_enabled tips_variant{id}customer_webauthn}\n";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default "mutation AddWebauthn($shopID:String!$data:WebauthnAdd!){storefrontCustomersWebauthn(shop_id:$shopID data:$data)}";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default "mutation DeleteWebauthn($shopID:String!$ids:[String!]!){storefrontCustomersWebauthnDelete(shop_id:$shopID ids:$ids)}";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export default "mutation DisconnectOAuth2($shopID:String!){storefrontCustomersOauthDelete(shop_id:$shopID)}";
|
|
1
|
+
export default "mutation DisconnectOAuth2($shopID:String!$provider:CustomerOAuthProviderKind!){storefrontCustomersOauthDelete(shop_id:$shopID provider:$provider)}";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default "mutation InitWebauthn($shopID:String!$name:String$email:String){storefrontCustomersInitWebauthn(shop_id:$shopID name:$name email:$email){session_id options}}";
|