File size: 9,416 Bytes
46d04ec
 
 
 
 
 
 
 
 
 
 
 
 
79ef7e1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46d04ec
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
---
title: AIDA
emoji: πŸ“š
colorFrom: purple
colorTo: red
sdk: gradio
sdk_version: 6.0.0
app_file: app.py
pinned: false
license: mit
short_description: The ai model for Lojiz
---


"""
# Lojiz Authentication API - Python FastAPI Edition

Modern, secure, and production-ready authentication backend built with FastAPI, MongoDB, and Resend.

## Features

βœ… **Dual Authentication** - Email or phone-based signup & login
βœ… **OTP Verification** - 4-digit OTP with configurable expiry (15 min default)
βœ… **Password Reset** - Secure password reset flow with temporary tokens
βœ… **JWT Tokens** - 60-day login tokens + 10-minute reset tokens
βœ… **Bcrypt Hashing** - Industry-standard password hashing
βœ… **Email Templates** - Beautiful, responsive HTML email templates via Resend
βœ… **Rate Limiting** - OTP attempt limits (5 max attempts)
βœ… **MongoDB** - Async MongoDB with Motor driver
βœ… **API Documentation** - Auto-generated Swagger docs
βœ… **Production Ready** - Error handling, logging, security best practices

## Prerequisites

- Python 3.11+
- MongoDB Atlas account (free tier available)
- Resend account (for email sending)
- Git & GitHub account
- Render.com account (for deployment)

## Local Development Setup

### 1. Clone Repository
```bash
git clone https://github.com/yourusername/lojiz-auth-api.git
cd lojiz-auth-api
```

### 2. Create Virtual Environment
```bash
python3 -m venv venv
source venv/bin/activate  # On Windows: venv\\Scripts\\activate
```

### 3. Install Dependencies
```bash
pip install -r requirements.txt
```

### 4. Setup Environment Variables
```bash
cp .env.example .env
```

Edit `.env` with:
```
DEBUG=True
ENVIRONMENT=development
MONGODB_URL=mongodb://localhost:27017
MONGODB_DATABASE=lojiz
JWT_SECRET=your-secret-key-here
RESEND_API_KEY=your-resend-api-key
RESEND_FROM_EMAIL=noreply@yourdomain.com
```

### 5. Run Application
```bash
uvicorn app.main:app --reload
```

Visit: http://localhost:8000/docs (Swagger UI)

## Project Structure

```
lojiz-auth-api/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ core/
β”‚   β”‚   β”œβ”€β”€ security.py        # JWT & password hashing
β”‚   β”‚   └── schemas.py         # Pydantic models
β”‚   β”œβ”€β”€ database.py            # MongoDB connection
β”‚   β”œβ”€β”€ config.py              # Configuration
β”‚   β”œβ”€β”€ models/
β”‚   β”‚   β”œβ”€β”€ user.py            # User model
β”‚   β”‚   └── otp.py             # OTP model
β”‚   β”œβ”€β”€ routes/
β”‚   β”‚   └── auth.py            # Auth endpoints
β”‚   β”œβ”€β”€ services/
β”‚   β”‚   β”œβ”€β”€ auth_service.py    # Auth logic
β”‚   β”‚   β”œβ”€β”€ otp_service.py     # OTP logic
β”‚   β”‚   └── user_service.py    # User logic
β”‚   β”œβ”€β”€ schemas/
β”‚   β”‚   β”œβ”€β”€ auth.py            # Auth DTOs
β”‚   β”‚   └── user.py            # User DTOs
β”‚   β”œβ”€β”€ guards/
β”‚   β”‚   └── jwt_guard.py       # JWT auth
β”‚   β”œβ”€β”€ utils/
β”‚   β”‚   └── logger.py          # Logging
β”‚   └── main.py                # App entry point
β”œβ”€β”€ requirements.txt
β”œβ”€β”€ .env.example
β”œβ”€β”€ .gitignore
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ render.yaml
└── README.md
```

## API Endpoints

### Authentication

**POST** `/api/auth/signup`
- Create new account
- Returns: Confirmation to check email/phone for OTP

**POST** `/api/auth/verify-signup-otp`
- Verify signup OTP
- Returns: User data + JWT token

**POST** `/api/auth/login`
- Authenticate with email/phone + password
- Returns: User data + JWT token

**POST** `/api/auth/send-password-reset-otp`
- Request password reset
- Returns: Generic success (doesn't reveal if email exists)

**POST** `/api/auth/verify-password-reset-otp`
- Verify password reset OTP
- Returns: Temporary reset token

**POST** `/api/auth/reset-password`
- Reset password with token
- Header: `x-reset-token`

**POST** `/api/auth/resend-otp`
- Resend OTP for signup or password reset

### User Profile

**GET** `/api/auth/profile`
- Get current user profile
- Requires: Bearer token

**POST** `/api/auth/logout`
- Logout (client removes token)
- Requires: Bearer token

## MongoDB Setup

### 1. Create MongoDB Atlas Account
- Go to https://www.mongodb.com/cloud/atlas
- Sign up for free
- Create a project

### 2. Create Cluster
- Choose shared cluster (free)
- Select region closest to your users
- Create cluster

### 3. Get Connection String
- Click "Connect"
- Choose "Drivers"
- Copy connection string
- Replace `<password>` and `myFirstDatabase` with actual values

### 4. Update .env
```
MONGODB_URL=mongodb+srv://username:password@cluster.mongodb.net/lojiz?retryWrites=true&w=majority
```

### 5. Create Database Indexes (Auto-created on startup)
- Email (unique, sparse)
- Phone (unique, sparse)
- Role
- OTP TTL (15 minutes)

## Resend Email Setup

### 1. Create Resend Account
- Go to https://resend.com
- Sign up
- Get API key from dashboard

### 2. Verify Domain (Optional for Production)
- Add domain to Resend
- Update DNS records
- Verify domain

### 3. Update .env
```
RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxxxx
RESEND_FROM_EMAIL=noreply@yourdomain.com
```

## Password Requirements

Passwords must contain:
- Minimum 8 characters
- At least one uppercase letter (A-Z)
- At least one lowercase letter (a-z)
- At least one digit (0-9)
- At least one special character (!@#$%^&*(),.?\":{}|<>)

Example: `SecurePass123!@`

## Token Details

### Login Token (JWT)
- **Expiry**: 60 days
- **Use Case**: Long-lived access token for normal users
- **Payload**: user_id, email, phone, role

### Reset Token (JWT)
- **Expiry**: 10 minutes
- **Use Case**: Short-lived token for password reset
- **Payload**: identifier, purpose

## Error Handling

All endpoints return structured error responses:

```json
{
  "success": false,
  "message": "Error description",
  "errors": {}
}
```

Common HTTP Status Codes:
- `200 OK` - Success
- `400 Bad Request` - Validation/business logic error
- `401 Unauthorized` - Invalid/missing token
- `404 Not Found` - Resource not found
- `409 Conflict` - Resource already exists
- `500 Internal Server Error` - Server error

## Deployment to Render.com

### 1. Push to GitHub
```bash
git add .
git commit -m "Initial commit"
git push origin main
```

### 2. Deploy on Render
- Go to https://render.com
- Click "New +"
- Select "Web Service"
- Connect GitHub repository
- Choose Python runtime
- Set build command: `pip install -r requirements.txt`
- Set start command: `uvicorn app.main:app --host 0.0.0.0 --port $PORT`

### 3. Add Environment Variables
Set in Render dashboard:
```
ENVIRONMENT=production
DEBUG=False
JWT_SECRET=(generate: python -c "import secrets; print(secrets.token_urlsafe(32))")
MONGODB_URL=<your-mongodb-url>
RESEND_API_KEY=<your-resend-key>
RESEND_FROM_EMAIL=noreply@yourdomain.com
```

### 4. Monitor
- Check deployment logs
- Test health endpoint: https://your-app.render.com/health
- View real-time logs in Render dashboard

## Testing Endpoints

### Using cURL

**Signup:**
```bash
curl -X POST http://localhost:8000/api/auth/signup \\
  -H "Content-Type: application/json" \\
  -d '{
    "first_name": "John",
    "last_name": "Doe",
    "email": "john@example.com",
    "password": "SecurePass123!@",
    "role": "renter"
  }'
```

**Login:**
```bash
curl -X POST http://localhost:8000/api/auth/login \\
  -H "Content-Type: application/json" \\
  -d '{
    "identifier": "john@example.com",
    "password": "SecurePass123!@"
  }'
```

**Get Profile:**
```bash
curl -X GET http://localhost:8000/api/auth/profile \\
  -H "Authorization: Bearer <your-jwt-token>"
```

## Security Best Practices

βœ… Passwords hashed with bcrypt (10 rounds)
βœ… JWT tokens signed with HS256
βœ… Password reset tokens expire in 10 minutes
βœ… OTP expires in 15 minutes
βœ… Max 5 OTP attempts before deletion
βœ… CORS configured for specific origins
βœ… Sensitive data excluded from responses
βœ… Non-root user in Docker
βœ… HTTPS enforced in production
βœ… Environment variables for secrets

## Troubleshooting

### MongoDB Connection Error
```
Error: connect ECONNREFUSED
```
- Ensure MONGODB_URL is correct
- Check MongoDB Atlas network access
- Verify IP whitelist includes your server

### Resend Email Not Sending
```
Failed to send email
```
- Check RESEND_API_KEY is valid
- Verify RESEND_FROM_EMAIL is correct
- Check Resend dashboard for quota limits

### Token Validation Error
```
Invalid or expired token
```
- Ensure Bearer token format: `Authorization: Bearer <token>`
- Check token hasn't expired (60 days for login)
- Regenerate token if needed

## Performance Tips

1. **MongoDB Indexes**: Already created on startup
2. **Async/Await**: All I/O operations are async
3. **Connection Pooling**: Motor manages connection pool
4. **Caching**: Implement Redis for OTP caching (future)
5. **Rate Limiting**: Add rate limiter middleware (future)

## Future Enhancements

- [ ] Refresh token rotation
- [ ] Social login (Google, GitHub)
- [ ] 2FA support
- [ ] Account recovery questions
- [ ] Redis caching layer
- [ ] Rate limiting middleware
- [ ] API key authentication
- [ ] Admin dashboard

## License

MIT License - see LICENSE file

## Support

For issues or questions:
- GitHub Issues: https://github.com/yourusername/lojiz-auth-api/issues
- Email: support@lojiz.com

---

**Built with ❀️ using FastAPI, MongoDB, and Resend**
"""

Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference