hazo_auth 4.1.0 → 4.3.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.
Files changed (157) hide show
  1. package/README.md +230 -0
  2. package/SETUP_CHECKLIST.md +202 -0
  3. package/bin/hazo_auth.mjs +35 -0
  4. package/cli-src/assets/images/forgot_password_default.jpg +0 -0
  5. package/cli-src/assets/images/login_default.jpg +0 -0
  6. package/cli-src/assets/images/register_default.jpg +0 -0
  7. package/cli-src/assets/images/reset_password_default.jpg +0 -0
  8. package/cli-src/assets/images/verify_email_default.jpg +0 -0
  9. package/cli-src/cli/generate.ts +276 -0
  10. package/cli-src/cli/index.ts +207 -0
  11. package/cli-src/cli/init.ts +254 -0
  12. package/cli-src/cli/init_users.ts +376 -0
  13. package/cli-src/cli/validate.ts +581 -0
  14. package/cli-src/lib/already_logged_in_config.server.ts +46 -0
  15. package/cli-src/lib/app_logger.ts +24 -0
  16. package/cli-src/lib/auth/auth_cache.ts +220 -0
  17. package/cli-src/lib/auth/auth_rate_limiter.ts +121 -0
  18. package/cli-src/lib/auth/auth_types.ts +110 -0
  19. package/cli-src/lib/auth/auth_utils.server.ts +196 -0
  20. package/cli-src/lib/auth/hazo_get_auth.server.ts +512 -0
  21. package/cli-src/lib/auth/index.ts +23 -0
  22. package/cli-src/lib/auth/nextauth_config.ts +227 -0
  23. package/cli-src/lib/auth/scope_cache.ts +233 -0
  24. package/cli-src/lib/auth/server_auth.ts +88 -0
  25. package/cli-src/lib/auth/session_token_validator.edge.ts +91 -0
  26. package/cli-src/lib/auth_utility_config.server.ts +136 -0
  27. package/cli-src/lib/config/config_loader.server.ts +164 -0
  28. package/cli-src/lib/config/default_config.ts +199 -0
  29. package/cli-src/lib/email_verification_config.server.ts +63 -0
  30. package/cli-src/lib/file_types_config.server.ts +25 -0
  31. package/cli-src/lib/forgot_password_config.server.ts +63 -0
  32. package/cli-src/lib/hazo_connect_instance.server.ts +101 -0
  33. package/cli-src/lib/hazo_connect_setup.server.ts +194 -0
  34. package/cli-src/lib/hazo_connect_setup.ts +54 -0
  35. package/cli-src/lib/index.ts +46 -0
  36. package/cli-src/lib/login_config.server.ts +106 -0
  37. package/cli-src/lib/messages_config.server.ts +45 -0
  38. package/cli-src/lib/migrations/apply_migration.ts +105 -0
  39. package/cli-src/lib/my_settings_config.server.ts +135 -0
  40. package/cli-src/lib/oauth_config.server.ts +87 -0
  41. package/cli-src/lib/password_requirements_config.server.ts +40 -0
  42. package/cli-src/lib/profile_pic_menu_config.server.ts +138 -0
  43. package/cli-src/lib/profile_picture_config.server.ts +56 -0
  44. package/cli-src/lib/register_config.server.ts +101 -0
  45. package/cli-src/lib/reset_password_config.server.ts +103 -0
  46. package/cli-src/lib/scope_hierarchy_config.server.ts +151 -0
  47. package/cli-src/lib/services/email_service.ts +587 -0
  48. package/cli-src/lib/services/email_verification_service.ts +270 -0
  49. package/cli-src/lib/services/index.ts +16 -0
  50. package/cli-src/lib/services/login_service.ts +150 -0
  51. package/cli-src/lib/services/oauth_service.ts +494 -0
  52. package/cli-src/lib/services/password_change_service.ts +154 -0
  53. package/cli-src/lib/services/password_reset_service.ts +418 -0
  54. package/cli-src/lib/services/profile_picture_remove_service.ts +120 -0
  55. package/cli-src/lib/services/profile_picture_service.ts +451 -0
  56. package/cli-src/lib/services/profile_picture_source_mapper.ts +62 -0
  57. package/cli-src/lib/services/registration_service.ts +185 -0
  58. package/cli-src/lib/services/scope_labels_service.ts +348 -0
  59. package/cli-src/lib/services/scope_service.ts +778 -0
  60. package/cli-src/lib/services/session_token_service.ts +177 -0
  61. package/cli-src/lib/services/token_service.ts +240 -0
  62. package/cli-src/lib/services/user_profiles_cache.ts +189 -0
  63. package/cli-src/lib/services/user_profiles_service.ts +264 -0
  64. package/cli-src/lib/services/user_scope_service.ts +554 -0
  65. package/cli-src/lib/services/user_update_service.ts +141 -0
  66. package/cli-src/lib/ui_shell_config.server.ts +73 -0
  67. package/cli-src/lib/ui_sizes_config.server.ts +37 -0
  68. package/cli-src/lib/user_fields_config.server.ts +31 -0
  69. package/cli-src/lib/user_management_config.server.ts +39 -0
  70. package/cli-src/lib/user_profiles_config.server.ts +55 -0
  71. package/cli-src/lib/utils/api_route_helpers.ts +60 -0
  72. package/cli-src/lib/utils/error_sanitizer.ts +75 -0
  73. package/cli-src/lib/utils/password_validator.ts +65 -0
  74. package/cli-src/lib/utils.ts +11 -0
  75. package/cli-src/server/logging/logger_service.ts +56 -0
  76. package/dist/app/api/hazo_auth/forgot_password/route.d.ts.map +1 -1
  77. package/dist/app/api/hazo_auth/forgot_password/route.js +15 -0
  78. package/dist/app/api/hazo_auth/logout/route.d.ts.map +1 -1
  79. package/dist/app/api/hazo_auth/logout/route.js +31 -0
  80. package/dist/app/api/hazo_auth/me/route.d.ts.map +1 -1
  81. package/dist/app/api/hazo_auth/me/route.js +10 -0
  82. package/dist/cli/index.js +18 -0
  83. package/dist/cli/init_users.d.ts +17 -0
  84. package/dist/cli/init_users.d.ts.map +1 -0
  85. package/dist/cli/init_users.js +307 -0
  86. package/dist/components/layouts/forgot_password/hooks/use_forgot_password_form.d.ts +2 -0
  87. package/dist/components/layouts/forgot_password/hooks/use_forgot_password_form.d.ts.map +1 -1
  88. package/dist/components/layouts/forgot_password/hooks/use_forgot_password_form.js +8 -0
  89. package/dist/components/layouts/forgot_password/index.d.ts +7 -1
  90. package/dist/components/layouts/forgot_password/index.d.ts.map +1 -1
  91. package/dist/components/layouts/forgot_password/index.js +7 -2
  92. package/dist/components/layouts/login/index.d.ts +13 -1
  93. package/dist/components/layouts/login/index.d.ts.map +1 -1
  94. package/dist/components/layouts/login/index.js +11 -2
  95. package/dist/components/layouts/my_settings/components/connected_accounts_section.d.ts +17 -0
  96. package/dist/components/layouts/my_settings/components/connected_accounts_section.d.ts.map +1 -0
  97. package/dist/components/layouts/my_settings/components/connected_accounts_section.js +17 -0
  98. package/dist/components/layouts/my_settings/components/set_password_section.d.ts +26 -0
  99. package/dist/components/layouts/my_settings/components/set_password_section.d.ts.map +1 -0
  100. package/dist/components/layouts/my_settings/components/set_password_section.js +127 -0
  101. package/dist/components/layouts/my_settings/hooks/use_my_settings.d.ts +3 -0
  102. package/dist/components/layouts/my_settings/hooks/use_my_settings.d.ts.map +1 -1
  103. package/dist/components/layouts/my_settings/hooks/use_my_settings.js +9 -0
  104. package/dist/components/layouts/my_settings/index.d.ts.map +1 -1
  105. package/dist/components/layouts/my_settings/index.js +4 -2
  106. package/dist/components/layouts/shared/components/google_icon.d.ts +12 -0
  107. package/dist/components/layouts/shared/components/google_icon.d.ts.map +1 -0
  108. package/dist/components/layouts/shared/components/google_icon.js +9 -0
  109. package/dist/components/layouts/shared/components/google_sign_in_button.d.ts +21 -0
  110. package/dist/components/layouts/shared/components/google_sign_in_button.d.ts.map +1 -0
  111. package/dist/components/layouts/shared/components/google_sign_in_button.js +50 -0
  112. package/dist/components/layouts/shared/components/oauth_divider.d.ts +13 -0
  113. package/dist/components/layouts/shared/components/oauth_divider.d.ts.map +1 -0
  114. package/dist/components/layouts/shared/components/oauth_divider.js +13 -0
  115. package/dist/components/layouts/shared/config/layout_customization.d.ts +2 -7
  116. package/dist/components/layouts/shared/config/layout_customization.d.ts.map +1 -1
  117. package/dist/components/layouts/shared/hooks/use_auth_status.d.ts +3 -0
  118. package/dist/components/layouts/shared/hooks/use_auth_status.d.ts.map +1 -1
  119. package/dist/components/layouts/shared/hooks/use_auth_status.js +4 -0
  120. package/dist/components/layouts/shared/index.d.ts +5 -0
  121. package/dist/components/layouts/shared/index.d.ts.map +1 -1
  122. package/dist/components/layouts/shared/index.js +3 -0
  123. package/dist/components/ui/button.d.ts +1 -1
  124. package/dist/lib/auth/nextauth_config.d.ts +34 -0
  125. package/dist/lib/auth/nextauth_config.d.ts.map +1 -0
  126. package/dist/lib/auth/nextauth_config.js +171 -0
  127. package/dist/lib/config/default_config.d.ts +24 -0
  128. package/dist/lib/config/default_config.d.ts.map +1 -1
  129. package/dist/lib/config/default_config.js +14 -0
  130. package/dist/lib/index.d.ts +2 -0
  131. package/dist/lib/index.d.ts.map +1 -1
  132. package/dist/lib/index.js +1 -0
  133. package/dist/lib/login_config.server.d.ts +3 -0
  134. package/dist/lib/login_config.server.d.ts.map +1 -1
  135. package/dist/lib/login_config.server.js +4 -0
  136. package/dist/lib/oauth_config.server.d.ts +29 -0
  137. package/dist/lib/oauth_config.server.d.ts.map +1 -0
  138. package/dist/lib/oauth_config.server.js +40 -0
  139. package/dist/lib/services/login_service.d.ts.map +1 -1
  140. package/dist/lib/services/login_service.js +16 -1
  141. package/dist/lib/services/oauth_service.d.ts +88 -0
  142. package/dist/lib/services/oauth_service.d.ts.map +1 -0
  143. package/dist/lib/services/oauth_service.js +376 -0
  144. package/dist/lib/services/password_reset_service.d.ts +2 -0
  145. package/dist/lib/services/password_reset_service.d.ts.map +1 -1
  146. package/dist/lib/services/password_reset_service.js +10 -0
  147. package/dist/lib/services/registration_service.d.ts.map +1 -1
  148. package/dist/lib/services/registration_service.js +1 -0
  149. package/dist/lib/utils/password_validator.d.ts +19 -0
  150. package/dist/lib/utils/password_validator.d.ts.map +1 -0
  151. package/dist/lib/utils/password_validator.js +36 -0
  152. package/dist/server_pages/login.d.ts.map +1 -1
  153. package/dist/server_pages/login.js +6 -1
  154. package/dist/server_pages/login_client_wrapper.d.ts +5 -2
  155. package/dist/server_pages/login_client_wrapper.d.ts.map +1 -1
  156. package/dist/server_pages/login_client_wrapper.js +2 -2
  157. package/package.json +6 -2
