Skip to content

Commit 7266f66

Browse files
Merge pull request #22 from StreetSupport/feature/3011-build-user-management-interface
Feature/3011 build user management interface
2 parents cf8685d + 7f45030 commit 7266f66

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+8382
-624
lines changed

AUTH0_SETUP.md

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
# Auth0 User Creation Setup
2+
3+
## Overview
4+
The API now integrates with Auth0 Management API to create users programmatically when admins add new users through the admin panel.
5+
6+
## Required Environment Variables
7+
8+
Add the following environment variables to your `.env` file:
9+
10+
```env
11+
# Existing Auth0 Configuration (for JWT verification)
12+
AUTH0_DOMAIN=your-tenant.auth0.com
13+
AUTH0_AUDIENCE=https://your-api-identifier
14+
15+
# Auth0 Management API Configuration (for user creation)
16+
AUTH0_MANAGEMENT_CLIENT_ID=your_management_api_client_id
17+
AUTH0_MANAGEMENT_CLIENT_SECRET=your_management_api_client_secret
18+
AUTH0_MANAGEMENT_AUDIENCE=https://your-tenant.auth0.com/api/v2/
19+
AUTH0_USER_DB_CONNECTION=Username-Password-Authentication
20+
```
21+
22+
## Setting Up Auth0 Management API
23+
24+
### 1. Create a Machine-to-Machine Application
25+
26+
1. Go to your Auth0 Dashboard
27+
2. Navigate to **Applications****Applications**
28+
3. Click **Create Application**
29+
4. Name it "Street Support Management API" (or similar)
30+
5. Select **Machine to Machine Applications**
31+
6. Click **Create**
32+
33+
### 2. Authorize the Application
34+
35+
1. Select **Auth0 Management API** as the API
36+
2. Grant the following permissions (scopes):
37+
- `create:users` - Create users
38+
- `update:users` - Update user metadata
39+
- `delete:users` - Delete users (for cleanup on errors)
40+
- `read:users` - Read user information
41+
3. Click **Authorize**
42+
43+
### 3. Get Credentials
44+
45+
1. Go to the **Settings** tab of your Machine-to-Machine application
46+
2. Copy the **Client ID** → Use as `AUTH0_MANAGEMENT_CLIENT_ID`
47+
3. Copy the **Client Secret** → Use as `AUTH0_MANAGEMENT_CLIENT_SECRET`
48+
49+
### 4. Configure Database Connection
50+
51+
1. Go to **Authentication****Database**
52+
2. Note the name of your database connection (usually "Username-Password-Authentication")
53+
3. Use this as `AUTH0_USER_DB_CONNECTION`
54+
55+
### 5. Set Management API Audience
56+
57+
The audience is typically: `https://YOUR_DOMAIN/api/v2/`
58+
59+
For example: `https://your-tenant.auth0.com/api/v2/`
60+
61+
## How It Works
62+
63+
### User Creation Flow
64+
65+
1. **Admin creates user** in the admin panel
66+
2. **API validates** user data with Zod schema
67+
3. **Auth0 user created** first via Management API with:
68+
- `email`: User's email
69+
- `name`: User's email (used as display name)
70+
- `password`: Auto-generated secure password
71+
- `app_metadata.authorization.roles`: User's AuthClaims array
72+
- `email_verified`: false (requires email verification)
73+
- `verify_email`: true (sends verification email)
74+
- Auth0 auto-generates unique `user_id` (e.g., `auth0|507f1f77bcf86cd799439011`)
75+
4. **MongoDB user created** with Auth0's generated `user_id` stored in `Auth0Id` field
76+
77+
### Error Handling
78+
79+
- If **Auth0 creation fails**: Error returned immediately, no MongoDB user created
80+
- If **MongoDB creation fails**: Auth0 user is deleted (rollback for consistency)
81+
- Detailed error messages returned to admin panel
82+
83+
### Password Management
84+
85+
- **Auto-generated** secure 30-character password
86+
- Contains uppercase, lowercase, numbers, and special characters
87+
- Meets Auth0 password policy requirements
88+
- Users will use **password reset** flow for first login
89+
90+
## API Functions
91+
92+
### `createAuth0User(email, authClaims)`
93+
Creates a new user in Auth0 with auto-generated user ID
94+
95+
**Parameters:**
96+
- `email`: User's email address
97+
- `authClaims`: Array of role strings (e.g., `['SuperAdmin']`, `['CityAdmin', 'CityAdminFor:manchester']`)
98+
99+
**Returns:** Auth0 user object with auto-generated `user_id` (e.g., `auth0|507f1f77bcf86cd799439011`)
100+
101+
### `deleteAuth0User(auth0UserId)`
102+
Deletes a user from Auth0
103+
104+
**Parameters:**
105+
- `auth0UserId`: Auth0 user ID (e.g., `"auth0|123456"`)
106+
107+
### `updateAuth0UserRoles(auth0UserId, authClaims)`
108+
Updates user roles in Auth0 app_metadata
109+
110+
**Parameters:**
111+
- `auth0UserId`: Auth0 user ID
112+
- `authClaims`: Updated array of role strings
113+
114+
## Testing
115+
116+
### Test User Creation
117+
118+
```bash
119+
curl -X POST http://localhost:5000/api/users \
120+
-H "Content-Type: application/json" \
121+
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
122+
-d '{
123+
"Email": "[email protected]",
124+
"UserName": "testuser",
125+
"AuthClaims": ["CityAdmin", "CityAdminFor:manchester"]
126+
}'
127+
```
128+
129+
### Verify in Auth0 Dashboard
130+
131+
1. Go to **User Management****Users**
132+
2. Find the newly created user
133+
3. Check **app_metadata** contains authorization roles
134+
4. Copy the **user_id** and verify it matches the `Auth0Id` field in MongoDB
135+
136+
## Troubleshooting
137+
138+
### "Failed to get Auth0 management token"
139+
- Verify `AUTH0_MANAGEMENT_CLIENT_ID` and `AUTH0_MANAGEMENT_CLIENT_SECRET` are correct
140+
- Check that Machine-to-Machine application is authorized for Management API
141+
142+
### "Failed to create Auth0 user"
143+
- Verify `AUTH0_DOMAIN` is correct (without `https://`)
144+
- Check `AUTH0_USER_DB_CONNECTION` matches your database connection name
145+
- Ensure Management API has `create:users` permission
146+
- Check Auth0 Dashboard → Logs for detailed error messages
147+
148+
### "User created in Auth0 but not in MongoDB"
149+
- Check server logs for MongoDB error details
150+
- Auth0 user should be automatically deleted on MongoDB failure
151+
- If Auth0 user remains without MongoDB record, it will be cleaned up on retry
152+
153+
## Security Considerations
154+
155+
- **Management API credentials** are highly sensitive - store securely
156+
- **Never expose** `AUTH0_MANAGEMENT_CLIENT_SECRET` in client-side code
157+
- **Auto-generated passwords** are not accessible after creation
158+
- Users must use **password reset flow** for first login
159+
- **Role-based access control** enforced via RBAC middleware
160+
161+
## Next Steps
162+
163+
1. Set up password reset email templates in Auth0
164+
2. Configure Auth0 Actions/Rules if needed
165+
3. Set up user invitation email flow (optional)
166+
4. Configure multi-factor authentication (recommended)

