@misiki/gocommerce-connector 0.4.6 → 0.4.8

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.
@@ -132,6 +132,7 @@ function toMe(c) {
132
132
  avatar: null,
133
133
  role: "USER",
134
134
  emailVerified: c.email_verified,
135
+ phoneVerified: !!c.phone_verified,
135
136
  storeId: null
136
137
  };
137
138
  }
@@ -954,6 +955,7 @@ function toUser(c) {
954
955
  email: c.email,
955
956
  emailVerified: c.email_verified,
956
957
  phone: c.phone || null,
958
+ phoneVerified: !!c.phone_verified,
957
959
  firstName: firstName || "",
958
960
  lastName: rest.join(" "),
959
961
  name: c.name,
@@ -2064,11 +2066,24 @@ var orderService = new OrderService();
2064
2066
 
2065
2067
  // src/services/user-service.ts
2066
2068
  var UserService = class extends BaseService {
2067
- /** Email and password. The answer is the user object the storefront keeps in its `me` cookie. */
2068
- async login({ email, password }) {
2069
+ /**
2070
+ * Email and password. The answer is the user object the storefront keeps in its `me` cookie.
2071
+ * With `phone` and `phoneToken` from `verifyOtp({ askIfNew: true })`, the phone is added to
2072
+ * the account as it signs in (D123).
2073
+ */
2074
+ async login({
2075
+ email,
2076
+ password,
2077
+ phone,
2078
+ phoneToken
2079
+ }) {
2069
2080
  const auth = await this.account("/x/identity/login", {
2070
2081
  method: "POST",
2071
- body: { email: String(email ?? "").trim(), password: String(password ?? "") }
2082
+ body: {
2083
+ email: String(email ?? "").trim(),
2084
+ password: String(password ?? ""),
2085
+ ...phoneToken ? { phone: String(phone ?? "").trim(), phone_token: phoneToken } : {}
2086
+ }
2072
2087
  });
2073
2088
  return this.signedIn(auth);
2074
2089
  }
@@ -2201,7 +2216,7 @@ var AuthService = class extends UserService {
2201
2216
  async loginMethod() {
2202
2217
  try {
2203
2218
  const method = (await this.facts.plugins()).get("identity")?.settings?.login_method;
2204
- return method === "phone_otp" ? "phone_otp" : "email_password";
2219
+ return method === "phone_otp" || method === "email_or_phone" ? method : "email_password";
2205
2220
  } catch {
2206
2221
  return "email_password";
2207
2222
  }
@@ -2240,11 +2255,29 @@ var AuthService = class extends UserService {
2240
2255
  });
2241
2256
  return { expiresInMinutes: res?.expires_in_minutes ?? 10 };
2242
2257
  }
2243
- /** Signs in the account on `phone` with the code it was sent, opening one the first time. */
2244
- async verifyOtp({ phone, otp }) {
2245
- const auth = await this.account("/x/identity/otp/verify", {
2258
+ /**
2259
+ * Signs in the account on `phone` with the code it was sent, opening one the first time.
2260
+ * With `askIfNew`, on a store that signs in either way, a phone with no account opens none:
2261
+ * the answer is `{ newPhone: true, phoneToken }`, and the storefront asks "Already have an
2262
+ * account?" — `login` with the token adds the phone to it, `openPhoneAccount` opens a new one (D123).
2263
+ */
2264
+ async verifyOtp({ phone, otp, askIfNew }) {
2265
+ const res = await this.account("/x/identity/otp/verify", {
2246
2266
  method: "POST",
2247
- body: { phone: String(phone ?? "").trim(), code: String(otp ?? "").trim() }
2267
+ body: {
2268
+ phone: String(phone ?? "").trim(),
2269
+ code: String(otp ?? "").trim(),
2270
+ ...askIfNew ? { ask_if_new: true } : {}
2271
+ }
2272
+ });
2273
+ if ("new_phone" in res && res.new_phone) return { newPhone: true, phoneToken: res.phone_token };
2274
+ return this.signedIn(res);
2275
+ }
2276
+ /** Opens a new account on a phone `verifyOtp({ askIfNew: true })` proved, and signs it in (D123). */
2277
+ async openPhoneAccount({ phone, phoneToken }) {
2278
+ const auth = await this.account("/x/identity/otp/new-account", {
2279
+ method: "POST",
2280
+ body: { phone: String(phone ?? "").trim(), phone_token: phoneToken }
2248
2281
  });
2249
2282
  return this.signedIn(auth);
2250
2283
  }
@@ -2259,6 +2292,25 @@ var ProfileService = class extends UserService {
2259
2292
  async save(profile) {
2260
2293
  return this.updateProfile(profile);
2261
2294
  }
2295
+ /** Texts a code to a phone the signed-in shopper wants to add (D118). */
2296
+ async requestPhoneLink({ phone }) {
2297
+ const res = await this.account("/x/identity/me/phone", {
2298
+ method: "POST",
2299
+ auth: true,
2300
+ body: { phone: String(phone ?? "").trim() }
2301
+ });
2302
+ return { expiresInMinutes: res?.expires_in_minutes ?? 10 };
2303
+ }
2304
+ /** Adds the phone with its code; from then on it signs in to this account too. */
2305
+ async verifyPhoneLink({ phone, otp }) {
2306
+ const c = await this.account("/x/identity/me/phone/verify", {
2307
+ method: "POST",
2308
+ auth: true,
2309
+ body: { phone: String(phone ?? "").trim(), code: String(otp ?? "").trim() }
2310
+ });
2311
+ updateMe(c);
2312
+ return toUser(c);
2313
+ }
2262
2314
  };
2263
2315
  var userService = new UserService();
2264
2316
  var authService = new AuthService();
@@ -2608,7 +2660,7 @@ var StoreService = class extends BaseService {
2608
2660
  // The one way this store signs customers in (D116), which the sign-in
2609
2661
  // form reads as PHONE or EMAIL. Without the accounts module the static
2610
2662
  // record says.
2611
- ...plugins.has("identity") ? { loginType: plugins.get("identity")?.settings?.login_method === "phone_otp" ? "PHONE" : "EMAIL" } : {}
2663
+ ...plugins.has("identity") ? { loginType: LOGIN_TYPES[String(plugins.get("identity")?.settings?.login_method)] ?? "EMAIL" } : {}
2612
2664
  };
2613
2665
  }
2614
2666
  };
@@ -2627,6 +2679,7 @@ function regionName(code) {
2627
2679
  return code;
2628
2680
  }
2629
2681
  }
2682
+ var LOGIN_TYPES = { phone_otp: "PHONE", email_or_phone: "BOTH", email_password: "EMAIL" };
2630
2683
 
2631
2684
  // src/services/page-service.ts
2632
2685
  var PageService = class extends BaseService {