hazo_auth 5.1.25 → 5.1.28
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 +59 -21
- package/SETUP_CHECKLIST.md +159 -48
- package/bin/hazo_auth.mjs +8 -1
- package/cli-src/assets/images/new_firm_default.jpg +0 -0
- package/cli-src/cli/index.ts +36 -2
- package/cli-src/cli/init.ts +119 -7
- package/cli-src/cli/init_db.ts +144 -0
- package/cli-src/cli/init_permissions.ts +4 -6
- package/cli-src/cli/validate.ts +215 -0
- package/cli-src/lib/auth/hazo_get_auth.server.ts +2 -2
- package/cli-src/lib/auth/with_auth.server.ts +6 -0
- package/cli-src/lib/config/default_config.ts +13 -0
- package/cli-src/lib/constants.ts +15 -0
- package/cli-src/lib/cookies_config.edge.ts +15 -2
- package/cli-src/lib/cookies_config.server.ts +15 -6
- package/cli-src/lib/hazo_connect_setup.server.ts +33 -4
- package/cli-src/lib/multi_tenancy_config.server.ts +4 -71
- package/cli-src/lib/schema/sqlite_schema.ts +141 -0
- package/cli-src/lib/services/post_verification_service.ts +23 -0
- package/config/hazo_auth_config.example.ini +6 -5
- package/dist/cli/index.js +34 -2
- package/dist/cli/init.d.ts +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +110 -7
- package/dist/cli/init_db.d.ts +2 -0
- package/dist/cli/init_db.d.ts.map +1 -0
- package/dist/cli/init_db.js +119 -0
- package/dist/cli/init_permissions.d.ts.map +1 -1
- package/dist/cli/init_permissions.js +5 -6
- package/dist/cli/validate.d.ts.map +1 -1
- package/dist/cli/validate.js +210 -4
- package/dist/client.d.ts +1 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +2 -0
- package/dist/components/layouts/shared/components/visual_panel.d.ts.map +1 -1
- package/dist/components/layouts/shared/components/visual_panel.js +3 -1
- package/dist/components/layouts/user_management/index.d.ts.map +1 -1
- package/dist/components/layouts/user_management/index.js +3 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/lib/auth/hazo_get_auth.server.js +2 -2
- package/dist/lib/auth/with_auth.server.d.ts.map +1 -1
- package/dist/lib/auth/with_auth.server.js +6 -5
- package/dist/lib/config/default_config.d.ts +20 -0
- package/dist/lib/config/default_config.d.ts.map +1 -1
- package/dist/lib/config/default_config.js +12 -0
- package/dist/lib/constants.d.ts +11 -0
- package/dist/lib/constants.d.ts.map +1 -0
- package/dist/lib/constants.js +13 -0
- package/dist/lib/cookies_config.edge.d.ts +2 -1
- package/dist/lib/cookies_config.edge.d.ts.map +1 -1
- package/dist/lib/cookies_config.edge.js +11 -2
- package/dist/lib/cookies_config.server.d.ts +1 -1
- package/dist/lib/cookies_config.server.d.ts.map +1 -1
- package/dist/lib/cookies_config.server.js +12 -5
- package/dist/lib/hazo_connect_setup.server.d.ts.map +1 -1
- package/dist/lib/hazo_connect_setup.server.js +31 -4
- package/dist/lib/multi_tenancy_config.server.d.ts +7 -0
- package/dist/lib/multi_tenancy_config.server.d.ts.map +1 -0
- package/dist/lib/multi_tenancy_config.server.js +16 -0
- package/dist/lib/schema/sqlite_schema.d.ts +2 -0
- package/dist/lib/schema/sqlite_schema.d.ts.map +1 -0
- package/dist/lib/schema/sqlite_schema.js +140 -0
- package/dist/lib/services/post_verification_service.d.ts.map +1 -1
- package/dist/lib/services/post_verification_service.js +20 -0
- package/dist/page_components/index.d.ts.map +1 -1
- package/dist/server/middleware.d.ts +1 -1
- package/dist/server/middleware.d.ts.map +1 -1
- package/dist/server/routes/create_firm.d.ts +2 -2
- package/dist/server/routes/index.d.ts.map +1 -1
- package/dist/server/routes/invitations.d.ts +2 -2
- package/dist/server/routes/verify_email.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,6 +2,38 @@
|
|
|
2
2
|
|
|
3
3
|
A reusable authentication UI component package powered by Next.js, TailwindCSS, and shadcn. It integrates `hazo_config` for configuration management and `hazo_connect` for data access, enabling future components to stay aligned with platform conventions.
|
|
4
4
|
|
|
5
|
+
### What's New in v5.1.28
|
|
6
|
+
|
|
7
|
+
**Schema Validation, Permission Constants & DX Improvements**
|
|
8
|
+
|
|
9
|
+
- **Schema validation** - `npx hazo_auth validate` now checks SQLite schema: required tables, TEXT ID types, `hazo_user_scopes` columns, admin permissions, and warns about v4 remnant tables
|
|
10
|
+
- **Permission constants** - New `HAZO_AUTH_PERMISSIONS` and `ALL_ADMIN_PERMISSIONS` exports from both `hazo_auth` and `hazo_auth/client` for programmatic permission checks
|
|
11
|
+
- **CLI fix** - CLI wrapper now sets `--conditions react-server` in NODE_OPTIONS, fixing "server-only" import errors when running `npx hazo_auth validate`, `init-permissions`, etc.
|
|
12
|
+
- **Silent permission fix** - `hazo_get_auth` now applies `String()` normalization to role_id/permission_id comparisons, fixing empty permissions when SQLite returns INTEGER IDs
|
|
13
|
+
- **DB-generated IDs** - `init-permissions` no longer generates UUIDs client-side; lets the database generate IDs (supports both TEXT UUID and INTEGER PK schemas)
|
|
14
|
+
- **Dev debug info** - `withAuth` 403 responses and `UserManagementLayout` "Access Denied" view now include permission debug details in development mode
|
|
15
|
+
- **Import cleanup** - Removed `.js` extensions from internal imports for better TypeScript/bundler compatibility
|
|
16
|
+
|
|
17
|
+
### What's New in v5.1.27
|
|
18
|
+
|
|
19
|
+
**Mandatory Cookie Prefix** - `cookie_prefix` is now required for all consuming apps.
|
|
20
|
+
|
|
21
|
+
- **Breaking:** `get_cookies_config()` throws if `cookie_prefix` is not set in `[hazo_auth__cookies]` config section
|
|
22
|
+
- **Breaking:** `get_cookie_prefix_edge()` throws if `HAZO_AUTH_COOKIE_PREFIX` env var is not set
|
|
23
|
+
- **Validation:** `npx hazo_auth validate` now checks for cookie_prefix configuration
|
|
24
|
+
- **Init:** `.env.local.example` template includes `HAZO_AUTH_COOKIE_PREFIX` as required
|
|
25
|
+
- **Docs:** shadcn/ui components are bundled — consumers do NOT need to install them separately
|
|
26
|
+
|
|
27
|
+
### What's New in v5.1.26
|
|
28
|
+
|
|
29
|
+
**Consumer Setup Improvements** - Five fixes that improve the out-of-box experience for new consumers:
|
|
30
|
+
|
|
31
|
+
- **Multi-tenancy bypass** - `enable_multi_tenancy = false` (the default) now correctly skips scope/invitation checks in OAuth and post-verification flows. No more redirect loops to `/hazo_auth/create_firm` for simple apps.
|
|
32
|
+
- **Clear SQLite errors** - Missing `sqlite_path` in config now throws a clear error instead of silently falling back to a test fixture database. Unrecognized config keys produce warnings with typo suggestions.
|
|
33
|
+
- **Auto-schema creation** - `npx hazo_auth init` now creates the SQLite database with all required tables automatically. Also available standalone via `npx hazo_auth init-db`. Use `npx hazo_auth schema` to print the canonical SQL.
|
|
34
|
+
- **Auth page images** - `npx hazo_auth init` now copies default login/register/forgot-password images to `public/hazo_auth/images/`.
|
|
35
|
+
- **Graceful image fallback** - Visual panels on auth pages fall back to a colored background instead of crashing when images are missing.
|
|
36
|
+
|
|
5
37
|
### What's New in v5.2.0 ⚠️ BREAKING CHANGE
|
|
6
38
|
|
|
7
39
|
**Server/Client Module Separation** - Complete fix for "Module not found: Can't resolve 'fs'" errors.
|
|
@@ -117,9 +149,12 @@ See [CHANGE_LOG.md](./CHANGE_LOG.md) for detailed migration guide, rationale, an
|
|
|
117
149
|
## Installation
|
|
118
150
|
|
|
119
151
|
```bash
|
|
120
|
-
|
|
152
|
+
# Install hazo_auth and required peer dependencies
|
|
153
|
+
npm install hazo_auth hazo_config hazo_connect hazo_logs
|
|
121
154
|
```
|
|
122
155
|
|
|
156
|
+
**Note:** `hazo_config`, `hazo_connect`, and `hazo_logs` are required peer dependencies.
|
|
157
|
+
|
|
123
158
|
---
|
|
124
159
|
|
|
125
160
|
## Quick Start
|
|
@@ -127,20 +162,31 @@ npm install hazo_auth
|
|
|
127
162
|
The fastest way to get started is using the CLI commands:
|
|
128
163
|
|
|
129
164
|
```bash
|
|
130
|
-
# 1. Install the package
|
|
131
|
-
npm install hazo_auth
|
|
165
|
+
# 1. Install the package and peer dependencies
|
|
166
|
+
npm install hazo_auth hazo_config hazo_connect hazo_logs
|
|
132
167
|
|
|
133
|
-
# 2. Initialize your project (
|
|
168
|
+
# 2. Initialize your project (directories, config, database, images)
|
|
134
169
|
npx hazo_auth init
|
|
135
170
|
|
|
136
|
-
# 3.
|
|
137
|
-
|
|
171
|
+
# 3. Configure cookie prefix (REQUIRED)
|
|
172
|
+
# Edit config/hazo_auth_config.ini and set a unique prefix:
|
|
173
|
+
# [hazo_auth__cookies]
|
|
174
|
+
# cookie_prefix = myapp_
|
|
138
175
|
|
|
139
176
|
# 4. Set up environment variables
|
|
140
177
|
cp .env.local.example .env.local
|
|
141
|
-
# Edit .env.local and
|
|
178
|
+
# Edit .env.local and set:
|
|
179
|
+
# HAZO_AUTH_COOKIE_PREFIX=myapp_ (MUST match cookie_prefix above)
|
|
180
|
+
# JWT_SECRET=<your-secret>
|
|
181
|
+
# ZEPTOMAIL_API_KEY=<your-key>
|
|
182
|
+
|
|
183
|
+
# 5. Initialize default permissions and roles
|
|
184
|
+
npx hazo_auth init-users
|
|
142
185
|
|
|
143
|
-
#
|
|
186
|
+
# 6. Generate API routes and pages
|
|
187
|
+
npx hazo_auth generate-routes --pages
|
|
188
|
+
|
|
189
|
+
# 7. Start your dev server
|
|
144
190
|
npm run dev
|
|
145
191
|
```
|
|
146
192
|
|
|
@@ -309,22 +355,14 @@ import { hazo_get_auth } from "hazo_auth/lib/auth/hazo_get_auth.server";
|
|
|
309
355
|
|
|
310
356
|
## Required Dependencies
|
|
311
357
|
|
|
312
|
-
**
|
|
313
|
-
|
|
314
|
-
hazo_auth uses shadcn/ui components. Install the required dependencies in your project:
|
|
315
|
-
|
|
358
|
+
**Peer Dependencies (Required):**
|
|
316
359
|
```bash
|
|
317
|
-
|
|
318
|
-
npx shadcn@latest add button input label
|
|
319
|
-
|
|
320
|
-
# Required for My Settings page
|
|
321
|
-
npx shadcn@latest add dialog tabs switch avatar dropdown-menu
|
|
322
|
-
|
|
323
|
-
# Required for toast notifications
|
|
324
|
-
npx shadcn@latest add sonner
|
|
360
|
+
npm install hazo_config hazo_connect hazo_logs
|
|
325
361
|
```
|
|
326
362
|
|
|
327
|
-
**
|
|
363
|
+
**UI Components:** All shadcn/ui components are bundled with hazo_auth. You do NOT need to install them separately.
|
|
364
|
+
|
|
365
|
+
**Toast Notifications:** Add the Toaster component to your app layout:
|
|
328
366
|
|
|
329
367
|
```tsx
|
|
330
368
|
// app/layout.tsx
|
package/SETUP_CHECKLIST.md
CHANGED
|
@@ -10,24 +10,35 @@ The fastest way to set up hazo_auth:
|
|
|
10
10
|
# 1. Install the package and peer dependencies
|
|
11
11
|
npm install hazo_auth hazo_config hazo_connect hazo_logs
|
|
12
12
|
|
|
13
|
-
# 2. Initialize project (creates directories,
|
|
13
|
+
# 2. Initialize project (creates directories, config files, database, images)
|
|
14
14
|
npx hazo_auth init
|
|
15
15
|
|
|
16
|
-
# 3.
|
|
17
|
-
|
|
16
|
+
# 3. Configure cookie prefix (REQUIRED)
|
|
17
|
+
# Edit config/hazo_auth_config.ini and set a unique prefix:
|
|
18
|
+
# [hazo_auth__cookies]
|
|
19
|
+
# cookie_prefix = myapp_
|
|
18
20
|
|
|
19
21
|
# 4. Set up environment variables
|
|
20
22
|
cp .env.local.example .env.local
|
|
21
|
-
# Edit .env.local and
|
|
23
|
+
# Edit .env.local and set:
|
|
24
|
+
# HAZO_AUTH_COOKIE_PREFIX=myapp_ (MUST match cookie_prefix above)
|
|
25
|
+
# JWT_SECRET=<generate with: openssl rand -base64 32>
|
|
26
|
+
# ZEPTOMAIL_API_KEY=your_key_here
|
|
27
|
+
|
|
28
|
+
# 5. Initialize default permissions and roles
|
|
29
|
+
npx hazo_auth init-users
|
|
22
30
|
|
|
23
|
-
#
|
|
24
|
-
|
|
31
|
+
# 6. Generate API routes and pages
|
|
32
|
+
npx hazo_auth generate-routes --pages
|
|
33
|
+
|
|
34
|
+
# 7. Configure navbar logo and company name (IMPORTANT)
|
|
35
|
+
# Edit config/hazo_auth_config.ini and set:
|
|
25
36
|
# [hazo_auth__navbar]
|
|
26
37
|
# logo_path = /logo.png
|
|
27
38
|
# company_name = My Company
|
|
28
39
|
# Note: Copy your logo to public/logo.png
|
|
29
40
|
|
|
30
|
-
#
|
|
41
|
+
# 8. Start dev server and test
|
|
31
42
|
npm run dev
|
|
32
43
|
# Visit http://localhost:3000/hazo_auth/login
|
|
33
44
|
```
|
|
@@ -69,26 +80,11 @@ ls node_modules/hazo_auth/package.json
|
|
|
69
80
|
# Expected: file exists
|
|
70
81
|
```
|
|
71
82
|
|
|
72
|
-
### Step 1.2:
|
|
73
|
-
|
|
74
|
-
hazo_auth uses shadcn/ui components. Install the required dependencies:
|
|
75
|
-
|
|
76
|
-
**For all auth pages (login, register, etc.):**
|
|
77
|
-
```bash
|
|
78
|
-
npx shadcn@latest add button input label
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
**For My Settings page:**
|
|
82
|
-
```bash
|
|
83
|
-
npx shadcn@latest add dialog tabs switch avatar dropdown-menu
|
|
84
|
-
```
|
|
83
|
+
### Step 1.2: Add Toast Notifications
|
|
85
84
|
|
|
86
|
-
|
|
87
|
-
```bash
|
|
88
|
-
npx shadcn@latest add sonner
|
|
89
|
-
```
|
|
85
|
+
All shadcn/ui components are bundled with hazo_auth — you do NOT need to install them separately.
|
|
90
86
|
|
|
91
|
-
**Add Toaster to your app layout
|
|
87
|
+
**Add Toaster to your app layout** (required for toast notifications):
|
|
92
88
|
|
|
93
89
|
Edit `app/layout.tsx` and add the Toaster component:
|
|
94
90
|
|
|
@@ -178,7 +174,18 @@ This command:
|
|
|
178
174
|
- Creates `data/` directory (for SQLite database)
|
|
179
175
|
- Copies `hazo_auth_config.ini` and `hazo_notify_config.ini`
|
|
180
176
|
- Copies profile picture library images
|
|
177
|
+
- Copies default auth page images (login, register, forgot password, etc.)
|
|
181
178
|
- Creates `.env.local.example` template
|
|
179
|
+
- Creates SQLite database with all required tables (if `better-sqlite3` is installed)
|
|
180
|
+
|
|
181
|
+
**Additional CLI commands:**
|
|
182
|
+
```bash
|
|
183
|
+
# Create/recreate SQLite database with schema (standalone)
|
|
184
|
+
npx hazo_auth init-db
|
|
185
|
+
|
|
186
|
+
# Print the canonical SQLite schema SQL
|
|
187
|
+
npx hazo_auth schema
|
|
188
|
+
```
|
|
182
189
|
|
|
183
190
|
### Step 1.2b: Manual config setup (Alternative)
|
|
184
191
|
|
|
@@ -238,18 +245,20 @@ layout_mode = standalone
|
|
|
238
245
|
Create `.env.local` in your project root:
|
|
239
246
|
|
|
240
247
|
```env
|
|
248
|
+
# REQUIRED: Cookie prefix (MUST match cookie_prefix in hazo_auth_config.ini)
|
|
249
|
+
# Each app using hazo_auth needs a unique prefix to prevent cookie conflicts
|
|
250
|
+
HAZO_AUTH_COOKIE_PREFIX=myapp_
|
|
251
|
+
|
|
252
|
+
# Required for JWT authentication
|
|
253
|
+
JWT_SECRET=your_secure_random_string_at_least_32_characters
|
|
254
|
+
|
|
241
255
|
# Required for email functionality (Zeptomail)
|
|
242
256
|
ZEPTOMAIL_API_KEY=your_zeptomail_api_key_here
|
|
243
257
|
|
|
244
258
|
# Required for PostgreSQL/PostgREST (if using)
|
|
245
259
|
HAZO_CONNECT_POSTGREST_API_KEY=your_postgrest_api_key_here
|
|
246
260
|
|
|
247
|
-
#
|
|
248
|
-
JWT_SECRET=your_secure_random_string_at_least_32_characters
|
|
249
|
-
# Note: JWT_SECRET is required for JWT session token functionality (Edge-compatible proxy/middleware authentication)
|
|
250
|
-
|
|
251
|
-
# Optional: Cookie customization (prevents conflicts when running multiple apps)
|
|
252
|
-
HAZO_AUTH_COOKIE_PREFIX=myapp_
|
|
261
|
+
# Optional: Cookie domain (for cross-subdomain sharing)
|
|
253
262
|
HAZO_AUTH_COOKIE_DOMAIN=
|
|
254
263
|
```
|
|
255
264
|
|
|
@@ -258,17 +267,25 @@ HAZO_AUTH_COOKIE_DOMAIN=
|
|
|
258
267
|
openssl rand -base64 32
|
|
259
268
|
```
|
|
260
269
|
|
|
261
|
-
**Cookie
|
|
262
|
-
|
|
263
|
-
- App 1 (port 3000): `HAZO_AUTH_COOKIE_PREFIX=app1_`
|
|
264
|
-
- App 2 (port 3001): `HAZO_AUTH_COOKIE_PREFIX=app2_`
|
|
270
|
+
**Cookie Prefix (REQUIRED):**
|
|
271
|
+
Every app using hazo_auth MUST set a unique cookie prefix. This prevents cookie conflicts between apps. The value must be set in TWO places:
|
|
265
272
|
|
|
266
|
-
|
|
267
|
-
```ini
|
|
268
|
-
[hazo_auth__cookies]
|
|
269
|
-
cookie_prefix = myapp_
|
|
270
|
-
|
|
271
|
-
|
|
273
|
+
1. **Config file** (`config/hazo_auth_config.ini`):
|
|
274
|
+
```ini
|
|
275
|
+
[hazo_auth__cookies]
|
|
276
|
+
cookie_prefix = myapp_
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
2. **Environment variable** (`.env.local`):
|
|
280
|
+
```env
|
|
281
|
+
HAZO_AUTH_COOKIE_PREFIX=myapp_
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Both values MUST match. The env var is needed because Edge runtime (middleware/proxy) cannot read config files.
|
|
285
|
+
|
|
286
|
+
**Examples for multiple apps:**
|
|
287
|
+
- App 1 (port 3000): `cookie_prefix = app1_` / `HAZO_AUTH_COOKIE_PREFIX=app1_`
|
|
288
|
+
- App 2 (port 3001): `cookie_prefix = app2_` / `HAZO_AUTH_COOKIE_PREFIX=app2_`
|
|
272
289
|
|
|
273
290
|
### Step 2.2: Configure email settings
|
|
274
291
|
|
|
@@ -282,8 +299,9 @@ from_name = Your App Name
|
|
|
282
299
|
|
|
283
300
|
**Checklist:**
|
|
284
301
|
- [ ] `.env.local` file created
|
|
302
|
+
- [ ] `HAZO_AUTH_COOKIE_PREFIX` set (REQUIRED - must match config file)
|
|
303
|
+
- [ ] `JWT_SECRET` set (required for JWT session tokens)
|
|
285
304
|
- [ ] `ZEPTOMAIL_API_KEY` set (or email will not work)
|
|
286
|
-
- [ ] `JWT_SECRET` set (required for JWT session tokens - Edge-compatible proxy/middleware authentication)
|
|
287
305
|
- [ ] `from_email` configured in `hazo_notify_config.ini`
|
|
288
306
|
|
|
289
307
|
---
|
|
@@ -1108,20 +1126,23 @@ If you prefer a simpler approach without JWT validation:
|
|
|
1108
1126
|
import { NextResponse } from "next/server";
|
|
1109
1127
|
import type { NextRequest } from "next/server";
|
|
1110
1128
|
|
|
1129
|
+
// Cookie prefix must match HAZO_AUTH_COOKIE_PREFIX env var
|
|
1130
|
+
const COOKIE_PREFIX = process.env.HAZO_AUTH_COOKIE_PREFIX || "";
|
|
1131
|
+
|
|
1111
1132
|
export async function proxy(request: NextRequest) {
|
|
1112
1133
|
const { pathname } = request.nextUrl;
|
|
1113
|
-
|
|
1134
|
+
|
|
1114
1135
|
if (pathname.startsWith("/members")) {
|
|
1115
|
-
const user_id = request.cookies.get(
|
|
1116
|
-
const user_email = request.cookies.get(
|
|
1117
|
-
|
|
1136
|
+
const user_id = request.cookies.get(`${COOKIE_PREFIX}hazo_auth_user_id`)?.value;
|
|
1137
|
+
const user_email = request.cookies.get(`${COOKIE_PREFIX}hazo_auth_user_email`)?.value;
|
|
1138
|
+
|
|
1118
1139
|
if (!user_id || !user_email) {
|
|
1119
1140
|
const login_url = new URL("/hazo_auth/login", request.url);
|
|
1120
1141
|
login_url.searchParams.set("redirect", pathname);
|
|
1121
1142
|
return NextResponse.redirect(login_url);
|
|
1122
1143
|
}
|
|
1123
1144
|
}
|
|
1124
|
-
|
|
1145
|
+
|
|
1125
1146
|
return NextResponse.next();
|
|
1126
1147
|
}
|
|
1127
1148
|
```
|
|
@@ -1944,14 +1965,104 @@ curl -H "Cookie: hazo_auth_session=YOUR_TOKEN; hazo_auth_scope_id=SCOPE_UUID" \
|
|
|
1944
1965
|
|
|
1945
1966
|
**Note:** By default, `logo_path` and `company_name` are empty strings, so nothing displays until you configure them.
|
|
1946
1967
|
|
|
1968
|
+
### Issue: Migrating from v4 to v5 schema
|
|
1969
|
+
|
|
1970
|
+
**Symptoms:** Permissions resolve to `[]`, "Access Denied" on all admin pages, 403 responses from withAuth, despite user having roles assigned.
|
|
1971
|
+
|
|
1972
|
+
**Cause:** v5 replaced `hazo_user_roles` with `hazo_user_scopes` (scope-based role assignments) and requires several new tables. If your database still has v4 schema, the permission lookup finds no role assignments.
|
|
1973
|
+
|
|
1974
|
+
**Key schema differences (v4 vs v5):**
|
|
1975
|
+
- `hazo_user_roles` replaced by `hazo_user_scopes` (with `root_scope_id` and `role_id` columns)
|
|
1976
|
+
- `hazo_org` replaced by `hazo_scopes` (unified hierarchical scope model)
|
|
1977
|
+
- All ID columns must be TEXT (UUID), not INTEGER
|
|
1978
|
+
- `hazo_role_permissions` uses composite PK `(role_id, permission_id)` with no `id` column
|
|
1979
|
+
|
|
1980
|
+
**Solution:**
|
|
1981
|
+
1. Run `npx hazo_auth validate` to identify schema issues
|
|
1982
|
+
2. Run migration 009: `npm run migrate migrations/009_scope_consolidation.sql`
|
|
1983
|
+
3. Migrate existing role assignments:
|
|
1984
|
+
```sql
|
|
1985
|
+
-- Example: migrate hazo_user_roles data to hazo_user_scopes
|
|
1986
|
+
INSERT INTO hazo_user_scopes (user_id, scope_id, root_scope_id, role_id, status)
|
|
1987
|
+
SELECT
|
|
1988
|
+
ur.user_id,
|
|
1989
|
+
'00000000-0000-0000-0000-000000000001', -- default system scope
|
|
1990
|
+
'00000000-0000-0000-0000-000000000001', -- default system scope
|
|
1991
|
+
ur.role_id,
|
|
1992
|
+
'ACTIVE'
|
|
1993
|
+
FROM hazo_user_roles ur;
|
|
1994
|
+
```
|
|
1995
|
+
4. Run `npx hazo_auth init-permissions` to ensure all admin permissions exist
|
|
1996
|
+
|
|
1997
|
+
### Issue: Understanding permission configuration
|
|
1998
|
+
|
|
1999
|
+
**Symptoms:** Confusion about which config sections control permissions and how they relate.
|
|
2000
|
+
|
|
2001
|
+
**Explanation:** Permissions are configured in three related places:
|
|
2002
|
+
|
|
2003
|
+
1. **`[hazo_auth__app_permissions]`** - Declares app-level permission names with descriptions (for documentation/UI display):
|
|
2004
|
+
```ini
|
|
2005
|
+
app_permission_1 = can_view_reports:View analytical reports
|
|
2006
|
+
app_permission_2 = can_export_data:Export data to CSV
|
|
2007
|
+
```
|
|
2008
|
+
|
|
2009
|
+
2. **`[hazo_auth__user_management] application_permission_list_defaults`** - Comma-separated list of permission names to create in the DB when running `npx hazo_auth init-permissions`:
|
|
2010
|
+
```ini
|
|
2011
|
+
application_permission_list_defaults = admin_user_management,admin_role_management,admin_permission_management,can_view_reports,can_export_data
|
|
2012
|
+
```
|
|
2013
|
+
|
|
2014
|
+
3. **Built-in admin permissions** (required by `UserManagementLayout` component): `admin_user_management`, `admin_role_management`, `admin_permission_management`, `admin_scope_hierarchy_management`, `admin_user_scope_assignment`, `admin_system`, `admin_test_access`. These are available programmatically via:
|
|
2015
|
+
```typescript
|
|
2016
|
+
import { HAZO_AUTH_PERMISSIONS, ALL_ADMIN_PERMISSIONS } from "hazo_auth/client";
|
|
2017
|
+
```
|
|
2018
|
+
|
|
2019
|
+
### Issue: Database ID type mismatches (silent permission failures)
|
|
2020
|
+
|
|
2021
|
+
**Symptoms:** User is authenticated but permissions array is always empty. No errors in console. `hazo_get_auth` returns `permissions: []` even though roles and permissions exist in the database.
|
|
2022
|
+
|
|
2023
|
+
**Cause:** SQLite drivers may return numeric values for columns defined as `INTEGER PRIMARY KEY`. v5 uses strict string comparison for role_id and permission_id matching. If the DB returns `role_id: 1` (number) but the code expects `"1"` (string), the comparison fails silently.
|
|
2024
|
+
|
|
2025
|
+
**Solutions:**
|
|
2026
|
+
1. **Ensure all ID columns are TEXT type** in your schema. v5 requires TEXT (UUID) IDs:
|
|
2027
|
+
```sql
|
|
2028
|
+
-- CORRECT (v5)
|
|
2029
|
+
CREATE TABLE hazo_roles (id TEXT PRIMARY KEY, ...);
|
|
2030
|
+
|
|
2031
|
+
-- WRONG (v4 legacy)
|
|
2032
|
+
CREATE TABLE hazo_roles (id INTEGER PRIMARY KEY, ...);
|
|
2033
|
+
```
|
|
2034
|
+
2. Run `npx hazo_auth validate` — the schema check will flag INTEGER ID columns
|
|
2035
|
+
3. If you cannot change the schema, v5.1.28+ applies `String()` normalization to role_id and permission_id comparisons, which handles mixed types
|
|
2036
|
+
|
|
2037
|
+
**Note for PostgreSQL users:** PostgREST typically returns UUID values as strings, so this issue primarily affects SQLite with INTEGER PKs.
|
|
2038
|
+
|
|
2039
|
+
### Issue: CLI commands fail with "server-only" import error
|
|
2040
|
+
|
|
2041
|
+
**Symptoms:** Running `npx hazo_auth validate`, `npx hazo_auth init-permissions`, etc. throws:
|
|
2042
|
+
```
|
|
2043
|
+
Error: This module cannot be imported from a Client Component module.
|
|
2044
|
+
It should only be used from a Server Component.
|
|
2045
|
+
```
|
|
2046
|
+
|
|
2047
|
+
**Cause:** The `server-only` package throws when imported outside a React Server Component context. CLI commands run in plain Node.js.
|
|
2048
|
+
|
|
2049
|
+
**Solution (v5.1.28+):** Fixed automatically — the CLI wrapper now sets `--conditions react-server` in NODE_OPTIONS.
|
|
2050
|
+
|
|
2051
|
+
**Workaround for older versions:** Set the condition manually:
|
|
2052
|
+
```bash
|
|
2053
|
+
NODE_OPTIONS='--conditions react-server' npx hazo_auth validate
|
|
2054
|
+
```
|
|
2055
|
+
|
|
1947
2056
|
---
|
|
1948
2057
|
|
|
1949
2058
|
## Final Checklist
|
|
1950
2059
|
|
|
1951
2060
|
**Configuration:**
|
|
1952
2061
|
- [ ] `hazo_auth_config.ini` configured
|
|
2062
|
+
- [ ] `cookie_prefix` set in `[hazo_auth__cookies]` section (REQUIRED)
|
|
2063
|
+
- [ ] `HAZO_AUTH_COOKIE_PREFIX` env var matches `cookie_prefix` (REQUIRED)
|
|
1953
2064
|
- [ ] `hazo_notify_config.ini` configured
|
|
1954
|
-
- [ ] `.env.local` with all required variables (
|
|
2065
|
+
- [ ] `.env.local` with all required variables (HAZO_AUTH_COOKIE_PREFIX, JWT_SECRET, ZEPTOMAIL_API_KEY)
|
|
1955
2066
|
- [ ] Navbar configured with logo and company name (see Step 1.4)
|
|
1956
2067
|
|
|
1957
2068
|
**Database:**
|
package/bin/hazo_auth.mjs
CHANGED
|
@@ -18,10 +18,17 @@ const args = process.argv.slice(2);
|
|
|
18
18
|
// Use tsx to run the TypeScript source directly
|
|
19
19
|
// This avoids ESM module resolution issues with compiled JS
|
|
20
20
|
// tsx is a dependency of hazo_auth so it should be available
|
|
21
|
+
const existingNodeOptions = process.env.NODE_OPTIONS || '';
|
|
22
|
+
const reactServerCondition = '--conditions react-server';
|
|
23
|
+
const nodeOptions = existingNodeOptions.includes(reactServerCondition)
|
|
24
|
+
? existingNodeOptions
|
|
25
|
+
: `${existingNodeOptions} ${reactServerCondition}`.trim();
|
|
26
|
+
|
|
21
27
|
const child = spawn('npx', ['tsx', cliPath, ...args], {
|
|
22
28
|
stdio: 'inherit',
|
|
23
29
|
cwd: process.cwd(),
|
|
24
|
-
shell: true
|
|
30
|
+
shell: true,
|
|
31
|
+
env: { ...process.env, NODE_OPTIONS: nodeOptions },
|
|
25
32
|
});
|
|
26
33
|
|
|
27
34
|
child.on('exit', (code) => {
|
|
Binary file
|
package/cli-src/cli/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { run_validation } from "./validate.js";
|
|
|
7
7
|
import { generate_routes, type GenerateOptions } from "./generate.js";
|
|
8
8
|
import { handle_init } from "./init.js";
|
|
9
9
|
import { handle_init_users, show_init_users_help } from "./init_users.js";
|
|
10
|
+
import { handle_init_db } from "./init_db.js";
|
|
10
11
|
import { handle_init_permissions, show_init_permissions_help } from "./init_permissions.js";
|
|
11
12
|
|
|
12
13
|
// section: constants
|
|
@@ -18,11 +19,13 @@ const HELP_TEXT = `
|
|
|
18
19
|
Usage: hazo_auth <command> [options]
|
|
19
20
|
|
|
20
21
|
Commands:
|
|
21
|
-
init Initialize hazo_auth in your project (creates directories, copies config)
|
|
22
|
+
init Initialize hazo_auth in your project (creates directories, copies config, DB)
|
|
23
|
+
init-db Create SQLite database with hazo_auth schema (standalone)
|
|
22
24
|
init-permissions Create default permissions from config (no user required)
|
|
23
25
|
init-users Initialize permissions, roles, and super user from config
|
|
24
26
|
validate Check your hazo_auth setup and configuration
|
|
25
27
|
generate-routes Generate API route files and pages in your project
|
|
28
|
+
schema Print the canonical SQLite schema SQL
|
|
26
29
|
|
|
27
30
|
Options:
|
|
28
31
|
--help, -h Show this help message
|
|
@@ -30,12 +33,14 @@ Options:
|
|
|
30
33
|
|
|
31
34
|
Examples:
|
|
32
35
|
npx hazo_auth init
|
|
36
|
+
npx hazo_auth init-db
|
|
33
37
|
npx hazo_auth init-permissions
|
|
34
38
|
npx hazo_auth init-users
|
|
35
39
|
npx hazo_auth validate
|
|
36
40
|
npx hazo_auth generate-routes
|
|
37
41
|
npx hazo_auth generate-routes --pages
|
|
38
42
|
npx hazo_auth generate-routes --all --dir=src/app
|
|
43
|
+
npx hazo_auth schema
|
|
39
44
|
|
|
40
45
|
Documentation:
|
|
41
46
|
https://github.com/your-repo/hazo_auth/blob/main/SETUP_CHECKLIST.md
|
|
@@ -150,13 +155,42 @@ Actions:
|
|
|
150
155
|
- Creates data/ directory (for SQLite)
|
|
151
156
|
- Copies hazo_auth_config.ini and hazo_notify_config.ini
|
|
152
157
|
- Copies profile picture library images
|
|
158
|
+
- Copies default auth page images (login, register, etc.)
|
|
153
159
|
- Creates .env.local.example template
|
|
160
|
+
- Creates SQLite database with schema (if better-sqlite3 is installed)
|
|
154
161
|
`);
|
|
155
162
|
return;
|
|
156
163
|
}
|
|
157
|
-
handle_init();
|
|
164
|
+
await handle_init();
|
|
158
165
|
break;
|
|
159
166
|
|
|
167
|
+
case "init-db":
|
|
168
|
+
if (help) {
|
|
169
|
+
console.log(`
|
|
170
|
+
hazo_auth init-db
|
|
171
|
+
|
|
172
|
+
Create SQLite database with the hazo_auth schema.
|
|
173
|
+
|
|
174
|
+
This command:
|
|
175
|
+
- Reads sqlite_path from config/hazo_auth_config.ini (default: ./data/hazo_auth.sqlite)
|
|
176
|
+
- Creates the database file if it doesn't exist
|
|
177
|
+
- Creates all required tables (hazo_users, hazo_roles, hazo_scopes, etc.)
|
|
178
|
+
- Skips if tables already exist
|
|
179
|
+
|
|
180
|
+
Requires: better-sqlite3 (npm install better-sqlite3)
|
|
181
|
+
`);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
handle_init_db();
|
|
185
|
+
break;
|
|
186
|
+
|
|
187
|
+
case "schema": {
|
|
188
|
+
// Dynamic import to avoid bundling the schema in the main CLI entry
|
|
189
|
+
const { SQLITE_SCHEMA } = await import("../lib/schema/sqlite_schema.js");
|
|
190
|
+
console.log(SQLITE_SCHEMA);
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
|
|
160
194
|
case "init-permissions": {
|
|
161
195
|
if (help) {
|
|
162
196
|
show_init_permissions_help();
|