@umituz/react-native-auth 3.6.46 → 3.6.48

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umituz/react-native-auth",
3
- "version": "3.6.46",
3
+ "version": "3.6.48",
4
4
  "description": "Authentication service for React Native apps - Secure, type-safe, and production-ready. Provider-agnostic design with dependency injection, configurable validation, and comprehensive error handling.",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
package/src/index.ts CHANGED
@@ -167,8 +167,8 @@ export { AccountScreen } from './presentation/screens/AccountScreen';
167
167
  export type { AccountScreenConfig, AccountScreenProps } from './presentation/screens/AccountScreen';
168
168
  export { EditProfileScreen } from './presentation/screens/EditProfileScreen';
169
169
  export type { EditProfileConfig, EditProfileScreenProps } from './presentation/screens/EditProfileScreen';
170
- export { ChangePasswordScreen } from './presentation/screens/ChangePasswordScreen';
171
- export type { ChangePasswordTranslations, ChangePasswordScreenProps } from './presentation/screens/ChangePasswordScreen';
170
+ export { ChangePasswordScreen } from './presentation/screens/change-password';
171
+ export type { ChangePasswordTranslations, ChangePasswordScreenProps } from './presentation/screens/change-password';
172
172
  export { AuthNavigator } from './presentation/navigation/AuthNavigator';
