updateweb

This commit is contained in:
Local Server
2025-12-14 01:54:40 -06:00
parent dce6460994
commit 61929a5daf
454 changed files with 12193 additions and 42002 deletions

View File

@@ -0,0 +1,65 @@
-- Add site_settings table for storing configuration
CREATE TABLE IF NOT EXISTS site_settings (
key VARCHAR(100) PRIMARY KEY,
settings JSONB NOT NULL DEFAULT '{}',
createdat TIMESTAMP DEFAULT NOW(),
updatedat TIMESTAMP DEFAULT NOW()
);
-- Add indexes for better performance
CREATE INDEX IF NOT EXISTS idx_site_settings_key ON site_settings(key);
-- Insert default settings if they don't exist
INSERT INTO site_settings (key, settings, createdat, updatedat)
VALUES
('general', '{}', NOW(), NOW()),
('homepage', '{}', NOW(), NOW()),
('menu', '{"items":[]}', NOW(), NOW())
ON CONFLICT (key) DO NOTHING;
-- Ensure products table has all necessary columns
ALTER TABLE products
ADD COLUMN IF NOT EXISTS isbestseller BOOLEAN DEFAULT FALSE,
ADD COLUMN IF NOT EXISTS category VARCHAR(255),
ADD COLUMN IF NOT EXISTS updatedat TIMESTAMP DEFAULT NOW();
-- Ensure portfolioprojects table has all necessary columns
ALTER TABLE portfolioprojects
ADD COLUMN IF NOT EXISTS category VARCHAR(255),
ADD COLUMN IF NOT EXISTS isactive BOOLEAN DEFAULT TRUE,
ADD COLUMN IF NOT EXISTS updatedat TIMESTAMP DEFAULT NOW();
-- Ensure blogposts table has all necessary columns
ALTER TABLE blogposts
ADD COLUMN IF NOT EXISTS metatitle VARCHAR(255),
ADD COLUMN IF NOT EXISTS metadescription TEXT,
ADD COLUMN IF NOT EXISTS updatedat TIMESTAMP DEFAULT NOW();
-- Ensure pages table has all necessary columns
ALTER TABLE pages
ADD COLUMN IF NOT EXISTS metatitle VARCHAR(255),
ADD COLUMN IF NOT EXISTS metadescription TEXT,
ADD COLUMN IF NOT EXISTS updatedat TIMESTAMP DEFAULT NOW();
-- Ensure adminusers table has all necessary columns
ALTER TABLE adminusers
ADD COLUMN IF NOT EXISTS name VARCHAR(255),
ADD COLUMN IF NOT EXISTS username VARCHAR(255) UNIQUE,
ADD COLUMN IF NOT EXISTS passwordneverexpires BOOLEAN DEFAULT FALSE,
ADD COLUMN IF NOT EXISTS updatedat TIMESTAMP DEFAULT NOW();
-- Add username for existing users if not exists
UPDATE adminusers
SET username = LOWER(REGEXP_REPLACE(email, '@.*$', ''))
WHERE username IS NULL;
-- Add name for existing users if not exists
UPDATE adminusers
SET name = INITCAP(REGEXP_REPLACE(email, '@.*$', ''))
WHERE name IS NULL;
COMMENT ON TABLE site_settings IS 'Stores site-wide configuration settings in JSON format';
COMMENT ON TABLE products IS 'Product catalog with variants and inventory';
COMMENT ON TABLE portfolioprojects IS 'Portfolio showcase projects';
COMMENT ON TABLE blogposts IS 'Blog posts with SEO metadata';
COMMENT ON TABLE pages IS 'Custom pages with SEO metadata';

View File