CONTROLLER_REFACTORING_PLAN.md

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# Controller Response Refactoring Plan
2+
3+
## Summary
4+
Unify all controller responses to use standardized response utilities from `apiResponses.ts`.
5+
6+
## Response Utilities Available
7+
8+
### Success Responses
9+
- `sendSuccess<T>(res, data, message?)` - 200 OK with data
10+
- `sendCreated<T>(res, data, message?)` - 201 Created with data
11+
12+
### Error Responses
13+
- `sendUnauthorized(res, error?)` - 401 Unauthorized
14+
- `sendForbidden(res, error?)` - 403 Forbidden
15+
- `sendNotFound(res, error?)` - 404 Not Found
16+
- `sendBadRequest(res, error?)` - 400 Bad Request
17+
- `sendInternalError(res, error?)` - 500 Internal Server Error
18+
- `sendError(res, statusCode, error)` - Custom status code
19+
20+
## Current State Analysis
21+
22+
### 1. **cityController.ts** (90 lines)
23+
**Current Patterns:**
24+
-`res.status(200).json({ success: true, data: cities })`
25+
-`res.status(404).json({ success: false, message: 'City not found' })`
26+
-`res.status(201).json({ success: true, data: created })`
27+
28+
**Changes Needed:** 5 success responses, 3 error responses
29+
30+
---
31+
32+
### 2. **serviceController.ts** (71 lines)
33+
**Current Patterns:**
34+
-`res.status(200).json({ success: true, data: services })`
35+
-`res.status(404); throw new Error('Service not found');`
36+
-`res.status(201).json({ success: true, data: service })`
37+
38+
**Changes Needed:** 6 success responses, 3 error responses (throw pattern)
39+
40+
---
41+
42+
### 3. **faqController.ts** (68 lines)
43+
**Current Patterns:**
44+
-`res.status(200).json({ success: true, data: faqs })`
45+
-`res.status(404); throw new Error('FAQ not found');`
46+
-`res.status(201).json({ success: true, data: faq })`
47+
48+
**Changes Needed:** 6 success responses, 3 error responses (throw pattern)
49+
50+
---
51+
52+
### 4. **serviceProviderController.ts** (estimated ~70 lines)
53+
**Status:** Needs analysis
54+
**Expected Changes:** Similar to serviceController
55+
56+
---
57+
58+
### 5. **resourceController.ts** (1137 bytes)
59+
**Status:** Needs analysis
60+
**Expected Changes:** Minimal updates
61+
62+
---
63+
64+
### 6. **swepBannerController.ts** (1152 bytes)
65+
**Status:** Needs analysis
66+
**Expected Changes:** Minimal updates
67+
68+
---
69+
70+
### 7. **userController.ts** (8911 bytes)
71+
**Current Status:****Partially Updated**
72+
- Already uses `sendNotFound()` in some places
73+
- Mix of old and new patterns
74+
75+
**Remaining Changes:**
76+
- Replace remaining manual `res.status().json()` calls
77+
- Replace `throw new Error()` patterns with response utilities
78+
79+
---
80+
81+
### 8. **bannerController.ts** (16949 bytes)
82+
**Current Status:****Partially Updated**
83+
- Already uses `sendNotFound()` and `sendBadRequest()` in some places
84+
- Mix of old and new patterns
85+
86+
**Remaining Changes:**
87+
- Replace remaining manual `res.status().json()` calls
88+
- Standardize success responses with `sendSuccess()` and `sendCreated()`
89+
90+
---
91+
92+
## Refactoring Strategy
93+
94+
### Phase 1: Update Smaller Controllers (Fastest wins)
95+
1.**cityController.ts** - Simple CRUD, no complex logic
96+
2.**faqController.ts** - Simple CRUD
97+
3.**serviceController.ts** - Simple CRUD
98+
4.**serviceProviderController.ts** - Simple CRUD
99+
5.**resourceController.ts** - Minimal code
100+
6.**swepBannerController.ts** - Minimal code
101+
102+
### Phase 2: Complete Partially Updated Controllers
103+
7.**userController.ts** - Finish standardization
104+
8.**bannerController.ts** - Finish standardization
105+
106+
---
107+
108+
## Example Transformations
109+
110+
### Before (Multiple Inconsistent Patterns)
111+
```typescript
112+
// Pattern 1: Direct response
113+
res.status(200).json({ success: true, data: cities });
114+
115+
// Pattern 2: Throw error
116+
res.status(404);
117+
throw new Error('City not found');
118+
119+
// Pattern 3: Inline error
120+
return res.status(404).json({ success: false, message: 'City not found' });
121+
122+
// Pattern 4: Created
123+
res.status(201).json({ success: true, data: created });
124+
```
125+
126+
### After (Unified Pattern)
127+
```typescript
128+
// Success responses
129+
return sendSuccess(res, cities);
130+
return sendCreated(res, created);
131+
132+
// Error responses
133+
return sendNotFound(res, 'City not found');
134+
return sendBadRequest(res, 'Invalid data');
135+
return sendInternalError(res, 'Database error');
136+
```
137+
138+
---
139+
140+
## Benefits
141+
142+
1. **Consistency**: All controllers use the same response pattern
143+
2. **Type Safety**: Generic types ensure proper data typing
144+
3. **Maintainability**: Centralized response logic
145+
4. **Testability**: Easier to mock and test responses
146+
5. **Documentation**: Clear response structure
147+
6. **Error Handling**: Standardized error format across all endpoints
148+
149+
---
150+
151+
## Next Steps (Awaiting Approval)
152+
153+
1. ✅ Review this plan
154+
2. ⏳ Approve refactoring approach
155+
3. ⏳ Update controllers one by one
156+
4. ⏳ Test each controller after updates
157+
5. ⏳ Apply same pattern to Admin project
158+
159+
---
160+
161+
## Estimated Impact
162+
163+
- **Files to Update**: 8 controller files
164+
- **Approximate Changes**: ~80-100 response statements
165+
- **Risk Level**: Low (response format remains compatible)
166+
- **Breaking Changes**: None (JSON structure unchanged)
167+
- **Testing Required**: Verify all endpoints return expected structure

0 commit comments

Comments
 (0)