hazo_auth 1.0.5 → 1.2.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 +341 -0
- package/hazo_auth_config.example.ini +41 -0
- package/instrumentation.ts +2 -2
- package/package.json +2 -1
- package/scripts/init_users.ts +378 -0
- package/src/app/api/hazo_auth/login/route.ts +27 -1
- package/src/app/api/hazo_auth/register/route.ts +13 -10
- package/src/app/hazo_auth/forgot_password/page.tsx +3 -3
- package/src/app/hazo_auth/login/login_page_client.tsx +15 -0
- package/src/app/hazo_auth/login/page.tsx +16 -4
- package/src/app/hazo_auth/my_settings/page.tsx +3 -3
- package/src/app/hazo_auth/register/page.tsx +14 -4
- package/src/app/hazo_auth/register/register_page_client.tsx +9 -0
- package/src/app/hazo_auth/reset_password/page.tsx +3 -3
- package/src/app/hazo_auth/user_management/page.tsx +3 -3
- package/src/app/hazo_auth/verify_email/page.tsx +3 -3
- package/src/components/layouts/login/hooks/use_login_form.ts +13 -8
- package/src/components/layouts/login/index.tsx +28 -0
- package/src/components/layouts/register/hooks/use_register_form.ts +4 -1
- package/src/components/layouts/register/index.tsx +18 -0
- package/src/components/layouts/shared/components/auth_page_shell.tsx +36 -0
- package/src/components/layouts/shared/components/standalone_layout_wrapper.tsx +53 -0
- package/src/lib/config/config_loader.server.ts +20 -5
- package/src/lib/login_config.server.ts +25 -0
- package/src/lib/register_config.server.ts +17 -1
- package/src/lib/services/login_service.ts +19 -3
- package/src/lib/services/registration_service.ts +25 -4
- package/src/lib/services/user_profiles_service.ts +143 -0
- package/src/lib/services/user_update_service.ts +16 -3
- package/src/lib/ui_shell_config.server.ts +73 -0
- package/src/lib/utils/error_sanitizer.ts +75 -0
package/README.md
CHANGED
|
@@ -29,6 +29,215 @@ After installing the package, you need to set up configuration files in your pro
|
|
|
29
29
|
|
|
30
30
|
**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.
|
|
31
31
|
|
|
32
|
+
### Database Setup
|
|
33
|
+
|
|
34
|
+
Before using `hazo_auth`, you need to create the required database tables. Run the following SQL scripts in your PostgreSQL database:
|
|
35
|
+
|
|
36
|
+
#### 1. Create the Profile Source Enum Type
|
|
37
|
+
|
|
38
|
+
```sql
|
|
39
|
+
-- Enum type for profile picture source
|
|
40
|
+
CREATE TYPE hazo_enum_profile_source_enum AS ENUM ('gravatar', 'custom', 'predefined');
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
#### 2. Create the Users Table
|
|
44
|
+
|
|
45
|
+
```sql
|
|
46
|
+
-- Main users table
|
|
47
|
+
CREATE TABLE hazo_users (
|
|
48
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
49
|
+
email_address TEXT NOT NULL UNIQUE,
|
|
50
|
+
password_hash TEXT NOT NULL,
|
|
51
|
+
name TEXT,
|
|
52
|
+
email_verified BOOLEAN NOT NULL DEFAULT FALSE,
|
|
53
|
+
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
54
|
+
login_attempts INTEGER NOT NULL DEFAULT 0,
|
|
55
|
+
last_logon TIMESTAMP WITH TIME ZONE,
|
|
56
|
+
profile_picture_url TEXT,
|
|
57
|
+
profile_source hazo_enum_profile_source_enum,
|
|
58
|
+
mfa_secret TEXT,
|
|
59
|
+
url_on_logon TEXT,
|
|
60
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
61
|
+
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
-- Index for email lookups
|
|
65
|
+
CREATE INDEX idx_hazo_users_email ON hazo_users(email_address);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
#### 3. Create the Refresh Tokens Table
|
|
69
|
+
|
|
70
|
+
```sql
|
|
71
|
+
-- Refresh tokens table (used for password reset, email verification, etc.)
|
|
72
|
+
CREATE TABLE hazo_refresh_tokens (
|
|
73
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
74
|
+
user_id UUID NOT NULL REFERENCES hazo_users(id) ON DELETE CASCADE,
|
|
75
|
+
token_hash TEXT NOT NULL,
|
|
76
|
+
token_type TEXT NOT NULL,
|
|
77
|
+
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
78
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
-- Index for token lookups
|
|
82
|
+
CREATE INDEX idx_hazo_refresh_tokens_user_id ON hazo_refresh_tokens(user_id);
|
|
83
|
+
CREATE INDEX idx_hazo_refresh_tokens_token_type ON hazo_refresh_tokens(token_type);
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### 4. Create the Permissions Table
|
|
87
|
+
|
|
88
|
+
```sql
|
|
89
|
+
-- Permissions table for RBAC
|
|
90
|
+
CREATE TABLE hazo_permissions (
|
|
91
|
+
id SERIAL PRIMARY KEY,
|
|
92
|
+
permission_name TEXT NOT NULL UNIQUE,
|
|
93
|
+
description TEXT,
|
|
94
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
95
|
+
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
96
|
+
);
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
#### 5. Create the Roles Table
|
|
100
|
+
|
|
101
|
+
```sql
|
|
102
|
+
-- Roles table for RBAC
|
|
103
|
+
CREATE TABLE hazo_roles (
|
|
104
|
+
id SERIAL PRIMARY KEY,
|
|
105
|
+
role_name TEXT NOT NULL UNIQUE,
|
|
106
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
107
|
+
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
108
|
+
);
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### 6. Create the Role-Permissions Junction Table
|
|
112
|
+
|
|
113
|
+
```sql
|
|
114
|
+
-- Junction table linking roles to permissions
|
|
115
|
+
CREATE TABLE hazo_role_permissions (
|
|
116
|
+
role_id INTEGER NOT NULL REFERENCES hazo_roles(id) ON DELETE CASCADE,
|
|
117
|
+
permission_id INTEGER NOT NULL REFERENCES hazo_permissions(id) ON DELETE CASCADE,
|
|
118
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
119
|
+
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
120
|
+
PRIMARY KEY (role_id, permission_id)
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
-- Indexes for lookups
|
|
124
|
+
CREATE INDEX idx_hazo_role_permissions_role_id ON hazo_role_permissions(role_id);
|
|
125
|
+
CREATE INDEX idx_hazo_role_permissions_permission_id ON hazo_role_permissions(permission_id);
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
#### 7. Create the User-Roles Junction Table
|
|
129
|
+
|
|
130
|
+
```sql
|
|
131
|
+
-- Junction table linking users to roles
|
|
132
|
+
CREATE TABLE hazo_user_roles (
|
|
133
|
+
user_id UUID NOT NULL REFERENCES hazo_users(id) ON DELETE CASCADE,
|
|
134
|
+
role_id INTEGER NOT NULL REFERENCES hazo_roles(id) ON DELETE CASCADE,
|
|
135
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
136
|
+
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
137
|
+
PRIMARY KEY (user_id, role_id)
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
-- Indexes for lookups
|
|
141
|
+
CREATE INDEX idx_hazo_user_roles_user_id ON hazo_user_roles(user_id);
|
|
142
|
+
CREATE INDEX idx_hazo_user_roles_role_id ON hazo_user_roles(role_id);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
#### Complete Setup Script
|
|
146
|
+
|
|
147
|
+
For convenience, here's the complete SQL script to create all tables at once:
|
|
148
|
+
|
|
149
|
+
```sql
|
|
150
|
+
-- ============================================
|
|
151
|
+
-- hazo_auth Database Setup Script
|
|
152
|
+
-- ============================================
|
|
153
|
+
|
|
154
|
+
-- 1. Create enum type
|
|
155
|
+
CREATE TYPE hazo_enum_profile_source_enum AS ENUM ('gravatar', 'custom', 'predefined');
|
|
156
|
+
|
|
157
|
+
-- 2. Create users table
|
|
158
|
+
CREATE TABLE hazo_users (
|
|
159
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
160
|
+
email_address TEXT NOT NULL UNIQUE,
|
|
161
|
+
password_hash TEXT NOT NULL,
|
|
162
|
+
name TEXT,
|
|
163
|
+
email_verified BOOLEAN NOT NULL DEFAULT FALSE,
|
|
164
|
+
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
165
|
+
login_attempts INTEGER NOT NULL DEFAULT 0,
|
|
166
|
+
last_logon TIMESTAMP WITH TIME ZONE,
|
|
167
|
+
profile_picture_url TEXT,
|
|
168
|
+
profile_source hazo_enum_profile_source_enum,
|
|
169
|
+
mfa_secret TEXT,
|
|
170
|
+
url_on_logon TEXT,
|
|
171
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
172
|
+
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
173
|
+
);
|
|
174
|
+
CREATE INDEX idx_hazo_users_email ON hazo_users(email_address);
|
|
175
|
+
|
|
176
|
+
-- 3. Create refresh tokens table
|
|
177
|
+
CREATE TABLE hazo_refresh_tokens (
|
|
178
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
179
|
+
user_id UUID NOT NULL REFERENCES hazo_users(id) ON DELETE CASCADE,
|
|
180
|
+
token_hash TEXT NOT NULL,
|
|
181
|
+
token_type TEXT NOT NULL,
|
|
182
|
+
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
183
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
184
|
+
);
|
|
185
|
+
CREATE INDEX idx_hazo_refresh_tokens_user_id ON hazo_refresh_tokens(user_id);
|
|
186
|
+
CREATE INDEX idx_hazo_refresh_tokens_token_type ON hazo_refresh_tokens(token_type);
|
|
187
|
+
|
|
188
|
+
-- 4. Create permissions table
|
|
189
|
+
CREATE TABLE hazo_permissions (
|
|
190
|
+
id SERIAL PRIMARY KEY,
|
|
191
|
+
permission_name TEXT NOT NULL UNIQUE,
|
|
192
|
+
description TEXT,
|
|
193
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
194
|
+
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
195
|
+
);
|
|
196
|
+
|
|
197
|
+
-- 5. Create roles table
|
|
198
|
+
CREATE TABLE hazo_roles (
|
|
199
|
+
id SERIAL PRIMARY KEY,
|
|
200
|
+
role_name TEXT NOT NULL UNIQUE,
|
|
201
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
202
|
+
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
-- 6. Create role-permissions junction table
|
|
206
|
+
CREATE TABLE hazo_role_permissions (
|
|
207
|
+
role_id INTEGER NOT NULL REFERENCES hazo_roles(id) ON DELETE CASCADE,
|
|
208
|
+
permission_id INTEGER NOT NULL REFERENCES hazo_permissions(id) ON DELETE CASCADE,
|
|
209
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
210
|
+
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
211
|
+
PRIMARY KEY (role_id, permission_id)
|
|
212
|
+
);
|
|
213
|
+
CREATE INDEX idx_hazo_role_permissions_role_id ON hazo_role_permissions(role_id);
|
|
214
|
+
CREATE INDEX idx_hazo_role_permissions_permission_id ON hazo_role_permissions(permission_id);
|
|
215
|
+
|
|
216
|
+
-- 7. Create user-roles junction table
|
|
217
|
+
CREATE TABLE hazo_user_roles (
|
|
218
|
+
user_id UUID NOT NULL REFERENCES hazo_users(id) ON DELETE CASCADE,
|
|
219
|
+
role_id INTEGER NOT NULL REFERENCES hazo_roles(id) ON DELETE CASCADE,
|
|
220
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
221
|
+
changed_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
222
|
+
PRIMARY KEY (user_id, role_id)
|
|
223
|
+
);
|
|
224
|
+
CREATE INDEX idx_hazo_user_roles_user_id ON hazo_user_roles(user_id);
|
|
225
|
+
CREATE INDEX idx_hazo_user_roles_role_id ON hazo_user_roles(role_id);
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
#### Initialize Default Permissions and Super User
|
|
229
|
+
|
|
230
|
+
After creating the tables, you can use the `init-users` script to set up default permissions and a super user:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
npm run init-users
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
This script reads from `hazo_auth_config.ini` and:
|
|
237
|
+
1. Creates default permissions from `application_permission_list_defaults`
|
|
238
|
+
2. Creates a `default_super_user_role` role with all permissions
|
|
239
|
+
3. Assigns the role to the user specified in `default_super_user_email`
|
|
240
|
+
|
|
32
241
|
### Expose hazo_auth Routes in the Consumer App
|
|
33
242
|
|
|
34
243
|
Because `src/app/hazo_auth` (pages) and `src/app/api/hazo_auth` (API routes) need to be part of the consuming Next.js app’s routing tree, make sure they exist in your project’s `src/app` directory. Two recommended approaches:
|
|
@@ -50,6 +259,56 @@ Because `src/app/hazo_auth` (pages) and `src/app/api/hazo_auth` (API routes) nee
|
|
|
50
259
|
|
|
51
260
|
> The package expects these routes to live at `src/app/api/hazo_auth` and `src/app/hazo_auth` inside the consumer project. Without copying or linking them, Next.js won’t mount the auth pages or APIs.
|
|
52
261
|
|
|
262
|
+
### Choose the UI Shell (Test Sidebar vs Standalone)
|
|
263
|
+
|
|
264
|
+
By default, the pages render inside the “test workspace” sidebar so you can quickly preview every flow. When you reuse the routes inside another project you’ll usually want a clean, standalone wrapper instead. Set this in `hazo_auth_config.ini`:
|
|
265
|
+
|
|
266
|
+
```ini
|
|
267
|
+
[hazo_auth__ui_shell]
|
|
268
|
+
# Options: test_sidebar | standalone
|
|
269
|
+
layout_mode = standalone
|
|
270
|
+
# Optional tweaks for the standalone header wrapper/classes:
|
|
271
|
+
# standalone_heading = Welcome back
|
|
272
|
+
# standalone_description = Your description here
|
|
273
|
+
# standalone_wrapper_class = min-h-screen bg-background py-8
|
|
274
|
+
# standalone_content_class = mx-auto w-full max-w-4xl rounded-2xl border bg-card
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
- `test_sidebar`: keeps the developer sidebar (perfect for the demo workspace or Storybook screenshots).
|
|
278
|
+
- `standalone`: renders the page body directly so it inherits your own app shell, layout, and theme tokens.
|
|
279
|
+
- The wrapper and content class overrides let you align spacing/borders with your design system without editing package code.
|
|
280
|
+
|
|
281
|
+
Every route (`/hazo_auth/login`, `/hazo_auth/register`, etc.) automatically looks at this config, so switching modes is instant.
|
|
282
|
+
|
|
283
|
+
### Using Just the Layout Components
|
|
284
|
+
|
|
285
|
+
Prefer to drop the forms into your own routes without copying the provided pages? Import the layouts directly and feed them a `data_client` plus any label/button overrides:
|
|
286
|
+
|
|
287
|
+
```tsx
|
|
288
|
+
// app/(auth)/login/page.tsx in your project
|
|
289
|
+
import login_layout from "hazo_auth/components/layouts/login";
|
|
290
|
+
import { createLayoutDataClient } from "hazo_auth/components/layouts/shared/data/layout_data_client";
|
|
291
|
+
import { create_sqlite_hazo_connect } from "hazo_auth/lib/hazo_connect_setup";
|
|
292
|
+
|
|
293
|
+
export default async function LoginPage() {
|
|
294
|
+
const hazoConnect = create_sqlite_hazo_connect();
|
|
295
|
+
const dataClient = createLayoutDataClient(hazoConnect);
|
|
296
|
+
const LoginLayout = login_layout;
|
|
297
|
+
|
|
298
|
+
return (
|
|
299
|
+
<div className="my-app-shell">
|
|
300
|
+
<LoginLayout
|
|
301
|
+
image_src="/marketing/login-hero.svg"
|
|
302
|
+
data_client={dataClient}
|
|
303
|
+
redirectRoute="/dashboard"
|
|
304
|
+
/>
|
|
305
|
+
</div>
|
|
306
|
+
);
|
|
307
|
+
}
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
The same import pattern works for every layout under `components/layouts/*`, so you can mix-and-match pieces (profile picture dialog, password field, etc.) wherever you need them.
|
|
311
|
+
|
|
53
312
|
## Authentication Service
|
|
54
313
|
|
|
55
314
|
The `hazo_auth` package provides a comprehensive authentication and authorization system with role-based access control (RBAC). The main authentication utility is `hazo_get_auth`, which provides user details, permissions, and permission checking with built-in caching and rate limiting.
|
|
@@ -959,6 +1218,88 @@ Example custom styling:
|
|
|
959
1218
|
}
|
|
960
1219
|
```
|
|
961
1220
|
|
|
1221
|
+
## User Profile Service
|
|
1222
|
+
|
|
1223
|
+
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.
|
|
1224
|
+
|
|
1225
|
+
### `hazo_get_user_profiles`
|
|
1226
|
+
|
|
1227
|
+
Retrieves basic profile information for multiple users in a single batch call.
|
|
1228
|
+
|
|
1229
|
+
**Location:** `src/lib/services/user_profiles_service.ts`
|
|
1230
|
+
|
|
1231
|
+
**Function Signature:**
|
|
1232
|
+
```typescript
|
|
1233
|
+
import { hazo_get_user_profiles } from "hazo_auth/lib/services/user_profiles_service";
|
|
1234
|
+
import type { GetProfilesResult, UserProfileInfo } from "hazo_auth/lib/services/user_profiles_service";
|
|
1235
|
+
|
|
1236
|
+
async function hazo_get_user_profiles(
|
|
1237
|
+
adapter: HazoConnectAdapter,
|
|
1238
|
+
user_ids: string[],
|
|
1239
|
+
): Promise<GetProfilesResult>
|
|
1240
|
+
```
|
|
1241
|
+
|
|
1242
|
+
**Return Type:**
|
|
1243
|
+
```typescript
|
|
1244
|
+
type UserProfileInfo = {
|
|
1245
|
+
user_id: string;
|
|
1246
|
+
profile_picture_url: string | null;
|
|
1247
|
+
email: string;
|
|
1248
|
+
name: string | null;
|
|
1249
|
+
days_since_created: number;
|
|
1250
|
+
};
|
|
1251
|
+
|
|
1252
|
+
type GetProfilesResult = {
|
|
1253
|
+
success: boolean;
|
|
1254
|
+
profiles: UserProfileInfo[];
|
|
1255
|
+
not_found_ids: string[];
|
|
1256
|
+
error?: string;
|
|
1257
|
+
};
|
|
1258
|
+
```
|
|
1259
|
+
|
|
1260
|
+
**Features:**
|
|
1261
|
+
- **Batch Retrieval:** Fetches multiple user profiles in a single database query
|
|
1262
|
+
- **Deduplication:** Automatically removes duplicate user IDs from input
|
|
1263
|
+
- **Not Found Tracking:** Returns list of user IDs that were not found in the database
|
|
1264
|
+
- **Profile Picture:** Returns the resolved profile picture URL (Gravatar, library, or uploaded)
|
|
1265
|
+
- **Account Age:** Calculates days since account creation
|
|
1266
|
+
|
|
1267
|
+
**Example Usage:**
|
|
1268
|
+
|
|
1269
|
+
```typescript
|
|
1270
|
+
// In an API route or server component
|
|
1271
|
+
import { hazo_get_user_profiles } from "hazo_auth/lib/services/user_profiles_service";
|
|
1272
|
+
import { get_hazo_connect_instance } from "hazo_auth/lib/hazo_connect_instance.server";
|
|
1273
|
+
|
|
1274
|
+
export async function GET(request: NextRequest) {
|
|
1275
|
+
const adapter = get_hazo_connect_instance();
|
|
1276
|
+
|
|
1277
|
+
// Get profiles for multiple users (e.g., chat participants)
|
|
1278
|
+
const result = await hazo_get_user_profiles(adapter, [
|
|
1279
|
+
"user-id-1",
|
|
1280
|
+
"user-id-2",
|
|
1281
|
+
"user-id-3",
|
|
1282
|
+
]);
|
|
1283
|
+
|
|
1284
|
+
if (!result.success) {
|
|
1285
|
+
return NextResponse.json({ error: result.error }, { status: 500 });
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
// result.profiles contains found user profiles
|
|
1289
|
+
// result.not_found_ids contains IDs that weren't found
|
|
1290
|
+
return NextResponse.json({
|
|
1291
|
+
profiles: result.profiles,
|
|
1292
|
+
not_found: result.not_found_ids,
|
|
1293
|
+
});
|
|
1294
|
+
}
|
|
1295
|
+
```
|
|
1296
|
+
|
|
1297
|
+
**Use Cases:**
|
|
1298
|
+
- Chat applications displaying participant information
|
|
1299
|
+
- User lists with profile pictures and names
|
|
1300
|
+
- Activity feeds showing user details
|
|
1301
|
+
- Any feature requiring batch user profile lookups
|
|
1302
|
+
|
|
962
1303
|
### Local Development (for package contributors)
|
|
963
1304
|
|
|
964
1305
|
- `npm install` to install dependencies.
|
|
@@ -7,6 +7,31 @@
|
|
|
7
7
|
# Database type: sqlite, postgrest, supabase, or file
|
|
8
8
|
type = sqlite
|
|
9
9
|
|
|
10
|
+
# UI shell controls whether pages render inside the developer sidebar or a minimal wrapper.
|
|
11
|
+
[hazo_auth__ui_shell]
|
|
12
|
+
# layout_mode = test_sidebar
|
|
13
|
+
# Options:
|
|
14
|
+
# - test_sidebar: keeps the demo sidebar for quick testing in the package workspace.
|
|
15
|
+
# - standalone: renders pages in a minimal wrapper so consumers inherit their own shell/theme.
|
|
16
|
+
#
|
|
17
|
+
# Heading shown above standalone layouts
|
|
18
|
+
# standalone_heading = Welcome to hazo auth
|
|
19
|
+
#
|
|
20
|
+
# Description beneath the heading for standalone layouts
|
|
21
|
+
# standalone_description = Reuse the packaged authentication flows while inheriting your existing app shell styles.
|
|
22
|
+
#
|
|
23
|
+
# Tailwind utility classes applied to the standalone wrapper div
|
|
24
|
+
# standalone_wrapper_class = cls_standalone_shell flex min-h-screen w-full items-center justify-center bg-background px-4 py-10
|
|
25
|
+
#
|
|
26
|
+
# Tailwind utility classes applied to the standalone inner content div
|
|
27
|
+
# standalone_content_class = cls_standalone_shell_content w-full max-w-5xl shadow-xl rounded-2xl border bg-card
|
|
28
|
+
#
|
|
29
|
+
# Show/hide heading in standalone mode (true/false, default: true)
|
|
30
|
+
# standalone_show_heading = true
|
|
31
|
+
#
|
|
32
|
+
# Show/hide description in standalone mode (true/false, default: true)
|
|
33
|
+
# standalone_show_description = true
|
|
34
|
+
|
|
10
35
|
# SQLite database configuration
|
|
11
36
|
# Path to SQLite database file (relative to process.cwd() or absolute)
|
|
12
37
|
sqlite_path = ./data/hazo_auth.sqlite
|
|
@@ -57,6 +82,10 @@ enable_admin_ui = true
|
|
|
57
82
|
# Show name field (true/false)
|
|
58
83
|
# Note: This is now deprecated, use hazo_auth__user_fields section instead
|
|
59
84
|
# show_name_field = false
|
|
85
|
+
#
|
|
86
|
+
# Sign in link shown below register button
|
|
87
|
+
# sign_in_path = /hazo_auth/login
|
|
88
|
+
# sign_in_label = Sign in
|
|
60
89
|
|
|
61
90
|
[hazo_auth__user_fields]
|
|
62
91
|
# Shared user fields configuration used by register and my_settings layouts
|
|
@@ -104,6 +133,12 @@ enable_admin_ui = true
|
|
|
104
133
|
# Redirect on successful login (leave empty to show success message instead)
|
|
105
134
|
# redirect_route_on_successful_login = /
|
|
106
135
|
|
|
136
|
+
# Forgot password + sign up links shown under login button
|
|
137
|
+
# forgot_password_path = /hazo_auth/forgot_password
|
|
138
|
+
# forgot_password_label = Forgot password?
|
|
139
|
+
# create_account_path = /hazo_auth/register
|
|
140
|
+
# create_account_label = Create account
|
|
141
|
+
|
|
107
142
|
# Success message (shown when no redirect route is provided)
|
|
108
143
|
# success_message = Successfully logged in
|
|
109
144
|
|
|
@@ -263,6 +298,12 @@ enable_admin_ui = true
|
|
|
263
298
|
# Example: application_permission_list_defaults = PERM_ONE,PERM_TWO,PERM_THREE
|
|
264
299
|
# application_permission_list_defaults =
|
|
265
300
|
|
|
301
|
+
[hazo_auth__initial_setup]
|
|
302
|
+
# Initial setup configuration for initializing users, roles, and permissions
|
|
303
|
+
# Email address of the super user to assign the default_super_user_role
|
|
304
|
+
# This user will receive all permissions from application_permission_list_defaults
|
|
305
|
+
# default_super_user_email = admin@example.com
|
|
306
|
+
|
|
266
307
|
[hazo_auth__auth_utility]
|
|
267
308
|
# Authentication utility configuration
|
|
268
309
|
|
package/instrumentation.ts
CHANGED
|
@@ -9,13 +9,13 @@ export async function register() {
|
|
|
9
9
|
const hazo_notify_module = await import("hazo_notify");
|
|
10
10
|
|
|
11
11
|
// Step 2: Load hazo_notify emailer configuration
|
|
12
|
-
// This reads from hazo_notify_config.ini in the
|
|
12
|
+
// This reads from hazo_notify_config.ini in the ui_component directory (same location as hazo_auth_config.ini)
|
|
13
13
|
const { load_emailer_config } = hazo_notify_module;
|
|
14
14
|
const notify_config = load_emailer_config();
|
|
15
15
|
|
|
16
16
|
// Step 3: Pass the initialized configuration to hazo_auth email service
|
|
17
17
|
// This allows the email service to reuse the same configuration instance
|
|
18
|
-
const { set_hazo_notify_instance } = await import("
|
|
18
|
+
const { set_hazo_notify_instance } = await import("./src/lib/services/email_service");
|
|
19
19
|
set_hazo_notify_instance(notify_config);
|
|
20
20
|
|
|
21
21
|
// Log successful initialization
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hazo_auth",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"files": [
|
|
5
5
|
"src/**/*",
|
|
6
6
|
"public/file.svg",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"build-storybook": "storybook build",
|
|
32
32
|
"dev:server": "tsx src/server/index.ts",
|
|
33
33
|
"migrate": "tsx scripts/apply_migration.ts",
|
|
34
|
+
"init-users": "tsx scripts/init_users.ts init_users",
|
|
34
35
|
"test": "cross-env NODE_ENV=test POSTGREST_URL=http://209.38.26.241:4402 POSTGREST_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYXBpX3VzZXIifQ.zBoUGymrxTUk1DNYIGUCtQU4HFaWEHlbE9_8Y3hUaTw jest --runInBand",
|
|
35
36
|
"test:watch": "cross-env NODE_ENV=test POSTGREST_URL=http://209.38.26.241:4402 POSTGREST_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYXBpX3VzZXIifQ.zBoUGymrxTUk1DNYIGUCtQU4HFaWEHlbE9_8Y3hUaTw jest --watch"
|
|
36
37
|
},
|