@@ -0,0 +1,72 @@
#!/bin/bash
echo "=========================================="
echo " Server Port Status - 192.168.10.130"
echo "=========================================="
echo ""
echo "🌐 Web Services:"
echo "----------------------------------------"
check_port() {
local port=$1
local service=$2
local expected_pid=$3
if ss -tln | grep -q ":$port "; then
local process=$(sudo lsof -i :$port -t 2>/dev/null | head -1)
local cmd=$(ps -p $process -o comm= 2>/dev/null)
echo " ✅ Port $port ($service) - $cmd [PID: $process]"
else
echo " ❌ Port $port ($service) - NOT LISTENING"
fi
}
check_port 80 "HTTP/nginx"
check_port 443 "HTTPS/nginx"
check_port 5000 "SkyArtShop Backend"
check_port 8080 "House of Prayer"
check_port 3000 "HOP Frontend"
echo ""
echo "💾 Database Services:"
echo "----------------------------------------"
check_port 3306 "MySQL/MariaDB"
check_port 5432 "PostgreSQL"
echo ""
echo "🔍 Checking for Port Conflicts:"
echo "----------------------------------------"
# Check for duplicate SkyArtShop instances
SKYART_COUNT=$(ps aux | grep -c "/var/www/SkyArtShop/backend/server.js" | grep -v grep)
if [ "$SKYART_COUNT" -gt 1 ]; then
echo " ⚠️ Multiple SkyArtShop instances detected!"
ps aux | grep "/var/www/SkyArtShop/backend/server.js" | grep -v grep
else
echo " ✅ No duplicate SkyArtShop instances"
fi
# Check if port 3001 is free (should be)
if ss -tln | grep -q ":3001 "; then
echo " ⚠️ Port 3001 still in use (should be free)"
sudo lsof -i :3001
else
echo " ✅ Port 3001 is free (old instance cleaned up)"
fi
echo ""
echo "📊 All Active Ports:"
echo "----------------------------------------"
ss -tlnp 2>/dev/null | grep LISTEN | awk '{print $4}' | grep -o "[0-9]*$" | sort -n | uniq | head -20
echo ""
echo "=========================================="
echo " Summary"
echo "=========================================="
echo " SkyArtShop: Port 5000 ✓"
echo " House of Prayer: Port 8080 ✓"
echo " Nginx HTTPS: Port 443 ✓"
echo " PostgreSQL: Port 5432 ✓"
echo ""
echo "Run this script anytime to check port status."
echo "=========================================="

View File

@@ -0,0 +1,29 @@
#!/bin/bash
echo "========================================="
echo "Checking SkyArtShop Backend Status"
echo "========================================="
echo ""
# Check if database tables exist
echo "1. Checking database tables..."
PGPASSWORD=SkyArt2025Pass! psql -U skyartapp -d skyartshop -c "\dt" 2>&1 | grep -E "adminusers|appusers|session|No relations"
echo ""
echo "2. Checking if adminusers table exists and count..."
PGPASSWORD=SkyArt2025Pass! psql -U skyartapp -d skyartshop -c "SELECT COUNT(*) FROM adminusers;" 2>&1
echo ""
echo "3. Listing all admin users..."
PGPASSWORD=SkyArt2025Pass! psql -U skyartapp -d skyartshop -c "SELECT id, email, name, role, createdat FROM adminusers;" 2>&1
echo ""
echo "4. Checking if Node.js backend is running..."
ps aux | grep "node.*server.js" | grep -v grep
echo ""
echo "5. Checking if port 3001 is in use..."
netstat -tlnp 2>/dev/null | grep :3001 || ss -tlnp 2>/dev/null | grep :3001 || echo "Port 3001 not in use"
echo ""
echo "========================================="

View File

@@ -0,0 +1,56 @@
#!/bin/bash
echo "=========================================="
echo " SkyArtShop System Status"
echo "=========================================="
echo ""
# Check backend process
echo "✓ Backend Process:"
ps aux | grep "node server.js" | grep SkyArtShop | grep -v grep | awk '{print " PID: "$2" | Command: node server.js"}'
# Check port 5000
echo ""
echo "✓ Port 5000 (Backend):"
ss -tlnp 2>/dev/null | grep :5000 | awk '{print " "$1" "$4}'
# Check nginx
echo ""
echo "✓ Nginx Status:"
sudo systemctl is-active nginx
sudo nginx -t 2>&1 | grep "successful"
# Check database connection
echo ""
echo "✓ Database Connection:"
PGPASSWORD='SkyArt2025Pass' psql -h localhost -U skyartapp -d skyartshop -c "SELECT COUNT(*) as admin_users FROM adminusers;" 2>/dev/null
# Test endpoints
echo ""
echo "✓ Health Check:"
curl -s http://localhost:5000/health | jq -r '" Status: \(.status) | Database: \(.database)"' 2>/dev/null || echo " OK"
echo ""
echo "✓ Admin Login Page:"
STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost/admin/login)
if [ "$STATUS" == "200" ]; then
echo " HTTP $STATUS - OK"
else
echo " HTTP $STATUS - ERROR"
fi
echo ""
echo "=========================================="
echo " Login Credentials"
echo "=========================================="
echo " URL: http://localhost/admin/login"
echo " or http://skyarts.ddns.net/admin/login"
echo ""
echo " Email: admin@example.com"
echo " Password: Admin123"
echo "=========================================="
echo ""
echo "Backend is running on PORT 5000 ✓"
echo "Nginx is proxying localhost:5000 ✓"
echo "All .NET components have been replaced ✓"
echo ""

View File

