hazo_auth 1.6.0 → 1.6.2
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/README.md +191 -19
- package/SETUP_CHECKLIST.md +190 -65
- package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.d.ts +9 -0
- package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.d.ts.map +1 -0
- package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.js +82 -0
- package/dist/app/api/hazo_auth/library_photos/route.d.ts +9 -0
- package/dist/app/api/hazo_auth/library_photos/route.d.ts.map +1 -1
- package/dist/app/api/hazo_auth/library_photos/route.js +31 -6
- package/dist/cli/generate.d.ts +6 -1
- package/dist/cli/generate.d.ts.map +1 -1
- package/dist/cli/generate.js +101 -34
- package/dist/cli/index.js +64 -11
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +206 -0
- package/dist/client.d.ts +8 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +25 -0
- package/dist/components/layouts/email_verification/index.d.ts +2 -1
- package/dist/components/layouts/email_verification/index.d.ts.map +1 -1
- package/dist/components/layouts/email_verification/index.js +3 -2
- package/dist/components/layouts/forgot_password/index.d.ts +3 -1
- package/dist/components/layouts/forgot_password/index.d.ts.map +1 -1
- package/dist/components/layouts/forgot_password/index.js +3 -2
- package/dist/components/layouts/my_settings/components/editable_field.js +1 -1
- package/dist/components/layouts/my_settings/components/password_change_dialog.js +1 -1
- package/dist/components/layouts/my_settings/components/profile_picture_display.js +1 -1
- package/dist/components/layouts/my_settings/components/profile_picture_gravatar_tab.js +1 -1
- package/dist/components/layouts/my_settings/components/profile_picture_library_tab.js +4 -4
- package/dist/components/layouts/my_settings/components/profile_picture_upload_tab.js +4 -4
- package/dist/components/layouts/my_settings/index.js +1 -1
- package/dist/components/layouts/shared/components/profile_pic_menu.js +2 -2
- package/dist/lib/auth_utility_config.server.js +2 -2
- package/dist/lib/services/profile_picture_service.d.ts +34 -2
- package/dist/lib/services/profile_picture_service.d.ts.map +1 -1
- package/dist/lib/services/profile_picture_service.js +157 -15
- package/dist/lib/services/user_profiles_cache.d.ts +76 -0
- package/dist/lib/services/user_profiles_cache.d.ts.map +1 -0
- package/dist/lib/services/user_profiles_cache.js +141 -0
- package/dist/lib/services/user_profiles_service.d.ts +17 -0
- package/dist/lib/services/user_profiles_service.d.ts.map +1 -1
- package/dist/lib/services/user_profiles_service.js +136 -44
- package/dist/lib/user_profiles_config.server.d.ts +15 -0
- package/dist/lib/user_profiles_config.server.d.ts.map +1 -0
- package/dist/lib/user_profiles_config.server.js +23 -0
- package/dist/page_components/forgot_password.d.ts +19 -0
- package/dist/page_components/forgot_password.d.ts.map +1 -0
- package/dist/page_components/forgot_password.js +36 -0
- package/dist/page_components/index.d.ts +7 -0
- package/dist/page_components/index.d.ts.map +1 -0
- package/dist/page_components/index.js +9 -0
- package/dist/page_components/login.d.ts +26 -0
- package/dist/page_components/login.d.ts.map +1 -0
- package/dist/page_components/login.js +40 -0
- package/dist/page_components/my_settings.d.ts +64 -0
- package/dist/page_components/my_settings.d.ts.map +1 -0
- package/dist/page_components/my_settings.js +67 -0
- package/dist/page_components/register.d.ts +25 -0
- package/dist/page_components/register.d.ts.map +1 -0
- package/dist/page_components/register.js +43 -0
- package/dist/page_components/reset_password.d.ts +25 -0
- package/dist/page_components/reset_password.d.ts.map +1 -0
- package/dist/page_components/reset_password.js +43 -0
- package/dist/page_components/verify_email.d.ts +21 -0
- package/dist/page_components/verify_email.d.ts.map +1 -0
- package/dist/page_components/verify_email.js +36 -0
- package/dist/server/routes/index.d.ts +1 -0
- package/dist/server/routes/index.d.ts.map +1 -1
- package/dist/server/routes/index.js +1 -0
- package/dist/server/routes/library_photo.d.ts +2 -0
- package/dist/server/routes/library_photo.d.ts.map +1 -0
- package/dist/server/routes/library_photo.js +3 -0
- package/hazo_auth_config.example.ini +25 -5
- package/package.json +33 -1
|
@@ -2,16 +2,60 @@ import { createCrudService } from "hazo_connect/server";
|
|
|
2
2
|
import { differenceInDays } from "date-fns";
|
|
3
3
|
import { create_app_logger } from "../app_logger";
|
|
4
4
|
import { sanitize_error_for_user } from "../utils/error_sanitizer";
|
|
5
|
+
import { get_user_profiles_cache } from "./user_profiles_cache";
|
|
6
|
+
import { get_user_profiles_cache_config } from "../user_profiles_config.server";
|
|
5
7
|
// section: helpers
|
|
8
|
+
/**
|
|
9
|
+
* Fetches profiles from database for given user IDs
|
|
10
|
+
* @param adapter - The hazo_connect adapter instance
|
|
11
|
+
* @param user_ids - Array of user IDs to fetch
|
|
12
|
+
* @returns Object with profiles and not found IDs
|
|
13
|
+
*/
|
|
14
|
+
async function fetch_profiles_from_db(adapter, user_ids) {
|
|
15
|
+
const users_service = createCrudService(adapter, "hazo_users");
|
|
16
|
+
// Query users by IDs using the 'in' filter
|
|
17
|
+
// PostgREST supports 'in' filter syntax: id=in.(id1,id2,id3)
|
|
18
|
+
const users = await users_service.findBy({
|
|
19
|
+
id: `in.(${user_ids.join(",")})`,
|
|
20
|
+
});
|
|
21
|
+
// Handle case where no users are found
|
|
22
|
+
if (!Array.isArray(users)) {
|
|
23
|
+
return {
|
|
24
|
+
profiles: [],
|
|
25
|
+
not_found_ids: user_ids,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
// Build set of found user IDs for quick lookup
|
|
29
|
+
const found_user_ids = new Set(users.map((user) => user.id));
|
|
30
|
+
// Determine which user IDs were not found
|
|
31
|
+
const not_found_ids = user_ids.filter((id) => !found_user_ids.has(id));
|
|
32
|
+
// Transform database records to UserProfileInfo
|
|
33
|
+
const now = new Date();
|
|
34
|
+
const profiles = users.map((user) => {
|
|
35
|
+
const created_at = user.created_at;
|
|
36
|
+
const created_date = new Date(created_at);
|
|
37
|
+
const days_since_created = differenceInDays(now, created_date);
|
|
38
|
+
return {
|
|
39
|
+
user_id: user.id,
|
|
40
|
+
profile_picture_url: user.profile_picture_url || null,
|
|
41
|
+
email: user.email_address,
|
|
42
|
+
name: user.name || null,
|
|
43
|
+
days_since_created,
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
return { profiles, not_found_ids };
|
|
47
|
+
}
|
|
6
48
|
/**
|
|
7
49
|
* Retrieves basic profile information for multiple users in a single batch call
|
|
8
50
|
* Useful for chat applications and similar use cases where basic user info is needed
|
|
51
|
+
* Uses LRU cache with configurable TTL for performance (default: 5 minutes)
|
|
9
52
|
* @param adapter - The hazo_connect adapter instance
|
|
10
53
|
* @param user_ids - Array of user IDs to retrieve profiles for
|
|
11
54
|
* @returns GetProfilesResult with found profiles and list of not found IDs
|
|
12
55
|
*/
|
|
13
56
|
export async function hazo_get_user_profiles(adapter, user_ids) {
|
|
14
57
|
const logger = create_app_logger();
|
|
58
|
+
const config = get_user_profiles_cache_config();
|
|
15
59
|
try {
|
|
16
60
|
// Handle empty input
|
|
17
61
|
if (!user_ids || user_ids.length === 0) {
|
|
@@ -19,62 +63,85 @@ export async function hazo_get_user_profiles(adapter, user_ids) {
|
|
|
19
63
|
success: true,
|
|
20
64
|
profiles: [],
|
|
21
65
|
not_found_ids: [],
|
|
66
|
+
cache_stats: {
|
|
67
|
+
hits: 0,
|
|
68
|
+
misses: 0,
|
|
69
|
+
cache_enabled: config.cache_enabled,
|
|
70
|
+
},
|
|
22
71
|
};
|
|
23
72
|
}
|
|
24
73
|
// Remove duplicates from input
|
|
25
74
|
const unique_user_ids = [...new Set(user_ids)];
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
75
|
+
// Initialize variables for cache tracking
|
|
76
|
+
let cache_hits = 0;
|
|
77
|
+
let cache_misses = 0;
|
|
78
|
+
let all_profiles = [];
|
|
79
|
+
let all_not_found_ids = [];
|
|
80
|
+
if (config.cache_enabled) {
|
|
81
|
+
// Get cache instance with config settings
|
|
82
|
+
const cache = get_user_profiles_cache(config.cache_max_entries, config.cache_ttl_minutes);
|
|
83
|
+
// Check cache first
|
|
84
|
+
const { cached, missing_ids } = cache.get_many(unique_user_ids);
|
|
85
|
+
cache_hits = cached.length;
|
|
86
|
+
cache_misses = missing_ids.length;
|
|
87
|
+
// If all profiles were cached, return immediately
|
|
88
|
+
if (missing_ids.length === 0) {
|
|
89
|
+
logger.info("hazo_get_user_profiles_cache_hit_all", {
|
|
90
|
+
filename: "user_profiles_service.ts",
|
|
91
|
+
line_number: 130,
|
|
92
|
+
message: "All profiles served from cache",
|
|
93
|
+
requested_count: unique_user_ids.length,
|
|
94
|
+
cache_hits,
|
|
95
|
+
});
|
|
96
|
+
return {
|
|
97
|
+
success: true,
|
|
98
|
+
profiles: cached,
|
|
99
|
+
not_found_ids: [],
|
|
100
|
+
cache_stats: {
|
|
101
|
+
hits: cache_hits,
|
|
102
|
+
misses: 0,
|
|
103
|
+
cache_enabled: true,
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
// Fetch missing profiles from database
|
|
108
|
+
const db_result = await fetch_profiles_from_db(adapter, missing_ids);
|
|
109
|
+
// Cache the newly fetched profiles
|
|
110
|
+
if (db_result.profiles.length > 0) {
|
|
111
|
+
cache.set_many(db_result.profiles);
|
|
112
|
+
}
|
|
113
|
+
// Combine cached and freshly fetched profiles
|
|
114
|
+
all_profiles = [...cached, ...db_result.profiles];
|
|
115
|
+
all_not_found_ids = db_result.not_found_ids;
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
// Cache disabled - fetch all from database
|
|
119
|
+
cache_misses = unique_user_ids.length;
|
|
120
|
+
const db_result = await fetch_profiles_from_db(adapter, unique_user_ids);
|
|
121
|
+
all_profiles = db_result.profiles;
|
|
122
|
+
all_not_found_ids = db_result.not_found_ids;
|
|
46
123
|
}
|
|
47
|
-
// Build set of found user IDs for quick lookup
|
|
48
|
-
const found_user_ids = new Set(users.map((user) => user.id));
|
|
49
|
-
// Determine which user IDs were not found
|
|
50
|
-
const not_found_ids = unique_user_ids.filter((id) => !found_user_ids.has(id));
|
|
51
|
-
// Transform database records to UserProfileInfo
|
|
52
|
-
const now = new Date();
|
|
53
|
-
const profiles = users.map((user) => {
|
|
54
|
-
const created_at = user.created_at;
|
|
55
|
-
const created_date = new Date(created_at);
|
|
56
|
-
const days_since_created = differenceInDays(now, created_date);
|
|
57
|
-
return {
|
|
58
|
-
user_id: user.id,
|
|
59
|
-
profile_picture_url: user.profile_picture_url || null,
|
|
60
|
-
email: user.email_address,
|
|
61
|
-
name: user.name || null,
|
|
62
|
-
days_since_created,
|
|
63
|
-
};
|
|
64
|
-
});
|
|
65
124
|
// Log successful retrieval
|
|
66
125
|
logger.info("hazo_get_user_profiles_success", {
|
|
67
126
|
filename: "user_profiles_service.ts",
|
|
68
|
-
line_number:
|
|
127
|
+
line_number: 170,
|
|
69
128
|
message: "Successfully retrieved user profiles",
|
|
70
129
|
requested_count: unique_user_ids.length,
|
|
71
|
-
found_count:
|
|
72
|
-
not_found_count:
|
|
130
|
+
found_count: all_profiles.length,
|
|
131
|
+
not_found_count: all_not_found_ids.length,
|
|
132
|
+
cache_hits,
|
|
133
|
+
cache_misses,
|
|
134
|
+
cache_enabled: config.cache_enabled,
|
|
73
135
|
});
|
|
74
136
|
return {
|
|
75
137
|
success: true,
|
|
76
|
-
profiles,
|
|
77
|
-
not_found_ids,
|
|
138
|
+
profiles: all_profiles,
|
|
139
|
+
not_found_ids: all_not_found_ids,
|
|
140
|
+
cache_stats: {
|
|
141
|
+
hits: cache_hits,
|
|
142
|
+
misses: cache_misses,
|
|
143
|
+
cache_enabled: config.cache_enabled,
|
|
144
|
+
},
|
|
78
145
|
};
|
|
79
146
|
}
|
|
80
147
|
catch (error) {
|
|
@@ -84,7 +151,7 @@ export async function hazo_get_user_profiles(adapter, user_ids) {
|
|
|
84
151
|
logger,
|
|
85
152
|
context: {
|
|
86
153
|
filename: "user_profiles_service.ts",
|
|
87
|
-
line_number:
|
|
154
|
+
line_number: 195,
|
|
88
155
|
operation: "hazo_get_user_profiles",
|
|
89
156
|
user_ids_count: (user_ids === null || user_ids === void 0 ? void 0 : user_ids.length) || 0,
|
|
90
157
|
},
|
|
@@ -97,3 +164,28 @@ export async function hazo_get_user_profiles(adapter, user_ids) {
|
|
|
97
164
|
};
|
|
98
165
|
}
|
|
99
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* Invalidates cache for specific user IDs
|
|
169
|
+
* Call this after user profile updates to ensure fresh data on next fetch
|
|
170
|
+
* @param user_ids - Array of user IDs to invalidate from cache
|
|
171
|
+
*/
|
|
172
|
+
export function invalidate_user_profiles_cache(user_ids) {
|
|
173
|
+
const config = get_user_profiles_cache_config();
|
|
174
|
+
if (!config.cache_enabled) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const cache = get_user_profiles_cache(config.cache_max_entries, config.cache_ttl_minutes);
|
|
178
|
+
cache.invalidate_users(user_ids);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Invalidates the entire user profiles cache
|
|
182
|
+
* Use sparingly - prefer invalidating specific users when possible
|
|
183
|
+
*/
|
|
184
|
+
export function invalidate_all_user_profiles_cache() {
|
|
185
|
+
const config = get_user_profiles_cache_config();
|
|
186
|
+
if (!config.cache_enabled) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const cache = get_user_profiles_cache(config.cache_max_entries, config.cache_ttl_minutes);
|
|
190
|
+
cache.invalidate_all();
|
|
191
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* User profiles cache configuration options
|
|
3
|
+
*/
|
|
4
|
+
export type UserProfilesCacheConfig = {
|
|
5
|
+
cache_enabled: boolean;
|
|
6
|
+
cache_max_entries: number;
|
|
7
|
+
cache_ttl_minutes: number;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Reads user profiles cache configuration from hazo_auth_config.ini file
|
|
11
|
+
* Falls back to defaults if hazo_auth_config.ini is not found or section is missing
|
|
12
|
+
* @returns User profiles cache configuration options
|
|
13
|
+
*/
|
|
14
|
+
export declare function get_user_profiles_cache_config(): UserProfilesCacheConfig;
|
|
15
|
+
//# sourceMappingURL=user_profiles_config.server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user_profiles_config.server.d.ts","sourceRoot":"","sources":["../../src/lib/user_profiles_config.server.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,aAAa,EAAE,OAAO,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC;AAIF;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,uBAAuB,CA6BxE"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// file_description: server-only helper to read user profiles cache configuration from hazo_auth_config.ini
|
|
2
|
+
// section: imports
|
|
3
|
+
import { get_config_number, } from "./config/config_loader.server";
|
|
4
|
+
// section: helpers
|
|
5
|
+
/**
|
|
6
|
+
* Reads user profiles cache configuration from hazo_auth_config.ini file
|
|
7
|
+
* Falls back to defaults if hazo_auth_config.ini is not found or section is missing
|
|
8
|
+
* @returns User profiles cache configuration options
|
|
9
|
+
*/
|
|
10
|
+
export function get_user_profiles_cache_config() {
|
|
11
|
+
const section_name = "hazo_auth__user_profiles";
|
|
12
|
+
// Cache settings
|
|
13
|
+
// cache_enabled: 0 = disabled, 1 = enabled (default: 1)
|
|
14
|
+
const cache_enabled_num = get_config_number(section_name, "cache_enabled", 1);
|
|
15
|
+
const cache_enabled = cache_enabled_num === 1;
|
|
16
|
+
const cache_max_entries = get_config_number(section_name, "cache_max_entries", 5000);
|
|
17
|
+
const cache_ttl_minutes = get_config_number(section_name, "cache_ttl_minutes", 5);
|
|
18
|
+
return {
|
|
19
|
+
cache_enabled,
|
|
20
|
+
cache_max_entries,
|
|
21
|
+
cache_ttl_minutes,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type ForgotPasswordPageProps = {
|
|
2
|
+
alreadyLoggedInMessage?: string;
|
|
3
|
+
showLogoutButton?: boolean;
|
|
4
|
+
showReturnHomeButton?: boolean;
|
|
5
|
+
returnHomeButtonLabel?: string;
|
|
6
|
+
returnHomePath?: string;
|
|
7
|
+
imageSrc?: string;
|
|
8
|
+
imageAlt?: string;
|
|
9
|
+
imageBackgroundColor?: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Zero-config forgot password page component
|
|
13
|
+
* Uses sensible defaults and can be customized via props
|
|
14
|
+
* @param props - Optional configuration overrides
|
|
15
|
+
* @returns Forgot password page component
|
|
16
|
+
*/
|
|
17
|
+
export declare function ForgotPasswordPage({ alreadyLoggedInMessage, showLogoutButton, showReturnHomeButton, returnHomeButtonLabel, returnHomePath, imageSrc, imageAlt, imageBackgroundColor, }?: ForgotPasswordPageProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export default ForgotPasswordPage;
|
|
19
|
+
//# sourceMappingURL=forgot_password.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forgot_password.d.ts","sourceRoot":"","sources":["../../src/page_components/forgot_password.tsx"],"names":[],"mappings":"AAiBA,MAAM,MAAM,uBAAuB,GAAG;IACpC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,sBAAoD,EACpD,gBAAuB,EACvB,oBAA4B,EAC5B,qBAAqC,EACrC,cAAoB,EACpB,QAA4B,EAC5B,QAA4B,EAC5B,oBAAuC,GACxC,GAAE,uBAA4B,2CAmC9B;AAED,eAAe,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// file_description: zero-config forgot password page component for hazo_auth
|
|
2
|
+
// Consumers can use this directly without needing to configure props
|
|
3
|
+
"use client";
|
|
4
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
+
// section: imports
|
|
6
|
+
import { useEffect, useState } from "react";
|
|
7
|
+
import forgot_password_layout from "../components/layouts/forgot_password";
|
|
8
|
+
import { createLayoutDataClient } from "../components/layouts/shared/data/layout_data_client";
|
|
9
|
+
import { create_sqlite_hazo_connect } from "../lib/hazo_connect_setup";
|
|
10
|
+
// section: constants
|
|
11
|
+
const DEFAULT_IMAGE_SRC = "/globe.svg";
|
|
12
|
+
const DEFAULT_IMAGE_ALT = "Illustration of a globe representing secure authentication workflows";
|
|
13
|
+
const DEFAULT_IMAGE_BG = "#e2e8f0";
|
|
14
|
+
// section: component
|
|
15
|
+
/**
|
|
16
|
+
* Zero-config forgot password page component
|
|
17
|
+
* Uses sensible defaults and can be customized via props
|
|
18
|
+
* @param props - Optional configuration overrides
|
|
19
|
+
* @returns Forgot password page component
|
|
20
|
+
*/
|
|
21
|
+
export function ForgotPasswordPage({ alreadyLoggedInMessage = "You are already logged in", showLogoutButton = true, showReturnHomeButton = false, returnHomeButtonLabel = "Return home", returnHomePath = "/", imageSrc = DEFAULT_IMAGE_SRC, imageAlt = DEFAULT_IMAGE_ALT, imageBackgroundColor = DEFAULT_IMAGE_BG, } = {}) {
|
|
22
|
+
const [dataClient, setDataClient] = useState(null);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
// Initialize hazo_connect on client side
|
|
25
|
+
const hazoConnect = create_sqlite_hazo_connect();
|
|
26
|
+
const client = createLayoutDataClient(hazoConnect);
|
|
27
|
+
setDataClient(client);
|
|
28
|
+
}, []);
|
|
29
|
+
// Show loading state while initializing
|
|
30
|
+
if (!dataClient) {
|
|
31
|
+
return (_jsx("div", { className: "cls_forgot_password_page_loading flex items-center justify-center min-h-screen", children: _jsx("div", { className: "text-slate-600 animate-pulse", children: "Loading..." }) }));
|
|
32
|
+
}
|
|
33
|
+
const ForgotPasswordLayout = forgot_password_layout;
|
|
34
|
+
return (_jsx(ForgotPasswordLayout, { image_src: imageSrc, image_alt: imageAlt, image_background_color: imageBackgroundColor, data_client: dataClient, alreadyLoggedInMessage: alreadyLoggedInMessage, showLogoutButton: showLogoutButton, showReturnHomeButton: showReturnHomeButton, returnHomeButtonLabel: returnHomeButtonLabel, returnHomePath: returnHomePath }));
|
|
35
|
+
}
|
|
36
|
+
export default ForgotPasswordPage;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { LoginPage, type LoginPageProps } from "./login.js";
|
|
2
|
+
export { RegisterPage, type RegisterPageProps } from "./register.js";
|
|
3
|
+
export { ForgotPasswordPage, type ForgotPasswordPageProps } from "./forgot_password.js";
|
|
4
|
+
export { ResetPasswordPage, type ResetPasswordPageProps } from "./reset_password.js";
|
|
5
|
+
export { VerifyEmailPage, type VerifyEmailPageProps } from "./verify_email.js";
|
|
6
|
+
export { MySettingsPage, type MySettingsPageProps } from "./my_settings.js";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/page_components/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,KAAK,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,KAAK,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// file_description: barrel export for zero-config page components
|
|
2
|
+
// These components can be used directly by consumers with sensible defaults
|
|
3
|
+
// section: page_exports
|
|
4
|
+
export { LoginPage } from "./login.js";
|
|
5
|
+
export { RegisterPage } from "./register.js";
|
|
6
|
+
export { ForgotPasswordPage } from "./forgot_password.js";
|
|
7
|
+
export { ResetPasswordPage } from "./reset_password.js";
|
|
8
|
+
export { VerifyEmailPage } from "./verify_email.js";
|
|
9
|
+
export { MySettingsPage } from "./my_settings.js";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type LoginPageProps = {
|
|
2
|
+
redirectRoute?: string;
|
|
3
|
+
successMessage?: string;
|
|
4
|
+
alreadyLoggedInMessage?: string;
|
|
5
|
+
showLogoutButton?: boolean;
|
|
6
|
+
showReturnHomeButton?: boolean;
|
|
7
|
+
returnHomeButtonLabel?: string;
|
|
8
|
+
returnHomePath?: string;
|
|
9
|
+
forgotPasswordPath?: string;
|
|
10
|
+
forgotPasswordLabel?: string;
|
|
11
|
+
createAccountPath?: string;
|
|
12
|
+
createAccountLabel?: string;
|
|
13
|
+
urlOnLogon?: string;
|
|
14
|
+
imageSrc?: string;
|
|
15
|
+
imageAlt?: string;
|
|
16
|
+
imageBackgroundColor?: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Zero-config login page component
|
|
20
|
+
* Uses sensible defaults and can be customized via props
|
|
21
|
+
* @param props - Optional configuration overrides
|
|
22
|
+
* @returns Login page component
|
|
23
|
+
*/
|
|
24
|
+
export declare function LoginPage({ redirectRoute, successMessage, alreadyLoggedInMessage, showLogoutButton, showReturnHomeButton, returnHomeButtonLabel, returnHomePath, forgotPasswordPath, forgotPasswordLabel, createAccountPath, createAccountLabel, urlOnLogon, imageSrc, imageAlt, imageBackgroundColor, }?: LoginPageProps): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
export default LoginPage;
|
|
26
|
+
//# sourceMappingURL=login.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/page_components/login.tsx"],"names":[],"mappings":"AAkBA,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,EACxB,aAAa,EACb,cAAyC,EACzC,sBAAoD,EACpD,gBAAuB,EACvB,oBAA4B,EAC5B,qBAAqC,EACrC,cAAoB,EACpB,kBAAiD,EACjD,mBAAwC,EACxC,iBAAyC,EACzC,kBAAqC,EACrC,UAAU,EACV,QAA4B,EAC5B,QAA4B,EAC5B,oBAAuC,GACxC,GAAE,cAAmB,2CA8CrB;AAED,eAAe,SAAS,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// file_description: zero-config login page component for hazo_auth
|
|
2
|
+
// Consumers can use this directly without needing to configure props
|
|
3
|
+
"use client";
|
|
4
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
+
// section: imports
|
|
6
|
+
import { useEffect, useState } from "react";
|
|
7
|
+
import login_layout from "../components/layouts/login";
|
|
8
|
+
import { createLayoutDataClient } from "../components/layouts/shared/data/layout_data_client";
|
|
9
|
+
import { create_sqlite_hazo_connect } from "../lib/hazo_connect_setup";
|
|
10
|
+
import { create_app_logger } from "../lib/app_logger";
|
|
11
|
+
// section: constants
|
|
12
|
+
const DEFAULT_IMAGE_SRC = "/globe.svg";
|
|
13
|
+
const DEFAULT_IMAGE_ALT = "Illustration of a globe representing secure authentication workflows";
|
|
14
|
+
const DEFAULT_IMAGE_BG = "#e2e8f0";
|
|
15
|
+
// section: component
|
|
16
|
+
/**
|
|
17
|
+
* Zero-config login page component
|
|
18
|
+
* Uses sensible defaults and can be customized via props
|
|
19
|
+
* @param props - Optional configuration overrides
|
|
20
|
+
* @returns Login page component
|
|
21
|
+
*/
|
|
22
|
+
export function LoginPage({ redirectRoute, successMessage = "Successfully logged in", alreadyLoggedInMessage = "You are already logged in", showLogoutButton = true, showReturnHomeButton = false, returnHomeButtonLabel = "Return home", returnHomePath = "/", forgotPasswordPath = "/hazo_auth/forgot_password", forgotPasswordLabel = "Forgot password?", createAccountPath = "/hazo_auth/register", createAccountLabel = "Create account", urlOnLogon, imageSrc = DEFAULT_IMAGE_SRC, imageAlt = DEFAULT_IMAGE_ALT, imageBackgroundColor = DEFAULT_IMAGE_BG, } = {}) {
|
|
23
|
+
const [dataClient, setDataClient] = useState(null);
|
|
24
|
+
const [logger, setLogger] = useState(null);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
// Initialize hazo_connect and logger on client side
|
|
27
|
+
const hazoConnect = create_sqlite_hazo_connect();
|
|
28
|
+
const client = createLayoutDataClient(hazoConnect);
|
|
29
|
+
const appLogger = create_app_logger();
|
|
30
|
+
setDataClient(client);
|
|
31
|
+
setLogger(appLogger);
|
|
32
|
+
}, []);
|
|
33
|
+
// Show loading state while initializing
|
|
34
|
+
if (!dataClient || !logger) {
|
|
35
|
+
return (_jsx("div", { className: "cls_login_page_loading flex items-center justify-center min-h-screen", children: _jsx("div", { className: "text-slate-600 animate-pulse", children: "Loading..." }) }));
|
|
36
|
+
}
|
|
37
|
+
const LoginLayout = login_layout;
|
|
38
|
+
return (_jsx(LoginLayout, { image_src: imageSrc, image_alt: imageAlt, image_background_color: imageBackgroundColor, data_client: dataClient, logger: logger, redirectRoute: redirectRoute, successMessage: successMessage, alreadyLoggedInMessage: alreadyLoggedInMessage, showLogoutButton: showLogoutButton, showReturnHomeButton: showReturnHomeButton, returnHomeButtonLabel: returnHomeButtonLabel, returnHomePath: returnHomePath, forgot_password_path: forgotPasswordPath, forgot_password_label: forgotPasswordLabel, create_account_path: createAccountPath, create_account_label: createAccountLabel, urlOnLogon: urlOnLogon }));
|
|
39
|
+
}
|
|
40
|
+
export default LoginPage;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { PasswordRequirementOptions } from "../components/layouts/shared/config/layout_customization";
|
|
2
|
+
declare const DEFAULT_MESSAGES: {
|
|
3
|
+
photo_upload_disabled_message: string;
|
|
4
|
+
gravatar_setup_message: string;
|
|
5
|
+
gravatar_no_account_message: string;
|
|
6
|
+
library_tooltip_message: string;
|
|
7
|
+
};
|
|
8
|
+
declare const DEFAULT_UI_SIZES: {
|
|
9
|
+
gravatar_size: number;
|
|
10
|
+
profile_picture_size: number;
|
|
11
|
+
tooltip_icon_size_default: number;
|
|
12
|
+
tooltip_icon_size_small: number;
|
|
13
|
+
library_photo_grid_columns: number;
|
|
14
|
+
library_photo_preview_size: number;
|
|
15
|
+
image_compression_max_dimension: number;
|
|
16
|
+
upload_file_hard_limit_bytes: number;
|
|
17
|
+
};
|
|
18
|
+
export type MySettingsPageProps = {
|
|
19
|
+
userFields?: {
|
|
20
|
+
show_name_field?: boolean;
|
|
21
|
+
show_email_field?: boolean;
|
|
22
|
+
show_password_field?: boolean;
|
|
23
|
+
};
|
|
24
|
+
passwordRequirements?: Partial<PasswordRequirementOptions>;
|
|
25
|
+
profilePicture?: {
|
|
26
|
+
allow_photo_upload?: boolean;
|
|
27
|
+
upload_photo_path?: string;
|
|
28
|
+
max_photo_size?: number;
|
|
29
|
+
user_photo_default?: boolean;
|
|
30
|
+
user_photo_default_priority1?: "gravatar" | "library";
|
|
31
|
+
user_photo_default_priority2?: "library" | "gravatar";
|
|
32
|
+
library_photo_path?: string;
|
|
33
|
+
};
|
|
34
|
+
heading?: string;
|
|
35
|
+
subHeading?: string;
|
|
36
|
+
profilePhotoLabel?: string;
|
|
37
|
+
profilePhotoRecommendation?: string;
|
|
38
|
+
uploadPhotoButtonLabel?: string;
|
|
39
|
+
removePhotoButtonLabel?: string;
|
|
40
|
+
profileInformationLabel?: string;
|
|
41
|
+
passwordLabel?: string;
|
|
42
|
+
currentPasswordLabel?: string;
|
|
43
|
+
newPasswordLabel?: string;
|
|
44
|
+
confirmPasswordLabel?: string;
|
|
45
|
+
savePasswordButtonLabel?: string;
|
|
46
|
+
unauthorizedMessage?: string;
|
|
47
|
+
loginButtonLabel?: string;
|
|
48
|
+
loginPath?: string;
|
|
49
|
+
messages?: Partial<typeof DEFAULT_MESSAGES>;
|
|
50
|
+
uiSizes?: Partial<typeof DEFAULT_UI_SIZES>;
|
|
51
|
+
fileTypes?: {
|
|
52
|
+
allowed_image_extensions?: string[];
|
|
53
|
+
allowed_image_mime_types?: string[];
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Zero-config my settings page component
|
|
58
|
+
* Uses sensible defaults and can be customized via props
|
|
59
|
+
* @param props - Optional configuration overrides
|
|
60
|
+
* @returns My settings page component
|
|
61
|
+
*/
|
|
62
|
+
export declare function MySettingsPage({ userFields, passwordRequirements, profilePicture, heading, subHeading, profilePhotoLabel, profilePhotoRecommendation, uploadPhotoButtonLabel, removePhotoButtonLabel, profileInformationLabel, passwordLabel, currentPasswordLabel, newPasswordLabel, confirmPasswordLabel, savePasswordButtonLabel, unauthorizedMessage, loginButtonLabel, loginPath, messages, uiSizes, fileTypes, }?: MySettingsPageProps): import("react/jsx-runtime").JSX.Element;
|
|
63
|
+
export default MySettingsPage;
|
|
64
|
+
//# sourceMappingURL=my_settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"my_settings.d.ts","sourceRoot":"","sources":["../../src/page_components/my_settings.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0DAA0D,CAAC;AA2B3G,QAAA,MAAM,gBAAgB;;;;;CAKrB,CAAC;AAEF,QAAA,MAAM,gBAAgB;;;;;;;;;CASrB,CAAC;AAQF,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,CAAC,EAAE;QACX,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,mBAAmB,CAAC,EAAE,OAAO,CAAC;KAC/B,CAAC;IACF,oBAAoB,CAAC,EAAE,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAC3D,cAAc,CAAC,EAAE;QACf,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,4BAA4B,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;QACtD,4BAA4B,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;QACtD,kBAAkB,CAAC,EAAE,MAAM,CAAC;KAC7B,CAAC;IACF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC,OAAO,gBAAgB,CAAC,CAAC;IAC5C,OAAO,CAAC,EAAE,OAAO,CAAC,OAAO,gBAAgB,CAAC,CAAC;IAC3C,SAAS,CAAC,EAAE;QACV,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAC;QACpC,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAC;KACrC,CAAC;CACH,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,oBAAoB,EACpB,cAAc,EACd,OAA4B,EAC5B,UAAoE,EACpE,iBAAmC,EACnC,0BAAiF,EACjF,sBAAuC,EACvC,sBAAiC,EACjC,uBAA+C,EAC/C,aAA0B,EAC1B,oBAAyC,EACzC,gBAAiC,EACjC,oBAAyC,EACzC,uBAA2C,EAC3C,mBAAkE,EAClE,gBAAgC,EAChC,SAA8B,EAC9B,QAAQ,EACR,OAAO,EACP,SAAS,GACV,GAAE,mBAAwB,2CA0D1B;AAED,eAAe,cAAc,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// file_description: zero-config my settings page component for hazo_auth
|
|
2
|
+
// Consumers can use this directly without needing to configure props
|
|
3
|
+
"use client";
|
|
4
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
+
// section: imports
|
|
6
|
+
import my_settings_layout from "../components/layouts/my_settings";
|
|
7
|
+
// section: default_configuration
|
|
8
|
+
const DEFAULT_USER_FIELDS = {
|
|
9
|
+
show_name_field: true,
|
|
10
|
+
show_email_field: true,
|
|
11
|
+
show_password_field: true,
|
|
12
|
+
};
|
|
13
|
+
const DEFAULT_PASSWORD_REQUIREMENTS = {
|
|
14
|
+
minimum_length: 8,
|
|
15
|
+
require_uppercase: true,
|
|
16
|
+
require_lowercase: true,
|
|
17
|
+
require_number: true,
|
|
18
|
+
require_special: false,
|
|
19
|
+
};
|
|
20
|
+
const DEFAULT_PROFILE_PICTURE = {
|
|
21
|
+
allow_photo_upload: true,
|
|
22
|
+
upload_photo_path: "/api/hazo_auth/upload_profile_picture",
|
|
23
|
+
max_photo_size: 5242880, // 5MB
|
|
24
|
+
user_photo_default: true,
|
|
25
|
+
user_photo_default_priority1: "gravatar",
|
|
26
|
+
user_photo_default_priority2: "library",
|
|
27
|
+
library_photo_path: "/profile_pictures/library",
|
|
28
|
+
};
|
|
29
|
+
const DEFAULT_MESSAGES = {
|
|
30
|
+
photo_upload_disabled_message: "Photo upload is currently disabled. Contact your administrator.",
|
|
31
|
+
gravatar_setup_message: "To use Gravatar, create a free account at gravatar.com with the same email address you use here.",
|
|
32
|
+
gravatar_no_account_message: "No Gravatar account found for your email. Using library photo instead.",
|
|
33
|
+
library_tooltip_message: "Choose from our library of profile pictures",
|
|
34
|
+
};
|
|
35
|
+
const DEFAULT_UI_SIZES = {
|
|
36
|
+
gravatar_size: 200,
|
|
37
|
+
profile_picture_size: 128,
|
|
38
|
+
tooltip_icon_size_default: 16,
|
|
39
|
+
tooltip_icon_size_small: 14,
|
|
40
|
+
library_photo_grid_columns: 4,
|
|
41
|
+
library_photo_preview_size: 80,
|
|
42
|
+
image_compression_max_dimension: 800,
|
|
43
|
+
upload_file_hard_limit_bytes: 10485760, // 10MB
|
|
44
|
+
};
|
|
45
|
+
const DEFAULT_FILE_TYPES = {
|
|
46
|
+
allowed_image_extensions: [".jpg", ".jpeg", ".png", ".gif", ".webp"],
|
|
47
|
+
allowed_image_mime_types: ["image/jpeg", "image/png", "image/gif", "image/webp"],
|
|
48
|
+
};
|
|
49
|
+
// section: component
|
|
50
|
+
/**
|
|
51
|
+
* Zero-config my settings page component
|
|
52
|
+
* Uses sensible defaults and can be customized via props
|
|
53
|
+
* @param props - Optional configuration overrides
|
|
54
|
+
* @returns My settings page component
|
|
55
|
+
*/
|
|
56
|
+
export function MySettingsPage({ userFields, passwordRequirements, profilePicture, heading = "Account Settings", subHeading = "Manage your profile, password, and email preferences.", profilePhotoLabel = "Profile Photo", profilePhotoRecommendation = "Recommended: Square image, at least 200x200 pixels", uploadPhotoButtonLabel = "Upload Photo", removePhotoButtonLabel = "Remove", profileInformationLabel = "Profile Information", passwordLabel = "Password", currentPasswordLabel = "Current Password", newPasswordLabel = "New Password", confirmPasswordLabel = "Confirm Password", savePasswordButtonLabel = "Update Password", unauthorizedMessage = "You must be logged in to access this page.", loginButtonLabel = "Go to login", loginPath = "/hazo_auth/login", messages, uiSizes, fileTypes, } = {}) {
|
|
57
|
+
// Merge provided props with defaults
|
|
58
|
+
const mergedUserFields = Object.assign(Object.assign({}, DEFAULT_USER_FIELDS), userFields);
|
|
59
|
+
const mergedPasswordRequirements = Object.assign(Object.assign({}, DEFAULT_PASSWORD_REQUIREMENTS), passwordRequirements);
|
|
60
|
+
const mergedProfilePicture = Object.assign(Object.assign({}, DEFAULT_PROFILE_PICTURE), profilePicture);
|
|
61
|
+
const mergedMessages = Object.assign(Object.assign({}, DEFAULT_MESSAGES), messages);
|
|
62
|
+
const mergedUiSizes = Object.assign(Object.assign({}, DEFAULT_UI_SIZES), uiSizes);
|
|
63
|
+
const mergedFileTypes = Object.assign(Object.assign({}, DEFAULT_FILE_TYPES), fileTypes);
|
|
64
|
+
const MySettingsLayout = my_settings_layout;
|
|
65
|
+
return (_jsx(MySettingsLayout, { userFields: mergedUserFields, password_requirements: mergedPasswordRequirements, profilePicture: mergedProfilePicture, heading: heading, subHeading: subHeading, profilePhotoLabel: profilePhotoLabel, profilePhotoRecommendation: profilePhotoRecommendation, uploadPhotoButtonLabel: uploadPhotoButtonLabel, removePhotoButtonLabel: removePhotoButtonLabel, profileInformationLabel: profileInformationLabel, passwordLabel: passwordLabel, currentPasswordLabel: currentPasswordLabel, newPasswordLabel: newPasswordLabel, confirmPasswordLabel: confirmPasswordLabel, unauthorizedMessage: unauthorizedMessage, loginButtonLabel: loginButtonLabel, loginPath: loginPath, messages: mergedMessages, uiSizes: mergedUiSizes, fileTypes: mergedFileTypes }));
|
|
66
|
+
}
|
|
67
|
+
export default MySettingsPage;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { PasswordRequirementOverrides } from "../components/layouts/shared/config/layout_customization";
|
|
2
|
+
export type RegisterPageProps = {
|
|
3
|
+
showNameField?: boolean;
|
|
4
|
+
passwordRequirements?: PasswordRequirementOverrides;
|
|
5
|
+
alreadyLoggedInMessage?: string;
|
|
6
|
+
showLogoutButton?: boolean;
|
|
7
|
+
showReturnHomeButton?: boolean;
|
|
8
|
+
returnHomeButtonLabel?: string;
|
|
9
|
+
returnHomePath?: string;
|
|
10
|
+
signInPath?: string;
|
|
11
|
+
signInLabel?: string;
|
|
12
|
+
urlOnLogon?: string;
|
|
13
|
+
imageSrc?: string;
|
|
14
|
+
imageAlt?: string;
|
|
15
|
+
imageBackgroundColor?: string;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Zero-config register page component
|
|
19
|
+
* Uses sensible defaults and can be customized via props
|
|
20
|
+
* @param props - Optional configuration overrides
|
|
21
|
+
* @returns Register page component
|
|
22
|
+
*/
|
|
23
|
+
export declare function RegisterPage({ showNameField, passwordRequirements, alreadyLoggedInMessage, showLogoutButton, showReturnHomeButton, returnHomeButtonLabel, returnHomePath, signInPath, signInLabel, urlOnLogon, imageSrc, imageAlt, imageBackgroundColor, }?: RegisterPageProps): import("react/jsx-runtime").JSX.Element;
|
|
24
|
+
export default RegisterPage;
|
|
25
|
+
//# sourceMappingURL=register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../src/page_components/register.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,0DAA0D,CAAC;AAgB7G,MAAM,MAAM,iBAAiB,GAAG;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,oBAAoB,CAAC,EAAE,4BAA4B,CAAC;IACpD,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAC3B,aAAoB,EACpB,oBAAoD,EACpD,sBAAoD,EACpD,gBAAuB,EACvB,oBAA4B,EAC5B,qBAAqC,EACrC,cAAoB,EACpB,UAA+B,EAC/B,WAAuB,EACvB,UAAU,EACV,QAA4B,EAC5B,QAA4B,EAC5B,oBAAuC,GACxC,GAAE,iBAAsB,2CAwCxB;AAED,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// file_description: zero-config register page component for hazo_auth
|
|
2
|
+
// Consumers can use this directly without needing to configure props
|
|
3
|
+
"use client";
|
|
4
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
5
|
+
// section: imports
|
|
6
|
+
import { useEffect, useState } from "react";
|
|
7
|
+
import register_layout from "../components/layouts/register";
|
|
8
|
+
import { createLayoutDataClient } from "../components/layouts/shared/data/layout_data_client";
|
|
9
|
+
import { create_sqlite_hazo_connect } from "../lib/hazo_connect_setup";
|
|
10
|
+
// section: constants
|
|
11
|
+
const DEFAULT_IMAGE_SRC = "/globe.svg";
|
|
12
|
+
const DEFAULT_IMAGE_ALT = "Illustration of a globe representing secure authentication workflows";
|
|
13
|
+
const DEFAULT_IMAGE_BG = "#e2e8f0";
|
|
14
|
+
const DEFAULT_PASSWORD_REQUIREMENTS = {
|
|
15
|
+
minimum_length: 8,
|
|
16
|
+
require_uppercase: true,
|
|
17
|
+
require_lowercase: true,
|
|
18
|
+
require_number: true,
|
|
19
|
+
require_special: false,
|
|
20
|
+
};
|
|
21
|
+
// section: component
|
|
22
|
+
/**
|
|
23
|
+
* Zero-config register page component
|
|
24
|
+
* Uses sensible defaults and can be customized via props
|
|
25
|
+
* @param props - Optional configuration overrides
|
|
26
|
+
* @returns Register page component
|
|
27
|
+
*/
|
|
28
|
+
export function RegisterPage({ showNameField = true, passwordRequirements = DEFAULT_PASSWORD_REQUIREMENTS, alreadyLoggedInMessage = "You are already logged in", showLogoutButton = true, showReturnHomeButton = false, returnHomeButtonLabel = "Return home", returnHomePath = "/", signInPath = "/hazo_auth/login", signInLabel = "Sign in", urlOnLogon, imageSrc = DEFAULT_IMAGE_SRC, imageAlt = DEFAULT_IMAGE_ALT, imageBackgroundColor = DEFAULT_IMAGE_BG, } = {}) {
|
|
29
|
+
const [dataClient, setDataClient] = useState(null);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
// Initialize hazo_connect on client side
|
|
32
|
+
const hazoConnect = create_sqlite_hazo_connect();
|
|
33
|
+
const client = createLayoutDataClient(hazoConnect);
|
|
34
|
+
setDataClient(client);
|
|
35
|
+
}, []);
|
|
36
|
+
// Show loading state while initializing
|
|
37
|
+
if (!dataClient) {
|
|
38
|
+
return (_jsx("div", { className: "cls_register_page_loading flex items-center justify-center min-h-screen", children: _jsx("div", { className: "text-slate-600 animate-pulse", children: "Loading..." }) }));
|
|
39
|
+
}
|
|
40
|
+
const RegisterLayout = register_layout;
|
|
41
|
+
return (_jsx(RegisterLayout, { image_src: imageSrc, image_alt: imageAlt, image_background_color: imageBackgroundColor, password_requirements: passwordRequirements, show_name_field: showNameField, data_client: dataClient, alreadyLoggedInMessage: alreadyLoggedInMessage, showLogoutButton: showLogoutButton, showReturnHomeButton: showReturnHomeButton, returnHomeButtonLabel: returnHomeButtonLabel, returnHomePath: returnHomePath, signInPath: signInPath, signInLabel: signInLabel, urlOnLogon: urlOnLogon }));
|
|
42
|
+
}
|
|
43
|
+
export default RegisterPage;
|