@abpjs/account 1.1.0 → 2.0.0

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.
@@ -15,6 +15,15 @@ export interface AuthWrapperProps {
15
15
  * Cancel/footer content template reference
16
16
  */
17
17
  cancelContent?: ReactNode;
18
+ /**
19
+ * Whether local login (username/password) is enabled.
20
+ * When false, the wrapper will show a message that local login is disabled.
21
+ * This is read from ABP settings by default.
22
+ *
23
+ * @since 2.0.0
24
+ * @default true (from ABP settings or if not configured)
25
+ */
26
+ enableLocalLogin?: boolean;
18
27
  }
19
28
  /**
20
29
  * AuthWrapper - Authentication wrapper component
@@ -27,6 +36,7 @@ export interface AuthWrapperProps {
27
36
  * In React, we use children and render props pattern.
28
37
  *
29
38
  * @since 1.1.0
39
+ * @since 2.0.0 - Added enableLocalLogin prop to control local login visibility
30
40
  *
31
41
  * @example
32
42
  * ```tsx
@@ -36,5 +46,5 @@ export interface AuthWrapperProps {
36
46
  * />
37
47
  * ```
38
48
  */
39
- export declare function AuthWrapper({ children, mainContent, cancelContent, }: AuthWrapperProps): import("react/jsx-runtime").JSX.Element;
49
+ export declare function AuthWrapper({ children, mainContent, cancelContent, enableLocalLogin, }: AuthWrapperProps): import("react/jsx-runtime").JSX.Element;
40
50
  export default AuthWrapper;