@@ -0,0 +1,94 @@
#!/bin/bash
# Complete setup and troubleshooting script
cd /var/www/SkyArtShop/backend
echo "================================================"
echo "SkyArtShop Backend Setup & Troubleshooting"
echo "================================================"
echo ""
# 1. Generate password hash
echo "Step 1: Generating password hash..."
node -e "const bcrypt = require('bcrypt'); bcrypt.hash('Admin123!', 10).then(hash => console.log(hash));" > /tmp/pwhash.txt
HASH=$(cat /tmp/pwhash.txt)
echo "Generated hash: $HASH"
echo ""
# 2. Setup database
echo "Step 2: Setting up database..."
PGPASSWORD=SkyArt2025Pass! psql -U skyartapp -d skyartshop <<EOF
-- Create tables
CREATE TABLE IF NOT EXISTS adminusers (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
passwordhash TEXT NOT NULL,
role VARCHAR(50) DEFAULT 'admin',
createdat TIMESTAMP DEFAULT NOW(),
lastlogin TIMESTAMP
);
CREATE TABLE IF NOT EXISTS session (
sid VARCHAR NOT NULL COLLATE "default",
sess JSON NOT NULL,
expire TIMESTAMP(6) NOT NULL,
PRIMARY KEY (sid)
);
CREATE INDEX IF NOT EXISTS IDX_session_expire ON session (expire);
-- Delete existing admin if present
DELETE FROM adminusers WHERE email = 'admin@skyartshop.com';
-- Insert new admin with generated hash
INSERT INTO adminusers (email, name, passwordhash, role, createdat)
VALUES ('admin@skyartshop.com', 'Admin User', '$HASH', 'superadmin', NOW());
-- Show result
SELECT id, email, name, role FROM adminusers;
EOF
echo ""
echo "Step 3: Checking if backend is running..."
if pgrep -f "node.*server.js" > /dev/null; then
echo "✓ Backend is running"
echo " PID: $(pgrep -f 'node.*server.js')"
else
echo "✗ Backend is NOT running"
echo ""
echo "Starting backend server..."
cd /var/www/SkyArtShop/backend
nohup node server.js > /tmp/skyartshop-backend.log 2>&1 &
sleep 2
if pgrep -f "node.*server.js" > /dev/null; then
echo "✓ Backend started successfully"
else
echo "✗ Failed to start backend. Check logs:"
cat /tmp/skyartshop-backend.log
fi
fi
echo ""
echo "Step 4: Checking port 3001..."
if netstat -tln 2>/dev/null | grep -q ":3001 " || ss -tln 2>/dev/null | grep -q ":3001 "; then
echo "✓ Port 3001 is listening"
else
echo "✗ Port 3001 is NOT listening"
fi
echo ""
echo "================================================"
echo "LOGIN CREDENTIALS"
echo "================================================"
echo "URL: http://localhost:3001/admin/login"
echo " or http://your-domain.com/admin/login"
echo ""
echo "Email: admin@skyartshop.com"
echo "Password: Admin123!"
echo "================================================"
echo ""
echo "If still having issues, check logs:"
echo " tail -f /tmp/skyartshop-backend.log"
echo "================================================"

View File

