hazo_auth 1.6.0 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +191 -19
- package/SETUP_CHECKLIST.md +190 -65
- package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.d.ts +9 -0
- package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.d.ts.map +1 -0
- package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.js +82 -0
- package/dist/app/api/hazo_auth/library_photos/route.d.ts +9 -0
- package/dist/app/api/hazo_auth/library_photos/route.d.ts.map +1 -1
- package/dist/app/api/hazo_auth/library_photos/route.js +31 -6
- package/dist/cli/generate.d.ts +6 -1
- package/dist/cli/generate.d.ts.map +1 -1
- package/dist/cli/generate.js +101 -34
- package/dist/cli/index.js +64 -11
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +206 -0
- package/dist/client.d.ts +8 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +25 -0
- package/dist/components/layouts/email_verification/index.d.ts +2 -1
- package/dist/components/layouts/email_verification/index.d.ts.map +1 -1
- package/dist/components/layouts/email_verification/index.js +3 -2
- package/dist/components/layouts/forgot_password/index.d.ts +3 -1
- package/dist/components/layouts/forgot_password/index.d.ts.map +1 -1
- package/dist/components/layouts/forgot_password/index.js +3 -2
- package/dist/components/layouts/my_settings/components/editable_field.js +1 -1
- package/dist/components/layouts/my_settings/components/password_change_dialog.js +1 -1
- package/dist/components/layouts/my_settings/components/profile_picture_display.js +1 -1
- package/dist/components/layouts/my_settings/components/profile_picture_gravatar_tab.js +1 -1
- package/dist/components/layouts/my_settings/components/profile_picture_library_tab.js +4 -4
- package/dist/components/layouts/my_settings/components/profile_picture_upload_tab.js +4 -4
- package/dist/components/layouts/my_settings/index.js +1 -1
- package/dist/components/layouts/shared/components/profile_pic_menu.js +2 -2
- package/dist/lib/auth_utility_config.server.js +2 -2
- package/dist/lib/services/profile_picture_service.d.ts +34 -2
- package/dist/lib/services/profile_picture_service.d.ts.map +1 -1
- package/dist/lib/services/profile_picture_service.js +157 -15
- package/dist/lib/services/user_profiles_cache.d.ts +76 -0
- package/dist/lib/services/user_profiles_cache.d.ts.map +1 -0
- package/dist/lib/services/user_profiles_cache.js +141 -0
- package/dist/lib/services/user_profiles_service.d.ts +17 -0
- package/dist/lib/services/user_profiles_service.d.ts.map +1 -1
- package/dist/lib/services/user_profiles_service.js +136 -44
- package/dist/lib/user_profiles_config.server.d.ts +15 -0
- package/dist/lib/user_profiles_config.server.d.ts.map +1 -0
- package/dist/lib/user_profiles_config.server.js +23 -0
- package/dist/page_components/forgot_password.d.ts +19 -0
- package/dist/page_components/forgot_password.d.ts.map +1 -0
- package/dist/page_components/forgot_password.js +36 -0
- package/dist/page_components/index.d.ts +7 -0
- package/dist/page_components/index.d.ts.map +1 -0
- package/dist/page_components/index.js +9 -0
- package/dist/page_components/login.d.ts +26 -0
- package/dist/page_components/login.d.ts.map +1 -0
- package/dist/page_components/login.js +40 -0
- package/dist/page_components/my_settings.d.ts +64 -0
- package/dist/page_components/my_settings.d.ts.map +1 -0
- package/dist/page_components/my_settings.js +67 -0
- package/dist/page_components/register.d.ts +25 -0
- package/dist/page_components/register.d.ts.map +1 -0
- package/dist/page_components/register.js +43 -0
- package/dist/page_components/reset_password.d.ts +25 -0
- package/dist/page_components/reset_password.d.ts.map +1 -0
- package/dist/page_components/reset_password.js +43 -0
- package/dist/page_components/verify_email.d.ts +21 -0
- package/dist/page_components/verify_email.d.ts.map +1 -0
- package/dist/page_components/verify_email.js +36 -0
- package/dist/server/routes/index.d.ts +1 -0
- package/dist/server/routes/index.d.ts.map +1 -1
- package/dist/server/routes/index.js +1 -0
- package/dist/server/routes/library_photo.d.ts +2 -0
- package/dist/server/routes/library_photo.d.ts.map +1 -0
- package/dist/server/routes/library_photo.js +3 -0
- package/hazo_auth_config.example.ini +25 -5
- package/package.json +33 -1
package/README.md
CHANGED
|
@@ -26,32 +26,61 @@ npm install hazo_auth
|
|
|
26
26
|
|
|
27
27
|
## Quick Start
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
The fastest way to get started is using the CLI commands:
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
+
# 1. Install the package
|
|
32
33
|
npm install hazo_auth
|
|
34
|
+
|
|
35
|
+
# 2. Initialize your project (creates directories, copies config files)
|
|
36
|
+
npx hazo_auth init
|
|
37
|
+
|
|
38
|
+
# 3. Generate API routes and pages
|
|
39
|
+
npx hazo_auth generate-routes --pages
|
|
40
|
+
|
|
41
|
+
# 4. Set up environment variables
|
|
42
|
+
cp .env.local.example .env.local
|
|
43
|
+
# Edit .env.local and add your ZEPTOMAIL_API_KEY
|
|
44
|
+
|
|
45
|
+
# 5. Start your dev server
|
|
46
|
+
npm run dev
|
|
33
47
|
```
|
|
34
48
|
|
|
35
|
-
|
|
49
|
+
That's it! Visit `http://localhost:3000/hazo_auth/login` to see the login page.
|
|
50
|
+
|
|
51
|
+
### CLI Commands
|
|
36
52
|
|
|
37
53
|
```bash
|
|
38
|
-
|
|
39
|
-
|
|
54
|
+
npx hazo_auth init # Initialize project (creates dirs, copies config)
|
|
55
|
+
npx hazo_auth generate-routes # Generate API routes only
|
|
56
|
+
npx hazo_auth generate-routes --pages # Generate API routes + pages
|
|
57
|
+
npx hazo_auth validate # Check your setup and configuration
|
|
58
|
+
npx hazo_auth --help # Show all commands
|
|
40
59
|
```
|
|
41
60
|
|
|
42
|
-
###
|
|
61
|
+
### Using Zero-Config Page Components
|
|
43
62
|
|
|
44
|
-
|
|
63
|
+
The generated pages import from `hazo_auth/pages/*` which provides zero-config components:
|
|
45
64
|
|
|
46
|
-
```
|
|
47
|
-
|
|
65
|
+
```typescript
|
|
66
|
+
// Generated app/hazo_auth/login/page.tsx
|
|
67
|
+
import { LoginPage } from "hazo_auth/pages/login";
|
|
68
|
+
export default LoginPage;
|
|
48
69
|
```
|
|
49
70
|
|
|
50
|
-
|
|
71
|
+
Available zero-config pages:
|
|
72
|
+
- `LoginPage` - Login form with sensible defaults
|
|
73
|
+
- `RegisterPage` - Registration with password requirements
|
|
74
|
+
- `ForgotPasswordPage` - Password reset request
|
|
75
|
+
- `ResetPasswordPage` - Set new password
|
|
76
|
+
- `VerifyEmailPage` - Email verification
|
|
77
|
+
- `MySettingsPage` - User profile and settings
|
|
78
|
+
|
|
79
|
+
All pages work out-of-the-box with no props required!
|
|
51
80
|
|
|
52
|
-
|
|
81
|
+
### Manual Setup (Advanced)
|
|
53
82
|
|
|
54
|
-
|
|
83
|
+
If you prefer manual control, you can use the layout components directly:
|
|
55
84
|
|
|
56
85
|
```typescript
|
|
57
86
|
// Import layout components
|
|
@@ -77,6 +106,132 @@ import { hazo_get_auth } from "hazo_auth/lib/auth/hazo_get_auth.server";
|
|
|
77
106
|
|
|
78
107
|
---
|
|
79
108
|
|
|
109
|
+
## Required Dependencies
|
|
110
|
+
|
|
111
|
+
hazo_auth uses shadcn/ui components. Install the required dependencies in your project:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Required for all auth pages
|
|
115
|
+
npx shadcn@latest add button input label
|
|
116
|
+
|
|
117
|
+
# Required for My Settings page
|
|
118
|
+
npx shadcn@latest add dialog tabs switch avatar dropdown-menu
|
|
119
|
+
|
|
120
|
+
# Required for toast notifications
|
|
121
|
+
npx shadcn@latest add sonner
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Add Toaster to your app layout:**
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
// app/layout.tsx
|
|
128
|
+
import { Toaster } from "sonner";
|
|
129
|
+
|
|
130
|
+
export default function RootLayout({ children }) {
|
|
131
|
+
return (
|
|
132
|
+
<html>
|
|
133
|
+
<body>
|
|
134
|
+
{children}
|
|
135
|
+
<Toaster />
|
|
136
|
+
</body>
|
|
137
|
+
</html>
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Client vs Server Imports
|
|
145
|
+
|
|
146
|
+
hazo_auth provides separate entry points for client and server code to avoid bundling Node.js modules in the browser:
|
|
147
|
+
|
|
148
|
+
### Client Components
|
|
149
|
+
|
|
150
|
+
For client components (browser-safe, no Node.js dependencies):
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// Use hazo_auth/client for client components
|
|
154
|
+
import {
|
|
155
|
+
ProfilePicMenu,
|
|
156
|
+
use_auth_status,
|
|
157
|
+
use_hazo_auth,
|
|
158
|
+
cn
|
|
159
|
+
} from "hazo_auth/client";
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Server Components / API Routes
|
|
163
|
+
|
|
164
|
+
For server-side code (API routes, Server Components):
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
// Use the main hazo_auth export for server-side code
|
|
168
|
+
import { hazo_get_auth, get_config_value } from "hazo_auth";
|
|
169
|
+
import { hazo_get_user_profiles } from "hazo_auth";
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Why This Matters
|
|
173
|
+
|
|
174
|
+
If you import from the main `hazo_auth` entry in a client component, you'll get bundling errors like:
|
|
175
|
+
```
|
|
176
|
+
Module not found: Can't resolve 'fs'
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Use `hazo_auth/client` to avoid this.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Dark Mode / Theming
|
|
184
|
+
|
|
185
|
+
hazo_auth supports dark mode via CSS custom properties. To enable dark mode:
|
|
186
|
+
|
|
187
|
+
### 1. Import the theme CSS
|
|
188
|
+
|
|
189
|
+
Copy the variables file to your project:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
cp node_modules/hazo_auth/src/styles/hazo-auth-variables.css ./app/hazo-auth-theme.css
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Import in your `globals.css`:
|
|
196
|
+
|
|
197
|
+
```css
|
|
198
|
+
@import "./hazo-auth-theme.css";
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### 2. CSS Variables Reference
|
|
202
|
+
|
|
203
|
+
You can customize the theme by overriding these variables:
|
|
204
|
+
|
|
205
|
+
```css
|
|
206
|
+
:root {
|
|
207
|
+
/* Backgrounds */
|
|
208
|
+
--hazo-bg-subtle: #f8fafc; /* Light background */
|
|
209
|
+
--hazo-bg-muted: #f1f5f9; /* Slightly darker background */
|
|
210
|
+
|
|
211
|
+
/* Text */
|
|
212
|
+
--hazo-text-primary: #0f172a; /* Primary text */
|
|
213
|
+
--hazo-text-secondary: #334155; /* Secondary text */
|
|
214
|
+
--hazo-text-muted: #64748b; /* Muted/subtle text */
|
|
215
|
+
|
|
216
|
+
/* Borders */
|
|
217
|
+
--hazo-border: #e2e8f0; /* Standard border */
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.dark {
|
|
221
|
+
/* Dark mode overrides */
|
|
222
|
+
--hazo-bg-subtle: #18181b;
|
|
223
|
+
--hazo-bg-muted: #27272a;
|
|
224
|
+
--hazo-text-primary: #fafafa;
|
|
225
|
+
--hazo-text-secondary: #d4d4d8;
|
|
226
|
+
--hazo-text-muted: #a1a1aa;
|
|
227
|
+
--hazo-border: #3f3f46;
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
The dark class is typically added by next-themes or similar theme providers.
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
80
235
|
## Configuration Setup
|
|
81
236
|
|
|
82
237
|
After installing the package, you need to set up configuration files in your project root:
|
|
@@ -415,7 +570,25 @@ The package exports components through these paths:
|
|
|
415
570
|
// Main entry point - exports all public APIs
|
|
416
571
|
import { ... } from "hazo_auth";
|
|
417
572
|
|
|
418
|
-
//
|
|
573
|
+
// Zero-config page components (recommended for quick setup)
|
|
574
|
+
import { LoginPage } from "hazo_auth/pages/login";
|
|
575
|
+
import { RegisterPage } from "hazo_auth/pages/register";
|
|
576
|
+
import { ForgotPasswordPage } from "hazo_auth/pages/forgot_password";
|
|
577
|
+
import { ResetPasswordPage } from "hazo_auth/pages/reset_password";
|
|
578
|
+
import { VerifyEmailPage } from "hazo_auth/pages/verify_email";
|
|
579
|
+
import { MySettingsPage } from "hazo_auth/pages/my_settings";
|
|
580
|
+
|
|
581
|
+
// Or import all pages at once
|
|
582
|
+
import {
|
|
583
|
+
LoginPage,
|
|
584
|
+
RegisterPage,
|
|
585
|
+
ForgotPasswordPage,
|
|
586
|
+
ResetPasswordPage,
|
|
587
|
+
VerifyEmailPage,
|
|
588
|
+
MySettingsPage
|
|
589
|
+
} from "hazo_auth/pages";
|
|
590
|
+
|
|
591
|
+
// Layout components - for custom implementations
|
|
419
592
|
import { LoginLayout } from "hazo_auth/components/layouts/login";
|
|
420
593
|
import { RegisterLayout } from "hazo_auth/components/layouts/register";
|
|
421
594
|
import { ForgotPasswordLayout } from "hazo_auth/components/layouts/forgot_password";
|
|
@@ -903,22 +1076,21 @@ This compiles the `src/` directory to `dist/` with:
|
|
|
903
1076
|
|
|
904
1077
|
### Package Exports
|
|
905
1078
|
|
|
906
|
-
The `package.json` exports field defines the public API
|
|
1079
|
+
The `package.json` exports field defines the public API:
|
|
907
1080
|
|
|
908
1081
|
```json
|
|
909
1082
|
{
|
|
910
1083
|
"exports": {
|
|
911
1084
|
".": "./dist/index.js",
|
|
1085
|
+
"./pages": "./dist/page_components/index.js",
|
|
1086
|
+
"./pages/login": "./dist/page_components/login.js",
|
|
1087
|
+
"./pages/register": "./dist/page_components/register.js",
|
|
912
1088
|
"./components/layouts/login": "./dist/components/layouts/login/index.js",
|
|
913
1089
|
"./components/layouts/register": "./dist/components/layouts/register/index.js",
|
|
914
|
-
"./components/layouts/forgot_password": "./dist/components/layouts/forgot_password/index.js",
|
|
915
|
-
"./components/layouts/reset_password": "./dist/components/layouts/reset_password/index.js",
|
|
916
|
-
"./components/layouts/email_verification": "./dist/components/layouts/email_verification/index.js",
|
|
917
|
-
"./components/layouts/my_settings": "./dist/components/layouts/my_settings/index.js",
|
|
918
|
-
"./components/layouts/user_management": "./dist/components/layouts/user_management/index.js",
|
|
919
1090
|
"./components/layouts/shared": "./dist/components/layouts/shared/index.js",
|
|
920
1091
|
"./lib/auth/hazo_get_auth.server": "./dist/lib/auth/hazo_get_auth.server.js",
|
|
921
|
-
"./server": "./dist/server/index.js"
|
|
1092
|
+
"./server": "./dist/server/index.js",
|
|
1093
|
+
"./server/routes": "./dist/server/routes/index.js"
|
|
922
1094
|
}
|
|
923
1095
|
}
|
|
924
1096
|
```
|
package/SETUP_CHECKLIST.md
CHANGED
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
This checklist provides step-by-step instructions for setting up the `hazo_auth` package in your Next.js project. AI assistants can follow this guide to ensure complete and correct setup.
|
|
4
4
|
|
|
5
|
+
## Quick Start (Recommended)
|
|
6
|
+
|
|
7
|
+
The fastest way to set up hazo_auth:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# 1. Install the package
|
|
11
|
+
npm install hazo_auth
|
|
12
|
+
|
|
13
|
+
# 2. Initialize project (creates directories, copies config files)
|
|
14
|
+
npx hazo_auth init
|
|
15
|
+
|
|
16
|
+
# 3. Generate API routes and pages
|
|
17
|
+
npx hazo_auth generate-routes --pages
|
|
18
|
+
|
|
19
|
+
# 4. Set up environment variables
|
|
20
|
+
cp .env.local.example .env.local
|
|
21
|
+
# Edit .env.local and add ZEPTOMAIL_API_KEY
|
|
22
|
+
|
|
23
|
+
# 5. Start dev server and test
|
|
24
|
+
npm run dev
|
|
25
|
+
# Visit http://localhost:3000/hazo_auth/login
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
If this works, skip to [Phase 6: Verification Tests](#phase-6-verification-tests).
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
5
32
|
## Pre-flight Checks
|
|
6
33
|
|
|
7
34
|
Before starting, verify your project meets these requirements:
|
|
@@ -33,7 +60,79 @@ ls node_modules/hazo_auth/package.json
|
|
|
33
60
|
# Expected: file exists
|
|
34
61
|
```
|
|
35
62
|
|
|
36
|
-
### Step 1.2:
|
|
63
|
+
### Step 1.2: Install Required shadcn/ui Components
|
|
64
|
+
|
|
65
|
+
hazo_auth uses shadcn/ui components. Install the required dependencies:
|
|
66
|
+
|
|
67
|
+
**For all auth pages (login, register, etc.):**
|
|
68
|
+
```bash
|
|
69
|
+
npx shadcn@latest add button input label
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**For My Settings page:**
|
|
73
|
+
```bash
|
|
74
|
+
npx shadcn@latest add dialog tabs switch avatar dropdown-menu
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**For toast notifications:**
|
|
78
|
+
```bash
|
|
79
|
+
npx shadcn@latest add sonner
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Add Toaster to your app layout:**
|
|
83
|
+
|
|
84
|
+
Edit `app/layout.tsx` and add the Toaster component:
|
|
85
|
+
|
|
86
|
+
```tsx
|
|
87
|
+
import { Toaster } from "sonner";
|
|
88
|
+
|
|
89
|
+
export default function RootLayout({ children }) {
|
|
90
|
+
return (
|
|
91
|
+
<html>
|
|
92
|
+
<body>
|
|
93
|
+
{children}
|
|
94
|
+
<Toaster />
|
|
95
|
+
</body>
|
|
96
|
+
</html>
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Step 1.4: Enable Dark Mode Support (Optional)
|
|
102
|
+
|
|
103
|
+
hazo_auth components support dark mode via CSS custom properties. Add the CSS variables to your global styles:
|
|
104
|
+
|
|
105
|
+
**Copy the CSS variables file:**
|
|
106
|
+
```bash
|
|
107
|
+
cp node_modules/hazo_auth/src/styles/hazo-auth-variables.css ./app/hazo-auth-theme.css
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Import in your global styles (`app/globals.css`):**
|
|
111
|
+
```css
|
|
112
|
+
@import "./hazo-auth-theme.css";
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Or add the variables directly to your CSS - see the file for all available variables.
|
|
116
|
+
|
|
117
|
+
### Step 1.5: Initialize project (Recommended)
|
|
118
|
+
|
|
119
|
+
Use the CLI to automatically set up directories and copy config files:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npx hazo_auth init
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
This command:
|
|
126
|
+
- Creates `public/profile_pictures/library/` directory
|
|
127
|
+
- Creates `public/profile_pictures/uploads/` directory
|
|
128
|
+
- Creates `data/` directory (for SQLite database)
|
|
129
|
+
- Copies `hazo_auth_config.ini` and `hazo_notify_config.ini`
|
|
130
|
+
- Copies profile picture library images
|
|
131
|
+
- Creates `.env.local.example` template
|
|
132
|
+
|
|
133
|
+
### Step 1.2b: Manual config setup (Alternative)
|
|
134
|
+
|
|
135
|
+
If you prefer manual setup:
|
|
37
136
|
|
|
38
137
|
```bash
|
|
39
138
|
cp node_modules/hazo_auth/hazo_auth_config.example.ini ./hazo_auth_config.ini
|
|
@@ -424,86 +523,92 @@ export { GET } from "hazo_auth/server/routes/profile_picture_filename";
|
|
|
424
523
|
|
|
425
524
|
Create page files for each auth flow.
|
|
426
525
|
|
|
427
|
-
### Step 5.1:
|
|
526
|
+
### Step 5.1: Generate pages automatically (Recommended)
|
|
428
527
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
import { LoginLayout } from "hazo_auth/components/layouts/login";
|
|
432
|
-
|
|
433
|
-
export default function LoginPage() {
|
|
434
|
-
return <LoginLayout />;
|
|
435
|
-
}
|
|
528
|
+
```bash
|
|
529
|
+
npx hazo_auth generate-routes --pages
|
|
436
530
|
```
|
|
437
531
|
|
|
438
|
-
|
|
439
|
-
```typescript
|
|
440
|
-
import { RegisterLayout } from "hazo_auth/components/layouts/register";
|
|
532
|
+
This generates both API routes and page routes. The generated pages use zero-config components that work out of the box.
|
|
441
533
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
534
|
+
**Generated pages:**
|
|
535
|
+
```
|
|
536
|
+
app/hazo_auth/
|
|
537
|
+
├── login/page.tsx
|
|
538
|
+
├── register/page.tsx
|
|
539
|
+
├── forgot_password/page.tsx
|
|
540
|
+
├── reset_password/page.tsx
|
|
541
|
+
├── verify_email/page.tsx
|
|
542
|
+
└── my_settings/page.tsx
|
|
445
543
|
```
|
|
446
544
|
|
|
447
|
-
|
|
448
|
-
```typescript
|
|
449
|
-
import { ForgotPasswordLayout } from "hazo_auth/components/layouts/forgot_password";
|
|
545
|
+
### Step 5.2: Manual page creation (Alternative)
|
|
450
546
|
|
|
451
|
-
|
|
452
|
-
return <ForgotPasswordLayout />;
|
|
453
|
-
}
|
|
454
|
-
```
|
|
547
|
+
If you prefer manual setup or need custom paths, create these files:
|
|
455
548
|
|
|
456
|
-
**
|
|
549
|
+
**Login page** - `app/hazo_auth/login/page.tsx`:
|
|
457
550
|
```typescript
|
|
458
|
-
import {
|
|
551
|
+
import { LoginPage } from "hazo_auth/pages/login";
|
|
552
|
+
export default LoginPage;
|
|
553
|
+
```
|
|
459
554
|
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
}
|
|
555
|
+
**Register page** - `app/hazo_auth/register/page.tsx`:
|
|
556
|
+
```typescript
|
|
557
|
+
import { RegisterPage } from "hazo_auth/pages/register";
|
|
558
|
+
export default RegisterPage;
|
|
463
559
|
```
|
|
464
560
|
|
|
465
|
-
**
|
|
561
|
+
**Forgot password page** - `app/hazo_auth/forgot_password/page.tsx`:
|
|
466
562
|
```typescript
|
|
467
|
-
import {
|
|
563
|
+
import { ForgotPasswordPage } from "hazo_auth/pages/forgot_password";
|
|
564
|
+
export default ForgotPasswordPage;
|
|
565
|
+
```
|
|
468
566
|
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
}
|
|
567
|
+
**Reset password page** - `app/hazo_auth/reset_password/page.tsx`:
|
|
568
|
+
```typescript
|
|
569
|
+
import { ResetPasswordPage } from "hazo_auth/pages/reset_password";
|
|
570
|
+
export default ResetPasswordPage;
|
|
472
571
|
```
|
|
473
572
|
|
|
474
|
-
**
|
|
573
|
+
**Email verification page** - `app/hazo_auth/verify_email/page.tsx`:
|
|
475
574
|
```typescript
|
|
476
|
-
import {
|
|
575
|
+
import { VerifyEmailPage } from "hazo_auth/pages/verify_email";
|
|
576
|
+
export default VerifyEmailPage;
|
|
577
|
+
```
|
|
477
578
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
}
|
|
579
|
+
**My settings page** - `app/hazo_auth/my_settings/page.tsx`:
|
|
580
|
+
```typescript
|
|
581
|
+
import { MySettingsPage } from "hazo_auth/pages/my_settings";
|
|
582
|
+
export default MySettingsPage;
|
|
481
583
|
```
|
|
482
584
|
|
|
483
|
-
### Step 5.
|
|
585
|
+
### Step 5.3: Custom page routes (Advanced)
|
|
586
|
+
|
|
587
|
+
If you need custom paths or want to wrap pages with your own layout:
|
|
484
588
|
|
|
485
|
-
`app/(auth)/layout.tsx`:
|
|
486
589
|
```typescript
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
}) {
|
|
590
|
+
// app/(auth)/login/page.tsx
|
|
591
|
+
import { LoginPage } from "hazo_auth/pages/login";
|
|
592
|
+
|
|
593
|
+
export default function CustomLoginPage() {
|
|
492
594
|
return (
|
|
493
|
-
<div className="min-h-screen flex items-center justify-center
|
|
494
|
-
|
|
595
|
+
<div className="min-h-screen flex items-center justify-center">
|
|
596
|
+
<LoginPage
|
|
597
|
+
redirectRoute="/dashboard"
|
|
598
|
+
successMessage="Welcome back!"
|
|
599
|
+
/>
|
|
495
600
|
</div>
|
|
496
601
|
);
|
|
497
602
|
}
|
|
498
603
|
```
|
|
499
604
|
|
|
500
605
|
**Checklist:**
|
|
501
|
-
- [ ] Login page created (`/login`)
|
|
502
|
-
- [ ] Register page created (`/register`)
|
|
503
|
-
- [ ] Forgot password page created (`/
|
|
504
|
-
- [ ] Reset password page created (`/
|
|
505
|
-
- [ ] Email verification page created (`/
|
|
506
|
-
- [ ] My settings page created (`/
|
|
606
|
+
- [ ] Login page created (`/hazo_auth/login`)
|
|
607
|
+
- [ ] Register page created (`/hazo_auth/register`)
|
|
608
|
+
- [ ] Forgot password page created (`/hazo_auth/forgot_password`)
|
|
609
|
+
- [ ] Reset password page created (`/hazo_auth/reset_password`)
|
|
610
|
+
- [ ] Email verification page created (`/hazo_auth/verify_email`)
|
|
611
|
+
- [ ] My settings page created (`/hazo_auth/my_settings`)
|
|
507
612
|
|
|
508
613
|
---
|
|
509
614
|
|
|
@@ -578,15 +683,22 @@ curl -s http://localhost:3000/api/hazo_auth/library_photos | jq
|
|
|
578
683
|
**Expected response:**
|
|
579
684
|
```json
|
|
580
685
|
{
|
|
581
|
-
"
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
]
|
|
686
|
+
"success": true,
|
|
687
|
+
"categories": ["Cars", "Young Cartoons"],
|
|
688
|
+
"source": "project"
|
|
585
689
|
}
|
|
586
690
|
```
|
|
587
691
|
|
|
588
|
-
|
|
589
|
-
-
|
|
692
|
+
The `source` field indicates where photos are served from:
|
|
693
|
+
- `"project"` - Photos are in your project's `public/profile_pictures/library/`
|
|
694
|
+
- `"node_modules"` - Photos are served from `node_modules/hazo_auth/public/` via API route
|
|
695
|
+
|
|
696
|
+
**Test paginated photos:**
|
|
697
|
+
```bash
|
|
698
|
+
curl -s "http://localhost:3000/api/hazo_auth/library_photos?category=Cars&page=1&page_size=5" | jq
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
**Note:** Library photos work automatically whether they're copied to your project or still in node_modules. The API will serve them from node_modules as a fallback.
|
|
590
702
|
|
|
591
703
|
### Test 6: Visit Pages in Browser
|
|
592
704
|
|
|
@@ -596,10 +708,10 @@ npm run dev
|
|
|
596
708
|
```
|
|
597
709
|
|
|
598
710
|
Visit each page and verify it loads:
|
|
599
|
-
- [ ] `http://localhost:3000/login` - Login form displays
|
|
600
|
-
- [ ] `http://localhost:3000/register` - Registration form displays
|
|
601
|
-
- [ ] `http://localhost:3000/
|
|
602
|
-
- [ ] `http://localhost:3000/
|
|
711
|
+
- [ ] `http://localhost:3000/hazo_auth/login` - Login form displays
|
|
712
|
+
- [ ] `http://localhost:3000/hazo_auth/register` - Registration form displays
|
|
713
|
+
- [ ] `http://localhost:3000/hazo_auth/forgot_password` - Forgot password form displays
|
|
714
|
+
- [ ] `http://localhost:3000/hazo_auth/my_settings` - Settings page displays (after login)
|
|
603
715
|
|
|
604
716
|
---
|
|
605
717
|
|
|
@@ -620,13 +732,26 @@ Visit each page and verify it loads:
|
|
|
620
732
|
**Symptoms:** Avatar shows fallback initials, library photos empty.
|
|
621
733
|
|
|
622
734
|
**Solutions:**
|
|
623
|
-
1.
|
|
735
|
+
1. **Run init command** (copies library photos automatically):
|
|
736
|
+
```bash
|
|
737
|
+
npx hazo_auth init
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
2. **Or manually copy library photos:**
|
|
624
741
|
```bash
|
|
625
742
|
mkdir -p public/profile_pictures/library
|
|
626
743
|
cp -r node_modules/hazo_auth/public/profile_pictures/library/* public/profile_pictures/library/
|
|
627
744
|
```
|
|
628
|
-
|
|
629
|
-
3. Check
|
|
745
|
+
|
|
746
|
+
3. **Check API response source:**
|
|
747
|
+
```bash
|
|
748
|
+
curl -s http://localhost:3000/api/hazo_auth/library_photos | jq '.source'
|
|
749
|
+
```
|
|
750
|
+
- If `"node_modules"` - Photos are being served from the package (slower but works)
|
|
751
|
+
- If `"project"` - Photos are in your public folder (optimal)
|
|
752
|
+
|
|
753
|
+
4. Verify `library_photos` and `library_photo` API routes exist
|
|
754
|
+
5. Check file permissions on `public/profile_pictures/`
|
|
630
755
|
|
|
631
756
|
### Issue: Database connection failed
|
|
632
757
|
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from "next/server";
|
|
2
|
+
export declare const dynamic = "force-dynamic";
|
|
3
|
+
export declare function GET(request: NextRequest, { params }: {
|
|
4
|
+
params: {
|
|
5
|
+
category: string;
|
|
6
|
+
filename: string;
|
|
7
|
+
};
|
|
8
|
+
}): Promise<NextResponse<unknown>>;
|
|
9
|
+
//# sourceMappingURL=route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../src/app/api/hazo_auth/library_photo/[category]/[filename]/route.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AASxD,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAevC,wBAAsB,GAAG,CACvB,OAAO,EAAE,WAAW,EACpB,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,kCA4E/D"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// file_description: API route to serve library photos from node_modules fallback
|
|
2
|
+
// This route is used when library photos haven't been copied to the project's public folder
|
|
3
|
+
// section: imports
|
|
4
|
+
import { NextResponse } from "next/server";
|
|
5
|
+
import { get_library_photo_path } from "../../../../../../lib/services/profile_picture_service";
|
|
6
|
+
import { create_app_logger } from "../../../../../../lib/app_logger";
|
|
7
|
+
import { get_filename, get_line_number } from "../../../../../../lib/utils/api_route_helpers";
|
|
8
|
+
import fs from "fs";
|
|
9
|
+
import path from "path";
|
|
10
|
+
// section: route_config
|
|
11
|
+
// Cache library photos for 1 hour (they don't change)
|
|
12
|
+
export const dynamic = 'force-dynamic';
|
|
13
|
+
// section: constants
|
|
14
|
+
const MIME_TYPES = {
|
|
15
|
+
".jpg": "image/jpeg",
|
|
16
|
+
".jpeg": "image/jpeg",
|
|
17
|
+
".png": "image/png",
|
|
18
|
+
".gif": "image/gif",
|
|
19
|
+
".webp": "image/webp",
|
|
20
|
+
".svg": "image/svg+xml",
|
|
21
|
+
};
|
|
22
|
+
const CACHE_MAX_AGE = 3600; // 1 hour in seconds
|
|
23
|
+
// section: api_handler
|
|
24
|
+
export async function GET(request, { params }) {
|
|
25
|
+
const logger = create_app_logger();
|
|
26
|
+
const { category, filename } = params;
|
|
27
|
+
try {
|
|
28
|
+
// Validate inputs to prevent path traversal
|
|
29
|
+
if (category.includes("..") ||
|
|
30
|
+
category.includes("/") ||
|
|
31
|
+
category.includes("\\") ||
|
|
32
|
+
filename.includes("..") ||
|
|
33
|
+
filename.includes("/") ||
|
|
34
|
+
filename.includes("\\")) {
|
|
35
|
+
logger.warn("library_photo_invalid_path", {
|
|
36
|
+
filename: get_filename(),
|
|
37
|
+
line_number: get_line_number(),
|
|
38
|
+
category,
|
|
39
|
+
requested_filename: filename,
|
|
40
|
+
});
|
|
41
|
+
return NextResponse.json({ error: "Invalid path" }, { status: 400 });
|
|
42
|
+
}
|
|
43
|
+
// Get the physical file path
|
|
44
|
+
const photo_path = get_library_photo_path(category, filename);
|
|
45
|
+
if (!photo_path) {
|
|
46
|
+
logger.warn("library_photo_not_found", {
|
|
47
|
+
filename: get_filename(),
|
|
48
|
+
line_number: get_line_number(),
|
|
49
|
+
category,
|
|
50
|
+
requested_filename: filename,
|
|
51
|
+
});
|
|
52
|
+
return NextResponse.json({ error: "Photo not found" }, { status: 404 });
|
|
53
|
+
}
|
|
54
|
+
// Read the file
|
|
55
|
+
const file_buffer = fs.readFileSync(photo_path);
|
|
56
|
+
const ext = path.extname(filename).toLowerCase();
|
|
57
|
+
const content_type = MIME_TYPES[ext] || "application/octet-stream";
|
|
58
|
+
// Return the image with caching headers
|
|
59
|
+
return new NextResponse(file_buffer, {
|
|
60
|
+
status: 200,
|
|
61
|
+
headers: {
|
|
62
|
+
"Content-Type": content_type,
|
|
63
|
+
"Content-Length": file_buffer.length.toString(),
|
|
64
|
+
"Cache-Control": `public, max-age=${CACHE_MAX_AGE}, immutable`,
|
|
65
|
+
"X-Library-Source": "node_modules",
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
const error_message = error instanceof Error ? error.message : "Unknown error";
|
|
71
|
+
const error_stack = error instanceof Error ? error.stack : undefined;
|
|
72
|
+
logger.error("library_photo_error", {
|
|
73
|
+
filename: get_filename(),
|
|
74
|
+
line_number: get_line_number(),
|
|
75
|
+
category,
|
|
76
|
+
requested_filename: filename,
|
|
77
|
+
error_message,
|
|
78
|
+
error_stack,
|
|
79
|
+
});
|
|
80
|
+
return NextResponse.json({ error: "Failed to serve photo" }, { status: 500 });
|
|
81
|
+
}
|
|
82
|
+
}
|