@umituz/web-dashboard 2.0.8 → 2.1.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.
@@ -0,0 +1,280 @@
1
+ /**
2
+ * Auth Utilities
3
+ *
4
+ * Utility functions for authentication operations
5
+ */
6
+
7
+ import type { LoginCredentials, RegisterData, User } from "../types/auth";
8
+
9
+ /**
10
+ * Validate email format
11
+ *
12
+ * @param email - Email address
13
+ * @returns Whether email is valid
14
+ */
15
+ export function isValidEmail(email: string): boolean {
16
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
17
+ return emailRegex.test(email);
18
+ }
19
+
20
+ /**
21
+ * Validate password strength
22
+ *
23
+ * @param password - Password
24
+ * @param minLength - Minimum length (default: 8)
25
+ * @returns Whether password meets requirements
26
+ */
27
+ export function isValidPassword(password: string, minLength: number = 8): boolean {
28
+ return password.length >= minLength;
29
+ }
30
+
31
+ /**
32
+ * Validate login credentials
33
+ *
34
+ * @param credentials - Login credentials
35
+ * @returns Validation result with error message
36
+ */
37
+ export function validateLogin(credentials: LoginCredentials): {
38
+ valid: boolean;
39
+ error?: string;
40
+ } {
41
+ if (!credentials.email) {
42
+ return { valid: false, error: "Email is required" };
43
+ }
44
+
45
+ if (!isValidEmail(credentials.email)) {
46
+ return { valid: false, error: "Invalid email format" };
47
+ }
48
+
49
+ if (!credentials.password) {
50
+ return { valid: false, error: "Password is required" };
51
+ }
52
+
53
+ return { valid: true };
54
+ }
55
+
56
+ /**
57
+ * Validate registration data
58
+ *
59
+ * @param data - Registration data
60
+ * @param requireName - Whether name is required (default: false)
61
+ * @param requirePasswordConfirm - Whether password confirmation is required
62
+ * @returns Validation result with error message
63
+ */
64
+ export function validateRegister(
65
+ data: RegisterData,
66
+ requireName: boolean = false,
67
+ requirePasswordConfirm?: boolean
68
+ ): {
69
+ valid: boolean;
70
+ error?: string;
71
+ } {
72
+ if (!data.email) {
73
+ return { valid: false, error: "Email is required" };
74
+ }
75
+
76
+ if (!isValidEmail(data.email)) {
77
+ return { valid: false, error: "Invalid email format" };
78
+ }
79
+
80
+ if (requireName && !data.name) {
81
+ return { valid: false, error: "Name is required" };
82
+ }
83
+
84
+ if (!data.password) {
85
+ return { valid: false, error: "Password is required" };
86
+ }
87
+
88
+ if (!isValidPassword(data.password)) {
89
+ return { valid: false, error: "Password must be at least 8 characters" };
90
+ }
91
+
92
+ if (requirePasswordConfirm && data.password !== data.confirmPassword) {
93
+ return { valid: false, error: "Passwords do not match" };
94
+ }
95
+
96
+ return { valid: true };
97
+ }
98
+
99
+ /**
100
+ * Validate password reset request
101
+ *
102
+ * @param data - Forgot password data
103
+ * @returns Validation result with error message
104
+ */
105
+ export function validateForgotPassword(data: { email: string }): {
106
+ valid: boolean;
107
+ error?: string;
108
+ } {
109
+ if (!data.email) {
110
+ return { valid: false, error: "Email is required" };
111
+ }
112
+
113
+ if (!isValidEmail(data.email)) {
114
+ return { valid: false, error: "Invalid email format" };
115
+ }
116
+
117
+ return { valid: true };
118
+ }
119
+
120
+ /**
121
+ * Validate password reset confirmation
122
+ *
123
+ * @param data - Reset password data
124
+ * @returns Validation result with error message
125
+ */
126
+ export function validateResetPassword(data: {
127
+ token: string;
128
+ password: string;
129
+ confirmPassword: string;
130
+ }): {
131
+ valid: boolean;
132
+ error?: string;
133
+ } {
134
+ if (!data.token) {
135
+ return { valid: false, error: "Invalid reset token" };
136
+ }
137
+
138
+ if (!data.password) {
139
+ return { valid: false, error: "Password is required" };
140
+ }
141
+
142
+ if (!isValidPassword(data.password)) {
143
+ return { valid: false, error: "Password must be at least 8 characters" };
144
+ }
145
+
146
+ if (data.password !== data.confirmPassword) {
147
+ return { valid: false, error: "Passwords do not match" };
148
+ }
149
+
150
+ return { valid: true };
151
+ }
152
+
153
+ /**
154
+ * Get user display name
155
+ *
156
+ * @param user - User object
157
+ * @returns Display name or email fallback
158
+ */
159
+ export function getUserDisplayName(user: User | null): string {
160
+ if (!user) return "Guest";
161
+ return user.name || user.email || "User";
162
+ }
163
+
164
+ /**
165
+ * Get user initials
166
+ *
167
+ * @param user - User object
168
+ * @returns User initials (up to 2 characters)
169
+ */
170
+ export function getUserInitials(user: User | null): string {
171
+ if (!user) return "G";
172
+ const name = user.name || user.email || "";
173
+ const parts = name.trim().split(" ");
174
+ if (parts.length >= 2) {
175
+ return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
176
+ }
177
+ return name.slice(0, 2).toUpperCase();
178
+ }
179
+
180
+ /**
181
+ * Check if user has verified email
182
+ *
183
+ * @param user - User object
184
+ * @returns Whether email is verified
185
+ */
186
+ export function isEmailVerified(user: User | null): boolean {
187
+ return user?.emailVerified === true;
188
+ }
189
+
190
+ /**
191
+ * Format user creation date
192
+ *
193
+ * @param user - User object
194
+ * @param locale - Locale for formatting (default: en-US)
195
+ * @returns Formatted date string or empty string
196
+ */
197
+ export function formatUserCreatedAt(user: User | null, locale: string = "en-US"): string {
198
+ if (!user.createdAt) return "";
199
+ return new Date(user.createdAt).toLocaleDateString(locale, {
200
+ year: "numeric",
201
+ month: "long",
202
+ day: "numeric",
203
+ });
204
+ }
205
+
206
+ /**
207
+ * Mask email for privacy (e.g., u***@example.com)
208
+ *
209
+ * @param email - Email address
210
+ * @returns Masked email
211
+ */
212
+ export function maskEmail(email: string): string {
213
+ const [local, domain] = email.split("@");
214
+ if (!local || !domain) return email;
215
+
216
+ const maskedLocal = local[0] + "***";
217
+ return `${maskedLocal}@${domain}`;
218
+ }
219
+
220
+ /**
221
+ * Generate secure random token (for demo purposes)
222
+ * In production, use a proper crypto library
223
+ *
224
+ * @param length - Token length in bytes (default: 32)
225
+ * @returns Random hex token
226
+ */
227
+ export function generateResetToken(length: number = 32): string {
228
+ const chars = "0123456789abcdef";
229
+ let token = "";
230
+ for (let i = 0; i < length * 2; i++) {
231
+ token += chars[Math.floor(Math.random() * chars.length)];
232
+ }
233
+ return token;
234
+ }
235
+
236
+ /**
237
+ * Calculate password strength score (0-100)
238
+ *
239
+ * @param password - Password to evaluate
240
+ * @returns Strength score
241
+ */
242
+ export function calculatePasswordStrength(password: string): number {
243
+ let score = 0;
244
+
245
+ // Length
246
+ if (password.length >= 8) score += 25;
247
+ if (password.length >= 12) score += 25;
248
+
249
+ // Variety
250
+ if (/[a-z]/.test(password)) score += 12.5;
251
+ if (/[A-Z]/.test(password)) score += 12.5;
252
+ if (/[0-9]/.test(password)) score += 12.5;
253
+ if (/[^a-zA-Z0-9]/.test(password)) score += 12.5;
254
+
255
+ return Math.min(score, 100);
256
+ }
257
+
258
+ /**
259
+ * Get password strength label
260
+ *
261
+ * @param password - Password to evaluate
262
+ * @returns Strength label
263
+ */
264
+ export function getPasswordStrengthLabel(password: string): string {
265
+ const score = calculatePasswordStrength(password);
266
+ if (score < 25) return "Weak";
267
+ if (score < 50) return "Fair";
268
+ if (score < 75) return "Good";
269
+ return "Strong";
270
+ }
271
+
272
+ /**
273
+ * Sanitize user input for display
274
+ *
275
+ * @param input - User input string
276
+ * @returns Sanitized string
277
+ */
278
+ export function sanitizeInput(input: string): string {
279
+ return input.trim().slice(0, 1000);
280
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Auth Utilities
3
+ *
4
+ * Export all auth utilities
5
+ */
6
+
7
+ export {
8
+ isValidEmail,
9
+ isValidPassword,
10
+ validateLogin,
11
+ validateRegister,
12
+ validateForgotPassword,
13
+ validateResetPassword,
14
+ getUserDisplayName,
15
+ getUserInitials,
16
+ isEmailVerified,
17
+ formatUserCreatedAt,
18
+ maskEmail,
19
+ generateResetToken,
20
+ calculatePasswordStrength,
21
+ getPasswordStrengthLabel,
22
+ sanitizeInput,
23
+ } from "./auth";