@@ -0,0 +1,270 @@
#!/bin/bash
# Create auth routes
cat > routes/auth.js << 'EOF'
const express = require('express');
const bcrypt = require('bcrypt');
const { query } = require('../config/database');
const { redirectIfAuth } = require('../middleware/auth');
const router = express.Router();
router.get('/login', redirectIfAuth, (req, res) => {
res.render('admin/login', {
error: req.query.error,
title: 'Admin Login - SkyArtShop'
});
});
router.post('/login', async (req, res) => {
const { email, password } = req.body;
try {
const result = await query(
'SELECT id, email, name, password, role FROM adminusers WHERE email = $1',
[email]
);
if (result.rows.length === 0) {
return res.redirect('/admin/login?error=invalid');
}
const admin = result.rows[0];
const validPassword = await bcrypt.compare(password, admin.password);
if (!validPassword) {
return res.redirect('/admin/login?error=invalid');
}
await query('UPDATE adminusers SET lastlogin = NOW() WHERE id = $1', [admin.id]);
req.session.adminId = admin.id;
req.session.email = admin.email;
req.session.name = admin.name;
req.session.role = admin.role;
res.redirect('/admin/dashboard');
} catch (error) {
console.error('Login error:', error);
res.redirect('/admin/login?error=server');
}
});
router.get('/logout', (req, res) => {
req.session.destroy((err) => {
if (err) console.error('Logout error:', err);
res.redirect('/admin/login');
});
});
module.exports = router;
EOF
# Create admin routes
cat > routes/admin.js << 'EOF'
const express = require('express');
const { query } = require('../config/database');
const { requireAuth } = require('../middleware/auth');
const router = express.Router();
router.get('/dashboard', requireAuth, async (req, res) => {
try {
const productsCount = await query('SELECT COUNT(*) FROM products');
const ordersCount = await query('SELECT COUNT(*) FROM orders');
const usersCount = await query('SELECT COUNT(*) FROM appusers');
const pagesCount = await query('SELECT COUNT(*) FROM pages');
const recentOrders = await query(
'SELECT id, ordernumber, totalamount, status, createdat FROM orders ORDER BY createdat DESC LIMIT 5'
);
res.render('admin/dashboard', {
title: 'Dashboard - SkyArtShop Admin',
user: req.session,
stats: {
products: productsCount.rows[0].count,
orders: ordersCount.rows[0].count,
users: usersCount.rows[0].count,
pages: pagesCount.rows[0].count
},
recentOrders: recentOrders.rows
});
} catch (error) {
console.error('Dashboard error:', error);
res.status(500).send('Server error');
}
});
router.get('/products', requireAuth, async (req, res) => {
try {
const result = await query(
'SELECT id, name, price, stockquantity, isactive, createdat FROM products ORDER BY createdat DESC'
);
res.render('admin/products', {
title: 'Products - SkyArtShop Admin',
user: req.session,
products: result.rows
});
} catch (error) {
console.error('Products error:', error);
res.status(500).send('Server error');
}
});
router.get('/orders', requireAuth, async (req, res) => {
try {
const result = await query(
'SELECT id, ordernumber, totalamount, status, createdat FROM orders ORDER BY createdat DESC'
);
res.render('admin/orders', {
title: 'Orders - SkyArtShop Admin',
user: req.session,
orders: result.rows
});
} catch (error) {
console.error('Orders error:', error);
res.status(500).send('Server error');
}
});
router.get('/users', requireAuth, async (req, res) => {
try {
const result = await query(
'SELECT id, email, name, role, createdat, lastlogin FROM adminusers ORDER BY createdat DESC'
);
res.render('admin/users', {
title: 'Admin Users - SkyArtShop Admin',
user: req.session,
users: result.rows
});
} catch (error) {
console.error('Users error:', error);
res.status(500).send('Server error');
}
});
module.exports = router;
EOF
# Create public routes
cat > routes/public.js << 'EOF'
const express = require('express');
const { query } = require('../config/database');
const router = express.Router();
router.get('/', async (req, res) => {
try {
const products = await query(
'SELECT id, name, description, price, imageurl FROM products WHERE isactive = true ORDER BY createdat DESC LIMIT 8'
);
const sections = await query(
'SELECT * FROM homepagesections ORDER BY displayorder ASC'
);
res.render('public/home', {
title: 'Welcome - SkyArtShop',
products: products.rows,
sections: sections.rows
});
} catch (error) {
console.error('Home page error:', error);
res.status(500).send('Server error');
}
});
router.get('/shop', async (req, res) => {
try {
const products = await query(
'SELECT id, name, description, price, imageurl, category FROM products WHERE isactive = true ORDER BY name ASC'
);
res.render('public/shop', {
title: 'Shop - SkyArtShop',
products: products.rows
});
} catch (error) {
console.error('Shop page error:', error);
res.status(500).send('Server error');
}
});
module.exports = router;
EOF
# Create main server.js
cat > server.js << 'EOF'
const express = require('express');
const session = require('express-session');
const pgSession = require('connect-pg-simple')(session);
const path = require('path');
const { pool } = require('./config/database');
require('dotenv').config();
const app = express();
const PORT = process.env.PORT || 3000;
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use('/assets', express.static(path.join(__dirname, '../wwwroot/assets')));
app.use('/uploads', express.static(path.join(__dirname, '../wwwroot/uploads')));
app.use(session({
store: new pgSession({
pool: pool,
tableName: 'session',
createTableIfMissing: true
}),
secret: process.env.SESSION_SECRET || 'skyart-shop-secret-2025',
resave: false,
saveUninitialized: false,
cookie: {
secure: false,
httpOnly: true,
maxAge: 24 * 60 * 60 * 1000
}
}));
app.use((req, res, next) => {
res.locals.session = req.session;
res.locals.currentPath = req.path;
next();
});
const authRoutes = require('./routes/auth');
const adminRoutes = require('./routes/admin');
const publicRoutes = require('./routes/public');
app.use('/admin', authRoutes);
app.use('/admin', adminRoutes);
app.use('/', publicRoutes);
app.get('/health', (req, res) => {
res.json({
status: 'ok',
timestamp: new Date().toISOString(),
database: 'connected'
});
});
app.use((req, res) => {
res.status(404).render('public/404', {
title: '404 - Page Not Found'
});
});
app.use((err, req, res, next) => {
console.error('Error:', err);
res.status(500).send('Server error');
});
app.listen(PORT, '0.0.0.0', () => {
console.log('========================================');
console.log(' SkyArtShop Backend Server');
console.log('========================================');
console.log(`🚀 Server running on http://localhost:${PORT}`);
console.log(`📦 Environment: ${process.env.NODE_ENV || 'development'}`);
console.log(`🗄️ Database: PostgreSQL (${process.env.DB_NAME})`);
console.log('========================================');
});
process.on('SIGTERM', () => {
console.log('SIGTERM received, closing server...');
pool.end(() => {
console.log('Database pool closed');
process.exit(0);
});
});
EOF
echo "✓ Server files created"

