Skip to content

ais1175/ulog_shop

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

1 Commit
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ›’ ULOG Tebex Store - Complete Setup Guide

A modern, premium FiveM store frontend integrated with Tebex Headless API, featuring Discord OAuth authentication, product reviews, and a beautiful UI.


πŸ“‹ Table of Contents


✨ Features

  • 🎨 Modern UI - Beautiful, responsive design with Mantine components
  • πŸ” Discord OAuth - Secure authentication with Discord
  • πŸ›οΈ Tebex Integration - Full integration with Tebex Headless API
  • ⭐ Review System - MySQL-powered product reviews
  • πŸ›’ Shopping Cart - Persistent cart with local storage
  • πŸ”’ Security - Rate limiting, input validation, XSS protection
  • πŸ“± Responsive - Works perfectly on all devices
  • πŸš€ Fast - Optimized build with Vite

πŸ› οΈ Tech Stack

Frontend

  • React 18 with TypeScript
  • Vite - Fast build tool
  • Mantine UI - Component library
  • React Router - Client-side routing
  • Axios - HTTP client

Backend

  • Node.js with Express
  • MySQL - Reviews database
  • Discord OAuth2 - Authentication
  • Tebex API - Payment processing
  • Helmet.js - Security headers
  • Rate Limiting - DDoS protection

πŸ“¦ Prerequisites

Before you begin, ensure you have:

  • Node.js 16+ installed
  • pnpm package manager (npm install -g pnpm)
  • MySQL 5.7+ or MariaDB 10+
  • Tebex Account with Headless API access
  • Discord Application (for OAuth)

πŸš€ Quick Start (Localhost)

Step 1: Clone and Install

# Navigate to project directory
cd ulog_tebex_site_v2

# Install backend dependencies
cd server
pnpm install

# Install frontend dependencies
cd ../client
pnpm install

Step 2: Database Setup

-- Create database
CREATE DATABASE ulog_reviews CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- Use database
USE ulog_reviews;

