Sync current dev state
This commit is contained in:
782
docs/API_DOCUMENTATION.md
Normal file
782
docs/API_DOCUMENTATION.md
Normal file
@@ -0,0 +1,782 @@
|
||||
# EasyStream API Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
EasyStream provides a RESTful API for managing videos, users, comments, and subscriptions. All API endpoints return JSON responses and support both JWT token authentication and session-based authentication.
|
||||
|
||||
**Base URL:** `/api/`
|
||||
|
||||
**Content-Type:** `application/json`
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Authentication](#authentication)
|
||||
2. [Videos API](#videos-api)
|
||||
3. [User API](#user-api)
|
||||
4. [Comments API](#comments-api)
|
||||
5. [Subscriptions API](#subscriptions-api)
|
||||
6. [Error Handling](#error-handling)
|
||||
7. [Rate Limiting](#rate-limiting)
|
||||
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
### Overview
|
||||
|
||||
EasyStream supports two authentication methods:
|
||||
|
||||
1. **JWT Token Authentication** (Recommended for API clients)
|
||||
2. **Session-based Authentication** (For web pages)
|
||||
|
||||
### Endpoints
|
||||
|
||||
#### Login with JWT Token
|
||||
|
||||
```http
|
||||
POST /api/auth.php?action=login_token
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"identifier": "username or email",
|
||||
"password": "password",
|
||||
"expires_in": 86400
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
|
||||
"expires_in": 86400,
|
||||
"user": {
|
||||
"usr_id": 1,
|
||||
"usr_user": "john",
|
||||
"usr_email": "john@example.com"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Login with Session
|
||||
|
||||
```http
|
||||
POST /api/auth.php?action=login
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"identifier": "username or email",
|
||||
"password": "password",
|
||||
"remember": true,
|
||||
"csrf_token": "token"
|
||||
}
|
||||
```
|
||||
|
||||
#### Get CSRF Token
|
||||
|
||||
```http
|
||||
GET /api/auth.php?action=csrf_token
|
||||
```
|
||||
|
||||
#### Verify Token
|
||||
|
||||
```http
|
||||
GET /api/auth.php?action=verify_token
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### Get Current User
|
||||
|
||||
```http
|
||||
GET /api/auth.php?action=me
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
#### Logout
|
||||
|
||||
```http
|
||||
POST /api/auth.php?action=logout
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Videos API
|
||||
|
||||
Base endpoint: `/api/videos.php`
|
||||
|
||||
### List Videos
|
||||
|
||||
Get a paginated list of videos with filtering options.
|
||||
|
||||
```http
|
||||
GET /api/videos.php?page=1&limit=20&sort=recent&category=music
|
||||
```
|
||||
|
||||
**Query Parameters:**
|
||||
- `page` (integer, optional): Page number (default: 1)
|
||||
- `limit` (integer, optional): Items per page, max 100 (default: 20)
|
||||
- `sort` (string, optional): Sort order - `recent`, `popular`, `featured`, `oldest`, `title` (default: recent)
|
||||
- `category` (string, optional): Filter by category
|
||||
- `channel_id` (integer, optional): Filter by channel/user ID
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"videos": [
|
||||
{
|
||||
"file_key": "123456",
|
||||
"file_title": "My Video",
|
||||
"file_description": "Description",
|
||||
"file_duration": "00:05:30",
|
||||
"file_views": 1500,
|
||||
"upload_date": "2025-01-15 10:30:00",
|
||||
"thumbnail": "/path/to/thumb.jpg",
|
||||
"usr_id": 1,
|
||||
"usr_user": "john",
|
||||
"usr_dname": "John Doe",
|
||||
"like_count": 50,
|
||||
"comment_count": 10
|
||||
}
|
||||
],
|
||||
"pagination": {
|
||||
"page": 1,
|
||||
"limit": 20,
|
||||
"total": 100,
|
||||
"pages": 5
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Get Single Video
|
||||
|
||||
```http
|
||||
GET /api/videos.php?id=123456
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"file_key": "123456",
|
||||
"file_title": "My Video",
|
||||
"file_description": "Description",
|
||||
"file_name": "video.mp4",
|
||||
"file_duration": "00:05:30",
|
||||
"file_views": 1500,
|
||||
"privacy": "public",
|
||||
"upload_date": "2025-01-15 10:30:00",
|
||||
"usr_id": 1,
|
||||
"usr_user": "john",
|
||||
"usr_dname": "John Doe",
|
||||
"usr_avatar": "/path/to/avatar.jpg",
|
||||
"like_count": 50,
|
||||
"dislike_count": 2,
|
||||
"comment_count": 10,
|
||||
"subscriber_count": 1000,
|
||||
"user_like_status": "like",
|
||||
"user_subscribed": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Search Videos
|
||||
|
||||
```http
|
||||
GET /api/videos.php?action=search&q=search+query&page=1&limit=20
|
||||
```
|
||||
|
||||
### Create Video
|
||||
|
||||
```http
|
||||
POST /api/videos.php?action=create
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"title": "Video Title",
|
||||
"description": "Video description",
|
||||
"privacy": "public",
|
||||
"category": "entertainment",
|
||||
"tags": "tag1,tag2,tag3"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"file_key": "789012",
|
||||
"message": "Video created successfully"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Update Video
|
||||
|
||||
```http
|
||||
PUT /api/videos.php?id=123456
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"file_title": "Updated Title",
|
||||
"file_description": "Updated description",
|
||||
"privacy": "private"
|
||||
}
|
||||
```
|
||||
|
||||
### Delete Video
|
||||
|
||||
```http
|
||||
DELETE /api/videos.php?id=123456
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
### Like/Dislike Video
|
||||
|
||||
```http
|
||||
POST /api/videos.php?action=like
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"file_key": "123456",
|
||||
"like_type": "like"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"action": "added",
|
||||
"like_count": 51,
|
||||
"dislike_count": 2
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Record Video View
|
||||
|
||||
```http
|
||||
POST /api/videos.php?action=view
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"file_key": "123456"
|
||||
}
|
||||
```
|
||||
|
||||
### Watch Later
|
||||
|
||||
Add/remove video from watch later list.
|
||||
|
||||
```http
|
||||
POST /api/videos.php?action=watch_later
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"file_key": "123456"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## User API
|
||||
|
||||
Base endpoint: `/api/user.php`
|
||||
|
||||
### Get User Profile
|
||||
|
||||
Get current user's profile (requires authentication):
|
||||
|
||||
```http
|
||||
GET /api/user.php?action=profile
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
Get another user's public profile:
|
||||
|
||||
```http
|
||||
GET /api/user.php?id=123
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"usr_id": 1,
|
||||
"usr_user": "john",
|
||||
"usr_dname": "John Doe",
|
||||
"usr_email": "john@example.com",
|
||||
"usr_avatar": "/path/to/avatar.jpg",
|
||||
"usr_about": "About me",
|
||||
"usr_website": "https://example.com",
|
||||
"usr_verified": true,
|
||||
"usr_partner": false,
|
||||
"stats": {
|
||||
"videos": 50,
|
||||
"subscribers": 1000,
|
||||
"subscriptions": 75,
|
||||
"views": 50000
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Update Profile
|
||||
|
||||
```http
|
||||
PUT /api/user.php
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"usr_dname": "John Doe",
|
||||
"usr_about": "Updated bio",
|
||||
"usr_website": "https://newsite.com",
|
||||
"usr_location": "New York, USA"
|
||||
}
|
||||
```
|
||||
|
||||
### Upload Avatar
|
||||
|
||||
```http
|
||||
POST /api/user.php?action=avatar
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: multipart/form-data
|
||||
```
|
||||
|
||||
**Form Data:**
|
||||
- `avatar`: Image file (JPG, PNG, GIF, max 5MB)
|
||||
|
||||
### Get User Statistics
|
||||
|
||||
```http
|
||||
GET /api/user.php?action=stats
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"total_videos": 50,
|
||||
"videos_last_30_days": 5,
|
||||
"total_views": 50000,
|
||||
"total_subscribers": 1000,
|
||||
"total_subscriptions": 75,
|
||||
"total_comments": 250,
|
||||
"total_likes_given": 500
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Get User's Videos
|
||||
|
||||
```http
|
||||
GET /api/user.php?action=videos&id=123&page=1&limit=20
|
||||
```
|
||||
|
||||
### Get User's Subscriptions
|
||||
|
||||
```http
|
||||
GET /api/user.php?action=subscriptions
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
### Get User's Subscribers
|
||||
|
||||
```http
|
||||
GET /api/user.php?action=subscribers&id=123
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Comments API
|
||||
|
||||
Base endpoint: `/api/comments.php`
|
||||
|
||||
### List Comments
|
||||
|
||||
Get comments for a video:
|
||||
|
||||
```http
|
||||
GET /api/comments.php?file_key=123456&page=1&limit=50&sort=recent
|
||||
```
|
||||
|
||||
**Query Parameters:**
|
||||
- `file_key` (required): Video file key
|
||||
- `page` (optional): Page number
|
||||
- `limit` (optional): Items per page, max 100
|
||||
- `sort` (optional): `recent`, `top`, `oldest`
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"comments": [
|
||||
{
|
||||
"comment_id": 1,
|
||||
"usr_id": 5,
|
||||
"usr_user": "jane",
|
||||
"usr_dname": "Jane Smith",
|
||||
"usr_avatar": "/path/to/avatar.jpg",
|
||||
"comment_text": "Great video!",
|
||||
"comment_date": "2025-01-15 12:00:00",
|
||||
"comment_likes": 10,
|
||||
"reply_count": 3,
|
||||
"user_liked": false
|
||||
}
|
||||
],
|
||||
"pagination": {
|
||||
"page": 1,
|
||||
"limit": 50,
|
||||
"total": 120,
|
||||
"pages": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Get Single Comment
|
||||
|
||||
Get comment with replies:
|
||||
|
||||
```http
|
||||
GET /api/comments.php?id=123
|
||||
```
|
||||
|
||||
### Create Comment
|
||||
|
||||
```http
|
||||
POST /api/comments.php?action=create
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"file_key": "123456",
|
||||
"comment_text": "This is my comment",
|
||||
"parent_id": null
|
||||
}
|
||||
```
|
||||
|
||||
Set `parent_id` to reply to another comment.
|
||||
|
||||
### Update Comment
|
||||
|
||||
```http
|
||||
PUT /api/comments.php?id=123
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"comment_text": "Updated comment text"
|
||||
}
|
||||
```
|
||||
|
||||
### Delete Comment
|
||||
|
||||
```http
|
||||
DELETE /api/comments.php?id=123
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
### Like Comment
|
||||
|
||||
```http
|
||||
POST /api/comments.php?action=like
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"comment_id": 123
|
||||
}
|
||||
```
|
||||
|
||||
### Report Comment
|
||||
|
||||
```http
|
||||
POST /api/comments.php?action=report
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"comment_id": 123,
|
||||
"reason": "Spam or abuse"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Subscriptions API
|
||||
|
||||
Base endpoint: `/api/subscriptions.php`
|
||||
|
||||
### Get User's Subscriptions
|
||||
|
||||
```http
|
||||
GET /api/subscriptions.php?action=list
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"subscriptions": [
|
||||
{
|
||||
"usr_id": 5,
|
||||
"usr_user": "creator",
|
||||
"usr_dname": "Creator Name",
|
||||
"usr_avatar": "/path/to/avatar.jpg",
|
||||
"usr_verified": true,
|
||||
"sub_date": "2025-01-01 10:00:00",
|
||||
"video_count": 50,
|
||||
"subscriber_count": 10000
|
||||
}
|
||||
],
|
||||
"total": 15
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Get Channel's Subscribers
|
||||
|
||||
```http
|
||||
GET /api/subscriptions.php?action=subscribers&channel_id=5&page=1
|
||||
```
|
||||
|
||||
### Get Subscription Feed
|
||||
|
||||
Get latest videos from subscribed channels:
|
||||
|
||||
```http
|
||||
GET /api/subscriptions.php?action=feed&page=1&limit=20
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
### Check Subscription Status
|
||||
|
||||
```http
|
||||
GET /api/subscriptions.php?action=check&channel_id=5
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"is_subscribed": true,
|
||||
"subscribed_since": "2025-01-01 10:00:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Subscribe to Channel
|
||||
|
||||
```http
|
||||
POST /api/subscriptions.php
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"channel_id": 5
|
||||
}
|
||||
```
|
||||
|
||||
### Unsubscribe from Channel
|
||||
|
||||
```http
|
||||
DELETE /api/subscriptions.php?channel_id=5
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
All API endpoints return consistent error responses:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "Error message here",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
### HTTP Status Codes
|
||||
|
||||
- `200 OK`: Request successful
|
||||
- `400 Bad Request`: Invalid request parameters
|
||||
- `401 Unauthorized`: Authentication required or failed
|
||||
- `403 Forbidden`: Insufficient permissions
|
||||
- `404 Not Found`: Resource not found
|
||||
- `405 Method Not Allowed`: HTTP method not supported
|
||||
- `429 Too Many Requests`: Rate limit exceeded
|
||||
- `500 Internal Server Error`: Server error
|
||||
|
||||
---
|
||||
|
||||
## Rate Limiting
|
||||
|
||||
Rate limits are applied to prevent abuse:
|
||||
|
||||
- **Login attempts**: 5 per 15 minutes per IP
|
||||
- **Password reset**: 3 per hour per email
|
||||
- **API calls**: 100 per minute per user (when authenticated)
|
||||
- **Anonymous API calls**: 20 per minute per IP
|
||||
|
||||
Rate limit headers:
|
||||
|
||||
```
|
||||
X-RateLimit-Limit: 100
|
||||
X-RateLimit-Remaining: 95
|
||||
X-RateLimit-Reset: 1642512000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Frontend Integration
|
||||
|
||||
### Using api-helper.js
|
||||
|
||||
EasyStream provides a modern JavaScript API client for easy integration:
|
||||
|
||||
```javascript
|
||||
// Initialize (automatically done on page load)
|
||||
const api = window.api; // or new EasyStreamAPI()
|
||||
|
||||
// Login
|
||||
const loginResult = await api.login('username', 'password');
|
||||
if (loginResult.success) {
|
||||
console.log('Logged in!', loginResult.user);
|
||||
}
|
||||
|
||||
// Get videos
|
||||
const videos = await api.getVideos({ page: 1, sort: 'popular' });
|
||||
|
||||
// Get single video
|
||||
const video = await api.getVideo('123456');
|
||||
|
||||
// Like video
|
||||
await api.likeVideo('123456', 'like');
|
||||
|
||||
// Create comment
|
||||
await api.createComment('123456', 'Great video!');
|
||||
|
||||
// Subscribe to channel
|
||||
await api.subscribe(5);
|
||||
|
||||
// Get user profile
|
||||
const profile = await api.getUserProfile(123);
|
||||
|
||||
// Update profile
|
||||
await api.updateProfile({
|
||||
usr_dname: 'New Display Name',
|
||||
usr_about: 'Updated bio'
|
||||
});
|
||||
|
||||
// Error handling
|
||||
try {
|
||||
const result = await api.someAPICall();
|
||||
} catch (error) {
|
||||
console.error('API error:', error.message);
|
||||
api.handleError(error);
|
||||
}
|
||||
```
|
||||
|
||||
### Authentication Headers
|
||||
|
||||
When using JWT tokens, include the Authorization header:
|
||||
|
||||
```javascript
|
||||
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGc...
|
||||
```
|
||||
|
||||
The api-helper.js automatically handles this for you.
|
||||
|
||||
---
|
||||
|
||||
## CORS Configuration
|
||||
|
||||
Cross-Origin Resource Sharing (CORS) is configured securely:
|
||||
|
||||
- **Development**: Allows localhost and 127.0.0.1
|
||||
- **Production**: Only allows origins defined in `CORS_ALLOWED_ORIGINS` environment variable
|
||||
|
||||
To configure allowed origins in production, set:
|
||||
|
||||
```bash
|
||||
CORS_ALLOWED_ORIGINS=https://example.com,https://www.example.com
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Always use HTTPS** in production
|
||||
2. **Store JWT tokens securely** (httpOnly cookies or secure localStorage)
|
||||
3. **Include CSRF tokens** for session-based requests
|
||||
4. **Handle errors gracefully** and show user-friendly messages
|
||||
5. **Implement exponential backoff** for failed requests
|
||||
6. **Cache responses** when appropriate
|
||||
7. **Validate input** on both client and server side
|
||||
8. **Use pagination** for large datasets
|
||||
9. **Monitor rate limits** to avoid being throttled
|
||||
10. **Log errors** for debugging
|
||||
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
For issues or questions about the API:
|
||||
|
||||
- Check [docs/TROUBLESHOOTING.md](TROUBLESHOOTING.md)
|
||||
- Review [docs/BACKEND_FRONTEND_INTEGRATION_FIXES.md](BACKEND_FRONTEND_INTEGRATION_FIXES.md)
|
||||
- Open an issue in the project repository
|
||||
|
||||
---
|
||||
|
||||
**Last Updated:** January 2025
|
||||
**API Version:** 1.0.0
|
||||
Reference in New Issue
Block a user