hazo_auth 4.5.6 → 4.6.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 +206 -1
- package/SETUP_CHECKLIST.md +124 -21
- package/cli-src/lib/auth/auth_types.ts +2 -0
- package/cli-src/lib/auth/auth_utils.server.ts +9 -10
- package/cli-src/lib/auth/dev_lock_validator.edge.ts +5 -4
- package/cli-src/lib/auth/hazo_get_auth.server.ts +32 -5
- package/cli-src/lib/auth/server_auth.ts +3 -2
- package/cli-src/lib/auth/session_token_validator.edge.ts +4 -2
- package/cli-src/lib/cookies_config.edge.ts +55 -0
- package/cli-src/lib/cookies_config.server.ts +93 -0
- package/cli-src/lib/services/app_user_data_service.ts +294 -0
- package/cli-src/lib/services/index.ts +1 -0
- package/dist/app/api/hazo_auth/app_user_data/route.d.ts +64 -0
- package/dist/app/api/hazo_auth/app_user_data/route.d.ts.map +1 -0
- package/dist/app/api/hazo_auth/app_user_data/route.js +208 -0
- package/dist/app/api/hazo_auth/login/route.d.ts.map +1 -1
- package/dist/app/api/hazo_auth/login/route.js +8 -17
- package/dist/app/api/hazo_auth/logout/route.d.ts.map +1 -1
- package/dist/app/api/hazo_auth/logout/route.js +9 -13
- package/dist/app/api/hazo_auth/me/route.d.ts +2 -1
- package/dist/app/api/hazo_auth/me/route.d.ts.map +1 -1
- package/dist/app/api/hazo_auth/me/route.js +4 -1
- package/dist/app/api/hazo_auth/update_user/route.d.ts.map +1 -1
- package/dist/app/api/hazo_auth/update_user/route.js +6 -3
- package/dist/components/layouts/app_user_data_test/index.d.ts +6 -0
- package/dist/components/layouts/app_user_data_test/index.d.ts.map +1 -0
- package/dist/components/layouts/app_user_data_test/index.js +145 -0
- package/dist/components/layouts/shared/components/password_field.js +1 -1
- package/dist/components/layouts/shared/components/profile_pic_menu.d.ts.map +1 -1
- package/dist/components/layouts/shared/components/profile_pic_menu.js +49 -43
- package/dist/components/layouts/shared/components/sidebar_layout_wrapper.d.ts.map +1 -1
- package/dist/components/layouts/shared/components/sidebar_layout_wrapper.js +2 -2
- package/dist/components/layouts/shared/components/two_column_auth_layout.js +1 -1
- package/dist/lib/auth/auth_types.d.ts +1 -0
- package/dist/lib/auth/auth_types.d.ts.map +1 -1
- package/dist/lib/auth/auth_utils.server.d.ts.map +1 -1
- package/dist/lib/auth/auth_utils.server.js +9 -10
- package/dist/lib/auth/dev_lock_validator.edge.d.ts +2 -1
- package/dist/lib/auth/dev_lock_validator.edge.d.ts.map +1 -1
- package/dist/lib/auth/dev_lock_validator.edge.js +5 -4
- package/dist/lib/auth/hazo_get_auth.server.d.ts.map +1 -1
- package/dist/lib/auth/hazo_get_auth.server.js +29 -4
- package/dist/lib/auth/server_auth.d.ts.map +1 -1
- package/dist/lib/auth/server_auth.js +3 -2
- package/dist/lib/auth/session_token_validator.edge.d.ts +1 -0
- package/dist/lib/auth/session_token_validator.edge.d.ts.map +1 -1
- package/dist/lib/auth/session_token_validator.edge.js +4 -2
- package/dist/lib/cookies_config.edge.d.ts +33 -0
- package/dist/lib/cookies_config.edge.d.ts.map +1 -0
- package/dist/lib/cookies_config.edge.js +48 -0
- package/dist/lib/cookies_config.server.d.ts +42 -0
- package/dist/lib/cookies_config.server.d.ts.map +1 -0
- package/dist/lib/cookies_config.server.js +71 -0
- package/dist/lib/services/app_user_data_service.d.ts +34 -0
- package/dist/lib/services/app_user_data_service.d.ts.map +1 -0
- package/dist/lib/services/app_user_data_service.js +228 -0
- package/dist/lib/services/index.d.ts +1 -0
- package/dist/lib/services/index.d.ts.map +1 -1
- package/dist/lib/services/index.js +1 -0
- package/dist/server/routes/app_user_data.d.ts +2 -0
- package/dist/server/routes/app_user_data.d.ts.map +1 -0
- package/dist/server/routes/app_user_data.js +2 -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 +2 -0
- package/dist/server_pages/forgot_password.d.ts.map +1 -1
- package/dist/server_pages/forgot_password.js +3 -2
- package/dist/server_pages/login.d.ts.map +1 -1
- package/dist/server_pages/login.js +8 -7
- package/dist/server_pages/my_settings.d.ts.map +1 -1
- package/dist/server_pages/my_settings.js +3 -2
- package/dist/server_pages/register.d.ts.map +1 -1
- package/dist/server_pages/register.js +3 -2
- package/dist/server_pages/reset_password.d.ts.map +1 -1
- package/dist/server_pages/reset_password.js +3 -2
- package/dist/server_pages/verify_email.d.ts.map +1 -1
- package/dist/server_pages/verify_email.js +3 -2
- package/hazo_auth_config.example.ini +15 -0
- package/package.json +26 -1
package/README.md
CHANGED
|
@@ -94,6 +94,7 @@ export default function Page() {
|
|
|
94
94
|
- ✅ Database connection initialized server-side via hazo_connect singleton
|
|
95
95
|
- ✅ Configuration loaded from hazo_auth_config.ini (or uses sensible defaults)
|
|
96
96
|
- ✅ All props automatically configured
|
|
97
|
+
- ✅ Navbar automatically rendered based on config (no manual wrapping needed)
|
|
97
98
|
- ✅ Page renders immediately - NO loading state!
|
|
98
99
|
|
|
99
100
|
**Available zero-config pages:**
|
|
@@ -381,6 +382,22 @@ HAZO_AUTH_GOOGLE_CLIENT_SECRET=your_google_client_secret
|
|
|
381
382
|
|
|
382
383
|
See [Google OAuth Setup](#google-oauth-setup) for detailed instructions.
|
|
383
384
|
|
|
385
|
+
**For Cookie Customization (optional):**
|
|
386
|
+
```env
|
|
387
|
+
# Cookie prefix (prevents conflicts when running multiple apps on localhost)
|
|
388
|
+
HAZO_AUTH_COOKIE_PREFIX=myapp_
|
|
389
|
+
|
|
390
|
+
# Cookie domain (optional, for cross-subdomain sharing)
|
|
391
|
+
HAZO_AUTH_COOKIE_DOMAIN=.example.com
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
These environment variables are required for Edge Runtime (middleware) when using cookie customization. Also set in `hazo_auth_config.ini`:
|
|
395
|
+
```ini
|
|
396
|
+
[hazo_auth__cookies]
|
|
397
|
+
cookie_prefix = myapp_
|
|
398
|
+
cookie_domain = .example.com
|
|
399
|
+
```
|
|
400
|
+
|
|
384
401
|
**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.
|
|
385
402
|
|
|
386
403
|
---
|
|
@@ -1180,6 +1197,8 @@ vertical_center = auto # 'auto' enables vertical centering when navbar is prese
|
|
|
1180
1197
|
|
|
1181
1198
|
### Authentication Page Navbar
|
|
1182
1199
|
|
|
1200
|
+
**The navbar now works automatically** - zero-config server page components include the navbar based on configuration without manual wrapping.
|
|
1201
|
+
|
|
1183
1202
|
When using `layout_mode = standalone`, you can enable a configurable navbar that appears on all auth pages:
|
|
1184
1203
|
|
|
1185
1204
|
```ini
|
|
@@ -1199,7 +1218,17 @@ height = 64 # Navbar height in pixels
|
|
|
1199
1218
|
|
|
1200
1219
|
The navbar provides consistent branding across authentication pages with your company logo, name, and optional home link. It automatically vertically centers auth content when enabled.
|
|
1201
1220
|
|
|
1202
|
-
**
|
|
1221
|
+
**Zero-config usage (recommended):**
|
|
1222
|
+
```typescript
|
|
1223
|
+
// app/hazo_auth/login/page.tsx
|
|
1224
|
+
import { LoginPage } from "hazo_auth/pages/login";
|
|
1225
|
+
|
|
1226
|
+
export default function Page() {
|
|
1227
|
+
return <LoginPage />; // Navbar appears automatically if enabled in config
|
|
1228
|
+
}
|
|
1229
|
+
```
|
|
1230
|
+
|
|
1231
|
+
**Customize via props (advanced):**
|
|
1203
1232
|
```typescript
|
|
1204
1233
|
import { LoginLayout } from "hazo_auth/components/layouts/login";
|
|
1205
1234
|
|
|
@@ -1218,6 +1247,8 @@ export default function Page() {
|
|
|
1218
1247
|
|
|
1219
1248
|
**Disable for specific pages:**
|
|
1220
1249
|
```typescript
|
|
1250
|
+
<LoginPage disableNavbar={true} />
|
|
1251
|
+
// OR for layout components:
|
|
1221
1252
|
<LoginLayout navbar={{ enable_navbar: false }} />
|
|
1222
1253
|
```
|
|
1223
1254
|
|
|
@@ -2066,6 +2097,180 @@ For full documentation, see `CLAUDE.md` or `TECHDOC.md`.
|
|
|
2066
2097
|
|
|
2067
2098
|
---
|
|
2068
2099
|
|
|
2100
|
+
## App User Data (Custom User Metadata)
|
|
2101
|
+
|
|
2102
|
+
hazo_auth provides a flexible JSON field for storing custom user-specific data without modifying the `hazo_users` table schema. This allows consuming applications to store user preferences, settings, and app-specific state.
|
|
2103
|
+
|
|
2104
|
+
### Overview
|
|
2105
|
+
|
|
2106
|
+
- **JSON Storage**: Single TEXT column stores JSON objects (no schema restrictions)
|
|
2107
|
+
- **Deep Merge Support**: PATCH endpoint merges new data with existing data
|
|
2108
|
+
- **Full Replace**: PUT endpoint replaces entire JSON object
|
|
2109
|
+
- **Clear Data**: DELETE endpoint sets field to NULL
|
|
2110
|
+
- **Type-Safe**: TypeScript service layer with validation
|
|
2111
|
+
- **Included in Auth Response**: Available in `/api/hazo_auth/me` response
|
|
2112
|
+
|
|
2113
|
+
### Quick Start
|
|
2114
|
+
|
|
2115
|
+
1. **Run database migration**:
|
|
2116
|
+
```bash
|
|
2117
|
+
npm run migrate migrations/008_add_app_user_data_to_hazo_users.sql
|
|
2118
|
+
```
|
|
2119
|
+
|
|
2120
|
+
2. **Create API route** (`app/api/hazo_auth/app_user_data/route.ts`):
|
|
2121
|
+
```typescript
|
|
2122
|
+
export {
|
|
2123
|
+
appUserDataGET as GET,
|
|
2124
|
+
appUserDataPATCH as PATCH,
|
|
2125
|
+
appUserDataPUT as PUT,
|
|
2126
|
+
appUserDataDELETE as DELETE
|
|
2127
|
+
} from "hazo_auth/server/routes";
|
|
2128
|
+
```
|
|
2129
|
+
|
|
2130
|
+
Or use CLI: `npx hazo_auth generate-routes`
|
|
2131
|
+
|
|
2132
|
+
3. **Use in your app**:
|
|
2133
|
+
```typescript
|
|
2134
|
+
// Store user preferences (deep merge)
|
|
2135
|
+
PATCH /api/hazo_auth/app_user_data
|
|
2136
|
+
{
|
|
2137
|
+
data: {
|
|
2138
|
+
theme: "dark",
|
|
2139
|
+
language: "en-US",
|
|
2140
|
+
sidebar_collapsed: true
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
|
|
2144
|
+
// Access in client components
|
|
2145
|
+
const { app_user_data } = use_hazo_auth();
|
|
2146
|
+
console.log(app_user_data?.theme); // "dark"
|
|
2147
|
+
```
|
|
2148
|
+
|
|
2149
|
+
### API Endpoints
|
|
2150
|
+
|
|
2151
|
+
**GET `/api/hazo_auth/app_user_data`** - Get current user's data
|
|
2152
|
+
```typescript
|
|
2153
|
+
Response: { data: { theme: "dark", sidebar_collapsed: true } | null }
|
|
2154
|
+
```
|
|
2155
|
+
|
|
2156
|
+
**PATCH `/api/hazo_auth/app_user_data`** - Merge with existing data (preserves other fields)
|
|
2157
|
+
```typescript
|
|
2158
|
+
Request: { data: { theme: "light" } }
|
|
2159
|
+
// If existing: { theme: "dark", sidebar_collapsed: true }
|
|
2160
|
+
// Result: { theme: "light", sidebar_collapsed: true }
|
|
2161
|
+
```
|
|
2162
|
+
|
|
2163
|
+
**PUT `/api/hazo_auth/app_user_data`** - Replace entire object
|
|
2164
|
+
```typescript
|
|
2165
|
+
Request: { data: { theme: "light" } }
|
|
2166
|
+
// Result: { theme: "light" } (sidebar_collapsed removed)
|
|
2167
|
+
```
|
|
2168
|
+
|
|
2169
|
+
**DELETE `/api/hazo_auth/app_user_data`** - Clear all data (sets to NULL)
|
|
2170
|
+
|
|
2171
|
+
### Service Functions
|
|
2172
|
+
|
|
2173
|
+
```typescript
|
|
2174
|
+
import {
|
|
2175
|
+
get_app_user_data,
|
|
2176
|
+
update_app_user_data,
|
|
2177
|
+
clear_app_user_data
|
|
2178
|
+
} from "hazo_auth";
|
|
2179
|
+
|
|
2180
|
+
// Get data
|
|
2181
|
+
const data = await get_app_user_data(adapter, user_id);
|
|
2182
|
+
|
|
2183
|
+
// Update with merge (default)
|
|
2184
|
+
await update_app_user_data(adapter, user_id, { theme: "light" }, true);
|
|
2185
|
+
|
|
2186
|
+
// Replace entirely
|
|
2187
|
+
await update_app_user_data(adapter, user_id, { theme: "light" }, false);
|
|
2188
|
+
|
|
2189
|
+
// Clear data
|
|
2190
|
+
await clear_app_user_data(adapter, user_id);
|
|
2191
|
+
```
|
|
2192
|
+
|
|
2193
|
+
### Access in `/api/hazo_auth/me`
|
|
2194
|
+
|
|
2195
|
+
The `app_user_data` field is included in the authentication response:
|
|
2196
|
+
|
|
2197
|
+
```typescript
|
|
2198
|
+
{
|
|
2199
|
+
authenticated: true,
|
|
2200
|
+
user: { ... },
|
|
2201
|
+
permissions: [...],
|
|
2202
|
+
app_user_data: { theme: "dark", sidebar_collapsed: true } | null
|
|
2203
|
+
}
|
|
2204
|
+
```
|
|
2205
|
+
|
|
2206
|
+
### Use Cases
|
|
2207
|
+
|
|
2208
|
+
**Store user preferences:**
|
|
2209
|
+
```typescript
|
|
2210
|
+
{
|
|
2211
|
+
theme: "dark",
|
|
2212
|
+
language: "en-US",
|
|
2213
|
+
timezone: "America/New_York"
|
|
2214
|
+
}
|
|
2215
|
+
```
|
|
2216
|
+
|
|
2217
|
+
**Store app-specific state:**
|
|
2218
|
+
```typescript
|
|
2219
|
+
{
|
|
2220
|
+
dashboard_layout: "grid",
|
|
2221
|
+
sidebar_collapsed: true,
|
|
2222
|
+
recent_searches: ["tax forms", "invoices"]
|
|
2223
|
+
}
|
|
2224
|
+
```
|
|
2225
|
+
|
|
2226
|
+
**Store nested configuration:**
|
|
2227
|
+
```typescript
|
|
2228
|
+
{
|
|
2229
|
+
notifications: {
|
|
2230
|
+
email: true,
|
|
2231
|
+
sms: false,
|
|
2232
|
+
push: true
|
|
2233
|
+
},
|
|
2234
|
+
privacy: {
|
|
2235
|
+
profile_public: false,
|
|
2236
|
+
show_email: false
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
```
|
|
2240
|
+
|
|
2241
|
+
### Deep Merge Behavior
|
|
2242
|
+
|
|
2243
|
+
```typescript
|
|
2244
|
+
// Existing data
|
|
2245
|
+
{ user: { name: "Alice", age: 30 }, theme: "dark" }
|
|
2246
|
+
|
|
2247
|
+
// PATCH with
|
|
2248
|
+
{ user: { age: 31 }, sidebar: true }
|
|
2249
|
+
|
|
2250
|
+
// Result (deep merge)
|
|
2251
|
+
{ user: { name: "Alice", age: 31 }, theme: "dark", sidebar: true }
|
|
2252
|
+
```
|
|
2253
|
+
|
|
2254
|
+
### Test Page
|
|
2255
|
+
|
|
2256
|
+
Visit `/hazo_auth/app_user_data_test` in your dev environment to test the API with an interactive UI:
|
|
2257
|
+
- View current data (live refresh)
|
|
2258
|
+
- Merge data (PATCH)
|
|
2259
|
+
- Replace data (PUT)
|
|
2260
|
+
- Clear data (DELETE)
|
|
2261
|
+
- JSON validation
|
|
2262
|
+
|
|
2263
|
+
### Performance & Limits
|
|
2264
|
+
|
|
2265
|
+
- **Recommended max size**: ~10KB per user (for preferences/settings)
|
|
2266
|
+
- **Storage**: JSON stored as TEXT (no compression)
|
|
2267
|
+
- **Caching**: Benefits from `hazo_get_auth()` LRU cache
|
|
2268
|
+
- **Large datasets**: Use separate tables for complex relational data
|
|
2269
|
+
|
|
2270
|
+
For full documentation, see `CHANGE_LOG.md` and `TECHDOC.md`.
|
|
2271
|
+
|
|
2272
|
+
---
|
|
2273
|
+
|
|
2069
2274
|
## User Profile Service
|
|
2070
2275
|
|
|
2071
2276
|
The `hazo_auth` package provides a batch user profile retrieval service for applications that need basic user information, such as chat applications or user lists.
|
package/SETUP_CHECKLIST.md
CHANGED
|
@@ -197,6 +197,10 @@ HAZO_CONNECT_POSTGREST_API_KEY=your_postgrest_api_key_here
|
|
|
197
197
|
# Required for JWT authentication
|
|
198
198
|
JWT_SECRET=your_secure_random_string_at_least_32_characters
|
|
199
199
|
# Note: JWT_SECRET is required for JWT session token functionality (Edge-compatible proxy/middleware authentication)
|
|
200
|
+
|
|
201
|
+
# Optional: Cookie customization (prevents conflicts when running multiple apps)
|
|
202
|
+
HAZO_AUTH_COOKIE_PREFIX=myapp_
|
|
203
|
+
HAZO_AUTH_COOKIE_DOMAIN=
|
|
200
204
|
```
|
|
201
205
|
|
|
202
206
|
**Generate a secure JWT secret:**
|
|
@@ -204,6 +208,18 @@ JWT_SECRET=your_secure_random_string_at_least_32_characters
|
|
|
204
208
|
openssl rand -base64 32
|
|
205
209
|
```
|
|
206
210
|
|
|
211
|
+
**Cookie Customization (Optional):**
|
|
212
|
+
If you're running multiple apps that use hazo_auth on localhost (different ports), set `HAZO_AUTH_COOKIE_PREFIX` to prevent cookie conflicts. For example:
|
|
213
|
+
- App 1 (port 3000): `HAZO_AUTH_COOKIE_PREFIX=app1_`
|
|
214
|
+
- App 2 (port 3001): `HAZO_AUTH_COOKIE_PREFIX=app2_`
|
|
215
|
+
|
|
216
|
+
Also configure in `hazo_auth_config.ini`:
|
|
217
|
+
```ini
|
|
218
|
+
[hazo_auth__cookies]
|
|
219
|
+
cookie_prefix = myapp_
|
|
220
|
+
cookie_domain =
|
|
221
|
+
```
|
|
222
|
+
|
|
207
223
|
### Step 2.2: Configure email settings
|
|
208
224
|
|
|
209
225
|
Edit `hazo_notify_config.ini`:
|
|
@@ -312,15 +328,54 @@ Run this SQL script in your PostgreSQL database:
|
|
|
312
328
|
-- Ensure we're in the public schema (or your target schema)
|
|
313
329
|
SET search_path TO public;
|
|
314
330
|
|
|
315
|
-
-- Create enum
|
|
331
|
+
-- Create enum types (drop first if they exist to avoid conflicts)
|
|
316
332
|
DROP TYPE IF EXISTS hazo_enum_profile_source_enum CASCADE;
|
|
317
333
|
CREATE TYPE hazo_enum_profile_source_enum AS ENUM ('gravatar', 'custom', 'predefined');
|
|
318
334
|
|
|
335
|
+
DROP TYPE IF EXISTS hazo_enum_scope_types CASCADE;
|
|
336
|
+
CREATE TYPE hazo_enum_scope_types AS ENUM (
|
|
337
|
+
'hazo_scopes_l1', 'hazo_scopes_l2', 'hazo_scopes_l3',
|
|
338
|
+
'hazo_scopes_l4', 'hazo_scopes_l5', 'hazo_scopes_l6', 'hazo_scopes_l7'
|
|
339
|
+
);
|
|
340
|
+
|
|
341
|
+
DROP TYPE IF EXISTS hazo_enum_notify_chain_status CASCADE;
|
|
342
|
+
CREATE TYPE hazo_enum_notify_chain_status AS ENUM ('draft', 'published', 'inactive');
|
|
343
|
+
|
|
344
|
+
DROP TYPE IF EXISTS hazo_enum_notify_email_type CASCADE;
|
|
345
|
+
CREATE TYPE hazo_enum_notify_email_type AS ENUM ('system', 'user');
|
|
346
|
+
|
|
347
|
+
DROP TYPE IF EXISTS hazo_enum_group_type CASCADE;
|
|
348
|
+
CREATE TYPE hazo_enum_group_type AS ENUM ('support', 'peer', 'group');
|
|
349
|
+
|
|
350
|
+
DROP TYPE IF EXISTS hazo_enum_group_role CASCADE;
|
|
351
|
+
CREATE TYPE hazo_enum_group_role AS ENUM ('client', 'staff', 'owner', 'admin', 'member');
|
|
352
|
+
|
|
353
|
+
DROP TYPE IF EXISTS hazo_enum_chat_type CASCADE;
|
|
354
|
+
CREATE TYPE hazo_enum_chat_type AS ENUM ('chat', 'field', 'project', 'support', 'general');
|
|
355
|
+
|
|
356
|
+
-- Create organization table (multi-tenancy) - MUST be created before hazo_users
|
|
357
|
+
CREATE TABLE hazo_org (
|
|
358
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
359
|
+
name TEXT NOT NULL,
|
|
360
|
+
parent_org_id UUID REFERENCES hazo_org(id) ON DELETE SET NULL,
|
|
361
|
+
root_org_id UUID REFERENCES hazo_org(id) ON DELETE SET NULL,
|
|
362
|
+
user_limit INTEGER NOT NULL DEFAULT 0, -- 0 = unlimited
|
|
363
|
+
active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
364
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
365
|
+
created_by UUID, -- FK added after hazo_users exists
|
|
366
|
+
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
367
|
+
changed_by UUID -- FK added after hazo_users exists
|
|
368
|
+
);
|
|
369
|
+
CREATE INDEX idx_hazo_org_parent_org_id ON hazo_org(parent_org_id);
|
|
370
|
+
CREATE INDEX idx_hazo_org_root_org_id ON hazo_org(root_org_id);
|
|
371
|
+
CREATE INDEX idx_hazo_org_active ON hazo_org(active);
|
|
372
|
+
CREATE INDEX idx_hazo_org_name ON hazo_org(name);
|
|
373
|
+
|
|
319
374
|
-- Create users table
|
|
320
375
|
CREATE TABLE hazo_users (
|
|
321
376
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
322
377
|
email_address TEXT NOT NULL UNIQUE,
|
|
323
|
-
password_hash TEXT
|
|
378
|
+
password_hash TEXT, -- NULL for OAuth-only users
|
|
324
379
|
name TEXT,
|
|
325
380
|
email_verified BOOLEAN NOT NULL DEFAULT FALSE,
|
|
326
381
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
@@ -330,10 +385,25 @@ CREATE TABLE hazo_users (
|
|
|
330
385
|
profile_source hazo_enum_profile_source_enum,
|
|
331
386
|
mfa_secret TEXT,
|
|
332
387
|
url_on_logon TEXT,
|
|
388
|
+
user_type TEXT, -- Optional user categorization
|
|
389
|
+
google_id TEXT UNIQUE, -- Google OAuth ID
|
|
390
|
+
auth_providers TEXT DEFAULT 'email', -- 'email', 'google', or 'email,google'
|
|
391
|
+
org_id UUID REFERENCES hazo_org(id) ON DELETE SET NULL,
|
|
392
|
+
root_org_id UUID REFERENCES hazo_org(id) ON DELETE SET NULL,
|
|
333
393
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
334
394
|
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
335
395
|
);
|
|
336
396
|
CREATE INDEX idx_hazo_users_email ON hazo_users(email_address);
|
|
397
|
+
CREATE INDEX idx_hazo_users_user_type ON hazo_users(user_type);
|
|
398
|
+
CREATE UNIQUE INDEX idx_hazo_users_google_id ON hazo_users(google_id);
|
|
399
|
+
CREATE INDEX idx_hazo_users_org_id ON hazo_users(org_id);
|
|
400
|
+
CREATE INDEX idx_hazo_users_root_org_id ON hazo_users(root_org_id);
|
|
401
|
+
|
|
402
|
+
-- Add FK constraints to hazo_org now that hazo_users exists
|
|
403
|
+
ALTER TABLE hazo_org ADD CONSTRAINT fk_hazo_org_created_by
|
|
404
|
+
FOREIGN KEY (created_by) REFERENCES hazo_users(id) ON DELETE SET NULL;
|
|
405
|
+
ALTER TABLE hazo_org ADD CONSTRAINT fk_hazo_org_changed_by
|
|
406
|
+
FOREIGN KEY (changed_by) REFERENCES hazo_users(id) ON DELETE SET NULL;
|
|
337
407
|
|
|
338
408
|
-- Create refresh tokens table
|
|
339
409
|
CREATE TABLE hazo_refresh_tokens (
|
|
@@ -453,7 +523,22 @@ GRANT USAGE ON TYPE hazo_enum_profile_source_enum TO anon, authenticated;
|
|
|
453
523
|
|
|
454
524
|
**Checklist:**
|
|
455
525
|
- [ ] Database created (SQLite file or PostgreSQL)
|
|
456
|
-
- [ ] All
|
|
526
|
+
- [ ] All enum types created (PostgreSQL only):
|
|
527
|
+
- [ ] `hazo_enum_profile_source_enum`
|
|
528
|
+
- [ ] `hazo_enum_scope_types`
|
|
529
|
+
- [ ] `hazo_enum_notify_chain_status`
|
|
530
|
+
- [ ] `hazo_enum_notify_email_type`
|
|
531
|
+
- [ ] `hazo_enum_group_type`
|
|
532
|
+
- [ ] `hazo_enum_group_role`
|
|
533
|
+
- [ ] `hazo_enum_chat_type`
|
|
534
|
+
- [ ] All core tables exist:
|
|
535
|
+
- [ ] `hazo_org` (multi-tenancy - must be created before hazo_users)
|
|
536
|
+
- [ ] `hazo_users` (with google_id, auth_providers, org_id, root_org_id, user_type fields)
|
|
537
|
+
- [ ] `hazo_refresh_tokens`
|
|
538
|
+
- [ ] `hazo_permissions`
|
|
539
|
+
- [ ] `hazo_roles`
|
|
540
|
+
- [ ] `hazo_role_permissions`
|
|
541
|
+
- [ ] `hazo_user_roles`
|
|
457
542
|
|
|
458
543
|
---
|
|
459
544
|
|
|
@@ -1244,25 +1329,29 @@ $$ LANGUAGE plpgsql;
|
|
|
1244
1329
|
CREATE TABLE hazo_scopes_l1 (
|
|
1245
1330
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
1246
1331
|
seq TEXT NOT NULL DEFAULT hazo_scope_id_generator('hazo_scopes_l1'),
|
|
1247
|
-
|
|
1332
|
+
org_id UUID NOT NULL REFERENCES hazo_org(id) ON DELETE CASCADE,
|
|
1333
|
+
root_org_id UUID NOT NULL REFERENCES hazo_org(id) ON DELETE CASCADE,
|
|
1248
1334
|
name TEXT NOT NULL,
|
|
1249
1335
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
1250
1336
|
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
1251
1337
|
);
|
|
1252
|
-
CREATE INDEX
|
|
1338
|
+
CREATE INDEX idx_hazo_scopes_l1_org_id ON hazo_scopes_l1(org_id);
|
|
1339
|
+
CREATE INDEX idx_hazo_scopes_l1_root_org_id ON hazo_scopes_l1(root_org_id);
|
|
1253
1340
|
CREATE INDEX idx_hazo_scopes_l1_seq ON hazo_scopes_l1(seq);
|
|
1254
1341
|
|
|
1255
1342
|
-- Level 2 (parent: L1)
|
|
1256
1343
|
CREATE TABLE hazo_scopes_l2 (
|
|
1257
1344
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
1258
1345
|
seq TEXT NOT NULL DEFAULT hazo_scope_id_generator('hazo_scopes_l2'),
|
|
1259
|
-
|
|
1346
|
+
org_id UUID NOT NULL REFERENCES hazo_org(id) ON DELETE CASCADE,
|
|
1347
|
+
root_org_id UUID NOT NULL REFERENCES hazo_org(id) ON DELETE CASCADE,
|
|
1260
1348
|
name TEXT NOT NULL,
|
|
1261
1349
|
parent_scope_id UUID REFERENCES hazo_scopes_l1(id) ON DELETE CASCADE,
|
|
1262
1350
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
1263
1351
|
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
1264
1352
|
);
|
|
1265
|
-
CREATE INDEX
|
|
1353
|
+
CREATE INDEX idx_hazo_scopes_l2_org_id ON hazo_scopes_l2(org_id);
|
|
1354
|
+
CREATE INDEX idx_hazo_scopes_l2_root_org_id ON hazo_scopes_l2(root_org_id);
|
|
1266
1355
|
CREATE INDEX idx_hazo_scopes_l2_seq ON hazo_scopes_l2(seq);
|
|
1267
1356
|
CREATE INDEX idx_hazo_scopes_l2_parent ON hazo_scopes_l2(parent_scope_id);
|
|
1268
1357
|
|
|
@@ -1270,13 +1359,15 @@ CREATE INDEX idx_hazo_scopes_l2_parent ON hazo_scopes_l2(parent_scope_id);
|
|
|
1270
1359
|
CREATE TABLE hazo_scopes_l3 (
|
|
1271
1360
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
1272
1361
|
seq TEXT NOT NULL DEFAULT hazo_scope_id_generator('hazo_scopes_l3'),
|
|
1273
|
-
|
|
1362
|
+
org_id UUID NOT NULL REFERENCES hazo_org(id) ON DELETE CASCADE,
|
|
1363
|
+
root_org_id UUID NOT NULL REFERENCES hazo_org(id) ON DELETE CASCADE,
|
|
1274
1364
|
name TEXT NOT NULL,
|
|
1275
1365
|
parent_scope_id UUID REFERENCES hazo_scopes_l2(id) ON DELETE CASCADE,
|
|
1276
1366
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
1277
1367
|
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
1278
1368
|
);
|
|
1279
|
-
CREATE INDEX
|
|
1369
|
+
CREATE INDEX idx_hazo_scopes_l3_org_id ON hazo_scopes_l3(org_id);
|
|
1370
|
+
CREATE INDEX idx_hazo_scopes_l3_root_org_id ON hazo_scopes_l3(root_org_id);
|
|
1280
1371
|
CREATE INDEX idx_hazo_scopes_l3_seq ON hazo_scopes_l3(seq);
|
|
1281
1372
|
CREATE INDEX idx_hazo_scopes_l3_parent ON hazo_scopes_l3(parent_scope_id);
|
|
1282
1373
|
|
|
@@ -1284,13 +1375,15 @@ CREATE INDEX idx_hazo_scopes_l3_parent ON hazo_scopes_l3(parent_scope_id);
|
|
|
1284
1375
|
CREATE TABLE hazo_scopes_l4 (
|
|
1285
1376
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
1286
1377
|
seq TEXT NOT NULL DEFAULT hazo_scope_id_generator('hazo_scopes_l4'),
|
|
1287
|
-
|
|
1378
|
+
org_id UUID NOT NULL REFERENCES hazo_org(id) ON DELETE CASCADE,
|
|
1379
|
+
root_org_id UUID NOT NULL REFERENCES hazo_org(id) ON DELETE CASCADE,
|
|
1288
1380
|
name TEXT NOT NULL,
|
|
1289
1381
|
parent_scope_id UUID REFERENCES hazo_scopes_l3(id) ON DELETE CASCADE,
|
|
1290
1382
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
1291
1383
|
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
1292
1384
|
);
|
|
1293
|
-
CREATE INDEX
|
|
1385
|
+
CREATE INDEX idx_hazo_scopes_l4_org_id ON hazo_scopes_l4(org_id);
|
|
1386
|
+
CREATE INDEX idx_hazo_scopes_l4_root_org_id ON hazo_scopes_l4(root_org_id);
|
|
1294
1387
|
CREATE INDEX idx_hazo_scopes_l4_seq ON hazo_scopes_l4(seq);
|
|
1295
1388
|
CREATE INDEX idx_hazo_scopes_l4_parent ON hazo_scopes_l4(parent_scope_id);
|
|
1296
1389
|
|
|
@@ -1298,13 +1391,15 @@ CREATE INDEX idx_hazo_scopes_l4_parent ON hazo_scopes_l4(parent_scope_id);
|
|
|
1298
1391
|
CREATE TABLE hazo_scopes_l5 (
|
|
1299
1392
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
1300
1393
|
seq TEXT NOT NULL DEFAULT hazo_scope_id_generator('hazo_scopes_l5'),
|
|
1301
|
-
|
|
1394
|
+
org_id UUID NOT NULL REFERENCES hazo_org(id) ON DELETE CASCADE,
|
|
1395
|
+
root_org_id UUID NOT NULL REFERENCES hazo_org(id) ON DELETE CASCADE,
|
|
1302
1396
|
name TEXT NOT NULL,
|
|
1303
1397
|
parent_scope_id UUID REFERENCES hazo_scopes_l4(id) ON DELETE CASCADE,
|
|
1304
1398
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
1305
1399
|
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
1306
1400
|
);
|
|
1307
|
-
CREATE INDEX
|
|
1401
|
+
CREATE INDEX idx_hazo_scopes_l5_org_id ON hazo_scopes_l5(org_id);
|
|
1402
|
+
CREATE INDEX idx_hazo_scopes_l5_root_org_id ON hazo_scopes_l5(root_org_id);
|
|
1308
1403
|
CREATE INDEX idx_hazo_scopes_l5_seq ON hazo_scopes_l5(seq);
|
|
1309
1404
|
CREATE INDEX idx_hazo_scopes_l5_parent ON hazo_scopes_l5(parent_scope_id);
|
|
1310
1405
|
|
|
@@ -1312,13 +1407,15 @@ CREATE INDEX idx_hazo_scopes_l5_parent ON hazo_scopes_l5(parent_scope_id);
|
|
|
1312
1407
|
CREATE TABLE hazo_scopes_l6 (
|
|
1313
1408
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
1314
1409
|
seq TEXT NOT NULL DEFAULT hazo_scope_id_generator('hazo_scopes_l6'),
|
|
1315
|
-
|
|
1410
|
+
org_id UUID NOT NULL REFERENCES hazo_org(id) ON DELETE CASCADE,
|
|
1411
|
+
root_org_id UUID NOT NULL REFERENCES hazo_org(id) ON DELETE CASCADE,
|
|
1316
1412
|
name TEXT NOT NULL,
|
|
1317
1413
|
parent_scope_id UUID REFERENCES hazo_scopes_l5(id) ON DELETE CASCADE,
|
|
1318
1414
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
1319
1415
|
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
1320
1416
|
);
|
|
1321
|
-
CREATE INDEX
|
|
1417
|
+
CREATE INDEX idx_hazo_scopes_l6_org_id ON hazo_scopes_l6(org_id);
|
|
1418
|
+
CREATE INDEX idx_hazo_scopes_l6_root_org_id ON hazo_scopes_l6(root_org_id);
|
|
1322
1419
|
CREATE INDEX idx_hazo_scopes_l6_seq ON hazo_scopes_l6(seq);
|
|
1323
1420
|
CREATE INDEX idx_hazo_scopes_l6_parent ON hazo_scopes_l6(parent_scope_id);
|
|
1324
1421
|
|
|
@@ -1326,13 +1423,15 @@ CREATE INDEX idx_hazo_scopes_l6_parent ON hazo_scopes_l6(parent_scope_id);
|
|
|
1326
1423
|
CREATE TABLE hazo_scopes_l7 (
|
|
1327
1424
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
1328
1425
|
seq TEXT NOT NULL DEFAULT hazo_scope_id_generator('hazo_scopes_l7'),
|
|
1329
|
-
|
|
1426
|
+
org_id UUID NOT NULL REFERENCES hazo_org(id) ON DELETE CASCADE,
|
|
1427
|
+
root_org_id UUID NOT NULL REFERENCES hazo_org(id) ON DELETE CASCADE,
|
|
1330
1428
|
name TEXT NOT NULL,
|
|
1331
1429
|
parent_scope_id UUID REFERENCES hazo_scopes_l6(id) ON DELETE CASCADE,
|
|
1332
1430
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
1333
1431
|
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
1334
1432
|
);
|
|
1335
|
-
CREATE INDEX
|
|
1433
|
+
CREATE INDEX idx_hazo_scopes_l7_org_id ON hazo_scopes_l7(org_id);
|
|
1434
|
+
CREATE INDEX idx_hazo_scopes_l7_root_org_id ON hazo_scopes_l7(root_org_id);
|
|
1336
1435
|
CREATE INDEX idx_hazo_scopes_l7_seq ON hazo_scopes_l7(seq);
|
|
1337
1436
|
CREATE INDEX idx_hazo_scopes_l7_parent ON hazo_scopes_l7(parent_scope_id);
|
|
1338
1437
|
|
|
@@ -1353,14 +1452,14 @@ CREATE INDEX idx_hazo_user_scopes_scope_type ON hazo_user_scopes(scope_type);
|
|
|
1353
1452
|
-- 5. Create scope labels table
|
|
1354
1453
|
CREATE TABLE hazo_scope_labels (
|
|
1355
1454
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
1356
|
-
|
|
1455
|
+
org_id UUID NOT NULL REFERENCES hazo_org(id) ON DELETE CASCADE,
|
|
1357
1456
|
scope_type hazo_enum_scope_types NOT NULL,
|
|
1358
1457
|
label TEXT NOT NULL,
|
|
1359
1458
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
1360
1459
|
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
1361
|
-
UNIQUE(
|
|
1460
|
+
UNIQUE(org_id, scope_type)
|
|
1362
1461
|
);
|
|
1363
|
-
CREATE INDEX
|
|
1462
|
+
CREATE INDEX idx_hazo_scope_labels_org_id ON hazo_scope_labels(org_id);
|
|
1364
1463
|
```
|
|
1365
1464
|
|
|
1366
1465
|
#### PostgreSQL Grant Scripts
|
|
@@ -1522,7 +1621,11 @@ sqlite3 data/hazo_auth.sqlite ".tables" | grep -E "hazo_scopes|hazo_user_scopes|
|
|
|
1522
1621
|
**HRBAC Checklist:**
|
|
1523
1622
|
- [ ] `enable_hrbac = true` in config
|
|
1524
1623
|
- [ ] HRBAC permissions added to defaults
|
|
1525
|
-
- [ ] All 9 HRBAC tables created
|
|
1624
|
+
- [ ] All 9 HRBAC tables created:
|
|
1625
|
+
- [ ] `hazo_scopes_l1` through `hazo_scopes_l7` (with org_id, root_org_id FKs)
|
|
1626
|
+
- [ ] `hazo_user_scopes` (junction table)
|
|
1627
|
+
- [ ] `hazo_scope_labels` (custom labels per org)
|
|
1628
|
+
- [ ] Scope ID generator function created (PostgreSQL)
|
|
1526
1629
|
- [ ] Grants applied (PostgreSQL)
|
|
1527
1630
|
- [ ] HRBAC tabs visible in User Management
|
|
1528
1631
|
- [ ] Scope test page works
|
|
@@ -10,6 +10,8 @@ export type HazoAuthUser = {
|
|
|
10
10
|
email_address: string;
|
|
11
11
|
is_active: boolean;
|
|
12
12
|
profile_picture_url: string | null;
|
|
13
|
+
// App-specific user data (JSON object stored as TEXT in database)
|
|
14
|
+
app_user_data: Record<string, unknown> | null;
|
|
13
15
|
// Multi-tenancy fields (only populated when multi-tenancy is enabled)
|
|
14
16
|
org_id?: string | null;
|
|
15
17
|
org_name?: string | null;
|
|
@@ -4,6 +4,7 @@ import { NextRequest, NextResponse } from "next/server";
|
|
|
4
4
|
import { get_hazo_connect_instance } from "../hazo_connect_instance.server.js";
|
|
5
5
|
import { createCrudService } from "hazo_connect/server";
|
|
6
6
|
import { map_db_source_to_ui } from "../services/profile_picture_source_mapper.js";
|
|
7
|
+
import { get_cookie_name, get_cookie_options, BASE_COOKIE_NAMES } from "../cookies_config.server.js";
|
|
7
8
|
|
|
8
9
|
// section: types
|
|
9
10
|
export type AuthUser = {
|
|
@@ -24,19 +25,17 @@ export type AuthResult =
|
|
|
24
25
|
|
|
25
26
|
// section: helpers
|
|
26
27
|
/**
|
|
27
|
-
* Clears authentication cookies from response
|
|
28
|
+
* Clears authentication cookies from response (with configurable prefix and domain)
|
|
28
29
|
* @param response - NextResponse object to clear cookies from
|
|
29
30
|
* @returns The response with cleared cookies
|
|
30
31
|
*/
|
|
31
32
|
function clear_auth_cookies(response: NextResponse): NextResponse {
|
|
32
|
-
|
|
33
|
-
expires: new Date(0),
|
|
34
|
-
path: "/",
|
|
35
|
-
});
|
|
36
|
-
response.cookies.set("hazo_auth_user_id", "", {
|
|
33
|
+
const clear_cookie_options = get_cookie_options({
|
|
37
34
|
expires: new Date(0),
|
|
38
35
|
path: "/",
|
|
39
36
|
});
|
|
37
|
+
response.cookies.set(get_cookie_name(BASE_COOKIE_NAMES.USER_EMAIL), "", clear_cookie_options);
|
|
38
|
+
response.cookies.set(get_cookie_name(BASE_COOKIE_NAMES.USER_ID), "", clear_cookie_options);
|
|
40
39
|
return response;
|
|
41
40
|
}
|
|
42
41
|
|
|
@@ -48,8 +47,8 @@ function clear_auth_cookies(response: NextResponse): NextResponse {
|
|
|
48
47
|
* @returns AuthResult with user info or authenticated: false
|
|
49
48
|
*/
|
|
50
49
|
export async function get_authenticated_user(request: NextRequest): Promise<AuthResult> {
|
|
51
|
-
const user_id = request.cookies.get(
|
|
52
|
-
const user_email = request.cookies.get(
|
|
50
|
+
const user_id = request.cookies.get(get_cookie_name(BASE_COOKIE_NAMES.USER_ID))?.value;
|
|
51
|
+
const user_email = request.cookies.get(get_cookie_name(BASE_COOKIE_NAMES.USER_EMAIL))?.value;
|
|
53
52
|
|
|
54
53
|
if (!user_id || !user_email) {
|
|
55
54
|
return { authenticated: false };
|
|
@@ -132,8 +131,8 @@ export async function get_authenticated_user_with_response(request: NextRequest)
|
|
|
132
131
|
auth_result: AuthResult;
|
|
133
132
|
response?: NextResponse;
|
|
134
133
|
}> {
|
|
135
|
-
const user_id = request.cookies.get(
|
|
136
|
-
const user_email = request.cookies.get(
|
|
134
|
+
const user_id = request.cookies.get(get_cookie_name(BASE_COOKIE_NAMES.USER_ID))?.value;
|
|
135
|
+
const user_email = request.cookies.get(get_cookie_name(BASE_COOKIE_NAMES.USER_EMAIL))?.value;
|
|
137
136
|
|
|
138
137
|
if (!user_id || !user_email) {
|
|
139
138
|
return { auth_result: { authenticated: false } };
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
// Uses Web Crypto API which works in Edge Runtime (no Node.js crypto module)
|
|
3
3
|
// section: imports
|
|
4
4
|
import type { NextRequest } from "next/server";
|
|
5
|
+
import { get_cookie_name_edge, BASE_COOKIE_NAMES } from "../cookies_config.edge.js";
|
|
5
6
|
|
|
6
7
|
// section: constants
|
|
7
|
-
const COOKIE_NAME = "hazo_auth_dev_lock";
|
|
8
8
|
const SEPARATOR = "|";
|
|
9
9
|
|
|
10
10
|
// section: types
|
|
@@ -105,7 +105,7 @@ export async function validate_dev_lock_cookie(
|
|
|
105
105
|
return { valid: false };
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
const cookie = request.cookies.get(
|
|
108
|
+
const cookie = request.cookies.get(get_cookie_name_edge(BASE_COOKIE_NAMES.DEV_LOCK))?.value;
|
|
109
109
|
|
|
110
110
|
if (!cookie) {
|
|
111
111
|
return { valid: false };
|
|
@@ -162,10 +162,11 @@ export function validate_dev_lock_password(password: string): boolean {
|
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
/**
|
|
165
|
-
* Gets the dev lock cookie name
|
|
165
|
+
* Gets the dev lock cookie name (with configurable prefix)
|
|
166
166
|
* Exported for use in API routes when setting the cookie
|
|
167
|
+
* Uses HAZO_AUTH_COOKIE_PREFIX env var for configurable prefix
|
|
167
168
|
* @returns Cookie name string
|
|
168
169
|
*/
|
|
169
170
|
export function get_dev_lock_cookie_name(): string {
|
|
170
|
-
return
|
|
171
|
+
return get_cookie_name_edge(BASE_COOKIE_NAMES.DEV_LOCK);
|
|
171
172
|
}
|