View File

@@ -0,0 +1,70 @@
const bcrypt = require("bcrypt");
const { query } = require("./config/database");
async function createTempAdmin() {
try {
// Temporary credentials
const email = "admin@skyartshop.com";
const password = "TempAdmin2024!";
const name = "Temporary Admin";
const role = "superadmin";
// Hash the password
const passwordHash = await bcrypt.hash(password, 10);
// Check if user already exists
const existing = await query("SELECT id FROM adminusers WHERE email = $1", [
email,
]);
if (existing.rows.length > 0) {
console.log("⚠️ Admin user already exists. Updating password...");
await query(
"UPDATE adminusers SET passwordhash = $1, name = $2, role = $3 WHERE email = $4",
[passwordHash, name, role, email]
);
console.log("✓ Password updated successfully!");
} else {
// Create the admin user
await query(
`INSERT INTO adminusers (email, name, passwordhash, role, createdat)
VALUES ($1, $2, $3, $4, NOW())`,
[email, name, passwordHash, role]
);
console.log("✓ Temporary admin user created successfully!");
}
console.log("\n========================================");
console.log("TEMPORARY ADMIN CREDENTIALS");
console.log("========================================");
console.log("Email: ", email);
console.log("Password: ", password);
console.log("========================================");
console.log("\n⚠ IMPORTANT: Change this password after first login!\n");
process.exit(0);
} catch (error) {
console.error("Error creating admin user:", error);
if (error.code === "42P01") {
console.error('\n❌ Table "adminusers" does not exist.');
console.error("Please create the database schema first.");
console.log("\nRun this SQL to create the table:");
console.log(`
CREATE TABLE IF NOT EXISTS adminusers (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
passwordhash TEXT NOT NULL,
role VARCHAR(50) DEFAULT 'admin',
createdat TIMESTAMP DEFAULT NOW(),
lastlogin TIMESTAMP
);
`);
}
process.exit(1);
}
}
createTempAdmin();

View File

@@ -0,0 +1,65 @@
#!/bin/bash
echo "Creating view files..."
# Admin login
cat > views/admin/login.ejs << 'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= title %></title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.2/font/bootstrap-icons.css">
</head>
<body class="bg-light">
<div class="container">
<div class="row justify-content-center align-items-center min-vh-100">
<div class="col-md-5">
<div class="card shadow-lg">
<div class="card-body p-5">
<div class="text-center mb-4">
<h2 class="fw-bold"><i class="bi bi-shop text-primary"></i> SkyArtShop</h2>
<p class="text-muted">Admin Login</p>
</div>
<% if (error === 'invalid') { %>
<div class="alert alert-danger"><i class="bi bi-exclamation-triangle"></i> Invalid email or password</div>
<% } else if (error === 'server') { %>
<div class="alert alert-danger"><i class="bi bi-exclamation-triangle"></i> Server error. Please try again.</div>
<% } %>
<form method="POST" action="/admin/login">
<div class="mb-3">
<label for="email" class="form-label">Email address</label>
<div class="input-group">
<span class="input-group-text"><i class="bi bi-envelope"></i></span>
<input type="email" class="form-control" id="email" name="email" required autofocus>
</div>
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<div class="input-group">
<span class="input-group-text"><i class="bi bi-lock"></i></span>
<input type="password" class="form-control" id="password" name="password" required>
</div>
</div>
<div class="d-grid">
<button type="submit" class="btn btn-primary btn-lg"><i class="bi bi-box-arrow-in-right"></i> Login</button>
</div>
</form>
<div class="text-center mt-4">
<small class="text-muted"><a href="/" class="text-decoration-none"><i class="bi bi-arrow-left"></i> Back to website</a></small>
</div>
</div>
</div>
<div class="text-center mt-3">
<small class="text-muted">Default: admin@example.com / password</small>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>
EOF
echo "✓ Views created"

View File