173
173
  export type {
174
174
  AuthStackParamList,
@@ -69,9 +69,6 @@ export interface UseAuthResult {
69
69
  * Must call initializeAuthListener() once in app root.
70
70
  */
71
71
  export function useAuth(): UseAuthResult {
72
- if (typeof __DEV__ !== 'undefined' && __DEV__) {
73
- console.log('[useAuth] Hook called');
74
- }
75
72
  // State from store - using typed selectors
76
73
  const user = useAuthStore(selectUser);
77
74
  const loading = useAuthStore(selectLoading);
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Change Password Screen
3
+ */
4
+
1
5
  import React, { useState } from "react";
2
6
  import { View, StyleSheet, Alert } from "react-native";
3
7
  import {
@@ -13,38 +17,11 @@ import {
13
17
  reauthenticateWithPassword,
14
18
  getCurrentUserFromGlobal,
15
19
  } from "@umituz/react-native-firebase";
20
+ import { RequirementItem } from "./RequirementItem";
21
+ import { validatePassword } from "./ChangePasswordScreen.types";
22
+ import type { ChangePasswordScreenProps } from "./ChangePasswordScreen.types";
16
23
 
17
- export interface ChangePasswordTranslations {
18
- title: string;
19
- description: string;
20
- currentPassword: string;
21
- enterCurrentPassword: string;
22
- newPassword: string;
23
- enterNewPassword: string;
24
- confirmPassword: string;
25
- enterConfirmPassword: string;
26
- requirements: string;
27
- minLength: string;
28
- uppercase: string;
29
- lowercase: string;
30
- number: string;
31
- specialChar: string;
32
- passwordsMatch: string;
33
- changePassword: string;
34
- changing: string;
35
- cancel: string;
36
- success: string;
37
- error: string;
38
- fillAllFields: string;
39
- unauthorized: string;
40
- signInFailed: string;
41
- }
42
-
43
- export interface ChangePasswordScreenProps {
44
- translations: ChangePasswordTranslations;
45
- onSuccess?: () => void;
46
- onCancel?: () => void;
47
- }
24
+ export type { ChangePasswordTranslations, ChangePasswordScreenProps } from "./ChangePasswordScreen.types";
48
25
 
49
26
  export const ChangePasswordScreen: React.FC<ChangePasswordScreenProps> = ({
50
27
  translations,
@@ -59,24 +36,10 @@ export const ChangePasswordScreen: React.FC<ChangePasswordScreenProps> = ({
59
36
  const [loading, setLoading] = useState(false);
60
37
  const [error, setError] = useState<string | null>(null);
61
38
 
62
- const isLengthValid = newPassword.length >= 8;
63
- const hasUppercase = /[A-Z]/.test(newPassword);
64
- const hasLowercase = /[a-z]/.test(newPassword);
65
- const hasNumber = /[0-9]/.test(newPassword);
66
- const hasSpecialChar = /[!@#$%^&*]/.test(newPassword);
67
- const passwordsMatch = newPassword === confirmPassword && newPassword !== "";
68
-
69
- const isValid =
70
- isLengthValid &&
71
- hasUppercase &&
72
- hasLowercase &&
73
- hasNumber &&
74
- hasSpecialChar &&
75
- passwordsMatch &&
76
- currentPassword.length > 0;
39
+ const validation = validatePassword(newPassword, confirmPassword, currentPassword);
77
40
 
78
41
  const handleChangePassword = async () => {
79
- if (!isValid) {
42
+ if (!validation.isValid) {
80
43
  Alert.alert("Error", translations.fillAllFields);
81
44
  return;
82
45
  }
@@ -114,23 +77,6 @@ export const ChangePasswordScreen: React.FC<ChangePasswordScreenProps> = ({
114
77
  }
115
78
  };
116
79
 
117
- const RequirementItem = ({ label, met }: { label: string; met: boolean }) => (
118
- <View style={styles.requirementItem}>
119
- <View
120
- style={[
121
- styles.requirementBullet,
122
- { backgroundColor: met ? tokens.colors.success : tokens.colors.border },
123
- ]}
124
- />
125
- <AtomicText
126
- type="bodySmall"
127
- style={{ color: met ? tokens.colors.textPrimary : tokens.colors.textSecondary }}
128
- >
129
- {label}
130
- </AtomicText>
131
- </View>
132
- );
133
-
134
80
  return (
135
81
  <ScreenLayout
136
82
  scrollable
@@ -178,12 +124,12 @@ export const ChangePasswordScreen: React.FC<ChangePasswordScreenProps> = ({
178
124
  <AtomicText type="labelMedium" style={{ color: tokens.colors.textSecondary, marginBottom: 8 }}>
179
125
  {translations.requirements}
180
126
  </AtomicText>
181
- <RequirementItem label={translations.minLength} met={isLengthValid} />
182
- <RequirementItem label={translations.uppercase} met={hasUppercase} />
183
- <RequirementItem label={translations.lowercase} met={hasLowercase} />
184
- <RequirementItem label={translations.number} met={hasNumber} />
185
- <RequirementItem label={translations.specialChar} met={hasSpecialChar} />
186
- <RequirementItem label={translations.passwordsMatch} met={passwordsMatch} />
127
+ <RequirementItem label={translations.minLength} met={validation.isLengthValid} />
128
+ <RequirementItem label={translations.uppercase} met={validation.hasUppercase} />
129
+ <RequirementItem label={translations.lowercase} met={validation.hasLowercase} />
130
+ <RequirementItem label={translations.number} met={validation.hasNumber} />
131
+ <RequirementItem label={translations.specialChar} met={validation.hasSpecialChar} />
132
+ <RequirementItem label={translations.passwordsMatch} met={validation.passwordsMatch} />
187
133
  </View>
188
134
 
189
135
  {error && (
@@ -203,7 +149,7 @@ export const ChangePasswordScreen: React.FC<ChangePasswordScreenProps> = ({
203
149
  title={loading ? translations.changing : translations.changePassword}
204
150
  onPress={() => { void handleChangePassword(); }}
205
151
  loading={loading}
206
- disabled={!isValid || loading}
152
+ disabled={!validation.isValid || loading}
207
153
  style={{ flex: 1 }}
208
154
  />
209
155
  </View>
@@ -225,17 +171,6 @@ const styles = StyleSheet.create({
225
171
  padding: 12,
226
172
  borderRadius: 8,
227
173
  },
228
- requirementItem: {
229
- flexDirection: "row",
230
- alignItems: "center",
231
- marginBottom: 4,
232
- },
233
- requirementBullet: {
234
- width: 6,
235
- height: 6,
236
- borderRadius: 3,
237
- marginRight: 8,
238
- },
239
174
  actions: {
240
175
  flexDirection: "row",
241
176
  gap: 12,
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Change Password Screen Types
3
+ */
4
+
5
+ export interface ChangePasswordTranslations {
6
+ title: string;
7
+ description: string;
8
+ currentPassword: string;
9
+ enterCurrentPassword: string;
10
+ newPassword: string;
11
+ enterNewPassword: string;
12
+ confirmPassword: string;
13
+ enterConfirmPassword: string;
14
+ requirements: string;
15
+ minLength: string;
16
+ uppercase: string;
17
+ lowercase: string;
18
+ number: string;
19
+ specialChar: string;
20
+ passwordsMatch: string;
21
+ changePassword: string;
22
+ changing: string;
23
+ cancel: string;
24
+ success: string;
25
+ error: string;
26
+ fillAllFields: string;
27
+ unauthorized: string;
28
+ signInFailed: string;
29
+ }
30
+
31
+ export interface ChangePasswordScreenProps {
32
+ translations: ChangePasswordTranslations;
33
+ onSuccess?: () => void;
34
+ onCancel?: () => void;
35
+ }
36
+
37
+ export interface PasswordValidation {
38
+ isLengthValid: boolean;
39
+ hasUppercase: boolean;
40
+ hasLowercase: boolean;
41
+ hasNumber: boolean;
42
+ hasSpecialChar: boolean;
43
+ passwordsMatch: boolean;
44
+ isValid: boolean;
45
+ }
46
+
47
+ export function validatePassword(
48
+ newPassword: string,
49
+ confirmPassword: string,
50
+ currentPassword: string
51
+ ): PasswordValidation {
52
+ const isLengthValid = newPassword.length >= 8;
53
+ const hasUppercase = /[A-Z]/.test(newPassword);
54
+ const hasLowercase = /[a-z]/.test(newPassword);
55
+ const hasNumber = /[0-9]/.test(newPassword);
56
+ const hasSpecialChar = /[!@#$%^&*]/.test(newPassword);
57
+ const passwordsMatch = newPassword === confirmPassword && newPassword !== "";
58
+
59
+ const isValid =
60
+ isLengthValid &&
61
+ hasUppercase &&
62
+ hasLowercase &&
63
+ hasNumber &&
64
+ hasSpecialChar &&
65
+ passwordsMatch &&
66
+ currentPassword.length > 0;
67
+
68
+ return {
69
+ isLengthValid,
70
+ hasUppercase,
71
+ hasLowercase,
72
+ hasNumber,
73
+ hasSpecialChar,
74
+ passwordsMatch,
75
+ isValid,
76
+ };
77
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Password Requirement Item Component
3
+ */
4
+
5
+ import React from "react";
6
+ import { View, StyleSheet } from "react-native";
7
+ import { AtomicText, useAppDesignTokens } from "@umituz/react-native-design-system";
8
+
9
+ export interface RequirementItemProps {
10
+ label: string;
11
+ met: boolean;
12
+ }
13
+
14
+ export const RequirementItem: React.FC<RequirementItemProps> = ({ label, met }) => {
15
+ const tokens = useAppDesignTokens();
16
+
17
+ return (
18
+ <View style={styles.requirementItem}>
19
+ <View
20
+ style={[
21
+ styles.requirementBullet,
22
+ { backgroundColor: met ? tokens.colors.success : tokens.colors.border },
23
+ ]}
24
+ />
25
+ <AtomicText
26
+ type="bodySmall"
27
+ style={{ color: met ? tokens.colors.textPrimary : tokens.colors.textSecondary }}
28
+ >
29
+ {label}
30
+ </AtomicText>
31
+ </View>
32
+ );
33
+ };
34
+
35
+ const styles = StyleSheet.create({
36
+ requirementItem: {
37
+ flexDirection: "row",
38
+ alignItems: "center",
39
+ marginBottom: 4,
40
+ },
41
+ requirementBullet: {
42
+ width: 6,
43
+ height: 6,
44
+ borderRadius: 3,
45
+ marginRight: 8,
46
+ },
47
+ });
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Change Password Screen - Barrel export
3
+ */
4
+
5
+ export { ChangePasswordScreen } from "./ChangePasswordScreen";
6
+ export type { ChangePasswordTranslations, ChangePasswordScreenProps } from "./ChangePasswordScreen.types";
7
+ export { RequirementItem } from "./RequirementItem";
8
+ export type { RequirementItemProps } from "./RequirementItem";
9
+ export { validatePassword } from "./ChangePasswordScreen.types";
10
+ export type { PasswordValidation } from "./ChangePasswordScreen.types";