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.
- package/README.md +230 -0
- package/SETUP_CHECKLIST.md +202 -0
- package/bin/hazo_auth.mjs +35 -0
- package/cli-src/assets/images/forgot_password_default.jpg +0 -0
- package/cli-src/assets/images/login_default.jpg +0 -0
- package/cli-src/assets/images/register_default.jpg +0 -0
- package/cli-src/assets/images/reset_password_default.jpg +0 -0
- package/cli-src/assets/images/verify_email_default.jpg +0 -0
- package/cli-src/cli/generate.ts +276 -0
- package/cli-src/cli/index.ts +207 -0
- package/cli-src/cli/init.ts +254 -0
- package/cli-src/cli/init_users.ts +376 -0
- package/cli-src/cli/validate.ts +581 -0
- package/cli-src/lib/already_logged_in_config.server.ts +46 -0
- package/cli-src/lib/app_logger.ts +24 -0
- package/cli-src/lib/auth/auth_cache.ts +220 -0
- package/cli-src/lib/auth/auth_rate_limiter.ts +121 -0
- package/cli-src/lib/auth/auth_types.ts +110 -0
- package/cli-src/lib/auth/auth_utils.server.ts +196 -0
- package/cli-src/lib/auth/hazo_get_auth.server.ts +512 -0
- package/cli-src/lib/auth/index.ts +23 -0
- package/cli-src/lib/auth/nextauth_config.ts +227 -0
- package/cli-src/lib/auth/scope_cache.ts +233 -0
- package/cli-src/lib/auth/server_auth.ts +88 -0
- package/cli-src/lib/auth/session_token_validator.edge.ts +91 -0
- package/cli-src/lib/auth_utility_config.server.ts +136 -0
- package/cli-src/lib/config/config_loader.server.ts +164 -0
- package/cli-src/lib/config/default_config.ts +199 -0
- package/cli-src/lib/email_verification_config.server.ts +63 -0
- package/cli-src/lib/file_types_config.server.ts +25 -0
- package/cli-src/lib/forgot_password_config.server.ts +63 -0
- package/cli-src/lib/hazo_connect_instance.server.ts +101 -0
- package/cli-src/lib/hazo_connect_setup.server.ts +194 -0
- package/cli-src/lib/hazo_connect_setup.ts +54 -0
- package/cli-src/lib/index.ts +46 -0
- package/cli-src/lib/login_config.server.ts +106 -0
- package/cli-src/lib/messages_config.server.ts +45 -0
- package/cli-src/lib/migrations/apply_migration.ts +105 -0
- package/cli-src/lib/my_settings_config.server.ts +135 -0
- package/cli-src/lib/oauth_config.server.ts +87 -0
- package/cli-src/lib/password_requirements_config.server.ts +40 -0
- package/cli-src/lib/profile_pic_menu_config.server.ts +138 -0
- package/cli-src/lib/profile_picture_config.server.ts +56 -0
- package/cli-src/lib/register_config.server.ts +101 -0
- package/cli-src/lib/reset_password_config.server.ts +103 -0
- package/cli-src/lib/scope_hierarchy_config.server.ts +151 -0
- package/cli-src/lib/services/email_service.ts +587 -0
- package/cli-src/lib/services/email_verification_service.ts +270 -0
- package/cli-src/lib/services/index.ts +16 -0
- package/cli-src/lib/services/login_service.ts +150 -0
- package/cli-src/lib/services/oauth_service.ts +494 -0
- package/cli-src/lib/services/password_change_service.ts +154 -0
- package/cli-src/lib/services/password_reset_service.ts +418 -0
- package/cli-src/lib/services/profile_picture_remove_service.ts +120 -0
- package/cli-src/lib/services/profile_picture_service.ts +451 -0
- package/cli-src/lib/services/profile_picture_source_mapper.ts +62 -0
- package/cli-src/lib/services/registration_service.ts +185 -0
- package/cli-src/lib/services/scope_labels_service.ts +348 -0
- package/cli-src/lib/services/scope_service.ts +778 -0
- package/cli-src/lib/services/session_token_service.ts +177 -0
- package/cli-src/lib/services/token_service.ts +240 -0
- package/cli-src/lib/services/user_profiles_cache.ts +189 -0
- package/cli-src/lib/services/user_profiles_service.ts +264 -0
- package/cli-src/lib/services/user_scope_service.ts +554 -0
- package/cli-src/lib/services/user_update_service.ts +141 -0
- package/cli-src/lib/ui_shell_config.server.ts +73 -0
- package/cli-src/lib/ui_sizes_config.server.ts +37 -0
- package/cli-src/lib/user_fields_config.server.ts +31 -0
- package/cli-src/lib/user_management_config.server.ts +39 -0
- package/cli-src/lib/user_profiles_config.server.ts +55 -0
- package/cli-src/lib/utils/api_route_helpers.ts +60 -0
- package/cli-src/lib/utils/error_sanitizer.ts +75 -0
- package/cli-src/lib/utils/password_validator.ts +65 -0
- package/cli-src/lib/utils.ts +11 -0
- package/cli-src/server/logging/logger_service.ts +56 -0
- package/dist/app/api/hazo_auth/forgot_password/route.d.ts.map +1 -1
- package/dist/app/api/hazo_auth/forgot_password/route.js +15 -0
- package/dist/app/api/hazo_auth/logout/route.d.ts.map +1 -1
- package/dist/app/api/hazo_auth/logout/route.js +31 -0
- package/dist/app/api/hazo_auth/me/route.d.ts.map +1 -1
- package/dist/app/api/hazo_auth/me/route.js +10 -0
- package/dist/cli/index.js +18 -0
- package/dist/cli/init_users.d.ts +17 -0
- package/dist/cli/init_users.d.ts.map +1 -0
- package/dist/cli/init_users.js +307 -0
- package/dist/components/layouts/forgot_password/hooks/use_forgot_password_form.d.ts +2 -0
- package/dist/components/layouts/forgot_password/hooks/use_forgot_password_form.d.ts.map +1 -1
- package/dist/components/layouts/forgot_password/hooks/use_forgot_password_form.js +8 -0
- package/dist/components/layouts/forgot_password/index.d.ts +7 -1
- package/dist/components/layouts/forgot_password/index.d.ts.map +1 -1
- package/dist/components/layouts/forgot_password/index.js +7 -2
- package/dist/components/layouts/login/index.d.ts +13 -1
- package/dist/components/layouts/login/index.d.ts.map +1 -1
- package/dist/components/layouts/login/index.js +11 -2
- package/dist/components/layouts/my_settings/components/connected_accounts_section.d.ts +17 -0
- package/dist/components/layouts/my_settings/components/connected_accounts_section.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/components/connected_accounts_section.js +17 -0
- package/dist/components/layouts/my_settings/components/set_password_section.d.ts +26 -0
- package/dist/components/layouts/my_settings/components/set_password_section.d.ts.map +1 -0
- package/dist/components/layouts/my_settings/components/set_password_section.js +127 -0
- package/dist/components/layouts/my_settings/hooks/use_my_settings.d.ts +3 -0
- package/dist/components/layouts/my_settings/hooks/use_my_settings.d.ts.map +1 -1
- package/dist/components/layouts/my_settings/hooks/use_my_settings.js +9 -0
- package/dist/components/layouts/my_settings/index.d.ts.map +1 -1
- package/dist/components/layouts/my_settings/index.js +4 -2
- package/dist/components/layouts/shared/components/google_icon.d.ts +12 -0
- package/dist/components/layouts/shared/components/google_icon.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/google_icon.js +9 -0
- package/dist/components/layouts/shared/components/google_sign_in_button.d.ts +21 -0
- package/dist/components/layouts/shared/components/google_sign_in_button.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/google_sign_in_button.js +50 -0
- package/dist/components/layouts/shared/components/oauth_divider.d.ts +13 -0
- package/dist/components/layouts/shared/components/oauth_divider.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/oauth_divider.js +13 -0
- package/dist/components/layouts/shared/config/layout_customization.d.ts +2 -7
- package/dist/components/layouts/shared/config/layout_customization.d.ts.map +1 -1
- package/dist/components/layouts/shared/hooks/use_auth_status.d.ts +3 -0
- package/dist/components/layouts/shared/hooks/use_auth_status.d.ts.map +1 -1
- package/dist/components/layouts/shared/hooks/use_auth_status.js +4 -0
- package/dist/components/layouts/shared/index.d.ts +5 -0
- package/dist/components/layouts/shared/index.d.ts.map +1 -1
- package/dist/components/layouts/shared/index.js +3 -0
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/lib/auth/nextauth_config.d.ts +34 -0
- package/dist/lib/auth/nextauth_config.d.ts.map +1 -0
- package/dist/lib/auth/nextauth_config.js +171 -0
- package/dist/lib/config/default_config.d.ts +24 -0
- package/dist/lib/config/default_config.d.ts.map +1 -1
- package/dist/lib/config/default_config.js +14 -0
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +1 -0
- package/dist/lib/login_config.server.d.ts +3 -0
- package/dist/lib/login_config.server.d.ts.map +1 -1
- package/dist/lib/login_config.server.js +4 -0
- package/dist/lib/oauth_config.server.d.ts +29 -0
- package/dist/lib/oauth_config.server.d.ts.map +1 -0
- package/dist/lib/oauth_config.server.js +40 -0
- package/dist/lib/services/login_service.d.ts.map +1 -1
- package/dist/lib/services/login_service.js +16 -1
- package/dist/lib/services/oauth_service.d.ts +88 -0
- package/dist/lib/services/oauth_service.d.ts.map +1 -0
- package/dist/lib/services/oauth_service.js +376 -0
- package/dist/lib/services/password_reset_service.d.ts +2 -0
- package/dist/lib/services/password_reset_service.d.ts.map +1 -1
- package/dist/lib/services/password_reset_service.js +10 -0
- package/dist/lib/services/registration_service.d.ts.map +1 -1
- package/dist/lib/services/registration_service.js +1 -0
- package/dist/lib/utils/password_validator.d.ts +19 -0
- package/dist/lib/utils/password_validator.d.ts.map +1 -0
- package/dist/lib/utils/password_validator.js +36 -0
- package/dist/server_pages/login.d.ts.map +1 -1
- package/dist/server_pages/login.js +6 -1
- package/dist/server_pages/login_client_wrapper.d.ts +5 -2
- package/dist/server_pages/login_client_wrapper.d.ts.map +1 -1
- package/dist/server_pages/login_client_wrapper.js +2 -2
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -24,6 +24,7 @@ A reusable authentication UI component package powered by Next.js, TailwindCSS,
|
|
|
24
24
|
- [Quick Start](#quick-start)
|
|
25
25
|
- [Configuration Setup](#configuration-setup)
|
|
26
26
|
- [Database Setup](#database-setup)
|
|
27
|
+
- [Google OAuth Setup](#google-oauth-setup)
|
|
27
28
|
- [Using Components](#using-components)
|
|
28
29
|
- [Authentication Service](#authentication-service)
|
|
29
30
|
- [Proxy/Middleware Authentication](#proxymiddleware-authentication)
|
|
@@ -366,6 +367,19 @@ cp node_modules/hazo_auth/hazo_notify_config.example.ini ./hazo_notify_config.in
|
|
|
366
367
|
|
|
367
368
|
**Note:** `JWT_SECRET` is required for JWT session token functionality (used for Edge-compatible proxy/middleware authentication). Generate a secure random string at least 32 characters long.
|
|
368
369
|
|
|
370
|
+
**For Google OAuth (optional):**
|
|
371
|
+
```env
|
|
372
|
+
# NextAuth.js configuration (required for OAuth)
|
|
373
|
+
NEXTAUTH_SECRET=your_secure_random_string_at_least_32_characters
|
|
374
|
+
NEXTAUTH_URL=http://localhost:3000 # Change to production URL in production
|
|
375
|
+
|
|
376
|
+
# Google OAuth credentials (from Google Cloud Console)
|
|
377
|
+
HAZO_AUTH_GOOGLE_CLIENT_ID=your_google_client_id
|
|
378
|
+
HAZO_AUTH_GOOGLE_CLIENT_SECRET=your_google_client_secret
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
See [Google OAuth Setup](#google-oauth-setup) for detailed instructions.
|
|
382
|
+
|
|
369
383
|
**Important:** The configuration files must be located in your project root directory (where `process.cwd()` points to), not inside `node_modules`. The package reads configuration from `process.cwd()` at runtime, so storing them elsewhere (including `node_modules/hazo_auth`) will break runtime access.
|
|
370
384
|
|
|
371
385
|
---
|
|
@@ -672,6 +686,222 @@ npx tsx scripts/apply_migration.ts
|
|
|
672
686
|
|
|
673
687
|
---
|
|
674
688
|
|
|
689
|
+
## Google OAuth Setup
|
|
690
|
+
|
|
691
|
+
hazo_auth supports Google Sign-In via NextAuth.js v4, allowing users to authenticate with their Google accounts.
|
|
692
|
+
|
|
693
|
+
### Features
|
|
694
|
+
|
|
695
|
+
- **Dual authentication**: Users can have BOTH Google OAuth and email/password login
|
|
696
|
+
- **Auto-linking**: Automatically links Google login to existing unverified email/password accounts
|
|
697
|
+
- **Graceful degradation**: Login page adapts based on enabled authentication methods
|
|
698
|
+
- **Set password feature**: Google-only users can add a password later via My Settings
|
|
699
|
+
- **Profile data**: Full name and profile picture automatically populated from Google
|
|
700
|
+
|
|
701
|
+
### Step 1: Get Google OAuth Credentials
|
|
702
|
+
|
|
703
|
+
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
|
|
704
|
+
2. Create a project or select an existing project
|
|
705
|
+
3. Enable Google+ API (or Google Identity Services)
|
|
706
|
+
4. Navigate to **Credentials** → **Create Credentials** → **OAuth 2.0 Client ID**
|
|
707
|
+
5. Configure OAuth consent screen if prompted
|
|
708
|
+
6. Set **Application type** to "Web application"
|
|
709
|
+
7. Add **Authorized JavaScript origins**:
|
|
710
|
+
- Development: `http://localhost:3000`
|
|
711
|
+
- Production: `https://yourdomain.com`
|
|
712
|
+
8. Add **Authorized redirect URIs**:
|
|
713
|
+
- Development: `http://localhost:3000/api/auth/callback/google`
|
|
714
|
+
- Production: `https://yourdomain.com/api/auth/callback/google`
|
|
715
|
+
9. Copy the **Client ID** and **Client Secret**
|
|
716
|
+
|
|
717
|
+
### Step 2: Add Environment Variables
|
|
718
|
+
|
|
719
|
+
Add to your `.env.local`:
|
|
720
|
+
|
|
721
|
+
```env
|
|
722
|
+
# NextAuth.js configuration (REQUIRED for OAuth)
|
|
723
|
+
NEXTAUTH_SECRET=your_secure_random_string_at_least_32_characters
|
|
724
|
+
NEXTAUTH_URL=http://localhost:3000 # Change to production URL in production
|
|
725
|
+
|
|
726
|
+
# Google OAuth credentials (from Google Cloud Console)
|
|
727
|
+
HAZO_AUTH_GOOGLE_CLIENT_ID=your_google_client_id_from_step_1
|
|
728
|
+
HAZO_AUTH_GOOGLE_CLIENT_SECRET=your_google_client_secret_from_step_1
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
**Generate NEXTAUTH_SECRET:**
|
|
732
|
+
```bash
|
|
733
|
+
openssl rand -base64 32
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
### Step 3: Run Database Migration
|
|
737
|
+
|
|
738
|
+
Add OAuth fields to the `hazo_users` table:
|
|
739
|
+
|
|
740
|
+
```bash
|
|
741
|
+
npm run migrate migrations/005_add_oauth_fields_to_hazo_users.sql
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
This migration adds:
|
|
745
|
+
- `google_id` - Google's unique user ID (TEXT, UNIQUE)
|
|
746
|
+
- `auth_providers` - Tracks authentication methods: 'email', 'google', or 'email,google'
|
|
747
|
+
- Index on `google_id` for fast OAuth lookups
|
|
748
|
+
|
|
749
|
+
**Manual migration (if needed):**
|
|
750
|
+
|
|
751
|
+
**PostgreSQL:**
|
|
752
|
+
```sql
|
|
753
|
+
ALTER TABLE hazo_users
|
|
754
|
+
ADD COLUMN google_id TEXT UNIQUE;
|
|
755
|
+
|
|
756
|
+
ALTER TABLE hazo_users
|
|
757
|
+
ADD COLUMN auth_providers TEXT DEFAULT 'email';
|
|
758
|
+
|
|
759
|
+
CREATE INDEX IF NOT EXISTS idx_hazo_users_google_id ON hazo_users(google_id);
|
|
760
|
+
```
|
|
761
|
+
|
|
762
|
+
**SQLite:**
|
|
763
|
+
```sql
|
|
764
|
+
ALTER TABLE hazo_users
|
|
765
|
+
ADD COLUMN google_id TEXT;
|
|
766
|
+
|
|
767
|
+
ALTER TABLE hazo_users
|
|
768
|
+
ADD COLUMN auth_providers TEXT DEFAULT 'email';
|
|
769
|
+
|
|
770
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_hazo_users_google_id_unique ON hazo_users(google_id);
|
|
771
|
+
CREATE INDEX IF NOT EXISTS idx_hazo_users_google_id ON hazo_users(google_id);
|
|
772
|
+
```
|
|
773
|
+
|
|
774
|
+
### Step 4: Configure OAuth in hazo_auth_config.ini
|
|
775
|
+
|
|
776
|
+
```ini
|
|
777
|
+
[hazo_auth__oauth]
|
|
778
|
+
# Enable Google OAuth login (default: true)
|
|
779
|
+
enable_google = true
|
|
780
|
+
|
|
781
|
+
# Enable traditional email/password login (default: true)
|
|
782
|
+
enable_email_password = true
|
|
783
|
+
|
|
784
|
+
# Auto-link Google login to existing unverified email/password accounts (default: true)
|
|
785
|
+
auto_link_unverified_accounts = true
|
|
786
|
+
|
|
787
|
+
# Customize button text (optional)
|
|
788
|
+
google_button_text = Continue with Google
|
|
789
|
+
oauth_divider_text = or
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
### Step 5: Create NextAuth API Routes
|
|
793
|
+
|
|
794
|
+
Create `app/api/auth/[...nextauth]/route.ts`:
|
|
795
|
+
|
|
796
|
+
```typescript
|
|
797
|
+
export { GET, POST } from "hazo_auth/server/routes/nextauth";
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
Create `app/api/hazo_auth/oauth/google/callback/route.ts`:
|
|
801
|
+
|
|
802
|
+
```typescript
|
|
803
|
+
export { GET } from "hazo_auth/server/routes/oauth_google_callback";
|
|
804
|
+
```
|
|
805
|
+
|
|
806
|
+
Create `app/api/hazo_auth/set_password/route.ts`:
|
|
807
|
+
|
|
808
|
+
```typescript
|
|
809
|
+
export { POST } from "hazo_auth/server/routes/set_password";
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
**Or use the CLI generator:**
|
|
813
|
+
```bash
|
|
814
|
+
npx hazo_auth generate-routes --oauth
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
### Step 6: Test Google OAuth
|
|
818
|
+
|
|
819
|
+
1. Start your dev server: `npm run dev`
|
|
820
|
+
2. Visit `http://localhost:3000/hazo_auth/login`
|
|
821
|
+
3. You should see the "Sign in with Google" button
|
|
822
|
+
4. Click it and authenticate with your Google account
|
|
823
|
+
5. You'll be redirected back and logged in
|
|
824
|
+
|
|
825
|
+
### User Flows
|
|
826
|
+
|
|
827
|
+
**New User - Google Sign-In:**
|
|
828
|
+
- User clicks "Sign in with Google"
|
|
829
|
+
- Authenticates with Google
|
|
830
|
+
- Account created with Google profile data (email, name, profile picture)
|
|
831
|
+
- Email is automatically verified
|
|
832
|
+
- User can log in with Google anytime
|
|
833
|
+
|
|
834
|
+
**Existing Unverified User - Google Sign-In:**
|
|
835
|
+
- User has email/password account but hasn't verified email
|
|
836
|
+
- Clicks "Sign in with Google" with same email
|
|
837
|
+
- System auto-links Google account (if `auto_link_unverified_accounts = true`)
|
|
838
|
+
- Email becomes verified
|
|
839
|
+
- User can now log in with EITHER Google OR email/password
|
|
840
|
+
|
|
841
|
+
**Google-Only User Adds Password:**
|
|
842
|
+
- Google-only user visits My Settings
|
|
843
|
+
- "Set Password" section appears
|
|
844
|
+
- User sets a password
|
|
845
|
+
- User can now log in with EITHER method
|
|
846
|
+
|
|
847
|
+
**Google-Only User Tries Forgot Password:**
|
|
848
|
+
- User registered with Google tries "Forgot Password"
|
|
849
|
+
- System shows: "You registered with Google. Please sign in with Google instead."
|
|
850
|
+
|
|
851
|
+
### Configuration Options
|
|
852
|
+
|
|
853
|
+
**Disable email/password login (Google-only):**
|
|
854
|
+
```ini
|
|
855
|
+
[hazo_auth__oauth]
|
|
856
|
+
enable_google = true
|
|
857
|
+
enable_email_password = false
|
|
858
|
+
```
|
|
859
|
+
|
|
860
|
+
**Disable Google OAuth (email/password only):**
|
|
861
|
+
```ini
|
|
862
|
+
[hazo_auth__oauth]
|
|
863
|
+
enable_google = false
|
|
864
|
+
enable_email_password = true
|
|
865
|
+
```
|
|
866
|
+
|
|
867
|
+
### API Response Changes
|
|
868
|
+
|
|
869
|
+
The `/api/hazo_auth/me` endpoint now includes OAuth status:
|
|
870
|
+
|
|
871
|
+
```typescript
|
|
872
|
+
{
|
|
873
|
+
authenticated: true,
|
|
874
|
+
// ... existing fields
|
|
875
|
+
auth_providers: "email,google", // NEW: Tracks authentication methods
|
|
876
|
+
has_password: true, // NEW: Whether user has password set
|
|
877
|
+
google_connected: true, // NEW: Whether Google account is linked
|
|
878
|
+
}
|
|
879
|
+
```
|
|
880
|
+
|
|
881
|
+
### Dependencies
|
|
882
|
+
|
|
883
|
+
Google OAuth adds one new dependency:
|
|
884
|
+
- `next-auth@^4.24.11` - NextAuth.js for OAuth handling (automatically installed with hazo_auth)
|
|
885
|
+
|
|
886
|
+
### Troubleshooting
|
|
887
|
+
|
|
888
|
+
**"Sign in with Google" button not showing:**
|
|
889
|
+
- Verify `enable_google = true` in `[hazo_auth__oauth]` section
|
|
890
|
+
- Check `HAZO_AUTH_GOOGLE_CLIENT_ID` and `HAZO_AUTH_GOOGLE_CLIENT_SECRET` are set
|
|
891
|
+
- Check `NEXTAUTH_URL` matches your current URL
|
|
892
|
+
|
|
893
|
+
**OAuth callback error:**
|
|
894
|
+
- Verify redirect URI in Google Cloud Console matches exactly: `http://localhost:3000/api/auth/callback/google`
|
|
895
|
+
- Check `NEXTAUTH_SECRET` is set and at least 32 characters
|
|
896
|
+
- Verify API routes are created: `/api/auth/[...nextauth]/route.ts` and `/api/hazo_auth/oauth/google/callback/route.ts`
|
|
897
|
+
|
|
898
|
+
**User created but not logged in:**
|
|
899
|
+
- Check browser console for errors
|
|
900
|
+
- Verify `/api/hazo_auth/oauth/google/callback` route exists
|
|
901
|
+
- Check server logs for errors during session creation
|
|
902
|
+
|
|
903
|
+
---
|
|
904
|
+
|
|
675
905
|
## Using Components
|
|
676
906
|
|
|
677
907
|
### Package Exports
|
package/SETUP_CHECKLIST.md
CHANGED
|
@@ -492,6 +492,169 @@ This script will:
|
|
|
492
492
|
|
|
493
493
|
---
|
|
494
494
|
|
|
495
|
+
## Phase 3.2: Google OAuth Setup (Optional)
|
|
496
|
+
|
|
497
|
+
Google OAuth Sign-In allows users to authenticate with their Google accounts. This section is optional - skip if you don't need OAuth.
|
|
498
|
+
|
|
499
|
+
### Step 3.2.1: Get Google OAuth Credentials
|
|
500
|
+
|
|
501
|
+
1. Go to [Google Cloud Console](https://console.cloud.google.com/)
|
|
502
|
+
2. Create a project or select an existing project
|
|
503
|
+
3. Enable **Google+ API** (or Google Identity Services)
|
|
504
|
+
4. Navigate to **Credentials** → **Create Credentials** → **OAuth 2.0 Client ID**
|
|
505
|
+
5. Configure OAuth consent screen if prompted
|
|
506
|
+
6. Set **Application type** to "Web application"
|
|
507
|
+
7. Add **Authorized JavaScript origins**:
|
|
508
|
+
- Development: `http://localhost:3000`
|
|
509
|
+
- Production: `https://yourdomain.com`
|
|
510
|
+
8. Add **Authorized redirect URIs**:
|
|
511
|
+
- Development: `http://localhost:3000/api/auth/callback/google`
|
|
512
|
+
- Production: `https://yourdomain.com/api/auth/callback/google`
|
|
513
|
+
9. Copy the **Client ID** and **Client Secret**
|
|
514
|
+
|
|
515
|
+
### Step 3.2.2: Add OAuth Environment Variables
|
|
516
|
+
|
|
517
|
+
Add to your `.env.local`:
|
|
518
|
+
|
|
519
|
+
```env
|
|
520
|
+
# NextAuth.js configuration (REQUIRED for OAuth)
|
|
521
|
+
NEXTAUTH_SECRET=your_secure_random_string_at_least_32_characters
|
|
522
|
+
NEXTAUTH_URL=http://localhost:3000 # Change to production URL in production
|
|
523
|
+
|
|
524
|
+
# Google OAuth credentials (from Google Cloud Console)
|
|
525
|
+
HAZO_AUTH_GOOGLE_CLIENT_ID=your_google_client_id_from_step_1
|
|
526
|
+
HAZO_AUTH_GOOGLE_CLIENT_SECRET=your_google_client_secret_from_step_1
|
|
527
|
+
```
|
|
528
|
+
|
|
529
|
+
**Generate NEXTAUTH_SECRET:**
|
|
530
|
+
```bash
|
|
531
|
+
openssl rand -base64 32
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
### Step 3.2.3: Run OAuth Database Migration
|
|
535
|
+
|
|
536
|
+
Add OAuth fields to the `hazo_users` table:
|
|
537
|
+
|
|
538
|
+
```bash
|
|
539
|
+
npm run migrate migrations/005_add_oauth_fields_to_hazo_users.sql
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
**Verify migration applied:**
|
|
543
|
+
|
|
544
|
+
**PostgreSQL:**
|
|
545
|
+
```sql
|
|
546
|
+
SELECT column_name FROM information_schema.columns
|
|
547
|
+
WHERE table_name = 'hazo_users'
|
|
548
|
+
AND column_name IN ('google_id', 'auth_providers');
|
|
549
|
+
-- Expected: 2 rows returned
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
**SQLite:**
|
|
553
|
+
```bash
|
|
554
|
+
sqlite3 data/hazo_auth.sqlite ".schema hazo_users" | grep -E "google_id|auth_providers"
|
|
555
|
+
# Expected: google_id TEXT UNIQUE, auth_providers TEXT DEFAULT 'email'
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
**Manual migration (if needed):**
|
|
559
|
+
|
|
560
|
+
**PostgreSQL:**
|
|
561
|
+
```sql
|
|
562
|
+
ALTER TABLE hazo_users ADD COLUMN google_id TEXT UNIQUE;
|
|
563
|
+
ALTER TABLE hazo_users ADD COLUMN auth_providers TEXT DEFAULT 'email';
|
|
564
|
+
CREATE INDEX IF NOT EXISTS idx_hazo_users_google_id ON hazo_users(google_id);
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
**SQLite:**
|
|
568
|
+
```sql
|
|
569
|
+
ALTER TABLE hazo_users ADD COLUMN google_id TEXT;
|
|
570
|
+
ALTER TABLE hazo_users ADD COLUMN auth_providers TEXT DEFAULT 'email';
|
|
571
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_hazo_users_google_id_unique ON hazo_users(google_id);
|
|
572
|
+
CREATE INDEX IF NOT EXISTS idx_hazo_users_google_id ON hazo_users(google_id);
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
### Step 3.2.4: Configure OAuth in hazo_auth_config.ini
|
|
576
|
+
|
|
577
|
+
Add (or modify) the OAuth section:
|
|
578
|
+
|
|
579
|
+
```ini
|
|
580
|
+
[hazo_auth__oauth]
|
|
581
|
+
# Enable Google OAuth login (default: true)
|
|
582
|
+
enable_google = true
|
|
583
|
+
|
|
584
|
+
# Enable traditional email/password login (default: true)
|
|
585
|
+
enable_email_password = true
|
|
586
|
+
|
|
587
|
+
# Auto-link Google login to existing unverified email/password accounts (default: true)
|
|
588
|
+
auto_link_unverified_accounts = true
|
|
589
|
+
|
|
590
|
+
# Customize button text (optional)
|
|
591
|
+
google_button_text = Continue with Google
|
|
592
|
+
oauth_divider_text = or
|
|
593
|
+
```
|
|
594
|
+
|
|
595
|
+
**Configuration Options:**
|
|
596
|
+
|
|
597
|
+
- **Google-only authentication** (no email/password):
|
|
598
|
+
```ini
|
|
599
|
+
enable_google = true
|
|
600
|
+
enable_email_password = false
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
- **Email/password only** (no OAuth):
|
|
604
|
+
```ini
|
|
605
|
+
enable_google = false
|
|
606
|
+
enable_email_password = true
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
- **Both methods** (recommended):
|
|
610
|
+
```ini
|
|
611
|
+
enable_google = true
|
|
612
|
+
enable_email_password = true
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
### Step 3.2.5: Create OAuth API Routes
|
|
616
|
+
|
|
617
|
+
**Option A: Use CLI generator (Recommended):**
|
|
618
|
+
```bash
|
|
619
|
+
npx hazo_auth generate-routes --oauth
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
**Option B: Create manually:**
|
|
623
|
+
|
|
624
|
+
Create `app/api/auth/[...nextauth]/route.ts`:
|
|
625
|
+
```typescript
|
|
626
|
+
export { GET, POST } from "hazo_auth/server/routes/nextauth";
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
Create `app/api/hazo_auth/oauth/google/callback/route.ts`:
|
|
630
|
+
```typescript
|
|
631
|
+
export { GET } from "hazo_auth/server/routes/oauth_google_callback";
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
Create `app/api/hazo_auth/set_password/route.ts`:
|
|
635
|
+
```typescript
|
|
636
|
+
export { POST } from "hazo_auth/server/routes/set_password";
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
### Step 3.2.6: Verify OAuth API Routes
|
|
640
|
+
|
|
641
|
+
```bash
|
|
642
|
+
ls app/api/auth/\[...nextauth\]/route.ts
|
|
643
|
+
ls app/api/hazo_auth/oauth/google/callback/route.ts
|
|
644
|
+
ls app/api/hazo_auth/set_password/route.ts
|
|
645
|
+
# All files should exist
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
**OAuth Setup Checklist:**
|
|
649
|
+
- [ ] Google OAuth credentials obtained
|
|
650
|
+
- [ ] `NEXTAUTH_SECRET` and `NEXTAUTH_URL` set in `.env.local`
|
|
651
|
+
- [ ] `HAZO_AUTH_GOOGLE_CLIENT_ID` and `HAZO_AUTH_GOOGLE_CLIENT_SECRET` set
|
|
652
|
+
- [ ] OAuth migration applied (google_id and auth_providers columns added)
|
|
653
|
+
- [ ] `[hazo_auth__oauth]` section configured in `hazo_auth_config.ini`
|
|
654
|
+
- [ ] OAuth API routes created (`[...nextauth]`, `oauth/google/callback`, `set_password`)
|
|
655
|
+
|
|
656
|
+
---
|
|
657
|
+
|
|
495
658
|
## Phase 4: API Routes
|
|
496
659
|
|
|
497
660
|
Create API route files in your project. Each file re-exports handlers from hazo_auth.
|
|
@@ -956,6 +1119,45 @@ Visit each page and verify it loads:
|
|
|
956
1119
|
- [ ] `http://localhost:3000/hazo_auth/my_settings` - Settings page displays (after login)
|
|
957
1120
|
- [ ] `http://localhost:3000/hazo_auth/profile_stamp_test` - ProfileStamp component examples display
|
|
958
1121
|
|
|
1122
|
+
### Test 7: Google OAuth (if configured)
|
|
1123
|
+
|
|
1124
|
+
If you completed Phase 3.2 (Google OAuth Setup):
|
|
1125
|
+
|
|
1126
|
+
**Check login page:**
|
|
1127
|
+
1. Visit `http://localhost:3000/hazo_auth/login`
|
|
1128
|
+
2. Verify "Sign in with Google" button appears
|
|
1129
|
+
3. Verify divider with "or" text (if email/password is also enabled)
|
|
1130
|
+
|
|
1131
|
+
**Test Google sign-in:**
|
|
1132
|
+
1. Click "Sign in with Google" button
|
|
1133
|
+
2. You should be redirected to Google's login page
|
|
1134
|
+
3. Sign in with your Google account
|
|
1135
|
+
4. You should be redirected back to your app and logged in
|
|
1136
|
+
5. Visit `/hazo_auth/my_settings`
|
|
1137
|
+
6. Verify "Connected Accounts" section shows Google as connected
|
|
1138
|
+
|
|
1139
|
+
**Test Google-only user features:**
|
|
1140
|
+
1. If you signed in with Google (and didn't have a password account first):
|
|
1141
|
+
2. Visit `/hazo_auth/my_settings`
|
|
1142
|
+
3. Verify "Set Password" section appears
|
|
1143
|
+
4. Set a password
|
|
1144
|
+
5. Log out and try logging in with email/password (should work)
|
|
1145
|
+
|
|
1146
|
+
**Test forgot password with Google-only user:**
|
|
1147
|
+
1. Create a new user with Google OAuth only
|
|
1148
|
+
2. Try visiting `/hazo_auth/forgot_password`
|
|
1149
|
+
3. Enter the Google user's email
|
|
1150
|
+
4. Should show message: "You registered with Google. Please sign in with Google instead."
|
|
1151
|
+
|
|
1152
|
+
**OAuth Test Checklist:**
|
|
1153
|
+
- [ ] "Sign in with Google" button appears on login page
|
|
1154
|
+
- [ ] OAuth divider appears (if both auth methods enabled)
|
|
1155
|
+
- [ ] Google OAuth flow completes successfully
|
|
1156
|
+
- [ ] User is logged in after OAuth callback
|
|
1157
|
+
- [ ] Connected Accounts section shows Google in My Settings
|
|
1158
|
+
- [ ] Set Password feature works for Google-only users
|
|
1159
|
+
- [ ] Forgot password shows appropriate message for Google-only users
|
|
1160
|
+
|
|
959
1161
|
---
|
|
960
1162
|
|
|
961
1163
|
## Phase 7: HRBAC Setup (Optional)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// file_description: CLI entry wrapper that handles ESM module resolution
|
|
3
|
+
// This wrapper ensures the CLI works in consuming projects with proper module resolution
|
|
4
|
+
|
|
5
|
+
import { spawn } from 'child_process';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import { dirname, join } from 'path';
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = dirname(__filename);
|
|
11
|
+
|
|
12
|
+
// Get the path to the CLI TypeScript source file (included in the package)
|
|
13
|
+
// Structure: cli-src/cli/index.ts and cli-src/lib/* for relative imports
|
|
14
|
+
const cliPath = join(__dirname, '..', 'cli-src', 'cli', 'index.ts');
|
|
15
|
+
|
|
16
|
+
const args = process.argv.slice(2);
|
|
17
|
+
|
|
18
|
+
// Use tsx to run the TypeScript source directly
|
|
19
|
+
// This avoids ESM module resolution issues with compiled JS
|
|
20
|
+
// tsx is a dependency of hazo_auth so it should be available
|
|
21
|
+
const child = spawn('npx', ['tsx', cliPath, ...args], {
|
|
22
|
+
stdio: 'inherit',
|
|
23
|
+
cwd: process.cwd(),
|
|
24
|
+
shell: true
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
child.on('exit', (code) => {
|
|
28
|
+
process.exit(code ?? 0);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
child.on('error', (err) => {
|
|
32
|
+
console.error('Failed to start CLI:', err.message);
|
|
33
|
+
console.error('Make sure tsx is available: npm install -D tsx');
|
|
34
|
+
process.exit(1);
|
|
35
|
+
});
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|