@@ -32,6 +32,8 @@ export interface LoginFormProps {
32
32
  * This is the React equivalent of Angular's LoginComponent.
33
33
  * It handles user authentication using OAuth password flow.
34
34
  *
35
+ * @since 2.0.0 - Added isSelfRegistrationEnabled check from ABP settings
36
+ *
35
37
  * @example
36
38
  * ```tsx
37
39
  * function LoginPage() {
@@ -35,6 +35,7 @@ export interface RegisterFormProps {
35
35
  * AccountService and automatically logs in the user after successful registration.
36
36
  *
37
37
  * @since 0.9.0 - Now uses AccountService for registration
38
+ * @since 2.0.0 - Added isSelfRegistrationEnabled check from ABP settings
38
39
  *
39
40
  * @example
40
41
  * ```tsx
@@ -1,3 +1,4 @@
1
1
  export { usePasswordFlow, type PasswordFlowOptions } from './usePasswordFlow';
2
2
  export { useAccountOptions } from '../providers';
3
3
  export { useAccountService } from './useAccountService';
4
+ export { useSelfRegistrationEnabled } from './useSelfRegistration';
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Hook to check if self-registration is enabled.
3
+ *
4
+ * This reads the `Abp.Account.IsSelfRegistrationEnabled` setting from the
5
+ * ABP application configuration.
6
+ *
7
+ * @since 2.0.0
8
+ *
9
+ * @returns true if self-registration is enabled, false otherwise
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * function RegisterLink() {
14
+ * const isSelfRegistrationEnabled = useSelfRegistrationEnabled();
15
+ *
16
+ * if (!isSelfRegistrationEnabled) {
17
+ * return null;
18
+ * }
19
+ *
20
+ * return <Link to="/account/register">Register</Link>;
21
+ * }
22
+ * ```
23
+ */
24
+ export declare function useSelfRegistrationEnabled(): boolean;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,14 @@
1
1
  /**
2
2
  * @abpjs/account
3
3
  * ABP Framework Account module for React
4
- * Translated from @abp/ng.account v1.1.0
4
+ * Translated from @abp/ng.account v2.0.0
5
+ *
6
+ * @version 2.0.0
7
+ * @since 2.0.0 - Added Account namespace with component interface types
8
+ * @since 2.0.0 - Added isSelfRegistrationEnabled support in Login/Register components
9
+ * @since 2.0.0 - Added enableLocalLogin support in AuthWrapper component
10
+ * @since 2.0.0 - Removed deprecated ACCOUNT_ROUTES (use AccountProvider instead)
11
+ * @since 2.0.0 - TenantBoxComponent and AccountService now publicly exported
5
12
  */
6
13
  export * from './models';
7
14
  export * from './services';
package/dist/index.js CHANGED
@@ -21,7 +21,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  ACCOUNT_PATHS: () => ACCOUNT_PATHS,
24
- ACCOUNT_ROUTES: () => ACCOUNT_ROUTES,
25
24
  AccountProvider: () => AccountProvider,
26
25
  AccountService: () => AccountService,
27
26
  AuthWrapper: () => AuthWrapper,
@@ -37,7 +36,8 @@ __export(index_exports, {
37
36
  useAccountContext: () => useAccountContext,
38
37
  useAccountOptions: () => useAccountOptions,
39
38
  useAccountService: () => useAccountService,
40
- usePasswordFlow: () => usePasswordFlow
39
+ usePasswordFlow: () => usePasswordFlow,
40
+ useSelfRegistrationEnabled: () => useSelfRegistrationEnabled
41
41
  });
42
42
  module.exports = __toCommonJS(index_exports);
43
43
 
@@ -218,14 +218,34 @@ function useAccountService() {
218
218
  return (0, import_react3.useMemo)(() => new AccountService(restService), [restService]);
219
219
  }
220
220
 
221
+ // src/hooks/useSelfRegistration.ts
222
+ var import_core3 = require("@abpjs/core");
223
+ var SELF_REGISTRATION_SETTING = "Abp.Account.IsSelfRegistrationEnabled";
224
+ function useSelfRegistrationEnabled() {
225
+ const setting = (0, import_core3.useSetting)(SELF_REGISTRATION_SETTING);
226
+ if (setting === void 0 || setting === null) {
227
+ return true;
228
+ }
229
+ return setting.toLowerCase() === "true";
230
+ }
231
+
221
232
  // src/components/AuthWrapper/AuthWrapper.tsx
222
233
  var import_react4 = require("@chakra-ui/react");
234
+ var import_core4 = require("@abpjs/core");
223
235
  var import_jsx_runtime2 = require("react/jsx-runtime");
236
+ var ENABLE_LOCAL_LOGIN_SETTING = "Abp.Account.EnableLocalLogin";
224
237
  function AuthWrapper({
225
238
  children,
226
239
  mainContent,
227
- cancelContent
240
+ cancelContent,
241
+ enableLocalLogin
228
242
  }) {
243
+ const { t } = (0, import_core4.useLocalization)();
244
+ const localLoginSetting = (0, import_core4.useSetting)(ENABLE_LOCAL_LOGIN_SETTING);
245
+ const isLocalLoginEnabled = enableLocalLogin ?? (localLoginSetting === void 0 || localLoginSetting === null ? true : localLoginSetting.toLowerCase() === "true");
246
+ if (!isLocalLoginEnabled) {
247
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react4.Flex, { height: "full", flex: "1", className: "auth-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react4.Box, { flex: "1", py: { base: "24", md: "32" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react4.Container, { maxW: "md", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react4.Stack, { gap: "8", textAlign: "center", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react4.Text, { fontSize: "lg", color: "fg.muted", children: t("AbpAccount::LocalLoginDisabledMessage") || "Local login is disabled. Please use an external login provider." }) }) }) }) });
248
+ }
229
249
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react4.Flex, { height: "full", flex: "1", className: "auth-wrapper", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react4.Box, { flex: "1", py: { base: "24", md: "32" }, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react4.Container, { maxW: "md", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react4.Stack, { gap: "8", children: [
230
250
  mainContent || children,
231
251
  cancelContent && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react4.Box, { textAlign: "center", mt: 4, children: cancelContent })
@@ -237,7 +257,7 @@ var import_react5 = require("react");
237
257
  var import_react_hook_form = require("react-hook-form");
238
258
  var import_zod = require("@hookform/resolvers/zod");
239
259
  var import_zod2 = require("zod");
240
- var import_core3 = require("@abpjs/core");
260
+ var import_core5 = require("@abpjs/core");
241
261
  var import_theme_shared = require("@abpjs/theme-shared");
242
262
  var import_react6 = require("@chakra-ui/react");
243
263
  var import_react7 = require("@chakra-ui/react");
@@ -270,8 +290,8 @@ var changePasswordSchema = import_zod2.z.object({
270
290
  path: ["confirmNewPassword"]
271
291
  });
272
292
  function ChangePasswordForm({ onSuccess, onError }) {
273
- const { t } = (0, import_core3.useLocalization)();
274
- const { changePassword } = (0, import_core3.useProfile)();
293
+ const { t } = (0, import_core5.useLocalization)();
294
+ const { changePassword } = (0, import_core5.useProfile)();
275
295
  const toaster = (0, import_theme_shared.useToaster)();
276
296
  const [inProgress, setInProgress] = (0, import_react5.useState)(false);
277
297
  const {
@@ -371,23 +391,23 @@ var import_react_hook_form2 = require("react-hook-form");
371
391
  var import_zod3 = require("@hookform/resolvers/zod");
372
392
  var import_zod4 = require("zod");
373
393
  var import_react_router_dom2 = require("react-router-dom");
374
- var import_core5 = require("@abpjs/core");
394
+ var import_core7 = require("@abpjs/core");
375
395
  var import_theme_shared3 = require("@abpjs/theme-shared");
376
396
  var import_react10 = require("@chakra-ui/react");
377
397
 
378
398
  // src/components/TenantBox/TenantBox.tsx
379
399
  var import_react8 = require("react");
380
400
  var import_react_redux = require("react-redux");
381
- var import_core4 = require("@abpjs/core");
401
+ var import_core6 = require("@abpjs/core");
382
402
  var import_theme_shared2 = require("@abpjs/theme-shared");
383
403
  var import_react9 = require("@chakra-ui/react");
384
404
  var import_jsx_runtime4 = require("react/jsx-runtime");
385
405
  function TenantBox({ containerStyle }) {
386
- const { t } = (0, import_core4.useLocalization)();
406
+ const { t } = (0, import_core6.useLocalization)();
387
407
  const dispatch = (0, import_react_redux.useDispatch)();
388
408
  const accountService = useAccountService();
389
409
  const toaster = (0, import_theme_shared2.useToaster)();
390
- const currentTenant = (0, import_react_redux.useSelector)(import_core4.selectTenant);
410
+ const currentTenant = (0, import_react_redux.useSelector)(import_core6.selectTenant);
391
411
  const [tenantName, setTenantName] = (0, import_react8.useState)("");
392
412
  const [isModalVisible, setIsModalVisible] = (0, import_react8.useState)(false);
393
413
  const [inProgress, setInProgress] = (0, import_react8.useState)(false);
@@ -407,7 +427,7 @@ function TenantBox({ containerStyle }) {
407
427
  id: tenantId,
408
428
  name: tenantName
409
429
  };
410
- dispatch(import_core4.sessionActions.setTenant(newTenant));
430
+ dispatch(import_core6.sessionActions.setTenant(newTenant));
411
431
  setIsModalVisible(false);
412
432
  } else {
413
433
  toaster.error(
@@ -423,7 +443,7 @@ function TenantBox({ containerStyle }) {
423
443
  setInProgress(false);
424
444
  }
425
445
  } else {
426
- dispatch(import_core4.sessionActions.setTenant({ id: "", name: "" }));
446
+ dispatch(import_core6.sessionActions.setTenant({ id: "", name: "" }));
427
447
  setIsModalVisible(false);
428
448
  }
429
449
  }, [tenantName, accountService, dispatch, toaster, t]);
@@ -550,8 +570,9 @@ function LoginForm({
550
570
  onLoginSuccess,
551
571
  onLoginError
552
572
  }) {
553
- const { t } = (0, import_core5.useLocalization)();
573
+ const { t } = (0, import_core7.useLocalization)();
554
574
  const { login, isLoading, error, clearError } = usePasswordFlow();
575
+ const isSelfRegistrationEnabled = useSelfRegistrationEnabled();
555
576
  const {
556
577
  register,
557
578
  handleSubmit,
@@ -623,7 +644,7 @@ function LoginForm({
623
644
  ),
624
645
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react10.Link, { variant: "plain", children: t("AbpAccount::ForgotPassword") })
625
646
  ] }),
626
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react10.Show, { when: showRegisterLink, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react11.Card.Root, { size: "sm", mt: "10", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react11.Card.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react10.HStack, { textStyle: "sm", children: [
647
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react10.Show, { when: showRegisterLink && isSelfRegistrationEnabled, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react11.Card.Root, { size: "sm", mt: "10", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react11.Card.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react10.HStack, { textStyle: "sm", children: [
627
648
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react11.Text, { children: t("AbpAccount::AreYouANewUser") }),
628
649
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react10.Link, { asChild: true, variant: "underline", fontWeight: "semibold", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_router_dom2.Link, { to: registerUrl, children: t("AbpAccount::Register") }) })
629
650
  ] }) }) }) })
@@ -633,7 +654,7 @@ function LoginForm({
633
654
 
634
655
  // src/components/ManageProfile/ManageProfile.tsx
635
656
  var import_react15 = require("react");
636
- var import_core7 = require("@abpjs/core");
657
+ var import_core9 = require("@abpjs/core");
637
658
  var import_react16 = require("@chakra-ui/react");
638
659
 
639
660
  // src/components/PersonalSettingsForm/PersonalSettingsForm.tsx
@@ -641,7 +662,7 @@ var import_react12 = require("react");
641
662
  var import_react_hook_form3 = require("react-hook-form");
642
663
  var import_zod5 = require("@hookform/resolvers/zod");
643
664
  var import_zod6 = require("zod");
644
- var import_core6 = require("@abpjs/core");
665
+ var import_core8 = require("@abpjs/core");
645
666
  var import_theme_shared4 = require("@abpjs/theme-shared");
646
667
  var import_react13 = require("@chakra-ui/react");
647
668
  var import_react14 = require("@chakra-ui/react");
@@ -655,8 +676,8 @@ var personalSettingsSchema = import_zod6.z.object({
655
676
  phoneNumber: import_zod6.z.string().max(16, "Phone number must be at most 16 characters").optional()
656
677
  });
657
678
  function PersonalSettingsForm({ onSuccess, onError }) {
658
- const { t } = (0, import_core6.useLocalization)();
659
- const { profile, loading, fetchProfile, updateProfile } = (0, import_core6.useProfile)();
679
+ const { t } = (0, import_core8.useLocalization)();
680
+ const { profile, loading, fetchProfile, updateProfile } = (0, import_core8.useProfile)();
660
681
  const toaster = (0, import_theme_shared4.useToaster)();
661
682
  const [inProgress, setInProgress] = (0, import_react12.useState)(false);
662
683
  const {
@@ -801,7 +822,7 @@ function ManageProfile({
801
822
  onTabChange,
802
823
  customTabs
803
824
  }) {
804
- const { t } = (0, import_core7.useLocalization)();
825
+ const { t } = (0, import_core9.useLocalization)();
805
826
  const [selectedTab, setSelectedTab] = (0, import_react15.useState)(defaultTabIndex);
806
827
  const defaultTabs = [
807
828
  {
@@ -846,7 +867,7 @@ var import_react_hook_form4 = require("react-hook-form");
846
867
  var import_zod7 = require("@hookform/resolvers/zod");
847
868
  var import_zod8 = require("zod");
848
869
  var import_react_router_dom3 = require("react-router-dom");
849
- var import_core8 = require("@abpjs/core");
870
+ var import_core10 = require("@abpjs/core");
850
871
  var import_theme_shared5 = require("@abpjs/theme-shared");
851
872
  var import_react18 = require("@chakra-ui/react");
852
873
  var import_react19 = require("@chakra-ui/react");
@@ -882,13 +903,19 @@ function RegisterForm({
882
903
  onRegisterSuccess,
883
904
  onRegisterError
884
905
  }) {
885
- const { t } = (0, import_core8.useLocalization)();
906
+ const { t } = (0, import_core10.useLocalization)();
886
907
  const navigate = (0, import_react_router_dom3.useNavigate)();
887
908
  const accountService = useAccountService();
888
909
  const toaster = (0, import_theme_shared5.useToaster)();
889
- const userManager = (0, import_core8.useUserManager)();
890
- const { store, applicationConfigurationService } = (0, import_core8.useAbp)();
910
+ const userManager = (0, import_core10.useUserManager)();
911
+ const { store, applicationConfigurationService } = (0, import_core10.useAbp)();
891
912
  const [inProgress, setInProgress] = (0, import_react17.useState)(false);
913
+ const isSelfRegistrationEnabled = useSelfRegistrationEnabled();
914
+ (0, import_react17.useEffect)(() => {
915
+ if (!isSelfRegistrationEnabled) {
916
+ navigate(loginUrl, { replace: true });
917
+ }
918
+ }, [isSelfRegistrationEnabled, navigate, loginUrl]);
892
919
  const {
893
920
  register,
894
921
  handleSubmit,
@@ -918,7 +945,7 @@ function RegisterForm({
918
945
  password: newUser.password
919
946
  });
920
947
  const config = await applicationConfigurationService.getConfiguration();
921
- store.dispatch(import_core8.configActions.setApplicationConfiguration(config));
948
+ store.dispatch(import_core10.configActions.setApplicationConfiguration(config));
922
949
  navigate("/");
923
950
  onRegisterSuccess?.();
924
951
  } catch (loginErr) {
@@ -1034,29 +1061,6 @@ function RegisterPage({
1034
1061
  }
1035
1062
 
1036
1063
  // src/routes/index.ts
1037
- var import_core9 = require("@abpjs/core");
1038
- var ACCOUNT_ROUTES = {
1039
- routes: [
1040
- {
1041
- name: "Account",
1042
- path: "account",
1043
- invisible: true,
1044
- layout: import_core9.eLayoutType.application,
1045
- children: [
1046
- {
1047
- path: "login",
1048
- name: "Login",
1049
- order: 1
1050
- },
1051
- {
1052
- path: "register",
1053
- name: "Register",
1054
- order: 2
1055
- }
1056
- ]
1057
- }
1058
- ]
1059
- };
1060
1064
  var DEFAULT_REDIRECT_URL = "/";
1061
1065
  var ACCOUNT_PATHS = {
1062
1066
  login: "/account/login",
@@ -1065,7 +1069,6 @@ var ACCOUNT_PATHS = {
1065
1069
  // Annotate the CommonJS export names for ESM import in node:
1066
1070
  0 && (module.exports = {
1067
1071
  ACCOUNT_PATHS,
1068
- ACCOUNT_ROUTES,
1069
1072
  AccountProvider,
1070
1073
  AccountService,
1071
1074
  AuthWrapper,
@@ -1081,5 +1084,6 @@ var ACCOUNT_PATHS = {
1081
1084
  useAccountContext,
1082
1085
  useAccountOptions,
1083
1086
  useAccountService,
1084
- usePasswordFlow
1087
+ usePasswordFlow,
1088
+ useSelfRegistrationEnabled
1085
1089
  });
package/dist/index.mjs CHANGED
@@ -175,14 +175,34 @@ function useAccountService() {
175
175
  return useMemo2(() => new AccountService(restService), [restService]);
176
176
  }
177
177
 
178
+ // src/hooks/useSelfRegistration.ts
179
+ import { useSetting } from "@abpjs/core";
180
+ var SELF_REGISTRATION_SETTING = "Abp.Account.IsSelfRegistrationEnabled";
181
+ function useSelfRegistrationEnabled() {
182
+ const setting = useSetting(SELF_REGISTRATION_SETTING);
183
+ if (setting === void 0 || setting === null) {
184
+ return true;
185
+ }
186
+ return setting.toLowerCase() === "true";
187
+ }
188
+
178
189
  // src/components/AuthWrapper/AuthWrapper.tsx
179
- import { Box, Container, Stack, Flex } from "@chakra-ui/react";
190
+ import { Box, Container, Stack, Flex, Text } from "@chakra-ui/react";
191
+ import { useLocalization, useSetting as useSetting2 } from "@abpjs/core";
180
192
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
193
+ var ENABLE_LOCAL_LOGIN_SETTING = "Abp.Account.EnableLocalLogin";
181
194
  function AuthWrapper({
182
195
  children,
183
196
  mainContent,
184
- cancelContent
197
+ cancelContent,
198
+ enableLocalLogin
185
199
  }) {
200
+ const { t } = useLocalization();
201
+ const localLoginSetting = useSetting2(ENABLE_LOCAL_LOGIN_SETTING);
202
+ const isLocalLoginEnabled = enableLocalLogin ?? (localLoginSetting === void 0 || localLoginSetting === null ? true : localLoginSetting.toLowerCase() === "true");
203
+ if (!isLocalLoginEnabled) {
204
+ return /* @__PURE__ */ jsx2(Flex, { height: "full", flex: "1", className: "auth-wrapper", children: /* @__PURE__ */ jsx2(Box, { flex: "1", py: { base: "24", md: "32" }, children: /* @__PURE__ */ jsx2(Container, { maxW: "md", children: /* @__PURE__ */ jsx2(Stack, { gap: "8", textAlign: "center", children: /* @__PURE__ */ jsx2(Text, { fontSize: "lg", color: "fg.muted", children: t("AbpAccount::LocalLoginDisabledMessage") || "Local login is disabled. Please use an external login provider." }) }) }) }) });
205
+ }
186
206
  return /* @__PURE__ */ jsx2(Flex, { height: "full", flex: "1", className: "auth-wrapper", children: /* @__PURE__ */ jsx2(Box, { flex: "1", py: { base: "24", md: "32" }, children: /* @__PURE__ */ jsx2(Container, { maxW: "md", children: /* @__PURE__ */ jsxs(Stack, { gap: "8", children: [
187
207
  mainContent || children,
188
208
  cancelContent && /* @__PURE__ */ jsx2(Box, { textAlign: "center", mt: 4, children: cancelContent })
@@ -194,7 +214,7 @@ import { useState as useState2, useEffect } from "react";
194
214
  import { useForm } from "react-hook-form";
195
215
  import { zodResolver } from "@hookform/resolvers/zod";
196
216
  import { z } from "zod";
197
- import { useLocalization, useProfile } from "@abpjs/core";
217
+ import { useLocalization as useLocalization2, useProfile } from "@abpjs/core";
198
218
  import { Button, useToaster } from "@abpjs/theme-shared";
199
219
  import { Input, Stack as Stack2 } from "@chakra-ui/react";
200
220
  import { Field, InputGroup } from "@chakra-ui/react";
@@ -227,7 +247,7 @@ var changePasswordSchema = z.object({
227
247
  path: ["confirmNewPassword"]
228
248
  });
229
249
  function ChangePasswordForm({ onSuccess, onError }) {
230
- const { t } = useLocalization();
250
+ const { t } = useLocalization2();
231
251
  const { changePassword } = useProfile();
232
252
  const toaster = useToaster();
233
253
  const [inProgress, setInProgress] = useState2(false);
@@ -328,19 +348,19 @@ import { useForm as useForm2 } from "react-hook-form";
328
348
  import { zodResolver as zodResolver2 } from "@hookform/resolvers/zod";
329
349
  import { z as z2 } from "zod";
330
350
  import { Link as RouterLink } from "react-router-dom";
331
- import { useLocalization as useLocalization3 } from "@abpjs/core";
351
+ import { useLocalization as useLocalization4 } from "@abpjs/core";
332
352
  import { Alert, Button as Button3, Checkbox } from "@abpjs/theme-shared";
333
353
  import { Box as Box3, Heading, Input as Input3, Link as Link2, HStack, Show } from "@chakra-ui/react";
334
354
 
335
355
  // src/components/TenantBox/TenantBox.tsx
336
356
  import { useState as useState3, useCallback as useCallback2, useEffect as useEffect2 } from "react";
337
357
  import { useDispatch, useSelector } from "react-redux";
338
- import { useLocalization as useLocalization2, sessionActions, selectTenant } from "@abpjs/core";
358
+ import { useLocalization as useLocalization3, sessionActions, selectTenant } from "@abpjs/core";
339
359
  import { Modal, Button as Button2, useToaster as useToaster2 } from "@abpjs/theme-shared";
340
- import { Box as Box2, Text, Link, Input as Input2, VStack } from "@chakra-ui/react";
360
+ import { Box as Box2, Text as Text2, Link, Input as Input2, VStack } from "@chakra-ui/react";
341
361
  import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
342
362
  function TenantBox({ containerStyle }) {
343
- const { t } = useLocalization2();
363
+ const { t } = useLocalization3();
344
364
  const dispatch = useDispatch();
345
365
  const accountService = useAccountService();
346
366
  const toaster = useToaster2();
@@ -408,12 +428,12 @@ function TenantBox({ containerStyle }) {
408
428
  borderRadius: "md",
409
429
  style: containerStyle,
410
430
  children: [
411
- /* @__PURE__ */ jsxs3(Text, { as: "span", color: "gray.600", children: [
431
+ /* @__PURE__ */ jsxs3(Text2, { as: "span", color: "gray.600", children: [
412
432
  t("AbpUiMultiTenancy::Tenant"),
413
433
  ":",
414
434
  " "
415
435
  ] }),
416
- /* @__PURE__ */ jsx4(Text, { as: "strong", children: /* @__PURE__ */ jsx4(Text, { as: "i", children: currentTenant?.name || t("AbpUiMultiTenancy::NotSelected") }) }),
436
+ /* @__PURE__ */ jsx4(Text2, { as: "strong", children: /* @__PURE__ */ jsx4(Text2, { as: "i", children: currentTenant?.name || t("AbpUiMultiTenancy::NotSelected") }) }),
417
437
  " (",
418
438
  /* @__PURE__ */ jsx4(
419
439
  Link,
@@ -455,7 +475,7 @@ function TenantBox({ containerStyle }) {
455
475
  ] }),
456
476
  children: /* @__PURE__ */ jsx4("form", { onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs3(VStack, { gap: 4, align: "stretch", children: [
457
477
  /* @__PURE__ */ jsxs3(Box2, { children: [
458
- /* @__PURE__ */ jsx4(Text, { as: "label", mb: 1, display: "block", children: t("AbpUiMultiTenancy::Name") }),
478
+ /* @__PURE__ */ jsx4(Text2, { as: "label", mb: 1, display: "block", children: t("AbpUiMultiTenancy::Name") }),
459
479
  /* @__PURE__ */ jsx4(
460
480
  Input2,
461
481
  {
@@ -467,7 +487,7 @@ function TenantBox({ containerStyle }) {
467
487
  }
468
488
  )
469
489
  ] }),
470
- /* @__PURE__ */ jsx4(Text, { fontSize: "sm", color: "gray.600", children: t("AbpUiMultiTenancy::SwitchTenantHint") })
490
+ /* @__PURE__ */ jsx4(Text2, { fontSize: "sm", color: "gray.600", children: t("AbpUiMultiTenancy::SwitchTenantHint") })
471
491
  ] }) })
472
492
  }
473
493
  )
@@ -499,7 +519,7 @@ import {
499
519
  Flex as Flex2,
500
520
  InputGroup as InputGroup2,
501
521
  Stack as Stack3,
502
- Text as Text2
522
+ Text as Text3
503
523
  } from "@chakra-ui/react";
504
524
  import { LuLock as LuLock2, LuMail } from "react-icons/lu";
505
525
  import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
@@ -515,8 +535,9 @@ function LoginForm({
515
535
  onLoginSuccess,
516
536
  onLoginError
517
537
  }) {
518
- const { t } = useLocalization3();
538
+ const { t } = useLocalization4();
519
539
  const { login, isLoading, error, clearError } = usePasswordFlow();
540
+ const isSelfRegistrationEnabled = useSelfRegistrationEnabled();
520
541
  const {
521
542
  register,
522
543
  handleSubmit,
@@ -588,8 +609,8 @@ function LoginForm({
588
609
  ),
589
610
  /* @__PURE__ */ jsx5(Link2, { variant: "plain", children: t("AbpAccount::ForgotPassword") })
590
611
  ] }),
591
- /* @__PURE__ */ jsx5(Show, { when: showRegisterLink, children: /* @__PURE__ */ jsx5(Card.Root, { size: "sm", mt: "10", children: /* @__PURE__ */ jsx5(Card.Body, { children: /* @__PURE__ */ jsxs4(HStack, { textStyle: "sm", children: [
592
- /* @__PURE__ */ jsx5(Text2, { children: t("AbpAccount::AreYouANewUser") }),
612
+ /* @__PURE__ */ jsx5(Show, { when: showRegisterLink && isSelfRegistrationEnabled, children: /* @__PURE__ */ jsx5(Card.Root, { size: "sm", mt: "10", children: /* @__PURE__ */ jsx5(Card.Body, { children: /* @__PURE__ */ jsxs4(HStack, { textStyle: "sm", children: [
613
+ /* @__PURE__ */ jsx5(Text3, { children: t("AbpAccount::AreYouANewUser") }),
593
614
  /* @__PURE__ */ jsx5(Link2, { asChild: true, variant: "underline", fontWeight: "semibold", children: /* @__PURE__ */ jsx5(RouterLink, { to: registerUrl, children: t("AbpAccount::Register") }) })
594
615
  ] }) }) }) })
595
616
  ] }) })
@@ -598,7 +619,7 @@ function LoginForm({
598
619
 
599
620
  // src/components/ManageProfile/ManageProfile.tsx
600
621
  import { useState as useState5 } from "react";
601
- import { useLocalization as useLocalization5 } from "@abpjs/core";
622
+ import { useLocalization as useLocalization6 } from "@abpjs/core";
602
623
  import { Box as Box4, Container as Container3, Heading as Heading2, Stack as Stack5, Tabs } from "@chakra-ui/react";
603
624
 
604
625
  // src/components/PersonalSettingsForm/PersonalSettingsForm.tsx
@@ -606,7 +627,7 @@ import { useState as useState4, useEffect as useEffect3 } from "react";
606
627
  import { useForm as useForm3 } from "react-hook-form";
607
628
  import { zodResolver as zodResolver3 } from "@hookform/resolvers/zod";
608
629
  import { z as z3 } from "zod";
609
- import { useLocalization as useLocalization4, useProfile as useProfile2 } from "@abpjs/core";
630
+ import { useLocalization as useLocalization5, useProfile as useProfile2 } from "@abpjs/core";
610
631
  import { Button as Button4, useToaster as useToaster3 } from "@abpjs/theme-shared";
611
632
  import { Input as Input4, Stack as Stack4 } from "@chakra-ui/react";
612
633
  import { Field as Field3, InputGroup as InputGroup3 } from "@chakra-ui/react";
@@ -620,7 +641,7 @@ var personalSettingsSchema = z3.object({
620
641
  phoneNumber: z3.string().max(16, "Phone number must be at most 16 characters").optional()
621
642
  });
622
643
  function PersonalSettingsForm({ onSuccess, onError }) {
623
- const { t } = useLocalization4();
644
+ const { t } = useLocalization5();
624
645
  const { profile, loading, fetchProfile, updateProfile } = useProfile2();
625
646
  const toaster = useToaster3();
626
647
  const [inProgress, setInProgress] = useState4(false);
@@ -766,7 +787,7 @@ function ManageProfile({
766
787
  onTabChange,
767
788
  customTabs
768
789
  }) {
769
- const { t } = useLocalization5();
790
+ const { t } = useLocalization6();
770
791
  const [selectedTab, setSelectedTab] = useState5(defaultTabIndex);
771
792
  const defaultTabs = [
772
793
  {
@@ -806,12 +827,12 @@ function ManageProfile({
806
827
  }
807
828
 
808
829
  // src/components/RegisterForm/RegisterForm.tsx
809
- import { useState as useState6 } from "react";
830
+ import { useState as useState6, useEffect as useEffect4 } from "react";
810
831
  import { useForm as useForm4 } from "react-hook-form";
811
832
  import { zodResolver as zodResolver4 } from "@hookform/resolvers/zod";
812
833
  import { z as z4 } from "zod";
813
834
  import { Link as RouterLink2, useNavigate as useNavigate2 } from "react-router-dom";
814
- import { useLocalization as useLocalization6, useUserManager, useAbp as useAbp2, configActions as configActions2 } from "@abpjs/core";
835
+ import { useLocalization as useLocalization7, useUserManager, useAbp as useAbp2, configActions as configActions2 } from "@abpjs/core";
815
836
  import { Button as Button5, useToaster as useToaster4 } from "@abpjs/theme-shared";
816
837
  import { Box as Box5, Heading as Heading3, Input as Input5, Link as Link3, HStack as HStack2, Show as Show2 } from "@chakra-ui/react";
817
838
  import {
@@ -821,7 +842,7 @@ import {
821
842
  Flex as Flex3,
822
843
  InputGroup as InputGroup4,
823
844
  Stack as Stack6,
824
- Text as Text3
845
+ Text as Text4
825
846
  } from "@chakra-ui/react";
826
847
  import { LuLock as LuLock3, LuMail as LuMail3, LuUser as LuUser2 } from "react-icons/lu";
827
848
  import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
@@ -855,13 +876,19 @@ function RegisterForm({
855
876
  onRegisterSuccess,
856
877
  onRegisterError
857
878
  }) {
858
- const { t } = useLocalization6();
879
+ const { t } = useLocalization7();
859
880
  const navigate = useNavigate2();
860
881
  const accountService = useAccountService();
861
882
  const toaster = useToaster4();
862
883
  const userManager = useUserManager();
863
884
  const { store, applicationConfigurationService } = useAbp2();
864
885
  const [inProgress, setInProgress] = useState6(false);
886
+ const isSelfRegistrationEnabled = useSelfRegistrationEnabled();
887
+ useEffect4(() => {
888
+ if (!isSelfRegistrationEnabled) {
889
+ navigate(loginUrl, { replace: true });
890
+ }
891
+ }, [isSelfRegistrationEnabled, navigate, loginUrl]);
865
892
  const {
866
893
  register,
867
894
  handleSubmit,
@@ -979,7 +1006,7 @@ function RegisterForm({
979
1006
  )
980
1007
  ] }),
981
1008
  /* @__PURE__ */ jsx8(Show2, { when: showLoginLink, children: /* @__PURE__ */ jsx8(Card2.Root, { size: "sm", mt: "10", children: /* @__PURE__ */ jsx8(Card2.Body, { children: /* @__PURE__ */ jsxs7(HStack2, { textStyle: "sm", children: [
982
- /* @__PURE__ */ jsx8(Text3, { children: t("AbpAccount::AlreadyRegistered") }),
1009
+ /* @__PURE__ */ jsx8(Text4, { children: t("AbpAccount::AlreadyRegistered") }),
983
1010
  /* @__PURE__ */ jsx8(Link3, { asChild: true, variant: "underline", fontWeight: "semibold", children: /* @__PURE__ */ jsx8(RouterLink2, { to: loginUrl, children: t("AbpAccount::Login") }) })
984
1011
  ] }) }) }) })
985
1012
  ] }) })
@@ -1007,29 +1034,6 @@ function RegisterPage({
1007
1034
  }
1008
1035
 
1009
1036
  // src/routes/index.ts
1010
- import { eLayoutType } from "@abpjs/core";
1011
- var ACCOUNT_ROUTES = {
1012
- routes: [
1013
- {
1014
- name: "Account",
1015
- path: "account",
1016
- invisible: true,
1017
- layout: eLayoutType.application,
1018
- children: [
1019
- {
1020
- path: "login",
1021
- name: "Login",
1022
- order: 1
1023
- },
1024
- {
1025
- path: "register",
1026
- name: "Register",
1027
- order: 2
1028
- }
1029
- ]
1030
- }
1031
- ]
1032
- };
1033
1037
  var DEFAULT_REDIRECT_URL = "/";
1034
1038
  var ACCOUNT_PATHS = {
1035
1039
  login: "/account/login",
@@ -1037,7 +1041,6 @@ var ACCOUNT_PATHS = {
1037
1041
  };
1038
1042
  export {
1039
1043
  ACCOUNT_PATHS,
1040
- ACCOUNT_ROUTES,
1041
1044
  AccountProvider,
1042
1045
  AccountService,
1043
1046
  AuthWrapper,
@@ -1053,5 +1056,6 @@ export {
1053
1056
  useAccountContext,
1054
1057
  useAccountOptions,
1055
1058
  useAccountService,
1056
- usePasswordFlow
1059
+ usePasswordFlow,
1060
+ useSelfRegistrationEnabled
1057
1061
  };
@@ -1,6 +1,62 @@
1
1
  /**
2
2
  * Account module type definitions
3
3
  */
4
+ import type { ReactNode } from 'react';
5
+ /**
6
+ * Account namespace containing component interface types.
7
+ * Translated from @abp/ng.account v2.0.0 Account namespace.
8
+ *
9
+ * These interfaces define the inputs and outputs for account components,
10
+ * enabling type-safe component customization and extension.
11
+ *
12
+ * @since 2.0.0
13
+ */
14
+ export declare namespace Account {
15
+ /**
16
+ * Inputs for AuthWrapper component
17
+ */
18
+ interface AuthWrapperComponentInputs {
19
+ /** Main content to render in the auth wrapper */
20
+ readonly mainContentRef?: ReactNode;
21
+ /** Optional cancel/secondary content */
22
+ readonly cancelContentRef?: ReactNode;
23
+ }
24
+ /**
25
+ * Outputs for AuthWrapper component
26
+ */
27
+ interface AuthWrapperComponentOutputs {
28
+ }
29
+ /**
30
+ * Inputs for TenantBox component
31
+ */
32
+ interface TenantBoxComponentInputs {
33
+ }
34
+ /**
35
+ * Outputs for TenantBox component
36
+ */
37
+ interface TenantBoxComponentOutputs {
38
+ }
39
+ /**
40
+ * Inputs for PersonalSettings component
41
+ */
42
+ interface PersonalSettingsComponentInputs {
43
+ }
44
+ /**
45
+ * Outputs for PersonalSettings component
46
+ */
47
+ interface PersonalSettingsComponentOutputs {
48
+ }
49
+ /**
50
+ * Inputs for ChangePassword component
51
+ */
52
+ interface ChangePasswordComponentInputs {
53
+ }
54
+ /**
55
+ * Outputs for ChangePassword component
56
+ */
57
+ interface ChangePasswordComponentOutputs {
58
+ }
59
+ }
4
60
  /**
5
61
  * Account module configuration options
6
62
  */
@@ -1,21 +1,8 @@
1
- import { type ABP } from '@abpjs/core';
2
1
  /**
3
- * Account module routes configuration
2
+ * Account module routes constants
4
3
  *
5
- * This is the React equivalent of Angular's ACCOUNT_ROUTES constant.
6
- * These routes are registered with the ABP routing system.
7
- *
8
- * Route structure:
9
- * - /account (invisible, uses account layout)
10
- * - /account/login
11
- * - /account/register
12
- *
13
- * @since 0.9.0 - Changed from array to object with `routes` property
14
- * @deprecated since version 0.9 - Routes are now configured via AccountProvider
4
+ * @since 2.0.0 - Removed deprecated ACCOUNT_ROUTES (use AccountProvider instead)
15
5
  */
16
- export declare const ACCOUNT_ROUTES: {
17
- routes: ABP.FullRoute[];
18
- };
19
6
  /**
20
7
  * Default redirect path after login
21
8
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abpjs/account",
3
- "version": "1.1.0",
3
+ "version": "2.0.0",
4
4
  "description": "ABP Framework Account module for React - Translation of @abp/ng.account",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -53,11 +53,11 @@
53
53
  "react-redux": "^9.0.0",
54
54
  "zod": "^3.22.0",
55
55
  "react-icons": "^5.0.0",
56
- "@abpjs/core": "1.1.0",
57
- "@abpjs/theme-shared": "1.1.0"
56
+ "@abpjs/core": "2.0.0",
57
+ "@abpjs/theme-shared": "2.0.0"
58
58
  },
59
59
  "devDependencies": {
60
- "@abp/ng.account": "1.0.0",
60
+ "@abp/ng.account": "2.0.0",
61
61
  "@reduxjs/toolkit": "^2.0.0",
62
62
  "@testing-library/jest-dom": "^6.4.0",
63
63
  "@testing-library/react": "^14.2.0",