openxiangda 1.0.103 → 1.0.104

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.
@@ -42,6 +42,10 @@ __export(react_exports, {
42
42
  createPageSdk: () => createPageSdk,
43
43
  createPublicAccessClient: () => createPublicAccessClient,
44
44
  createReactPage: () => createReactPage,
45
+ getAuthErrorExtra: () => getAuthErrorExtra,
46
+ getAuthErrorReason: () => getAuthErrorReason,
47
+ isAuthChallengeRequired: () => isAuthChallengeRequired,
48
+ isAuthClientError: () => isAuthClientError,
45
49
  useAppMenus: () => useAppMenus,
46
50
  useAuth: () => useAuth,
47
51
  useCanAccessRoute: () => useCanAccessRoute,
@@ -2742,8 +2746,43 @@ var AuthClientError = class extends Error {
2742
2746
  this.status = options.status;
2743
2747
  this.code = options.code;
2744
2748
  this.payload = options.payload;
2749
+ this.extra = normalizeAuthErrorExtra(
2750
+ options.extra || getRecordValue(options.payload, "extra")
2751
+ );
2752
+ this.reason = this.extra?.reason || this.extra?.guardCode || (typeof options.code === "string" ? options.code : void 0);
2753
+ this.challenge = this.extra?.challenge;
2754
+ this.retryAfter = readNumber(
2755
+ this.extra?.retryAfter ?? this.extra?.retryAfterSeconds
2756
+ );
2757
+ this.remainingAttempts = readNumber(this.extra?.remainingAttempts);
2758
+ this.lockUntil = this.extra?.lockUntil ?? null;
2745
2759
  }
2746
2760
  };
2761
+ var isAuthClientError = (error) => {
2762
+ if (error instanceof AuthClientError) return true;
2763
+ return Boolean(
2764
+ error && typeof error === "object" && error.name === "AuthClientError"
2765
+ );
2766
+ };
2767
+ var getAuthErrorExtra = (error) => {
2768
+ if (!error || typeof error !== "object") return void 0;
2769
+ const record = error;
2770
+ return normalizeAuthErrorExtra(record.extra || getRecordValue(record.payload, "extra"));
2771
+ };
2772
+ var getAuthErrorReason = (error) => {
2773
+ if (!error || typeof error !== "object") return void 0;
2774
+ const record = error;
2775
+ const extra = getAuthErrorExtra(error);
2776
+ return extra?.reason || extra?.guardCode || (typeof record.reason === "string" ? record.reason : void 0) || (typeof record.code === "string" ? record.code : void 0);
2777
+ };
2778
+ var isAuthChallengeRequired = (error) => {
2779
+ if (!error || typeof error !== "object") return false;
2780
+ const record = error;
2781
+ const code = record.code;
2782
+ const reason = getAuthErrorReason(error);
2783
+ const extra = getAuthErrorExtra(error);
2784
+ return code === 460 || code === "460" || code === "LOGIN_CHALLENGE_REQUIRED" || reason === "LOGIN_CHALLENGE_REQUIRED" || reason === "CHALLENGE_REQUIRED" || extra?.guardCode === "LOGIN_CHALLENGE_REQUIRED";
2785
+ };
2747
2786
  var createAuthClient = ({
2748
2787
  appType,
2749
2788
  servicePrefix = "/service",
@@ -2770,7 +2809,12 @@ var createAuthClient = ({
2770
2809
  if (!response.ok || success === false || !isSuccessCode3(code)) {
2771
2810
  throw new AuthClientError(
2772
2811
  String(getRecordValue(payload, "message") || `Auth request failed: ${response.status}`),
2773
- { status: response.status, code, payload }
2812
+ {
2813
+ status: response.status,
2814
+ code,
2815
+ payload,
2816
+ extra: normalizeAuthErrorExtra(getRecordValue(payload, "extra"))
2817
+ }
2774
2818
  );
2775
2819
  }
2776
2820
  return unwrapPayload(payload);
@@ -2820,6 +2864,27 @@ var getRecordValue = (value, key) => {
2820
2864
  if (!value || typeof value !== "object") return void 0;
2821
2865
  return value[key];
2822
2866
  };
2867
+ var normalizeAuthErrorExtra = (value) => {
2868
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
2869
+ const record = value;
2870
+ const challenge = record.challenge && typeof record.challenge === "object" && !Array.isArray(record.challenge) ? record.challenge : void 0;
2871
+ const reason = readString(record.reason);
2872
+ const guardCode = readString(record.guardCode);
2873
+ return {
2874
+ ...record,
2875
+ ...reason ? { reason } : {},
2876
+ ...guardCode ? { guardCode } : {},
2877
+ ...challenge ? { challenge } : {},
2878
+ ...readNumber(record.retryAfter) !== void 0 ? { retryAfter: readNumber(record.retryAfter) } : {},
2879
+ ...readNumber(record.retryAfterSeconds) !== void 0 ? { retryAfterSeconds: readNumber(record.retryAfterSeconds) } : {},
2880
+ ...readNumber(record.remainingAttempts) !== void 0 ? { remainingAttempts: readNumber(record.remainingAttempts) } : {}
2881
+ };
2882
+ };
2883
+ var readString = (value) => typeof value === "string" ? value : void 0;
2884
+ var readNumber = (value) => {
2885
+ const numberValue = Number(value);
2886
+ return Number.isFinite(numberValue) ? numberValue : void 0;
2887
+ };
2823
2888
  var isSuccessCode3 = (code) => {
2824
2889
  if (code === void 0 || code === null || code === "") return true;
2825
2890
  const normalized = Number(code);
@@ -2957,6 +3022,7 @@ var LoginPage = ({
2957
3022
  "login"
2958
3023
  );
2959
3024
  const [phoneChallengeId, setPhoneChallengeId] = (0, import_react7.useState)("");
3025
+ const [passwordChallenge, setPasswordChallenge] = (0, import_react7.useState)(null);
2960
3026
  const [submitting, setSubmitting] = (0, import_react7.useState)(false);
2961
3027
  const [sendingCode, setSendingCode] = (0, import_react7.useState)(false);
2962
3028
  const [error, setError] = (0, import_react7.useState)(null);
@@ -2979,6 +3045,7 @@ var LoginPage = ({
2979
3045
  children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2980
3046
  PasswordLoginForm,
2981
3047
  {
3048
+ challenge: passwordChallenge,
2982
3049
  form: passwordForm,
2983
3050
  loading: submitting,
2984
3051
  onFinish: async (values) => {
@@ -2987,12 +3054,25 @@ var LoginPage = ({
2987
3054
  try {
2988
3055
  await handleSuccess(
2989
3056
  await auth.passwordLogin({
3057
+ challengeAnswer: passwordChallenge ? values.challengeAnswer : void 0,
3058
+ challengeId: readChallengeId(passwordChallenge),
3059
+ clientFingerprint: getOrCreateLoginFingerprint(auth.client),
2990
3060
  username: values.username,
2991
3061
  password: values.password
2992
3062
  })
2993
3063
  );
3064
+ setPasswordChallenge(null);
2994
3065
  } catch (loginError) {
2995
- setError(normalizeError(loginError).message);
3066
+ if (isAuthChallengeRequired(loginError)) {
3067
+ const nextChallenge = getAuthErrorExtra(loginError)?.challenge;
3068
+ if (nextChallenge) {
3069
+ setPasswordChallenge(nextChallenge);
3070
+ passwordForm.setFieldValue("challengeAnswer", "");
3071
+ }
3072
+ } else {
3073
+ setPasswordChallenge(null);
3074
+ }
3075
+ setError(formatAuthErrorMessage(loginError));
2996
3076
  } finally {
2997
3077
  setSubmitting(false);
2998
3078
  }
@@ -3062,6 +3142,7 @@ var LoginPage = ({
3062
3142
  allowRegister,
3063
3143
  auth,
3064
3144
  handleSuccess,
3145
+ passwordChallenge,
3065
3146
  passwordForm,
3066
3147
  passwordMethod,
3067
3148
  phoneChallengeId,
@@ -3215,7 +3296,7 @@ var LoginPage = ({
3215
3296
  }
3216
3297
  );
3217
3298
  };
3218
- var PasswordLoginForm = ({ form, loading, onFinish }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_antd2.Form, { form, layout: "vertical", requiredMark: false, onFinish, children: [
3299
+ var PasswordLoginForm = ({ challenge, form, loading, onFinish }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_antd2.Form, { form, layout: "vertical", requiredMark: false, onFinish, children: [
3219
3300
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3220
3301
  import_antd2.Form.Item,
3221
3302
  {
@@ -3234,6 +3315,26 @@ var PasswordLoginForm = ({ form, loading, onFinish }) => /* @__PURE__ */ (0, imp
3234
3315
  children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_antd2.Input.Password, { autoComplete: "current-password" })
3235
3316
  }
3236
3317
  ),
3318
+ challenge ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
3319
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3320
+ import_antd2.Alert,
3321
+ {
3322
+ showIcon: true,
3323
+ type: "warning",
3324
+ message: "\u8BF7\u5B8C\u6210\u989D\u5916\u9A8C\u8BC1",
3325
+ description: readChallengeQuestion(challenge) || "\u8BF7\u8F93\u5165\u9A8C\u8BC1\u7801\u540E\u7EE7\u7EED\u767B\u5F55\u3002"
3326
+ }
3327
+ ),
3328
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3329
+ import_antd2.Form.Item,
3330
+ {
3331
+ label: "\u9A8C\u8BC1\u7B54\u6848",
3332
+ name: "challengeAnswer",
3333
+ rules: [{ required: true, message: "\u8BF7\u8F93\u5165\u9A8C\u8BC1\u7B54\u6848" }],
3334
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_antd2.Input, { autoComplete: "one-time-code" })
3335
+ }
3336
+ )
3337
+ ] }) : null,
3237
3338
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_antd2.Button, { block: true, htmlType: "submit", icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons.LoginOutlined, {}), loading, type: "primary", children: "\u767B\u5F55" })
3238
3339
  ] });
3239
3340
  var PhoneCodeLoginForm = ({
@@ -3295,6 +3396,22 @@ var PhoneCodeLoginForm = ({
3295
3396
  ] });
3296
3397
  var findMethod = (methods, type) => methods.find((method) => method.type === type);
3297
3398
  var normalizeError = (error) => error instanceof Error ? error : new Error(String(error || "\u8BF7\u6C42\u5931\u8D25"));
3399
+ var formatAuthErrorMessage = (error) => {
3400
+ const normalized = normalizeError(error);
3401
+ const extra = getAuthErrorExtra(error);
3402
+ const reason = getAuthErrorReason(error);
3403
+ if (isAuthChallengeRequired(error)) {
3404
+ return extra?.challenge?.question ? "\u8BF7\u5B8C\u6210\u4E0B\u65B9\u9A8C\u8BC1\u540E\u518D\u767B\u5F55" : normalized.message || "\u8BF7\u5148\u5B8C\u6210\u989D\u5916\u9A8C\u8BC1\u540E\u518D\u5C1D\u8BD5\u767B\u5F55";
3405
+ }
3406
+ if (reason === "LOGIN_BLOCKED" || reason === "USERNAME_BLOCKED" || reason === "IP_BLOCKED" || reason === "ACCOUNT_LOCKED") {
3407
+ const retryAfter = Number(extra?.retryAfter ?? extra?.retryAfterSeconds);
3408
+ if (Number.isFinite(retryAfter) && retryAfter > 0) {
3409
+ const minutes = Math.ceil(retryAfter / 60);
3410
+ return `\u767B\u5F55\u53D7\u9650\uFF0C\u8BF7\u7EA6 ${minutes} \u5206\u949F\u540E\u518D\u8BD5\u6216\u8054\u7CFB\u7BA1\u7406\u5458`;
3411
+ }
3412
+ }
3413
+ return normalized.message || "\u767B\u5F55\u5931\u8D25";
3414
+ };
3298
3415
  var getString = (value, key) => {
3299
3416
  if (!value || typeof value !== "object") return void 0;
3300
3417
  const result = value[key];
@@ -3328,7 +3445,21 @@ var getOrCreateGuestIdentifier = (client) => {
3328
3445
  window.localStorage.setItem(key, next);
3329
3446
  return next;
3330
3447
  };
3448
+ var getOrCreateLoginFingerprint = (client) => {
3449
+ const key = `openxiangda:${client.appType}:login_fingerprint`;
3450
+ if (typeof window === "undefined") return createGuestIdentifier();
3451
+ const current = window.localStorage.getItem(key);
3452
+ const id = current || createGuestIdentifier();
3453
+ if (!current) window.localStorage.setItem(key, id);
3454
+ return `${id}:${window.navigator?.userAgent || "unknown"}`;
3455
+ };
3331
3456
  var createGuestIdentifier = () => `guest_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
3457
+ var readChallengeId = (challenge) => {
3458
+ if (!challenge) return void 0;
3459
+ const id = challenge.id || challenge.challengeId;
3460
+ return typeof id === "string" && id.trim() ? id.trim() : void 0;
3461
+ };
3462
+ var readChallengeQuestion = (challenge) => typeof challenge.question === "string" ? challenge.question : void 0;
3332
3463
  var getCurrentHref3 = () => typeof window === "undefined" ? "" : window.location.href;
3333
3464
  var getCurrentHostname = () => typeof window === "undefined" ? "" : window.location.hostname;
3334
3465
  var getCallbackUrl = () => {