@@ -0,0 +1,127 @@
1
+ // file_description: Set password section for Google-only users to add email/password login
2
+ // section: client_directive
3
+ "use client";
4
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
+ // section: imports
6
+ import { useState, useCallback } from "react";
7
+ import { Button } from "../../../ui/button";
8
+ import { PasswordField } from "../../shared/components/password_field";
9
+ import { FormFieldWrapper } from "../../shared/components/form_field_wrapper";
10
+ import { toast } from "sonner";
11
+ import { useHazoAuthConfig } from "../../../../contexts/hazo_auth_provider";
12
+ // section: component
13
+ /**
14
+ * Set Password Section for My Settings
15
+ * Allows Google-only users to set a password for email/password login
16
+ * Only shown when user has no password set (Google-only account)
17
+ */
18
+ export function SetPasswordSection({ passwordRequirements, onPasswordSet, heading = "Set Password", description = "Add a password to your account to enable email/password login in addition to Google sign-in.", newPasswordLabel = "New Password", confirmPasswordLabel = "Confirm Password", submitButtonLabel = "Set Password", parentLoading = false, }) {
19
+ const { apiBasePath } = useHazoAuthConfig();
20
+ const [newPassword, setNewPassword] = useState("");
21
+ const [confirmPassword, setConfirmPassword] = useState("");
22
+ const [newPasswordVisible, setNewPasswordVisible] = useState(false);
23
+ const [confirmPasswordVisible, setConfirmPasswordVisible] = useState(false);
24
+ const [errors, setErrors] = useState({});
25
+ const [loading, setLoading] = useState(false);
26
+ /**
27
+ * Validates password against requirements
28
+ */
29
+ const validatePassword = useCallback((password) => {
30
+ if (!password || password.length < passwordRequirements.minimum_length) {
31
+ return `Password must be at least ${passwordRequirements.minimum_length} characters long`;
32
+ }
33
+ const missingRequirements = [];
34
+ if (passwordRequirements.require_uppercase && !/[A-Z]/.test(password)) {
35
+ missingRequirements.push("uppercase letter");
36
+ }
37
+ if (passwordRequirements.require_lowercase && !/[a-z]/.test(password)) {
38
+ missingRequirements.push("lowercase letter");
39
+ }
40
+ if (passwordRequirements.require_number && !/[0-9]/.test(password)) {
41
+ missingRequirements.push("number");
42
+ }
43
+ if (passwordRequirements.require_special &&
44
+ !/[^A-Za-z0-9]/.test(password)) {
45
+ missingRequirements.push("special character");
46
+ }
47
+ if (missingRequirements.length > 0) {
48
+ return `Password must contain at least one: ${missingRequirements.join(", ")}`;
49
+ }
50
+ return null;
51
+ }, [passwordRequirements]);
52
+ /**
53
+ * Validates the form before submission
54
+ */
55
+ const validateForm = useCallback(() => {
56
+ const newErrors = {};
57
+ const passwordError = validatePassword(newPassword);
58
+ if (passwordError) {
59
+ newErrors.newPassword = passwordError;
60
+ }
61
+ if (!confirmPassword) {
62
+ newErrors.confirmPassword = "Please confirm your new password";
63
+ }
64
+ else if (newPassword !== confirmPassword) {
65
+ newErrors.confirmPassword = "Passwords do not match";
66
+ }
67
+ setErrors(newErrors);
68
+ return Object.keys(newErrors).length === 0;
69
+ }, [newPassword, confirmPassword, validatePassword]);
70
+ /**
71
+ * Handles form submission
72
+ */
73
+ const handleSubmit = useCallback(async () => {
74
+ if (!validateForm()) {
75
+ return;
76
+ }
77
+ setLoading(true);
78
+ try {
79
+ const response = await fetch(`${apiBasePath}/set_password`, {
80
+ method: "POST",
81
+ headers: {
82
+ "Content-Type": "application/json",
83
+ },
84
+ credentials: "include",
85
+ body: JSON.stringify({
86
+ new_password: newPassword,
87
+ }),
88
+ });
89
+ const data = await response.json();
90
+ if (!response.ok || !data.success) {
91
+ const errorMessage = data.error || "Failed to set password";
92
+ toast.error(errorMessage);
93
+ return;
94
+ }
95
+ toast.success("Password set successfully! You can now sign in with your email and password.");
96
+ // Reset form
97
+ setNewPassword("");
98
+ setConfirmPassword("");
99
+ setErrors({});
100
+ // Notify parent
101
+ onPasswordSet === null || onPasswordSet === void 0 ? void 0 : onPasswordSet();
102
+ }
103
+ catch (error) {
104
+ const errorMessage = error instanceof Error ? error.message : "Failed to set password";
105
+ toast.error(errorMessage);
106
+ }
107
+ finally {
108
+ setLoading(false);
109
+ }
110
+ }, [validateForm, newPassword, apiBasePath, onPasswordSet]);
111
+ /**
112
+ * Handles new password field change
113
+ */
114
+ const handleNewPasswordChange = useCallback((value) => {
115
+ setNewPassword(value);
116
+ setErrors((prev) => (Object.assign(Object.assign({}, prev), { newPassword: undefined })));
117
+ }, []);
118
+ /**
119
+ * Handles confirm password field change
120
+ */
121
+ const handleConfirmPasswordChange = useCallback((value) => {
122
+ setConfirmPassword(value);
123
+ setErrors((prev) => (Object.assign(Object.assign({}, prev), { confirmPassword: undefined })));
124
+ }, []);
125
+ const isSubmitDisabled = loading || parentLoading || !newPassword || !confirmPassword;
126
+ return (_jsxs("div", { className: "cls_my_settings_set_password_section bg-white rounded-lg border border-[var(--hazo-border)] p-6", children: [_jsx("h2", { className: "cls_my_settings_section_heading text-lg font-semibold text-[var(--hazo-text-primary)] mb-2", children: heading }), _jsx("p", { className: "cls_set_password_description text-sm text-[var(--hazo-text-muted)] mb-4", children: description }), _jsxs("div", { className: "cls_set_password_fields flex flex-col gap-4", children: [_jsxs("div", { className: "cls_set_password_fields_row grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(FormFieldWrapper, { fieldId: "set-new-password", label: newPasswordLabel, input: _jsx(PasswordField, { inputId: "set-new-password", ariaLabel: newPasswordLabel, value: newPassword, placeholder: "Enter your new password", autoComplete: "new-password", isVisible: newPasswordVisible, onChange: handleNewPasswordChange, onToggleVisibility: () => setNewPasswordVisible(!newPasswordVisible), errorMessage: errors.newPassword }) }), _jsx(FormFieldWrapper, { fieldId: "set-confirm-password", label: confirmPasswordLabel, input: _jsx(PasswordField, { inputId: "set-confirm-password", ariaLabel: confirmPasswordLabel, value: confirmPassword, placeholder: "Confirm your new password", autoComplete: "new-password", isVisible: confirmPasswordVisible, onChange: handleConfirmPasswordChange, onToggleVisibility: () => setConfirmPasswordVisible(!confirmPasswordVisible), errorMessage: errors.confirmPassword }) })] }), _jsx("div", { className: "cls_set_password_actions flex justify-end", children: _jsx(Button, { type: "button", onClick: handleSubmit, disabled: isSubmitDisabled, className: "cls_set_password_submit_button", "aria-label": submitButtonLabel, children: loading ? "Setting password..." : submitButtonLabel }) })] })] }));
127
+ }
@@ -19,6 +19,9 @@ export type UseMySettingsResult = {
19
19
  profileSource?: "upload" | "library" | "gravatar" | "custom";
20
20
  lastLogon?: string;
21
21
  loading: boolean;
22
+ authProviders?: string;
23
+ hasPassword?: boolean;
24
+ googleConnected?: boolean;
22
25
  passwordFields?: PasswordFields;
23
26
  handlePasswordFieldChange: (field: "currentPassword" | "newPassword" | "confirmPassword", value: string) => void;
24
27
  togglePasswordVisibility: (field: "currentPassword" | "newPassword" | "confirmPassword") => void;
@@ -1 +1 @@
1
- {"version":3,"file":"use_my_settings.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/my_settings/hooks/use_my_settings.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0CAA0C,CAAC;AAI3F,MAAM,MAAM,cAAc,GAAG;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,EAAE,OAAO,CAAC;IAChC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,sBAAsB,EAAE,OAAO,CAAC;IAChC,MAAM,EAAE;QACN,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAChC,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAEhC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IAGjB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,yBAAyB,EAAE,CAAC,KAAK,EAAE,iBAAiB,GAAG,aAAa,GAAG,iBAAiB,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjH,wBAAwB,EAAE,CAAC,KAAK,EAAE,iBAAiB,GAAG,aAAa,GAAG,iBAAiB,KAAK,IAAI,CAAC;IACjG,kBAAkB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,sBAAsB,EAAE,OAAO,CAAC;IAGhC,wBAAwB,EAAE,OAAO,CAAC;IAClC,wBAAwB,EAAE,MAAM,IAAI,CAAC;IACrC,+BAA+B,EAAE,MAAM,IAAI,CAAC;IAC5C,wBAAwB,EAAE,CAAC,iBAAiB,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzH,0BAA0B,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAGhD,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAGlD,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,oBAAoB,EAAE,0BAA0B,CAAC;CAClD,CAAC;AA4BF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAC9B,oBAAoB,GACrB,EAAE,mBAAmB,GAAG,mBAAmB,CA2W3C"}
1
+ {"version":3,"file":"use_my_settings.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/my_settings/hooks/use_my_settings.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0CAA0C,CAAC;AAI3F,MAAM,MAAM,cAAc,GAAG;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,EAAE,OAAO,CAAC;IAChC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,sBAAsB,EAAE,OAAO,CAAC;IAChC,MAAM,EAAE;QACN,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAChC,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAEhC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IAGjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAG1B,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,yBAAyB,EAAE,CAAC,KAAK,EAAE,iBAAiB,GAAG,aAAa,GAAG,iBAAiB,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjH,wBAAwB,EAAE,CAAC,KAAK,EAAE,iBAAiB,GAAG,aAAa,GAAG,iBAAiB,KAAK,IAAI,CAAC;IACjG,kBAAkB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,sBAAsB,EAAE,OAAO,CAAC;IAGhC,wBAAwB,EAAE,OAAO,CAAC;IAClC,wBAAwB,EAAE,MAAM,IAAI,CAAC;IACrC,+BAA+B,EAAE,MAAM,IAAI,CAAC;IAC5C,wBAAwB,EAAE,CAAC,iBAAiB,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzH,0BAA0B,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAGhD,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAGlD,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,oBAAoB,EAAE,0BAA0B,CAAC;CAClD,CAAC;AA4BF;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,EAC9B,oBAAoB,GACrB,EAAE,mBAAmB,GAAG,mBAAmB,CAqX3C"}
@@ -56,6 +56,10 @@ export function use_my_settings({ passwordRequirements, }) {
56
56
  const profileSource = authStatus.profile_source;
57
57
  const lastLogon = authStatus.last_logon;
58
58
  const loading = authStatus.loading;
59
+ // OAuth-related data
60
+ const authProviders = authStatus.auth_providers;
61
+ const hasPassword = authStatus.has_password;
62
+ const googleConnected = authStatus.google_connected;
59
63
  /**
60
64
  * Refreshes user data by triggering auth status refresh
61
65
  */
@@ -339,6 +343,11 @@ export function use_my_settings({ passwordRequirements, }) {
339
343
  profileSource,
340
344
  lastLogon,
341
345
  loading,
346
+ // OAuth-related data
347
+ authProviders,
348
+ hasPassword,
349
+ googleConnected,
350
+ // Password fields
342
351
  passwordFields,
343
352
  handlePasswordFieldChange,
344
353
  togglePasswordVisibility,
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/my_settings/index.tsx"],"names":[],"mappings":"AAWA,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EACV,0BAA0B,EAC1B,sBAAsB,EACvB,MAAM,uCAAuC,CAAC;AAQ/C,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAClC,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC,qBAAqB,EAAE,0BAA0B,CAAC;IAClD,cAAc,EAAE;QACd,kBAAkB,EAAE,OAAO,CAAC;QAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,cAAc,EAAE,MAAM,CAAC;QACvB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,4BAA4B,EAAE,UAAU,GAAG,SAAS,CAAC;QACrD,4BAA4B,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;QACtD,kBAAkB,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF,UAAU,EAAE;QACV,eAAe,EAAE,OAAO,CAAC;QACzB,gBAAgB,EAAE,OAAO,CAAC;QAC1B,mBAAmB,EAAE,OAAO,CAAC;KAC9B,CAAC;IACF,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,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,QAAQ,EAAE;QACR,6BAA6B,EAAE,MAAM,CAAC;QACtC,sBAAsB,EAAE,MAAM,CAAC;QAC/B,2BAA2B,EAAE,MAAM,CAAC;QACpC,uBAAuB,EAAE,MAAM,CAAC;KACjC,CAAC;IACF,OAAO,EAAE;QACP,aAAa,EAAE,MAAM,CAAC;QACtB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,yBAAyB,EAAE,MAAM,CAAC;QAClC,uBAAuB,EAAE,MAAM,CAAC;QAChC,0BAA0B,EAAE,MAAM,CAAC;QACnC,0BAA0B,EAAE,MAAM,CAAC;QACnC,+BAA+B,EAAE,MAAM,CAAC;QACxC,4BAA4B,EAAE,MAAM,CAAC;KACtC,CAAC;IACF,SAAS,EAAE;QACT,wBAAwB,EAAE,MAAM,EAAE,CAAC;QACnC,wBAAwB,EAAE,MAAM,EAAE,CAAC;KACpC,CAAC;CACH,CAAC;AAGF;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EACzC,SAAS,EACT,MAAM,EACN,aAAa,EACb,qBAAqB,EACrB,cAAc,EACd,UAAU,EACV,mBAAkE,EAClE,gBAAgC,EAChC,SAA8B,EAC9B,OAA4B,EAC5B,UAAoE,EACpE,iBAAmC,EACnC,0BAAqE,EACrE,sBAA2C,EAC3C,sBAAiC,EACjC,uBAA+C,EAC/C,aAA0B,EAC1B,oBAAyC,EACzC,gBAAiC,EACjC,oBAAyC,EACzC,QAAQ,EACR,OAAO,EACP,SAAS,GACV,EAAE,qBAAqB,2CAqNvB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/my_settings/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAGL,KAAK,wBAAwB,EAC9B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EACV,0BAA0B,EAC1B,sBAAsB,EACvB,MAAM,uCAAuC,CAAC;AAQ/C,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAClC,aAAa,CAAC,EAAE,sBAAsB,CAAC;IACvC,qBAAqB,EAAE,0BAA0B,CAAC;IAClD,cAAc,EAAE;QACd,kBAAkB,EAAE,OAAO,CAAC;QAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,cAAc,EAAE,MAAM,CAAC;QACvB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,4BAA4B,EAAE,UAAU,GAAG,SAAS,CAAC;QACrD,4BAA4B,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;QACtD,kBAAkB,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF,UAAU,EAAE;QACV,eAAe,EAAE,OAAO,CAAC;QACzB,gBAAgB,EAAE,OAAO,CAAC;QAC1B,mBAAmB,EAAE,OAAO,CAAC;KAC9B,CAAC;IACF,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,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,QAAQ,EAAE;QACR,6BAA6B,EAAE,MAAM,CAAC;QACtC,sBAAsB,EAAE,MAAM,CAAC;QAC/B,2BAA2B,EAAE,MAAM,CAAC;QACpC,uBAAuB,EAAE,MAAM,CAAC;KACjC,CAAC;IACF,OAAO,EAAE;QACP,aAAa,EAAE,MAAM,CAAC;QACtB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,yBAAyB,EAAE,MAAM,CAAC;QAClC,uBAAuB,EAAE,MAAM,CAAC;QAChC,0BAA0B,EAAE,MAAM,CAAC;QACnC,0BAA0B,EAAE,MAAM,CAAC;QACnC,+BAA+B,EAAE,MAAM,CAAC;QACxC,4BAA4B,EAAE,MAAM,CAAC;KACtC,CAAC;IACF,SAAS,EAAE;QACT,wBAAwB,EAAE,MAAM,EAAE,CAAC;QACnC,wBAAwB,EAAE,MAAM,EAAE,CAAC;KACpC,CAAC;CACH,CAAC;AAGF;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,kBAAkB,CAAC,EACzC,SAAS,EACT,MAAM,EACN,aAAa,EACb,qBAAqB,EACrB,cAAc,EACd,UAAU,EACV,mBAAkE,EAClE,gBAAgC,EAChC,SAA8B,EAC9B,OAA4B,EAC5B,UAAoE,EACpE,iBAAmC,EACnC,0BAAqE,EACrE,sBAA2C,EAC3C,sBAAiC,EACjC,uBAA+C,EAC/C,aAA0B,EAC1B,oBAAyC,EACzC,gBAAiC,EACjC,oBAAyC,EACzC,QAAQ,EACR,OAAO,EACP,SAAS,GACV,EAAE,qBAAqB,2CAqOvB"}
@@ -7,6 +7,8 @@ import { Button } from "../../ui/button";
7
7
  import { EditableField } from "./components/editable_field";
8
8
  import { ProfilePictureDisplay } from "./components/profile_picture_display";
9
9
  import { ProfilePictureDialog } from "./components/profile_picture_dialog";
10
+ import { ConnectedAccountsSection } from "./components/connected_accounts_section";
11
+ import { SetPasswordSection } from "./components/set_password_section";
10
12
  import { UnauthorizedGuard } from "../shared/components/unauthorized_guard";
11
13
  import { use_my_settings } from "./hooks/use_my_settings";
12
14
  import { resolveMySettingsLabels, resolveMySettingsButtonPalette, } from "./config/my_settings_field_config";
@@ -29,10 +31,10 @@ export default function my_settings_layout({ className, labels, button_colors, p
29
31
  const settings = use_my_settings({
30
32
  passwordRequirements: password_requirements,
31
33
  });
32
- return (_jsx(UnauthorizedGuard, { message: unauthorizedMessage, loginButtonLabel: loginButtonLabel, loginPath: loginPath, children: _jsxs("div", { className: cn("cls_my_settings_layout flex flex-col gap-6 p-6 w-full", className), children: [_jsxs("div", { className: "cls_my_settings_layout_header flex flex-col gap-2", children: [_jsx("h1", { className: "cls_my_settings_layout_heading text-3xl font-bold text-[var(--hazo-text-primary)]", children: heading }), _jsx("p", { className: "cls_my_settings_layout_subheading text-[var(--hazo-text-muted)]", children: subHeading })] }), _jsxs("div", { className: "cls_my_settings_layout_profile_photo_section bg-white rounded-lg border border-[var(--hazo-border)] p-6", children: [_jsx("h2", { className: "cls_my_settings_layout_section_heading text-lg font-semibold text-[var(--hazo-text-primary)] mb-4", children: profilePhotoLabel }), _jsx("div", { className: "cls_my_settings_layout_profile_photo_content flex flex-col items-center", children: _jsxs("div", { className: "cls_my_settings_layout_profile_photo_display relative", children: [_jsx(ProfilePictureDisplay, { profilePictureUrl: settings.profilePictureUrl, name: settings.name, email: settings.email, onEdit: settings.handleProfilePictureEdit }), _jsxs("div", { className: "cls_my_settings_layout_profile_photo_actions absolute left-0 right-0 flex items-center justify-between px-2", style: { bottom: '-20px' }, children: [_jsx(Button, { type: "button", onClick: settings.handleProfilePictureEdit, disabled: settings.loading, variant: "ghost", size: "icon", className: "cls_my_settings_layout_upload_photo_button", "aria-label": uploadPhotoButtonLabel, children: _jsx(Pencil, { className: "h-4 w-4", "aria-hidden": "true" }) }), _jsx(Button, { type: "button", onClick: settings.handleProfilePictureRemove, disabled: settings.loading || !settings.profilePictureUrl, variant: "ghost", size: "icon", className: "cls_my_settings_layout_remove_photo_button text-red-600 hover:text-red-700 hover:bg-red-50", "aria-label": removePhotoButtonLabel, children: _jsx(Trash2, { className: "h-4 w-4", "aria-hidden": "true" }) })] })] }) })] }), _jsxs("div", { className: "cls_my_settings_layout_profile_information_section bg-white rounded-lg border border-[var(--hazo-border)] p-6", children: [_jsx("h2", { className: "cls_my_settings_layout_section_heading text-lg font-semibold text-[var(--hazo-text-primary)] mb-4", children: profileInformationLabel }), _jsxs("div", { className: "cls_my_settings_layout_profile_information_fields grid grid-cols-1 md:grid-cols-2 gap-6", children: [userFields.show_name_field && (_jsx(EditableField, { label: "Full Name", value: settings.name, type: "text", placeholder: "Enter your full name", onSave: settings.handleNameSave, validation: validateName, disabled: settings.loading, ariaLabel: "Full name input field" })), userFields.show_email_field && (_jsx(EditableField, { label: "Email Address", value: settings.email, type: "email", placeholder: "Enter your email address", onSave: settings.handleEmailSave, validation: validateEmail, disabled: settings.loading, ariaLabel: "Email address input field" }))] })] }), userFields.show_password_field && (_jsxs("div", { className: "cls_my_settings_layout_password_section bg-white rounded-lg border border-[var(--hazo-border)] p-6", children: [_jsx("h2", { className: "cls_my_settings_layout_section_heading text-lg font-semibold text-[var(--hazo-text-primary)] mb-4", children: passwordLabel }), _jsxs("div", { className: "cls_my_settings_layout_password_fields flex flex-col gap-6", children: [_jsx(FormFieldWrapper, { fieldId: "current-password", label: currentPasswordLabel, input: _jsx(PasswordField, { inputId: "current-password", ariaLabel: currentPasswordLabel, value: ((_a = settings.passwordFields) === null || _a === void 0 ? void 0 : _a.currentPassword) || "", placeholder: "Enter your current password", autoComplete: "current-password", isVisible: ((_b = settings.passwordFields) === null || _b === void 0 ? void 0 : _b.currentPasswordVisible) || false, onChange: (value) => settings.handlePasswordFieldChange("currentPassword", value), onToggleVisibility: () => settings.togglePasswordVisibility("currentPassword"), errorMessage: (_d = (_c = settings.passwordFields) === null || _c === void 0 ? void 0 : _c.errors) === null || _d === void 0 ? void 0 : _d.currentPassword }) }), _jsxs("div", { className: "cls_my_settings_layout_password_fields_row grid grid-cols-1 md:grid-cols-2 gap-6", children: [_jsx(FormFieldWrapper, { fieldId: "new-password", label: newPasswordLabel, input: _jsx(PasswordField, { inputId: "new-password", ariaLabel: newPasswordLabel, value: ((_e = settings.passwordFields) === null || _e === void 0 ? void 0 : _e.newPassword) || "", placeholder: "Enter your new password", autoComplete: "new-password", isVisible: ((_f = settings.passwordFields) === null || _f === void 0 ? void 0 : _f.newPasswordVisible) || false, onChange: (value) => settings.handlePasswordFieldChange("newPassword", value), onToggleVisibility: () => settings.togglePasswordVisibility("newPassword"), errorMessage: (_h = (_g = settings.passwordFields) === null || _g === void 0 ? void 0 : _g.errors) === null || _h === void 0 ? void 0 : _h.newPassword }) }), _jsx(FormFieldWrapper, { fieldId: "confirm-password", label: confirmPasswordLabel, input: _jsx(PasswordField, { inputId: "confirm-password", ariaLabel: confirmPasswordLabel, value: ((_j = settings.passwordFields) === null || _j === void 0 ? void 0 : _j.confirmPassword) || "", placeholder: "Confirm your new password", autoComplete: "new-password", isVisible: ((_k = settings.passwordFields) === null || _k === void 0 ? void 0 : _k.confirmPasswordVisible) || false, onChange: (value) => settings.handlePasswordFieldChange("confirmPassword", value), onToggleVisibility: () => settings.togglePasswordVisibility("confirmPassword"), errorMessage: (_m = (_l = settings.passwordFields) === null || _l === void 0 ? void 0 : _l.errors) === null || _m === void 0 ? void 0 : _m.confirmPassword }) })] })] }), _jsx("div", { className: "cls_my_settings_layout_password_actions flex justify-end mt-4", children: _jsx(Button, { type: "button", onClick: settings.handlePasswordSave, disabled: settings.loading || settings.isPasswordSaveDisabled, className: "cls_my_settings_layout_save_password_button", style: {
34
+ return (_jsx(UnauthorizedGuard, { message: unauthorizedMessage, loginButtonLabel: loginButtonLabel, loginPath: loginPath, children: _jsxs("div", { className: cn("cls_my_settings_layout flex flex-col gap-6 p-6 w-full", className), children: [_jsxs("div", { className: "cls_my_settings_layout_header flex flex-col gap-2", children: [_jsx("h1", { className: "cls_my_settings_layout_heading text-3xl font-bold text-[var(--hazo-text-primary)]", children: heading }), _jsx("p", { className: "cls_my_settings_layout_subheading text-[var(--hazo-text-muted)]", children: subHeading })] }), _jsxs("div", { className: "cls_my_settings_layout_profile_photo_section bg-white rounded-lg border border-[var(--hazo-border)] p-6", children: [_jsx("h2", { className: "cls_my_settings_layout_section_heading text-lg font-semibold text-[var(--hazo-text-primary)] mb-4", children: profilePhotoLabel }), _jsx("div", { className: "cls_my_settings_layout_profile_photo_content flex flex-col items-center", children: _jsxs("div", { className: "cls_my_settings_layout_profile_photo_display relative", children: [_jsx(ProfilePictureDisplay, { profilePictureUrl: settings.profilePictureUrl, name: settings.name, email: settings.email, onEdit: settings.handleProfilePictureEdit }), _jsxs("div", { className: "cls_my_settings_layout_profile_photo_actions absolute left-0 right-0 flex items-center justify-between px-2", style: { bottom: '-20px' }, children: [_jsx(Button, { type: "button", onClick: settings.handleProfilePictureEdit, disabled: settings.loading, variant: "ghost", size: "icon", className: "cls_my_settings_layout_upload_photo_button", "aria-label": uploadPhotoButtonLabel, children: _jsx(Pencil, { className: "h-4 w-4", "aria-hidden": "true" }) }), _jsx(Button, { type: "button", onClick: settings.handleProfilePictureRemove, disabled: settings.loading || !settings.profilePictureUrl, variant: "ghost", size: "icon", className: "cls_my_settings_layout_remove_photo_button text-red-600 hover:text-red-700 hover:bg-red-50", "aria-label": removePhotoButtonLabel, children: _jsx(Trash2, { className: "h-4 w-4", "aria-hidden": "true" }) })] })] }) })] }), _jsxs("div", { className: "cls_my_settings_layout_profile_information_section bg-white rounded-lg border border-[var(--hazo-border)] p-6", children: [_jsx("h2", { className: "cls_my_settings_layout_section_heading text-lg font-semibold text-[var(--hazo-text-primary)] mb-4", children: profileInformationLabel }), _jsxs("div", { className: "cls_my_settings_layout_profile_information_fields grid grid-cols-1 md:grid-cols-2 gap-6", children: [userFields.show_name_field && (_jsx(EditableField, { label: "Full Name", value: settings.name, type: "text", placeholder: "Enter your full name", onSave: settings.handleNameSave, validation: validateName, disabled: settings.loading, ariaLabel: "Full name input field" })), userFields.show_email_field && (_jsx(EditableField, { label: "Email Address", value: settings.email, type: "email", placeholder: "Enter your email address", onSave: settings.handleEmailSave, validation: validateEmail, disabled: settings.loading, ariaLabel: "Email address input field" }))] })] }), userFields.show_password_field && settings.hasPassword && (_jsxs("div", { className: "cls_my_settings_layout_password_section bg-white rounded-lg border border-[var(--hazo-border)] p-6", children: [_jsx("h2", { className: "cls_my_settings_layout_section_heading text-lg font-semibold text-[var(--hazo-text-primary)] mb-4", children: passwordLabel }), _jsxs("div", { className: "cls_my_settings_layout_password_fields flex flex-col gap-6", children: [_jsx(FormFieldWrapper, { fieldId: "current-password", label: currentPasswordLabel, input: _jsx(PasswordField, { inputId: "current-password", ariaLabel: currentPasswordLabel, value: ((_a = settings.passwordFields) === null || _a === void 0 ? void 0 : _a.currentPassword) || "", placeholder: "Enter your current password", autoComplete: "current-password", isVisible: ((_b = settings.passwordFields) === null || _b === void 0 ? void 0 : _b.currentPasswordVisible) || false, onChange: (value) => settings.handlePasswordFieldChange("currentPassword", value), onToggleVisibility: () => settings.togglePasswordVisibility("currentPassword"), errorMessage: (_d = (_c = settings.passwordFields) === null || _c === void 0 ? void 0 : _c.errors) === null || _d === void 0 ? void 0 : _d.currentPassword }) }), _jsxs("div", { className: "cls_my_settings_layout_password_fields_row grid grid-cols-1 md:grid-cols-2 gap-6", children: [_jsx(FormFieldWrapper, { fieldId: "new-password", label: newPasswordLabel, input: _jsx(PasswordField, { inputId: "new-password", ariaLabel: newPasswordLabel, value: ((_e = settings.passwordFields) === null || _e === void 0 ? void 0 : _e.newPassword) || "", placeholder: "Enter your new password", autoComplete: "new-password", isVisible: ((_f = settings.passwordFields) === null || _f === void 0 ? void 0 : _f.newPasswordVisible) || false, onChange: (value) => settings.handlePasswordFieldChange("newPassword", value), onToggleVisibility: () => settings.togglePasswordVisibility("newPassword"), errorMessage: (_h = (_g = settings.passwordFields) === null || _g === void 0 ? void 0 : _g.errors) === null || _h === void 0 ? void 0 : _h.newPassword }) }), _jsx(FormFieldWrapper, { fieldId: "confirm-password", label: confirmPasswordLabel, input: _jsx(PasswordField, { inputId: "confirm-password", ariaLabel: confirmPasswordLabel, value: ((_j = settings.passwordFields) === null || _j === void 0 ? void 0 : _j.confirmPassword) || "", placeholder: "Confirm your new password", autoComplete: "new-password", isVisible: ((_k = settings.passwordFields) === null || _k === void 0 ? void 0 : _k.confirmPasswordVisible) || false, onChange: (value) => settings.handlePasswordFieldChange("confirmPassword", value), onToggleVisibility: () => settings.togglePasswordVisibility("confirmPassword"), errorMessage: (_m = (_l = settings.passwordFields) === null || _l === void 0 ? void 0 : _l.errors) === null || _m === void 0 ? void 0 : _m.confirmPassword }) })] })] }), _jsx("div", { className: "cls_my_settings_layout_password_actions flex justify-end mt-4", children: _jsx(Button, { type: "button", onClick: settings.handlePasswordSave, disabled: settings.loading || settings.isPasswordSaveDisabled, className: "cls_my_settings_layout_save_password_button", style: {
33
35
  backgroundColor: resolvedButtonPalette.submitBackground,
34
36
  color: resolvedButtonPalette.submitText,
35
- }, "aria-label": "Save password", children: "Save Password" }) })] })), _jsx(ProfilePictureDialog, { open: settings.profilePictureDialogOpen, onOpenChange: (open) => {
37
+ }, "aria-label": "Save password", children: "Save Password" }) })] })), !settings.hasPassword && settings.googleConnected && (_jsx(SetPasswordSection, { passwordRequirements: password_requirements, onPasswordSet: settings.refreshUserData, parentLoading: settings.loading })), _jsx(ConnectedAccountsSection, { googleConnected: settings.googleConnected || false, email: settings.email, loading: settings.loading }), _jsx(ProfilePictureDialog, { open: settings.profilePictureDialogOpen, onOpenChange: (open) => {
36
38
  if (open) {
37
39
  settings.handleProfilePictureEdit();
38
40
  }
@@ -0,0 +1,12 @@
1
+ export type GoogleIconProps = {
2
+ className?: string;
3
+ width?: number;
4
+ height?: number;
5
+ };
6
+ /**
7
+ * Google logo SVG component
8
+ * Uses official Google brand colors
9
+ */
10
+ export declare function GoogleIcon({ className, width, height, }: GoogleIconProps): import("react/jsx-runtime").JSX.Element;
11
+ export default GoogleIcon;
12
+ //# sourceMappingURL=google_icon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google_icon.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/shared/components/google_icon.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,UAAU,CAAC,EACzB,SAAc,EACd,KAAU,EACV,MAAW,GACZ,EAAE,eAAe,2CA6BjB;AAED,eAAe,UAAU,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * Google logo SVG component
4
+ * Uses official Google brand colors
5
+ */
6
+ export function GoogleIcon({ className = "", width = 20, height = 20, }) {
7
+ return (_jsxs("svg", { className: className, width: width, height: height, viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [_jsx("path", { d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z", fill: "#4285F4" }), _jsx("path", { d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z", fill: "#34A853" }), _jsx("path", { d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z", fill: "#FBBC05" }), _jsx("path", { d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z", fill: "#EA4335" })] }));
8
+ }
9
+ export default GoogleIcon;
@@ -0,0 +1,21 @@
1
+ export type GoogleSignInButtonProps = {
2
+ /** Text displayed on the button */
3
+ label?: string;
4
+ /** Custom click handler - if not provided, redirects to Google OAuth */
5
+ onClick?: () => void;
6
+ /** Disable the button */
7
+ disabled?: boolean;
8
+ /** Additional CSS classes */
9
+ className?: string;
10
+ /** Callback URL after OAuth (default: /api/hazo_auth/oauth/google/callback) */
11
+ callbackUrl?: string;
12
+ };
13
+ /**
14
+ * Google Sign-In button component
15
+ * Displays the Google logo with configurable text
16
+ * Initiates the Google OAuth flow when clicked
17
+ * Uses next-auth/react signIn function for proper OAuth flow
18
+ */
19
+ export declare function GoogleSignInButton({ label, onClick, disabled, className, callbackUrl, }: GoogleSignInButtonProps): import("react/jsx-runtime").JSX.Element;
20
+ export default GoogleSignInButton;
21
+ //# sourceMappingURL=google_sign_in_button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google_sign_in_button.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/shared/components/google_sign_in_button.tsx"],"names":[],"mappings":"AAaA,MAAM,MAAM,uBAAuB,GAAG;IACpC,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,KAA8B,EAC9B,OAAO,EACP,QAAgB,EAChB,SAAS,EACT,WAAoD,GACrD,EAAE,uBAAuB,2CAmDzB;AAED,eAAe,kBAAkB,CAAC"}
@@ -0,0 +1,50 @@
1
+ // file_description: Google Sign-In button component with official Google icon
2
+ // section: client_directive
3
+ "use client";
4
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
+ // section: imports
6
+ import { Button } from "../../../ui/button";
7
+ import { GoogleIcon } from "./google_icon";
8
+ import { cn } from "../../../../lib/utils";
9
+ import { useState } from "react";
10
+ import { Loader2 } from "lucide-react";
11
+ import { signIn } from "next-auth/react";
12
+ // section: component
13
+ /**
14
+ * Google Sign-In button component
15
+ * Displays the Google logo with configurable text
16
+ * Initiates the Google OAuth flow when clicked
17
+ * Uses next-auth/react signIn function for proper OAuth flow
18
+ */
19
+ export function GoogleSignInButton({ label = "Continue with Google", onClick, disabled = false, className, callbackUrl = "/api/hazo_auth/oauth/google/callback", }) {
20
+ const [isLoading, setIsLoading] = useState(false);
21
+ const handleClick = async () => {
22
+ if (disabled || isLoading)
23
+ return;
24
+ if (onClick) {
25
+ onClick();
26
+ }
27
+ else {
28
+ setIsLoading(true);
29
+ try {
30
+ // Use next-auth/react signIn function for proper OAuth flow
31
+ // redirect: true (default) lets NextAuth handle the full flow
32
+ // including the redirect callback which goes to our custom callback URL
33
+ console.log("[GoogleSignInButton] Starting Google OAuth with callbackUrl:", callbackUrl);
34
+ await signIn("google", {
35
+ callbackUrl,
36
+ redirect: true,
37
+ });
38
+ // Note: redirect: true means this code won't execute after success
39
+ // as the browser will be redirected
40
+ }
41
+ catch (error) {
42
+ console.error("[GoogleSignInButton] Sign-in exception:", error);
43
+ alert(`Google Sign-In Exception: ${error}`);
44
+ setIsLoading(false);
45
+ }
46
+ }
47
+ };
48
+ return (_jsxs(Button, { type: "button", variant: "outline", onClick: handleClick, disabled: disabled || isLoading, className: cn("cls_google_sign_in_button w-full flex items-center justify-center gap-3 h-11 border-slate-300 hover:bg-slate-50 hover:border-slate-400 transition-colors", className), "aria-label": label, children: [isLoading ? (_jsx(Loader2, { className: "h-5 w-5 animate-spin text-slate-600", "aria-hidden": "true" })) : (_jsx(GoogleIcon, { className: "h-5 w-5" })), _jsx("span", { className: "text-slate-700 font-medium", children: isLoading ? "Signing in..." : label })] }));
49
+ }
50
+ export default GoogleSignInButton;
@@ -0,0 +1,13 @@
1
+ export type OAuthDividerProps = {
2
+ /** Text displayed in the divider */
3
+ text?: string;
4
+ /** Additional CSS classes */
5
+ className?: string;
6
+ };
7
+ /**
8
+ * Visual divider component to separate OAuth buttons from email/password form
9
+ * Displays a horizontal line with text in the center
10
+ */
11
+ export declare function OAuthDivider({ text, className, }: OAuthDividerProps): import("react/jsx-runtime").JSX.Element;
12
+ export default OAuthDivider;
13
+ //# sourceMappingURL=oauth_divider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth_divider.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/shared/components/oauth_divider.tsx"],"names":[],"mappings":"AAKA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,oCAAoC;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAGF;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAC3B,IAA+B,EAC/B,SAAS,GACV,EAAE,iBAAiB,2CAoBnB;AAED,eAAe,YAAY,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // file_description: Visual divider between OAuth buttons and email/password form
3
+ // section: imports
4
+ import { cn } from "../../../../lib/utils";
5
+ // section: component
6
+ /**
7
+ * Visual divider component to separate OAuth buttons from email/password form
8
+ * Displays a horizontal line with text in the center
9
+ */
10
+ export function OAuthDivider({ text = "or continue with email", className, }) {
11
+ return (_jsxs("div", { className: cn("cls_oauth_divider relative my-6", className), role: "separator", "aria-orientation": "horizontal", children: [_jsx("div", { className: "absolute inset-0 flex items-center", "aria-hidden": "true", children: _jsx("span", { className: "w-full border-t border-slate-200" }) }), _jsx("div", { className: "relative flex justify-center text-sm", children: _jsx("span", { className: "bg-white px-3 text-slate-500", children: text }) })] }));
12
+ }
13
+ export default OAuthDivider;
@@ -1,3 +1,5 @@
1
+ import type { PasswordRequirementOptions } from "../../../../lib/utils/password_validator";
2
+ export type { PasswordRequirementOptions };
1
3
  export type LayoutFieldId = string;
2
4
  export type LayoutFieldDefinition = {
3
5
  id: LayoutFieldId;
@@ -23,13 +25,6 @@ export type ButtonPaletteDefaults = {
23
25
  cancelText: string;
24
26
  };
25
27
  export type ButtonPaletteOverrides = Partial<ButtonPaletteDefaults>;
26
- export type PasswordRequirementOptions = {
27
- minimum_length: number;
28
- require_uppercase: boolean;
29
- require_lowercase: boolean;
30
- require_number: boolean;
31
- require_special: boolean;
32
- };
33
28
  export type PasswordRequirementOverrides = Partial<PasswordRequirementOptions>;
34
29
  export declare const resolveFieldDefinitions: (baseDefinitions: LayoutFieldMap, overrides?: LayoutFieldMapOverrides) => LayoutFieldMap;
35
30
  export declare const resolveLabels: (defaults: LayoutLabelDefaults, overrides?: LayoutLabelOverrides) => LayoutLabelDefaults;
@@ -1 +1 @@
1
- {"version":3,"file":"layout_customization.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/shared/config/layout_customization.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC;AAEnC,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,aAAa,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC;AAC1E,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAErG,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAEhE,MAAM,MAAM,qBAAqB,GAAG;IAClC,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAEpE,MAAM,MAAM,0BAA0B,GAAG;IACvC,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;AAG/E,eAAO,MAAM,uBAAuB,GAClC,iBAAiB,cAAc,EAC/B,YAAY,uBAAuB,KAClC,cAqBF,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,UAAU,mBAAmB,EAC7B,YAAY,oBAAoB,KAC/B,mBAGD,CAAC;AAEH,eAAO,MAAM,oBAAoB,GAC/B,UAAU,qBAAqB,EAC/B,YAAY,sBAAsB,KACjC,qBAGD,CAAC;AAEH,eAAO,MAAM,2BAA2B,GACtC,UAAU,0BAA0B,EACpC,YAAY,4BAA4B,KACvC,0BAGD,CAAC"}
1
+ {"version":3,"file":"layout_customization.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/shared/config/layout_customization.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,0CAA0C,CAAC;AAC3F,YAAY,EAAE,0BAA0B,EAAE,CAAC;AAG3C,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC;AAEnC,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,aAAa,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC;AAC1E,MAAM,MAAM,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAErG,MAAM,MAAM,mBAAmB,GAAG;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAEhE,MAAM,MAAM,qBAAqB,GAAG;IAClC,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAEpE,MAAM,MAAM,4BAA4B,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;AAG/E,eAAO,MAAM,uBAAuB,GAClC,iBAAiB,cAAc,EAC/B,YAAY,uBAAuB,KAClC,cAqBF,CAAC;AAEF,eAAO,MAAM,aAAa,GACxB,UAAU,mBAAmB,EAC7B,YAAY,oBAAoB,KAC/B,mBAGD,CAAC;AAEH,eAAO,MAAM,oBAAoB,GAC/B,UAAU,qBAAqB,EAC/B,YAAY,sBAAsB,KACjC,qBAGD,CAAC;AAEH,eAAO,MAAM,2BAA2B,GACtC,UAAU,0BAA0B,EACpC,YAAY,4BAA4B,KACvC,0BAGD,CAAC"}
@@ -13,6 +13,9 @@ export type AuthStatusData = {
13
13
  permissions?: string[];
14
14
  permission_ok?: boolean;
15
15
  missing_permissions?: string[];
16
+ auth_providers?: string;
17
+ has_password?: boolean;
18
+ google_connected?: boolean;
16
19
  loading: boolean;
17
20
  };
18
21
  export type AuthStatus = AuthStatusData & {
@@ -1 +1 @@
1
- {"version":3,"file":"use_auth_status.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/shared/hooks/use_auth_status.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;IAC9D,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG;IACxC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B,CAAC;AAMF;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,IAAI,CAIlD;AAGD,wBAAgB,eAAe,IAAI,UAAU,CAuE5C"}
1
+ {"version":3,"file":"use_auth_status.d.ts","sourceRoot":"","sources":["../../../../../src/components/layouts/shared/hooks/use_auth_status.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;IAC9D,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG;IACxC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B,CAAC;AAMF;;GAEG;AACH,wBAAgB,2BAA2B,IAAI,IAAI,CAIlD;AAGD,wBAAgB,eAAe,IAAI,UAAU,CA2E5C"}
@@ -48,6 +48,10 @@ export function use_auth_status() {
48
48
  permissions: data.permissions || [],
49
49
  permission_ok: (_a = data.permission_ok) !== null && _a !== void 0 ? _a : true,
50
50
  missing_permissions: data.missing_permissions,
51
+ // OAuth-related fields
52
+ auth_providers: data.auth_providers,
53
+ has_password: data.has_password,
54
+ google_connected: data.google_connected,
51
55
  loading: false,
52
56
  });
53
57
  }
@@ -12,6 +12,11 @@ export { StandaloneLayoutWrapper } from "./components/standalone_layout_wrapper"
12
12
  export { TwoColumnAuthLayout } from "./components/two_column_auth_layout";
13
13
  export { UnauthorizedGuard } from "./components/unauthorized_guard";
14
14
  export { VisualPanel } from "./components/visual_panel";
15
+ export { GoogleIcon } from "./components/google_icon";
16
+ export { GoogleSignInButton } from "./components/google_sign_in_button";
17
+ export type { GoogleSignInButtonProps } from "./components/google_sign_in_button";
18
+ export { OAuthDivider } from "./components/oauth_divider";
19
+ export type { OAuthDividerProps } from "./components/oauth_divider";
15
20
  export { use_auth_status } from "./hooks/use_auth_status";
16
21
  export { use_hazo_auth, trigger_hazo_auth_refresh } from "./hooks/use_hazo_auth";
17
22
  export type { UseHazoAuthOptions, UseHazoAuthResult } from "./hooks/use_hazo_auth";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/shared/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAE5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,YAAY,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAE7F,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGxD,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACjF,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAGnF,cAAc,+BAA+B,CAAC;AAG9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAGlE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,cAAc,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/layouts/shared/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAE5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,YAAY,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAE7F,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,YAAY,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,YAAY,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAGpE,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACjF,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAGnF,cAAc,+BAA+B,CAAC;AAG9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AACnE,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAGlE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,cAAc,oBAAoB,CAAC"}
@@ -16,6 +16,9 @@ export { StandaloneLayoutWrapper } from "./components/standalone_layout_wrapper"
16
16
  export { TwoColumnAuthLayout } from "./components/two_column_auth_layout";
17
17
  export { UnauthorizedGuard } from "./components/unauthorized_guard";
18
18
  export { VisualPanel } from "./components/visual_panel";
19
+ export { GoogleIcon } from "./components/google_icon";
20
+ export { GoogleSignInButton } from "./components/google_sign_in_button";
21
+ export { OAuthDivider } from "./components/oauth_divider";
19
22
  // section: hook_exports
20
23
  export { use_auth_status } from "./hooks/use_auth_status";
21
24
  export { use_hazo_auth, trigger_hazo_auth_refresh } from "./hooks/use_hazo_auth";
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
  import { type VariantProps } from "class-variance-authority";
3
3
  declare const buttonVariants: (props?: ({
4
- variant?: "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | null | undefined;
4
+ variant?: "default" | "link" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
5
5
  size?: "default" | "sm" | "lg" | "icon" | null | undefined;
6
6
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
7
7
  export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
@@ -0,0 +1,34 @@
1
+ import type { AuthOptions } from "next-auth";
2
+ export type NextAuthCallbackUser = {
3
+ id?: string;
4
+ email?: string | null;
5
+ name?: string | null;
6
+ image?: string | null;
7
+ };
8
+ export type NextAuthCallbackAccount = {
9
+ provider: string;
10
+ providerAccountId: string;
11
+ type: string;
12
+ access_token?: string;
13
+ id_token?: string;
14
+ expires_at?: number;
15
+ };
16
+ export type NextAuthCallbackProfile = {
17
+ sub?: string;
18
+ name?: string;
19
+ email?: string;
20
+ picture?: string;
21
+ email_verified?: boolean;
22
+ };
23
+ /**
24
+ * Gets NextAuth.js configuration with enabled OAuth providers
25
+ * Providers are dynamically configured based on hazo_auth_config.ini settings
26
+ * @returns NextAuth configuration object
27
+ */
28
+ export declare function get_nextauth_config(): AuthOptions;
29
+ /**
30
+ * Checks if any OAuth providers are configured and enabled
31
+ * @returns true if at least one OAuth provider is available
32
+ */
33
+ export declare function has_oauth_providers(): boolean;
34
+ //# sourceMappingURL=nextauth_config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nextauth_config.d.ts","sourceRoot":"","sources":["../../../src/lib/auth/nextauth_config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAW,MAAM,WAAW,CAAC;AAStD,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAGF;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,WAAW,CAwKjD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAW7C"}