701 lines
15 KiB
Markdown
701 lines
15 KiB
Markdown
# USER API & Password Reset Documentation
|
|
|
|
## Overview
|
|
|
|
This document provides comprehensive documentation for the USER API endpoints and password reset functionality of the Veranstaltungen APP. The USER API allows authenticated users to manage their profiles, events, and favorites.
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
|
|
1. [Authentication](#authentication)
|
|
2. [Password Reset System](#password-reset-system)
|
|
3. [USER API Endpoints](#user-api-endpoints)
|
|
4. [Web UI Pages](#web-ui-pages)
|
|
5. [Integration Examples](#integration-examples)
|
|
6. [Error Handling](#error-handling)
|
|
|
|
---
|
|
|
|
## Authentication
|
|
|
|
### Token-Based Authentication (Sanctum)
|
|
|
|
All protected endpoints require a valid authentication token sent via the `Authorization` header:
|
|
|
|
```
|
|
Authorization: Bearer YOUR_TOKEN_HERE
|
|
```
|
|
|
|
### Obtaining a Token
|
|
|
|
#### Login Endpoint
|
|
```
|
|
POST /api/auth/login
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"email": "user@example.com",
|
|
"password": "password123"
|
|
}
|
|
```
|
|
|
|
**Response (201 - Success):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Login erfolgreich",
|
|
"user": {
|
|
"id": 1,
|
|
"name": "Test User",
|
|
"email": "user@example.com",
|
|
"role": "user"
|
|
},
|
|
"token": "1|PZHueLvJEr6d9mU1d4J7FUVJiPh0LD1Uy6S2Qc"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Password Reset System
|
|
|
|
### 1. Request Password Reset
|
|
|
|
**Endpoint:** `POST /api/auth/forgot-password`
|
|
|
|
Request a password reset link to be sent to your email.
|
|
|
|
```
|
|
POST /api/auth/forgot-password
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"email": "user@example.com"
|
|
}
|
|
```
|
|
|
|
**Response (200 - Success):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Passwort-Zurücksetzen-Link wurde gesendet",
|
|
"token": "your_reset_token_here"
|
|
}
|
|
```
|
|
|
|
**Response (422 - Validation Error):**
|
|
```json
|
|
{
|
|
"success": false,
|
|
"message": "Validierungsfehler",
|
|
"errors": {
|
|
"email": ["Diese E-Mail Adresse existiert nicht"]
|
|
}
|
|
}
|
|
```
|
|
|
|
### 2. Verify Reset Token
|
|
|
|
**Endpoint:** `POST /api/auth/verify-reset-token`
|
|
|
|
Verify if a reset token is still valid before allowing password reset.
|
|
|
|
```
|
|
POST /api/auth/verify-reset-token
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"email": "user@example.com",
|
|
"token": "your_reset_token_here"
|
|
}
|
|
```
|
|
|
|
**Response (200 - Valid Token):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"valid": true,
|
|
"message": "Token ist gültig"
|
|
}
|
|
```
|
|
|
|
**Response (422 - Invalid/Expired Token):**
|
|
```json
|
|
{
|
|
"success": false,
|
|
"valid": false,
|
|
"message": "Token ist abgelaufen"
|
|
}
|
|
```
|
|
|
|
### 3. Reset Password
|
|
|
|
**Endpoint:** `POST /api/auth/reset-password`
|
|
|
|
Complete the password reset process.
|
|
|
|
```
|
|
POST /api/auth/reset-password
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"email": "user@example.com",
|
|
"token": "your_reset_token_here",
|
|
"password": "newpassword123",
|
|
"password_confirmation": "newpassword123"
|
|
}
|
|
```
|
|
|
|
**Response (200 - Success):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Passwort erfolgreich zurückgesetzt. Bitte melden Sie sich erneut an"
|
|
}
|
|
```
|
|
|
|
**Response (422 - Validation Error):**
|
|
```json
|
|
{
|
|
"success": false,
|
|
"message": "Validierungsfehler",
|
|
"errors": {
|
|
"password": ["Passwort muss mindestens 8 Zeichen lang sein"]
|
|
}
|
|
}
|
|
```
|
|
|
|
### Token Validity
|
|
|
|
- Tokens are valid for **1 hour** after generation
|
|
- Tokens are automatically invalidated after first use
|
|
- After password reset, all existing auth tokens are revoked
|
|
|
|
---
|
|
|
|
## USER API Endpoints
|
|
|
|
### 1. Get User Profile
|
|
|
|
**Endpoint:** `GET /api/user/profile`
|
|
**Authentication:** Required (Bearer Token)
|
|
**Method:** GET
|
|
|
|
Get the current authenticated user's profile information.
|
|
|
|
```
|
|
GET /api/user/profile
|
|
Authorization: Bearer YOUR_TOKEN_HERE
|
|
```
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"id": 1,
|
|
"name": "Test User",
|
|
"email": "user@example.com",
|
|
"role": "user",
|
|
"created_at": "2024-04-14T10:00:00Z",
|
|
"updated_at": "2024-04-14T10:00:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
### 2. Get User's Events
|
|
|
|
**Endpoint:** `GET /api/user/events`
|
|
**Authentication:** Required
|
|
**Pagination:** Yes (default: 15 per page)
|
|
|
|
Get all events created by the current user.
|
|
|
|
```
|
|
GET /api/user/events?page=1
|
|
Authorization: Bearer YOUR_TOKEN_HERE
|
|
```
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": [
|
|
{
|
|
"id": 1,
|
|
"title": "Großes Musikfestival",
|
|
"description": "Ein großes Musikfestival...",
|
|
"location": {
|
|
"id": 1,
|
|
"name": "Berlin",
|
|
"slug": "berlin"
|
|
},
|
|
"category": {
|
|
"id": 1,
|
|
"name": "Musik"
|
|
},
|
|
"occurrences": [
|
|
{
|
|
"id": 1,
|
|
"date": "2024-06-15",
|
|
"time": "19:00:00",
|
|
"status": "scheduled"
|
|
}
|
|
],
|
|
"created_at": "2024-04-14T10:00:00Z"
|
|
}
|
|
],
|
|
"pagination": {
|
|
"total": 5,
|
|
"per_page": 15,
|
|
"current_page": 1,
|
|
"last_page": 1
|
|
}
|
|
}
|
|
```
|
|
|
|
### 3. Get User's Favorite Events
|
|
|
|
**Endpoint:** `GET /api/user/favorites`
|
|
**Authentication:** Required
|
|
**Pagination:** Yes (default: 15 per page)
|
|
|
|
Get all events the user has marked as favorites.
|
|
|
|
```
|
|
GET /api/user/favorites?page=1
|
|
Authorization: Bearer YOUR_TOKEN_HERE
|
|
```
|
|
|
|
**Response (200):** Same structure as "Get User's Events"
|
|
|
|
### 4. Toggle Event Favorite Status
|
|
|
|
**Endpoint:** `POST /api/user/favorites/{event}/toggle`
|
|
**Authentication:** Required
|
|
**Method:** POST
|
|
|
|
Add or remove an event from the user's favorites.
|
|
|
|
```
|
|
POST /api/user/favorites/1/toggle
|
|
Authorization: Bearer YOUR_TOKEN_HERE
|
|
```
|
|
|
|
**Response (200 - Added to Favorites):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Event zu Favoriten hinzugefügt",
|
|
"is_favorite": true
|
|
}
|
|
```
|
|
|
|
**Response (200 - Removed from Favorites):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Event aus Favoriten entfernt",
|
|
"is_favorite": false
|
|
}
|
|
```
|
|
|
|
### 5. Get User Statistics
|
|
|
|
**Endpoint:** `GET /api/user/stats`
|
|
**Authentication:** Required
|
|
|
|
Get user account statistics.
|
|
|
|
```
|
|
GET /api/user/stats
|
|
Authorization: Bearer YOUR_TOKEN_HERE
|
|
```
|
|
|
|
**Response (200):**
|
|
```json
|
|
{
|
|
"success": true,
|
|
"data": {
|
|
"total_events_created": 3,
|
|
"total_favorites": 12,
|
|
"is_organizer": false,
|
|
"is_admin": false,
|
|
"user_role": "user"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Web UI Pages
|
|
|
|
### Login Page
|
|
- **URL:** `http://localhost:8000/login`
|
|
- **Template:** `resources/views/auth/login.blade.php`
|
|
- **Features:**
|
|
- Email/password form
|
|
- "Remember me" checkbox
|
|
- "Forgot password?" link
|
|
- Register link
|
|
- Demo credentials display
|
|
- Real-time validation
|
|
|
|
### Register Page
|
|
- **URL:** `http://localhost:8000/register`
|
|
- **Template:** `resources/views/auth/register.blade.php`
|
|
- **Features:**
|
|
- Name, email, password fields
|
|
- Password confirmation
|
|
- Terms agreement checkbox
|
|
- Error display
|
|
- Link to login page
|
|
- Responsive design
|
|
|
|
### Forgot Password Page
|
|
- **URL:** `http://localhost:8000/forgot-password`
|
|
- **Template:** `resources/views/auth/forgot-password.blade.php`
|
|
- **Features:**
|
|
- Email input field
|
|
- Reset token display (demo mode)
|
|
- Success/error messages
|
|
- Back to login link
|
|
|
|
### Reset Password Page
|
|
- **URL:** `http://localhost:8000/reset-password?token=TOKEN`
|
|
- **Template:** `resources/views/auth/reset-password.blade.php`
|
|
- **Features:**
|
|
- Email, token, password fields
|
|
- Auto-fills token from URL parameter
|
|
- Password confirmation
|
|
- Token verification
|
|
- Redirects to login after success
|
|
|
|
---
|
|
|
|
## Integration Examples
|
|
|
|
### JavaScript/Frontend Integration
|
|
|
|
#### Login Flow
|
|
```javascript
|
|
// Step 1: Send login credentials
|
|
const loginResponse = await fetch('/api/auth/login', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').content,
|
|
},
|
|
body: JSON.stringify({
|
|
email: 'user@example.com',
|
|
password: 'password123'
|
|
})
|
|
});
|
|
|
|
const loginData = await loginResponse.json();
|
|
|
|
// Step 2: Store token
|
|
if (loginData.success) {
|
|
localStorage.setItem('auth_token', loginData.token);
|
|
localStorage.setItem('user', JSON.stringify(loginData.user));
|
|
}
|
|
|
|
// Step 3: Use token for authenticated requests
|
|
const userProfile = await fetch('/api/user/profile', {
|
|
method: 'GET',
|
|
headers: {
|
|
'Authorization': `Bearer ${localStorage.getItem('auth_token')}`,
|
|
'Content-Type': 'application/json',
|
|
}
|
|
});
|
|
```
|
|
|
|
#### Password Reset Flow
|
|
```javascript
|
|
// Step 1: Request password reset
|
|
const forgotResponse = await fetch('/api/auth/forgot-password', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ email: 'user@example.com' })
|
|
});
|
|
|
|
const forgotData = await forgotResponse.json();
|
|
const resetToken = forgotData.token;
|
|
|
|
// Step 2: Verify token (optional)
|
|
const verifyResponse = await fetch('/api/auth/verify-reset-token', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
email: 'user@example.com',
|
|
token: resetToken
|
|
})
|
|
});
|
|
|
|
// Step 3: Reset password
|
|
const resetResponse = await fetch('/api/auth/reset-password', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
email: 'user@example.com',
|
|
token: resetToken,
|
|
password: 'newpassword123',
|
|
password_confirmation: 'newpassword123'
|
|
})
|
|
});
|
|
|
|
if (resetResponse.ok) {
|
|
// Redirect to login
|
|
window.location.href = '/login';
|
|
}
|
|
```
|
|
|
|
#### Favorites Management
|
|
```javascript
|
|
// Toggle favorite status
|
|
async function toggleFavorite(eventId) {
|
|
const response = await fetch(`/api/user/favorites/${eventId}/toggle`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Authorization': `Bearer ${localStorage.getItem('auth_token')}`,
|
|
'Content-Type': 'application/json',
|
|
}
|
|
});
|
|
|
|
const data = await response.json();
|
|
if (data.success) {
|
|
console.log(`Event is now ${data.is_favorite ? 'favorited' : 'unfavorited'}`);
|
|
}
|
|
}
|
|
|
|
// Get all favorites
|
|
async function getFavorites() {
|
|
const response = await fetch('/api/user/favorites?page=1', {
|
|
headers: {
|
|
'Authorization': `Bearer ${localStorage.getItem('auth_token')}`,
|
|
}
|
|
});
|
|
|
|
const data = await response.json();
|
|
return data.data; // Array of favorite events
|
|
}
|
|
```
|
|
|
|
### Mobile App Integration (React Native / Flutter)
|
|
|
|
```javascript
|
|
// React Native Example
|
|
import axios from 'axios';
|
|
|
|
const API_BASE_URL = 'http://localhost:8000/api';
|
|
|
|
const apiClient = axios.create({
|
|
baseURL: API_BASE_URL,
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
}
|
|
});
|
|
|
|
// Add token to requests
|
|
apiClient.interceptors.request.use((config) => {
|
|
const token = AsyncStorage.getItem('auth_token');
|
|
if (token) {
|
|
config.headers.Authorization = `Bearer ${token}`;
|
|
}
|
|
return config;
|
|
});
|
|
|
|
// Login
|
|
const login = async (email, password) => {
|
|
const { data } = await apiClient.post('/auth/login', { email, password });
|
|
if (data.success) {
|
|
await AsyncStorage.setItem('auth_token', data.token);
|
|
await AsyncStorage.setItem('user', JSON.stringify(data.user));
|
|
}
|
|
return data;
|
|
};
|
|
|
|
// Get user profile
|
|
const getUserProfile = async () => {
|
|
const { data } = await apiClient.get('/user/profile');
|
|
return data.data;
|
|
};
|
|
|
|
// Get user's favorite events
|
|
const getFavoriteEvents = async (page = 1) => {
|
|
const { data } = await apiClient.get(`/user/favorites?page=${page}`);
|
|
return data.data;
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## Error Handling
|
|
|
|
### HTTP Status Codes
|
|
|
|
| Code | Meaning | Example |
|
|
|------|---------|---------|
|
|
| 200 | OK | Request successful |
|
|
| 201 | Created | Resource created (registration/login) |
|
|
| 400 | Bad Request | Malformed request |
|
|
| 401 | Unauthorized | Missing/invalid token |
|
|
| 404 | Not Found | Resource not found |
|
|
| 422 | Unprocessable Entity | Validation error |
|
|
| 500 | Server Error | Internal server error |
|
|
|
|
### Error Response Format
|
|
|
|
```json
|
|
{
|
|
"success": false,
|
|
"message": "Human-readable error message",
|
|
"errors": {
|
|
"field_name": ["Error message for this field"]
|
|
}
|
|
}
|
|
```
|
|
|
|
### Common Errors
|
|
|
|
#### Invalid Credentials
|
|
```json
|
|
{
|
|
"success": false,
|
|
"message": "Ungültige Anmeldedaten"
|
|
}
|
|
```
|
|
|
|
#### Token Expired
|
|
```json
|
|
{
|
|
"success": false,
|
|
"message": "Token ist abgelaufen",
|
|
"valid": false
|
|
}
|
|
```
|
|
|
|
#### Validation Error
|
|
```json
|
|
{
|
|
"success": false,
|
|
"message": "Validierungsfehler",
|
|
"errors": {
|
|
"email": ["E-Mail Adresse ist erforderlich"],
|
|
"password": ["Passwort ist erforderlich"]
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Unauthorized Access
|
|
```json
|
|
{
|
|
"message": "Unauthenticated."
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Demo Test Users
|
|
|
|
Test the system with these pre-configured accounts:
|
|
|
|
| Email | Password | Role |
|
|
|-------|----------|------|
|
|
| user@example.com | password123 | user |
|
|
| organizer@example.com | password123 | organizer |
|
|
| admin@example.com | password123 | admin |
|
|
|
|
---
|
|
|
|
## API Security Best Practices
|
|
|
|
1. **Never share tokens** - Keep tokens secure and never expose them in logs
|
|
2. **Use HTTPS** - Always use HTTPS in production
|
|
3. **Token expiration** - Implement automatic token refresh mechanisms
|
|
4. **Rate limiting** - Implement rate limiting to prevent abuse
|
|
5. **Input validation** - Always validate user input on both client and server
|
|
6. **Password requirements** - Enforce strong password policies (min 8 characters)
|
|
7. **CORS headers** - Configure appropriate CORS headers for your domain
|
|
8. **Environment variables** - Store sensitive configuration in `.env` files
|
|
|
|
---
|
|
|
|
## Testing the API with cURL
|
|
|
|
### Login
|
|
```bash
|
|
curl -X POST http://localhost:8000/api/auth/login \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"email": "user@example.com",
|
|
"password": "password123"
|
|
}'
|
|
```
|
|
|
|
### Get User Profile
|
|
```bash
|
|
curl -X GET http://localhost:8000/api/user/profile \
|
|
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
|
|
-H "Content-Type: application/json"
|
|
```
|
|
|
|
### Forgot Password
|
|
```bash
|
|
curl -X POST http://localhost:8000/api/auth/forgot-password \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"email": "user@example.com"}'
|
|
```
|
|
|
|
### Reset Password
|
|
```bash
|
|
curl -X POST http://localhost:8000/api/auth/reset-password \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"email": "user@example.com",
|
|
"token": "YOUR_RESET_TOKEN",
|
|
"password": "newpassword123",
|
|
"password_confirmation": "newpassword123"
|
|
}'
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Issue: "Unauthenticated" error on protected endpoints
|
|
- **Solution:** Verify token is correctly sent in `Authorization: Bearer TOKEN` header
|
|
- Check token hasn't expired
|
|
- Re-login to get a fresh token
|
|
|
|
### Issue: Password reset token is invalid
|
|
- **Solution:** Tokens expire after 1 hour
|
|
- Request a new reset token
|
|
- Verify email address matches the account
|
|
|
|
### Issue: CORS errors when calling API from frontend
|
|
- **Solution:** Ensure frontend domain is configured in `config/cors.php`
|
|
- Use `Accept: application/json` header
|
|
- Use `Content-Type: application/json` header
|
|
|
|
### Issue: User can't register with valid email
|
|
- **Solution:** Verify email isn't already registered
|
|
- Check email format is correct
|
|
- Verify database connection
|
|
|
|
---
|
|
|
|
## Support & Additional Resources
|
|
|
|
- API Documentation: `/docs/API_AUTHENTICATION_GUIDE.md`
|
|
- Main README: `/README.md`
|
|
- Swagger UI: `http://localhost:8000/api/docs`
|
|
- Contact: [Your contact information]
|
|
|
|
---
|
|
|
|
**Last Updated:** April 14, 2024
|
|
**Version:** 1.0
|
|
**Framework:** Laravel 13.4
|
|
**PHP Version:** 8.5+
|