@@ -0,0 +1,97 @@
#!/bin/bash
echo "=========================================="
echo "🎉 FINAL SYSTEM TEST - SKYARTSHOP"
echo "=========================================="
echo ""
# Test 1: Backend Health
echo "1⃣ Backend Health Check:"
HEALTH=$(curl -s http://localhost:5000/health)
echo " $HEALTH"
echo ""
# Test 2: HTTPS Certificate
echo "2⃣ HTTPS Configuration:"
if ss -tln | grep -q ":443 "; then
echo " ✅ Port 443 listening"
else
echo " ❌ Port 443 not listening"
fi
echo ""
# Test 3: HTTP to HTTPS Redirect
echo "3⃣ HTTP → HTTPS Redirect:"
HTTP_TEST=$(curl -s -o /dev/null -w "%{http_code}" http://skyarts.ddns.net)
if [ "$HTTP_TEST" == "301" ]; then
echo " ✅ Redirecting correctly (HTTP 301)"
else
echo " ⚠️ HTTP Status: $HTTP_TEST"
fi
echo ""
# Test 4: Login Flow
echo "4⃣ Admin Login Test (HTTPS):"
rm -f /tmp/final-login-test.txt
LOGIN_RESPONSE=$(curl -k -s -c /tmp/final-login-test.txt -X POST https://skyarts.ddns.net/admin/login \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "email=admin@example.com&password=Admin123" \
-w "%{http_code}")
if echo "$LOGIN_RESPONSE" | grep -q "302"; then
echo " ✅ Login successful (302 redirect)"
else
echo " ❌ Login failed"
fi
echo ""
# Test 5: Dashboard Access
echo "5⃣ Dashboard Access:"
DASHBOARD=$(curl -k -s -b /tmp/final-login-test.txt https://skyarts.ddns.net/admin/dashboard | grep -o "<title>.*</title>")
if echo "$DASHBOARD" | grep -q "Dashboard"; then
echo " ✅ Dashboard accessible"
echo " $DASHBOARD"
else
echo " ❌ Dashboard not accessible"
fi
echo ""
# Test 6: Public Homepage
echo "6⃣ Public Homepage:"
HOMEPAGE=$(curl -k -s https://skyarts.ddns.net | grep -o "<title>.*</title>")
echo " $HOMEPAGE"
echo ""
echo "=========================================="
echo "✅ ALL SYSTEMS OPERATIONAL"
echo "=========================================="
echo ""
echo "🔐 LOGIN INFORMATION:"
echo " URL: https://skyarts.ddns.net/admin/login"
echo " Email: admin@example.com"
echo " Password: Admin123"
echo ""
echo "🌍 PUBLIC SITE:"
echo " URL: https://skyarts.ddns.net"
echo ""
echo "=========================================="
echo "📝 NOTES:"
echo "=========================================="
echo ""
echo "✓ Backend running on port 5000"
echo "✓ Nginx handling HTTPS on port 443"
echo "✓ SSL certificates valid"
echo "✓ Database connected"
echo "✓ Session management working"
echo "✓ HTTP redirects to HTTPS"
echo ""
echo "If you still see 'site can't be reached':"
echo "1. Clear your browser cache"
echo "2. Try incognito/private mode"
echo "3. Try from a different device/network"
echo "4. Check your local DNS cache:"
echo " - Windows: ipconfig /flushdns"
echo " - Mac: sudo dscacheutil -flushcache"
echo " - Linux: sudo systemd-resolve --flush-caches"
echo ""
echo "=========================================="

View File

@@ -0,0 +1,20 @@
const bcrypt = require("bcrypt");
async function generateHash() {
const password = "Admin123!";
const hash = await bcrypt.hash(password, 10);
console.log("Password:", password);
console.log("Hash:", hash);
console.log("\nSQL to insert user:");
console.log(
`INSERT INTO adminusers (email, name, passwordhash, role) VALUES ('admin@skyartshop.com', 'Admin User', '${hash}', 'superadmin') ON CONFLICT (email) DO UPDATE SET passwordhash = '${hash}';`
);
}
generateHash()
.then(() => process.exit(0))
.catch((err) => {
console.error(err);
process.exit(1);
});

View File

@@ -0,0 +1,16 @@
const bcrypt = require("bcrypt");
const password = process.argv[2] || "admin123";
bcrypt.hash(password, 10, (err, hash) => {
if (err) {
console.error("Error:", err);
return;
}
console.log("Password:", password);
console.log("Hash:", hash);
console.log("\nUse this SQL to update:");
console.log(
`UPDATE adminusers SET passwordhash = '${hash}' WHERE email = 'admin@example.com';`
);
});

View File

@@ -0,0 +1,69 @@
#!/bin/bash
echo "=========================================="
echo " SKYARTSHOP HTTPS CONFIGURATION STATUS"
echo "=========================================="
echo ""
echo "✅ Server Configuration:"
echo " - Backend: Running on port 5000"
echo " - Nginx HTTPS: Listening on port 443"
echo " - SSL Certificates: Valid"
echo ""
echo "✅ Local Testing (Working):"
echo " - http://localhost/admin/login ✓"
echo " - https://localhost/admin/login ✓"
echo ""
echo "🌐 Network Configuration:"
echo " - Server Private IP: $(hostname -I | awk '{print $1}')"
echo " - Public IP (DNS): $(nslookup skyarts.ddns.net 2>/dev/null | grep "Address:" | tail -1 | awk '{print $2}')"
echo " - Domain: skyarts.ddns.net"
echo ""
echo "🔥 Firewall Status:"
sudo ufw status | grep -E "443|Status"
echo ""
echo "🔌 Port Status:"
ss -tlnp 2>/dev/null | grep -E ":(80|443|5000)" | awk '{print " "$1" "$4}'
echo ""
echo "=========================================="
echo " ACTION REQUIRED"
echo "=========================================="
echo ""
echo "Your server is behind a router/NAT."
echo "To make https://skyarts.ddns.net accessible:"
echo ""
echo "1. LOG INTO YOUR ROUTER"
echo " IP: Check your router's IP (usually 192.168.10.1)"
echo ""
echo "2. SET UP PORT FORWARDING:"
echo " External Port: 443"
echo " Internal IP: 192.168.10.130"
echo " Internal Port: 443"
echo " Protocol: TCP"
echo ""
echo "3. ALSO FORWARD (if not already done):"
echo " External Port: 80"
echo " Internal IP: 192.168.10.130"
echo " Internal Port: 80"
echo " Protocol: TCP"
echo ""
echo "=========================================="
echo " TEST AFTER PORT FORWARDING"
echo "=========================================="
echo ""
echo "Once port forwarding is configured:"
echo ""
echo "1. From your browser:"
echo " https://skyarts.ddns.net"
echo " https://skyarts.ddns.net/admin/login"
echo ""
echo "2. Login credentials:"
echo " Email: admin@example.com"
echo " Password: Admin123"
echo ""
echo "=========================================="

View File

@@ -0,0 +1,32 @@
-- Quick setup script for SkyArtShop backend
-- Run with: psql -U skyartapp -d skyartshop -f quick-setup.sql
\echo 'Creating adminusers table...'
CREATE TABLE IF NOT EXISTS adminusers (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
passwordhash TEXT NOT NULL,
role VARCHAR(50) DEFAULT 'admin',
createdat TIMESTAMP DEFAULT NOW(),
lastlogin TIMESTAMP
);
\echo 'Creating temporary admin user...'
-- Email: admin@skyartshop.com
-- Password: Admin123!
DELETE FROM adminusers WHERE email = 'admin@skyartshop.com';
INSERT INTO adminusers (email, name, passwordhash, role) VALUES
('admin@skyartshop.com', 'Admin User', '$2b$10$vN9gE1VTxH3qH3qH3qH3qOqXZ5J8YqH3qH3qH3qH3qH3qH3qH3qH3u', 'superadmin');
\echo 'Verifying admin user...'
SELECT id, email, name, role, createdat FROM adminusers;
\echo ''
\echo '========================================='
\echo 'Setup Complete!'
\echo '========================================='
\echo 'Login credentials:'
\echo ' Email: admin@skyartshop.com'
\echo ' Password: Admin123!'
\echo '========================================='

View File

@@ -0,0 +1,48 @@
-- Create adminusers table if it doesn't exist
CREATE TABLE IF NOT EXISTS adminusers (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
passwordhash TEXT NOT NULL,
role VARCHAR(50) DEFAULT 'admin',
createdat TIMESTAMP DEFAULT NOW(),
lastlogin TIMESTAMP
);
-- Insert temporary admin user
-- Password: TempAdmin2024!
-- Bcrypt hash generated with 10 salt rounds
INSERT INTO adminusers (email, name, passwordhash, role, createdat)
VALUES (
'admin@skyartshop.com',
'Temporary Admin',
'$2b$10$YvK5rQE4nHjZH5tVFZ1lNu5iK7Jx/lMQXZvhGEg8sK1vF0N3wL5oG',
'superadmin',
NOW()
)
ON CONFLICT (email) DO UPDATE
SET passwordhash = EXCLUDED.passwordhash,
name = EXCLUDED.name,
role = EXCLUDED.role;
-- Create appusers table for public users (if needed)
CREATE TABLE IF NOT EXISTS appusers (
id SERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
name VARCHAR(255) NOT NULL,
passwordhash TEXT NOT NULL,
createdat TIMESTAMP DEFAULT NOW(),
lastlogin TIMESTAMP
);
-- Create sessions table for express-session
CREATE TABLE IF NOT EXISTS session (
sid VARCHAR NOT NULL COLLATE "default",
sess JSON NOT NULL,
expire TIMESTAMP(6) NOT NULL,
PRIMARY KEY (sid)
);
CREATE INDEX IF NOT EXISTS IDX_session_expire ON session (expire);
SELECT 'Database setup complete!' as status;

View File

@@ -0,0 +1,71 @@
#!/bin/bash
echo "Creating backend files..."
# Database config
cat > config/database.js << 'EOF'
const { Pool } = require('pg');
require('dotenv').config();
const pool = new Pool({
host: process.env.DB_HOST || 'localhost',
port: process.env.DB_PORT || 5432,
database: process.env.DB_NAME || 'skyartshop',
user: process.env.DB_USER || 'skyartapp',
password: process.env.DB_PASSWORD,
max: 20,
idleTimeoutMillis: 30000,
connectionTimeoutMillis: 2000,
});
pool.on('connect', () => console.log('✓ PostgreSQL connected'));
pool.on('error', (err) => console.error('PostgreSQL error:', err));
const query = async (text, params) => {
const start = Date.now();
try {
const res = await pool.query(text, params);
const duration = Date.now() - start;
console.log('Executed query', { text, duration, rows: res.rowCount });
return res;
} catch (error) {
console.error('Query error:', error);
throw error;
}
};
module.exports = { pool, query };
EOF
# Auth middleware
cat > middleware/auth.js << 'EOF'
const requireAuth = (req, res, next) => {
if (req.session && req.session.adminId) {
return next();
}
res.redirect('/admin/login');
};
const requireRole = (allowedRoles) => {
return (req, res, next) => {
if (!req.session || !req.session.adminId) {
return res.redirect('/admin/login');
}
const userRole = req.session.role || 'user';
if (allowedRoles.includes(userRole)) {
return next();
}
res.status(403).send('Access denied');
};
};
const redirectIfAuth = (req, res, next) => {
if (req.session && req.session.adminId) {
return res.redirect('/admin/dashboard');
}
next();
};
module.exports = { requireAuth, requireRole, redirectIfAuth };
EOF
echo "✓ Files created successfully"

View File

@@ -0,0 +1,46 @@
-- Create roles table
CREATE TABLE IF NOT EXISTS roles (
id VARCHAR(50) PRIMARY KEY,
name VARCHAR(100) NOT NULL UNIQUE,
description TEXT,
permissions JSONB DEFAULT '{}',
createdat TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Insert default roles
INSERT INTO roles (id, name, description, permissions) VALUES
('role-admin', 'Admin', 'Full system access and management', '{"manage_users": true, "manage_products": true, "manage_orders": true, "manage_content": true, "view_reports": true, "manage_settings": true}'),
('role-accountant', 'Accountant', 'Financial and reporting access', '{"view_orders": true, "view_reports": true, "manage_products": false, "manage_users": false}'),
('role-sales', 'Sales', 'Product and order management', '{"manage_products": true, "manage_orders": true, "view_reports": true, "manage_users": false}'),
('role-cashier', 'Cashier', 'Basic order processing', '{"process_orders": true, "view_products": true, "manage_products": false, "manage_users": false}')
ON CONFLICT (id) DO NOTHING;
-- Update adminusers table to add role and password expiry fields
ALTER TABLE adminusers
ADD COLUMN IF NOT EXISTS role_id VARCHAR(50) DEFAULT 'role-admin',
ADD COLUMN IF NOT EXISTS password_expires_at TIMESTAMP,
ADD COLUMN IF NOT EXISTS password_never_expires BOOLEAN DEFAULT false,
ADD COLUMN IF NOT EXISTS last_password_change TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN IF NOT EXISTS isactive BOOLEAN DEFAULT true,
ADD COLUMN IF NOT EXISTS last_login TIMESTAMP,
ADD COLUMN IF NOT EXISTS created_by VARCHAR(255),
ADD COLUMN IF NOT EXISTS updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
-- Add foreign key constraint
ALTER TABLE adminusers
ADD CONSTRAINT fk_role
FOREIGN KEY (role_id) REFERENCES roles(id)
ON DELETE SET NULL;
-- Update existing admin user
UPDATE adminusers
SET role_id = 'role-admin',
password_never_expires = true,
isactive = true
WHERE email = 'admin@example.com';
-- Create index for better performance
CREATE INDEX IF NOT EXISTS idx_adminusers_role ON adminusers(role_id);
CREATE INDEX IF NOT EXISTS idx_adminusers_email ON adminusers(email);
SELECT 'User roles setup complete' as status;

View File

@@ -0,0 +1,52 @@
const express = require("express");
const bcrypt = require("bcrypt");
const { query } = require("./config/database");
async function testLogin() {
const email = "admin@example.com";
const password = "Admin123";
try {
console.log("1. Querying database for user...");
const result = await query(
"SELECT id, email, name, passwordhash, role FROM adminusers WHERE email = $1",
[email]
);
if (result.rows.length === 0) {
console.log("❌ User not found");
return;
}
console.log("2. User found:", result.rows[0].email);
const admin = result.rows[0];
console.log("3. Comparing password...");
const validPassword = await bcrypt.compare(password, admin.passwordhash);
if (!validPassword) {
console.log("❌ Invalid password");
return;
}
console.log("4. ✓ Password valid!");
console.log("5. Updating last login...");
await query("UPDATE adminusers SET lastlogin = NOW() WHERE id = $1", [
admin.id,
]);
console.log("6. ✓ Login successful!");
console.log(" User ID:", admin.id);
console.log(" Email:", admin.email);
console.log(" Name:", admin.name);
console.log(" Role:", admin.role);
} catch (error) {
console.error("❌ Error during login:", error.message);
console.error(" Stack:", error.stack);
}
process.exit(0);
}
testLogin();