-- Create reviews table
CREATE TABLE reviews (
    id INT AUTO_INCREMENT PRIMARY KEY,
    transaction_id VARCHAR(255) UNIQUE NOT NULL,
    user_id VARCHAR(255) NOT NULL,
    user_username VARCHAR(255) NOT NULL,
    user_avatar VARCHAR(512),
    product_name VARCHAR(512) NOT NULL,
    review_description TEXT NOT NULL,
    rating INT NOT NULL CHECK (rating BETWEEN 1 AND 5),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_product_name (product_name(255)),
    INDEX idx_user_id (user_id),
    INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Step 3: Get API Keys

A. Tebex API Keys

  1. Headless API (Public/Private Token):

    • Go to Tebex Creator Dashboard
    • Select your Webstore
    • Navigate to Settings β†’ API Keys
    • Copy Public Token and Private Key
  2. Plugin API (Server Secret):

B. Discord OAuth2

  1. Go to Discord Developer Portal
  2. Create a new application or select existing
  3. Go to OAuth2 β†’ General
  4. Copy Client ID and Client Secret
  5. Add redirect URIs:
    • Development: http://localhost:5173/auth/discord/callback
    • Production: https://your-domain.com/auth/discord/callback

Step 4: Configure Environment Variables

Server Configuration (server/.env)

Create server/.env with the following content:

# Server Configuration
PORT=3001
FRONTEND_URL=http://localhost:5173

# Tebex Headless API Keys
TEBEX_PUBLIC_TOKEN=your_public_token_here
TEBEX_PRIVATE_KEY=your_private_key_here

# Tebex Plugin API (for recent payments)
TEBEX_SERVER_SECRET=your_server_secret_here

# Discord OAuth2
DISCORD_CLIENT_ID=your_discord_client_id_here
DISCORD_CLIENT_SECRET=your_discord_client_secret_here
DISCORD_REDIRECT_URI=http://localhost:5173/auth/discord/callback
DISCORD_BOT_TOKEN=your_discord_bot_token
DISCORD_GUILD_ID=your_discord_guild_id

# MySQL Database
DB_HOST=localhost
DB_PORT=3306
DB_USER=root
DB_PASSWORD=your_mysql_password
DB_NAME=ulog_reviews

Client Configuration (client/.env)

Create client/.env with:

# Backend API URL
VITE_BACKEND_URL=http://localhost:3001

# Discord OAuth2
VITE_DISCORD_CLIENT_ID=your_discord_client_id_here
VITE_DISCORD_REDIRECT_URI=http://localhost:5173/auth/discord/callback

# Tebex Public Token
VITE_TEBEX_PUBLIC_TOKEN=your_public_token_here

⚠️ Important: Replace all your_*_here placeholders with your actual values!


Step 5: Start Development Servers

# Terminal 1 - Start Backend
cd server
node index.js

# Terminal 2 - Start Frontend
cd client
pnpm dev

Access your store at: http://localhost:5173


🌐 Production Deployment

Step 1: Prepare Server Environment

# Update system
sudo apt update && sudo apt upgrade -y

# Install Node.js (Ubuntu/Debian)
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install -y nodejs

# Install pnpm
npm install -g pnpm

# Install MySQL
sudo apt install -y mysql-server
sudo mysql_secure_installation

# Install Nginx
sudo apt install -y nginx

# Install PM2 (process manager)
npm install -g pm2

Step 2: Clone and Setup Project

# Clone project to server
cd /var/www
git clone your-repo-url ulog_store
cd ulog_store

# Install dependencies
cd server && pnpm install
cd ../client && pnpm install

Step 3: Configure Production Environment

Server (server/.env)

PORT=3001
FRONTEND_URL=https://your-domain.com

TEBEX_PUBLIC_TOKEN=your_production_token
TEBEX_PRIVATE_KEY=your_production_key
TEBEX_SERVER_SECRET=your_production_secret

DISCORD_CLIENT_ID=your_client_id
DISCORD_CLIENT_SECRET=your_client_secret
DISCORD_REDIRECT_URI=https://your-domain.com/auth/discord/callback
DISCORD_BOT_TOKEN=your_discord_bot_token
DISCORD_GUILD_ID=your_discord_guild_id

DB_HOST=localhost
DB_PORT=3306
DB_USER=ulog_user
DB_PASSWORD=strong_production_password
DB_NAME=ulog_reviews

Client (client/.env.production)

VITE_BACKEND_URL=https://your-domain.com
VITE_DISCORD_CLIENT_ID=your_client_id
VITE_DISCORD_REDIRECT_URI=https://your-domain.com/auth/discord/callback
VITE_TEBEX_PUBLIC_TOKEN=your_public_token

Step 4: Build Frontend

cd client
pnpm build

# This creates a 'dist' folder with optimized production files

Step 5: Configure Nginx

Create /etc/nginx/sites-available/ulog_store:

server {
    listen 80;
    server_name your-domain.com;

    # Frontend (static files)
    root /var/www/ulog_store/client/dist;
    index index.html;

    # Frontend routing (SPA)
    location / {
        try_files $uri $uri/ /index.html;
    }

    # Backend API proxy
    location /api/ {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }

    # Security headers
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_types text/plain text/css text/xml text/javascript application/javascript application/json;
}

Enable the site:

sudo ln -s /etc/nginx/sites-available/ulog_store /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Step 6: Setup SSL with Certbot

# Install Certbot
sudo apt install -y certbot python3-certbot-nginx

# Get SSL certificate
sudo certbot --nginx -d your-domain.com

# Auto-renewal is configured automatically
# Test renewal: sudo certbot renew --dry-run

Step 7: Start Backend with PM2

cd /var/www/ulog_store/server

# Start backend
pm2 start index.js --name ulog-backend

# Save PM2 configuration
pm2 save

# Setup PM2 to start on boot
pm2 startup
# Follow the command it outputs

# Check status
pm2 status
pm2 logs ulog-backend

Step 8: Database Security (Production)

# Login to MySQL
sudo mysql

# Create dedicated user
CREATE USER 'ulog_user'@'localhost' IDENTIFIED BY 'strong_password_here';
GRANT ALL PRIVILEGES ON ulog_reviews.* TO 'ulog_user'@'localhost';
FLUSH PRIVILEGES;

# Create database (if not exists)
CREATE DATABASE ulog_reviews CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE ulog_reviews;

# Create reviews table (same as localhost)
CREATE TABLE reviews (
    id INT AUTO_INCREMENT PRIMARY KEY,
    transaction_id VARCHAR(255) UNIQUE NOT NULL,
    user_id VARCHAR(255) NOT NULL,
    user_username VARCHAR(255) NOT NULL,
    user_avatar VARCHAR(512),
    product_name VARCHAR(512) NOT NULL,
    review_description TEXT NOT NULL,
    rating INT NOT NULL CHECK (rating BETWEEN 1 AND 5),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_product_name (product_name(255)),
    INDEX idx_user_id (user_id),
    INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

EXIT;

Step 9: Update Discord Redirect URIs

  1. Go to Discord Developer Portal
  2. Select your application
  3. Go to OAuth2 β†’ General
  4. Add your production redirect URI: https://your-domain.com/auth/discord/callback
  5. Save changes

Step 10: Test Production Deployment

# Check backend status
pm2 status
pm2 logs ulog-backend

# Check Nginx
sudo systemctl status nginx
sudo nginx -t

# Test API endpoint
curl https://your-domain.com/api/health

# Visit your site
# https://your-domain.com

πŸ€– Discord Bot Setup

The Discord bot handles review submissions via slash commands.

Step 1: Create Discord Bot

  1. Go to Discord Developer Portal
  2. Create new application or use existing
  3. Go to Bot section
  4. Click Reset Token and copy the bot token
  5. Enable Server Members Intent and Message Content Intent

Step 2: Configure Bot

Navigate to the Discord bot directory:

cd ulog-discord-bot

Edit config.json:

{
  "token": "your_bot_token_here",
  "clientId": "your_application_id_here",
  "guildId": "your_discord_server_id_here",
  "tebexSecret": "your_tebex_server_secret",
  "db": {
    "host": "localhost",
    "port": 3306,
    "user": "root",
    "password": "your_mysql_password",
    "database": "ulog_reviews"
  }
}

Step 3: Deploy Slash Commands

# Install dependencies
npm install

# Deploy commands to Discord
node deploy-commands.js

# You should see: "Successfully registered application commands."

Step 4: Start Bot

# Development
node index.js

# Production (with PM2)
pm2 start index.js --name ulog-discord-bot
pm2 save

Step 5: Invite Bot to Server

  1. Go to Discord Developer Portal β†’ Your App β†’ OAuth2 β†’ URL Generator
  2. Select scopes: bot, applications.commands
  3. Select permissions: Send Messages, Use Slash Commands
  4. Copy generated URL and open in browser
  5. Select your server and authorize

Step 6: Using the Bot

In your Discord server:

/review

The bot will:

  1. Ask for a transaction ID
  2. Verify the transaction with Tebex API
  3. Check if already reviewed
  4. Open a modal for rating and review text
  5. Save to database
  6. Confirm submission

πŸ”§ Troubleshooting

Backend Issues

Problem: Error: listen EADDRINUSE: address already in use :::3001

# Windows
netstat -ano | findstr :3001
taskkill /PID <PID> /F

# Linux
sudo lsof -ti:3001 | xargs kill -9

Problem: Backend shows "Missing configuration"

  • Check that server/.env exists
  • Verify all values are filled in (no your_*_here placeholders)
  • No extra spaces around = sign
  • File is named exactly .env (with dot at start)

Problem: "Failed to connect to MySQL"

# Check MySQL is running
sudo systemctl status mysql

# Test connection
mysql -u root -p -e "SHOW DATABASES;"

# Verify database exists
mysql -u root -p -e "USE ulog_reviews; SHOW TABLES;"

Frontend Issues

Problem: "Network Error" when calling API

  • Check VITE_BACKEND_URL in .env or .env.production
  • Verify backend is running: curl http://localhost:3001/api/health
  • Check browser console for CORS errors
  • Clear browser cache (Ctrl+Shift+Delete)

Problem: Reviews not loading

  • Check backend logs: pm2 logs ulog-backend
  • Test endpoint: curl http://localhost:3001/api/reviews/product/TestProduct
  • Verify MySQL connection
  • Check if VITE_BACKEND_URL is correct

Problem: Discord auth fails

  1. Verify DISCORD_REDIRECT_URI matches in:
    • server/.env
    • client/.env or .env.production
    • Discord Developer Portal OAuth2 settings
  2. Check Discord Client ID and Secret are correct
  3. Test token exchange endpoint manually

Problem: Tebex API returns 403

  • Use Server Secret from Game Server settings (not webstore)
  • Verify secret is correct in server/.env
  • Check IP whitelist in Tebex settings (if applicable)

Production Issues

Problem: PM2 process keeps crashing

# Check logs
pm2 logs ulog-backend --lines 100

# Check error details
pm2 describe ulog-backend

# Restart with fresh environment
pm2 delete ulog-backend
pm2 start index.js --name ulog-backend
pm2 save

Problem: Nginx 502 Bad Gateway

# Check backend is running
pm2 status

# Check Nginx error log
sudo tail -f /var/log/nginx/error.log

# Verify proxy_pass URL in Nginx config
sudo nano /etc/nginx/sites-available/ulog_store

# Test Nginx config
sudo nginx -t

# Reload Nginx
sudo systemctl reload nginx

Problem: SSL certificate issues

# Check certificate status
sudo certbot certificates

# Renew manually
sudo certbot renew

# Check Nginx SSL config
sudo nano /etc/nginx/sites-available/ulog_store

πŸ“‘ API Documentation

Backend Endpoints

Health Check

GET /api/health

Returns server status.


Tebex Categories

GET /api/tebex/categories

Fetches all product categories with packages.


Tebex Packages

GET /api/tebex/packages
GET /api/tebex/packages/:packageId

Fetches all packages or a specific package by ID.


Recent Payments

GET /api/tebex/payments/recent?limit=10

Fetches recent payments from Tebex Plugin API.


Create Basket

POST /api/tebex/baskets
Body: { complete_url, cancel_url, custom }

Creates a new Tebex basket.


Add to Basket

POST /api/tebex/baskets/:basketIdent/packages
Body: { package_id, quantity, type }

Adds a package to basket.


Get Basket Auth URL

GET /api/tebex/baskets/:basketIdent/auth?returnUrl=...

Gets authentication URL for basket checkout.


Discord Token Exchange

POST /api/discord/token
Body: { code }

Exchanges Discord OAuth code for access token.


Product Reviews

GET /api/reviews/product/:productName

Fetches reviews and stats for a product.


πŸ” Security Features

  • βœ… Rate Limiting - Global (100 req/15min) and strict (20 req/15min) limiters
  • βœ… Input Validation - Joi schemas for all inputs
  • βœ… XSS Protection - DOMPurify sanitization on frontend
  • βœ… SQL Injection Prevention - Parameterized queries
  • βœ… CORS - Configured for frontend domain only
  • βœ… Helmet.js - Security headers
  • βœ… Environment Variables - Sensitive data in .env files
  • βœ… HTTPS - SSL/TLS encryption in production

πŸ“ Environment Variables Reference

Server Variables

Variable Description Example
PORT Backend server port 3001
FRONTEND_URL Frontend URL for CORS http://localhost:5173
TEBEX_PUBLIC_TOKEN Tebex Headless public token z5jb-xxxxx
TEBEX_PRIVATE_KEY Tebex Headless private key xxxxxxxx
TEBEX_SERVER_SECRET Tebex Plugin API secret xxxxxxxx
DISCORD_CLIENT_ID Discord OAuth client ID 1234567890
DISCORD_CLIENT_SECRET Discord OAuth secret xxxxxxxx
DISCORD_REDIRECT_URI Discord OAuth callback http://localhost:5173/auth/discord/callback
DB_HOST MySQL host localhost
DB_PORT MySQL port 3306
DB_USER MySQL user root
DB_PASSWORD MySQL password password
DB_NAME MySQL database ulog_reviews

Client Variables

Variable Description Example
VITE_BACKEND_URL Backend API URL http://localhost:3001
VITE_DISCORD_CLIENT_ID Discord client ID 1234567890
VITE_DISCORD_REDIRECT_URI Discord callback http://localhost:5173/auth/discord/callback
VITE_TEBEX_PUBLIC_TOKEN Tebex public token z5jb-xxxxx

⚠️ Note: Client variables MUST have VITE_ prefix!


πŸš€ Performance Optimization

Frontend

  • βœ… Vite for fast builds
  • βœ… Code splitting
  • βœ… Lazy loading routes
  • βœ… Image optimization
  • βœ… Gzip compression (Nginx)

Backend

  • βœ… Database indexing
  • βœ… Connection pooling
  • βœ… Rate limiting
  • βœ… Efficient queries
  • βœ… PM2 cluster mode (optional)

πŸ“¦ Project Structure

ulog_tebex_site_v2/
β”œβ”€β”€ client/                 # Frontend (React + Vite)
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ components/    # Reusable components
β”‚   β”‚   β”œβ”€β”€ contexts/      # React contexts (Auth, Cart)
β”‚   β”‚   β”œβ”€β”€ pages/         # Page components
β”‚   β”‚   β”œβ”€β”€ services/      # API services
β”‚   β”‚   β”œβ”€β”€ types/         # TypeScript types
β”‚   β”‚   └── utils/         # Utility functions
β”‚   β”œβ”€β”€ public/            # Static assets
β”‚   β”œβ”€β”€ .env               # Development config
β”‚   β”œβ”€β”€ .env.production    # Production config
β”‚   └── package.json
β”‚
β”œβ”€β”€ server/                # Backend (Node.js + Express)
β”‚   β”œβ”€β”€ database.js        # MySQL connection and queries
β”‚   β”œβ”€β”€ validators.js      # Input validation schemas
β”‚   β”œβ”€β”€ index.js           # Main server file
β”‚   β”œβ”€β”€ .env               # Server configuration
β”‚   └── package.json
β”‚
└── README.md              # This file

πŸ”„ Update Guide

Updating Dependencies

# Backend
cd server
pnpm update

# Frontend
cd client
pnpm update

Pulling Latest Changes

git pull origin main

# Reinstall dependencies
cd server && pnpm install
cd ../client && pnpm install

# Rebuild frontend
cd client && pnpm build

# Restart services
pm2 restart ulog-backend

πŸ“ž Support

For issues, questions, or contributions:

  • Check the Troubleshooting section
  • Review your environment configuration
  • Check server logs: pm2 logs ulog-backend
  • Verify MySQL connection
  • Test API endpoints manually

πŸ“„ License

This project is proprietary software. All rights reserved.


πŸŽ‰ Credits

Built with ❀️ for the FiveM community.

Technologies:

  • React + TypeScript
  • Node.js + Express
  • MySQL
  • Tebex API
  • Discord API
  • Mantine UI

Happy selling! πŸš€

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • TypeScript 88.2%
  • JavaScript 10.1%
  • CSS 1.4%
  • HTML 0.3%