Changeset 4dff800 for server.js


Ignore:
Timestamp:
02/22/26 20:32:09 (7 months ago)
Author:
Klimentina Efremova <klimentina08642@…>
Branches:
finki-main, main
Children:
79fff4f
Parents:
591278c
Message:

Fixed admin logging in and force change password

File:
1 edited

Legend:

Unmodified
Added
Removed
  • server.js

    r591278c r4dff800  
    1010
    1111const port = process.env.PORT || 3000;
    12 
    1312const sessions = new Map();
    1413const verificationCodes = new Map();
    … …  
    3231        }
    3332    };
    34 
    3533    emailTransporter = nodemailer.createTransport(emailConfig);
    36 
    3734    emailTransporter.verify(function(error, success) {
    3835        if (error) {
    … …  
    7572        subject: 'Your Verification Code - Handcraft Marketplace',
    7673        html: `
    77       <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; background: linear-gradient(135deg, #4169E1 0%, #FF69B4 100%); color: white; padding: 20px; border-radius: 10px;">
    78         <h2 style="text-align: center;">🎨 Handcraft Marketplace</h2>
    79         <div style="background-color: white; color: #333; padding: 20px; border-radius: 8px; margin: 20px 0;">
    80           <h3 style="color: #4169E1;">Account Verification</h3>
    81           <p>Your verification code is:</p>
    82           <div style="background-color: #f5f5f5; padding: 15px; border-radius: 5px; text-align: center; font-size: 24px; font-weight: bold; letter-spacing: 5px; margin: 20px 0; color: #4169E1;">
    83             ${code}
    84           </div>
    85           <p style="color: #e74c3c; font-weight: bold;">⚠️ This code will expire in 30 seconds</p>
    86           <p style="color: #666; font-size: 12px;">If you didn't request this verification, please ignore this email.</p>
    87         </div>
    88       </div>`
     74        <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; background: linear-gradient(135deg, #4169E1 0%, #FF69B4 100%); color: white; padding: 20px; border-radius: 10px;">
     75            <h2 style="text-align: center;">🎨 Handcraft Marketplace</h2>
     76            <div style="background-color: white; color: #333; padding: 20px; border-radius: 8px; margin: 20px 0;">
     77                <h3 style="color: #4169E1;">Account Verification</h3>
     78                <p>Your verification code is:</p>
     79                <div style="background-color: #f5f5f5; padding: 15px; border-radius: 5px; text-align: center; font-size: 24px; font-weight: bold; letter-spacing: 5px; margin: 20px 0; color: #4169E1;">
     80                    ${code}
     81                </div>
     82                <p style="color: #e74c3c; font-weight: bold;">⚠️ This code will expire in 30 seconds</p>
     83                <p style="color: #666; font-size: 12px;">If you didn't request this verification, please ignore this email.</p>
     84            </div>
     85        </div>`
    8986    };
    9087
    … …  
    106103        subject: 'Your 2FA Code - Handcraft Marketplace',
    107104        html: `
    108       <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; background: linear-gradient(135deg, #4169E1 0%, #FF69B4 100%); color: white; padding: 20px; border-radius: 10px;">
    109         <h2 style="text-align: center;">🎨 Handcraft Marketplace</h2>
    110         <div style="background-color: white; color: #333; padding: 20px; border-radius: 8px; margin: 20px 0;">
    111           <h3 style="color: #4169E1;">Two-Factor Authentication</h3>
    112           <p>Your login verification code is:</p>
    113           <div style="background-color: #f5f5f5; padding: 15px; border-radius: 5px; text-align: center; font-size: 24px; font-weight: bold; letter-spacing: 5px; margin: 20px 0; color: #4169E1;">
    114             ${code}
    115           </div>
    116           <p style="color: #e74c3c; font-weight: bold;">⚠️ This code will expire in 30 seconds</p>
    117           <p style="color: #666; font-size: 12px;">If you're not trying to login, please secure your account immediately.</p>
    118         </div>
    119       </div>`
     105        <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; background: linear-gradient(135deg, #4169E1 0%, #FF69B4 100%); color: white; padding: 20px; border-radius: 10px;">
     106            <h2 style="text-align: center;">🎨 Handcraft Marketplace</h2>
     107            <div style="background-color: white; color: #333; padding: 20px; border-radius: 8px; margin: 20px 0;">
     108                <h3 style="color: #4169E1;">Two-Factor Authentication</h3>
     109                <p>Your login verification code is:</p>
     110                <div style="background-color: #f5f5f5; padding: 15px; border-radius: 5px; text-align: center; font-size: 24px; font-weight: bold; letter-spacing: 5px; margin: 20px 0; color: #4169E1;">
     111                    ${code}
     112                </div>
     113                <p style="color: #e74c3c; font-weight: bold;">⚠️ This code will expire in 30 seconds</p>
     114                <p style="color: #666; font-size: 12px;">If you're not trying to login, please secure your account immediately.</p>
     115            </div>
     116        </div>`
    120117    };
    121118
    … …  
    137134        subject: 'Store Registration Verification - Handcraft Marketplace',
    138135        html: `
    139       <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; background: linear-gradient(135deg, #4169E1 0%, #FF69B4 100%); color: white; padding: 20px; border-radius: 10px;">
    140         <h2 style="text-align: center;">🎨 Handcraft Marketplace</h2>
    141         <div style="background-color: white; color: #333; padding: 20px; border-radius: 8px; margin: 20px 0;">
    142           <h3 style="color: #4169E1;">Store Registration Verification</h3>
    143           <p>Thank you for registering your store "<strong>${storeName}</strong>" on Handcraft Marketplace!</p>
    144           <p>Your verification code is:</p>
    145           <div style="background-color: #f5f5f5; padding: 15px; border-radius: 5px; text-align: center; font-size: 24px; font-weight: bold; letter-spacing: 5px; margin: 20px 0; color: #4169E1;">
    146             ${code}
    147           </div>
    148           <p style="color: #e74c3c; font-weight: bold;">⚠️ This code will expire in 30 seconds</p>
    149           <p style="color: #666; font-size: 12px;">If you didn't request this verification, please ignore this email.</p>
    150         </div>
    151       </div>`
     136        <div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; background: linear-gradient(135deg, #4169E1 0%, #FF69B4 100%); color: white; padding: 20px; border-radius: 10px;">
     137            <h2 style="text-align: center;">🎨 Handcraft Marketplace</h2>
     138            <div style="background-color: white; color: #333; padding: 20px; border-radius: 8px; margin: 20px 0;">
     139                <h3 style="color: #4169E1;">Store Registration Verification</h3>
     140                <p>Thank you for registering your store "<strong>${storeName}</strong>" on Handcraft Marketplace!</p>
     141                <p>Your verification code is:</p>
     142                <div style="background-color: #f5f5f5; padding: 15px; border-radius: 5px; text-align: center; font-size: 24px; font-weight: bold; letter-spacing: 5px; margin: 20px 0; color: #4169E1;">
     143                    ${code}
     144                </div>
     145                <p style="color: #e74c3c; font-weight: bold;">⚠️ This code will expire in 30 seconds</p>
     146                <p style="color: #666; font-size: 12px;">If you didn't request this verification, please ignore this email.</p>
     147            </div>
     148        </div>`
    152149    };
    153150
    … …  
    302299        requireAuth(req, res, (userId) => {
    303300            const userIdStr = String(userId);
    304             const personalId = userIdStr.replace('personal_', '');
    305 
    306             database.database.get(
    307                 'SELECT boss_id FROM boss WHERE boss_id = $1',
    308                 [personalId],
    309                 (err, boss) => {
    310                     if (err || !boss) {
    311                         res.writeHead(403, { 'Content-Type': 'application/json' });
    312                         res.end(JSON.stringify({ success: false, message: 'Access denied - not a store owner' }));
    313                         return;
    314                     }
    315 
    316                     callback(personalId);
    317                 }
    318             );
     301
     302            // Check if this is the admin user (ID 000000)
     303            if (userIdStr === '000000') {
     304                // Admin is not a store owner
     305                res.writeHead(403, { 'Content-Type': 'application/json' });
     306                res.end(JSON.stringify({ success: false, message: 'Access denied - not a store owner' }));
     307                return;
     308            }
     309
     310            // Check if it's a personal user
     311            if (userIdStr.startsWith('personal_')) {
     312                const personalId = userIdStr.replace('personal_', '');
     313
     314                database.database.get(
     315                    'SELECT boss_id FROM boss WHERE boss_id = ?',
     316                    [personalId],
     317                    (err, boss) => {
     318                        if (err || !boss) {
     319                            res.writeHead(403, { 'Content-Type': 'application/json' });
     320                            res.end(JSON.stringify({ success: false, message: 'Access denied - not a store owner' }));
     321                            return;
     322                        }
     323
     324                        callback(personalId);
     325                    }
     326                );
     327            } else {
     328                // Not a personal user, so not a store owner
     329                res.writeHead(403, { 'Content-Type': 'application/json' });
     330                res.end(JSON.stringify({ success: false, message: 'Access denied - not a store owner' }));
     331            }
    319332        });
    320333    };
    … …  
    386399        } else {
    387400            console.log('✅ All required tables exist');
     401            // Even if tables exist, ensure admin user exists with ID 000000
     402            await ensureAdminUser();
    388403        }
    389404    } catch (err) {
    … …  
    401416        }
    402417    }
     418}
     419
     420// Function to ensure admin user exists with ID 000000
     421function ensureAdminUser() {
     422    return new Promise((resolve) => {
     423        database.database.get(
     424            'SELECT * FROM users WHERE id = ? OR username = ? OR email = ?',
     425            ['000000', 'admin', 'admin@handcraft.com'],
     426            (err, existingAdmin) => {
     427                if (err) {
     428                    console.error('Error checking for existing admin:', err.message);
     429                    resolve();
     430                    return;
     431                }
     432
     433                // Insert admin user if it doesn't exist
     434                if (!existingAdmin) {
     435                    const adminId = '000000';
     436                    const adminPassword = bcrypt.hashSync('Admin123!', 10);
     437
     438                    // Start a transaction
     439                    database.database.run('BEGIN TRANSACTION', (err) => {
     440                        if (err) {
     441                            console.error('Error beginning transaction:', err);
     442                            resolve();
     443                            return;
     444                        }
     445
     446                        // Insert into users table
     447                        database.database.run(
     448                            `INSERT INTO users (id, username, email, password, user_type, force_password_change)
     449                             VALUES (?, ?, ?, ?, ?, ?)`,
     450                            [adminId, 'admin', 'admin@handcraft.com', adminPassword, 'admin', 1],
     451                            function(err) {
     452                                if (err) {
     453                                    database.database.run('ROLLBACK');
     454                                    console.error('Error inserting admin user:', err.message);
     455                                    resolve();
     456                                    return;
     457                                }
     458
     459                                // Insert into personal table (required for boss table)
     460                                database.database.run(
     461                                    `INSERT INTO personal (id, first_name, last_name, ssn, email, password)
     462                                     VALUES (?, ?, ?, ?, ?, ?)`,
     463                                    [adminId, 'Admin', 'User', '0000000000000', 'admin@handcraft.com', adminPassword],
     464                                    function(err) {
     465                                        if (err) {
     466                                            database.database.run('ROLLBACK');
     467                                            console.error('Error inserting admin personal:', err.message);
     468                                            resolve();
     469                                            return;
     470                                        }
     471
     472                                        // Insert into boss table (store owner)
     473                                        database.database.run(
     474                                            `INSERT INTO boss (boss_id, signature)
     475                                             VALUES (?, ?)`,
     476                                            [adminId, 'Admin Signature'],
     477                                            function(err) {
     478                                                if (err) {
     479                                                    database.database.run('ROLLBACK');
     480                                                    console.error('Error inserting admin boss:', err.message);
     481                                                    resolve();
     482                                                    return;
     483                                                }
     484
     485                                                // Insert into permissions
     486                                                database.database.run(
     487                                                    `INSERT INTO permissions (personal_id, type, authorisation)
     488                                                     VALUES (?, ?, ?)`,
     489                                                    [adminId, 'ADMIN', 'full_access'],
     490                                                    function(err) {
     491                                                        if (err) {
     492                                                            console.error('Error inserting admin permissions:', err.message);
     493                                                            // Continue even if this fails
     494                                                        }
     495
     496                                                        // Assign admin role
     497                                                        database.database.get(
     498                                                            'SELECT role_id FROM roles WHERE name = ?',
     499                                                            ['admin'],
     500                                                            (err, adminRole) => {
     501                                                                if (!err && adminRole) {
     502                                                                    database.database.run(
     503                                                                        'INSERT OR IGNORE INTO user_roles (user_id, role_id) VALUES (?, ?)',
     504                                                                        [adminId, adminRole.role_id],
     505                                                                        (err) => {
     506                                                                            if (err) {
     507                                                                                console.error('Error assigning admin role:', err.message);
     508                                                                            }
     509                                                                        }
     510                                                                    );
     511                                                                }
     512
     513                                                                database.database.run('COMMIT', (commitErr) => {
     514                                                                    if (commitErr) {
     515                                                                        console.error('Error committing transaction:', commitErr);
     516                                                                        database.database.run('ROLLBACK');
     517                                                                    } else {
     518                                                                        console.log('\n');
     519                                                                        console.log('🔐 ===== ADMIN CREDENTIALS =====');
     520                                                                        console.log('🆔 ID: 000000');
     521                                                                        console.log('👤 Username: admin');
     522                                                                        console.log('📧 Email: admin@handcraft.com');
     523                                                                        console.log('🔑 Password: Admin123!');
     524                                                                        console.log('⚠️ This is a first-time login. You will be required to change your password after 2FA verification.');
     525                                                                        console.log('================================\n');
     526                                                                    }
     527                                                                    resolve();
     528                                                                });
     529                                                            }
     530                                                        );
     531                                                    }
     532                                                );
     533                                            }
     534                                        );
     535                                    }
     536                                );
     537                            }
     538                        );
     539                    });
     540                } else {
     541                    console.log('✅ Admin user already exists with ID:', existingAdmin.id);
     542                    resolve();
     543                }
     544            }
     545        );
     546    });
    403547}
    404548
    … …  
    463607            // Client table (SERIAL ID starting from 1000)
    464608            `CREATE TABLE IF NOT EXISTS client (
    465         client_id INTEGER PRIMARY KEY AUTOINCREMENT,
    466         first_name VARCHAR(100) NOT NULL,
    467         last_name VARCHAR(100) NOT NULL,
    468         email VARCHAR(255) UNIQUE NOT NULL,
    469         password VARCHAR(255) NOT NULL,
    470         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    471       )`,
     609                client_id INTEGER PRIMARY KEY AUTOINCREMENT,
     610                first_name VARCHAR(100) NOT NULL,
     611                last_name VARCHAR(100) NOT NULL,
     612                email VARCHAR(255) UNIQUE NOT NULL,
     613                password VARCHAR(255) NOT NULL,
     614                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     615            )`,
    472616
    473617            // Store table (VARCHAR ID)
    474618            `CREATE TABLE IF NOT EXISTS store (
    475         store_id VARCHAR(10) PRIMARY KEY,
    476         name VARCHAR(255) NOT NULL,
    477         date_of_founding DATE NOT NULL,
    478         physical_address TEXT NOT NULL,
    479         store_email VARCHAR(255) UNIQUE NOT NULL,
    480         rating DECIMAL(3,2) DEFAULT 0.0
    481       )`,
     619                store_id VARCHAR(10) PRIMARY KEY,
     620                name VARCHAR(255) NOT NULL,
     621                date_of_founding DATE NOT NULL,
     622                physical_address TEXT NOT NULL,
     623                store_email VARCHAR(255) UNIQUE NOT NULL,
     624                rating DECIMAL(3,2) DEFAULT 0.0
     625            )`,
    482626
    483627            // Category table (SERIAL ID starting from 1)
    484628            `CREATE TABLE IF NOT EXISTS category (
    485         category_id INTEGER PRIMARY KEY AUTOINCREMENT,
    486         name VARCHAR(100) NOT NULL,
    487         description TEXT,
    488         parent_category_id INTEGER REFERENCES category(category_id) ON DELETE SET NULL
    489       )`,
     629                category_id INTEGER PRIMARY KEY AUTOINCREMENT,
     630                name VARCHAR(100) NOT NULL,
     631                description TEXT,
     632                parent_category_id INTEGER REFERENCES category(category_id) ON DELETE SET NULL
     633            )`,
    490634
    491635            // Users table (VARCHAR ID)
    492636            `CREATE TABLE IF NOT EXISTS users (
    493         id VARCHAR(50) PRIMARY KEY,
    494         username VARCHAR(100) UNIQUE NOT NULL,
    495         email VARCHAR(255) UNIQUE NOT NULL,
    496         password VARCHAR(255) NOT NULL,
    497         user_type VARCHAR(50) NOT NULL,
    498         force_password_change INTEGER DEFAULT 0,
    499         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    500       )`,
     637                id VARCHAR(50) PRIMARY KEY,
     638                username VARCHAR(100) UNIQUE NOT NULL,
     639                email VARCHAR(255) UNIQUE NOT NULL,
     640                password VARCHAR(255) NOT NULL,
     641                user_type VARCHAR(50) NOT NULL,
     642                force_password_change INTEGER DEFAULT 0,
     643                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     644            )`,
    501645
    502646            // Personal table (VARCHAR ID - format: storeId(3) + '001' for owner, storeId(3) + employeeNum(3) for employees)
    503647            `CREATE TABLE IF NOT EXISTS personal (
    504         id VARCHAR(10) PRIMARY KEY,
    505         first_name VARCHAR(100) NOT NULL,
    506         last_name VARCHAR(100) NOT NULL,
    507         ssn VARCHAR(13) UNIQUE NOT NULL,
    508         email VARCHAR(255) UNIQUE NOT NULL,
    509         password VARCHAR(255) NOT NULL,
    510         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    511       )`,
     648                id VARCHAR(10) PRIMARY KEY,
     649                first_name VARCHAR(100) NOT NULL,
     650                last_name VARCHAR(100) NOT NULL,
     651                ssn VARCHAR(13) UNIQUE NOT NULL,
     652                email VARCHAR(255) UNIQUE NOT NULL,
     653                password VARCHAR(255) NOT NULL,
     654                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     655            )`,
    512656
    513657            // Product table (VARCHAR ID)
    514658            `CREATE TABLE IF NOT EXISTS product (
    515         id VARCHAR(50) PRIMARY KEY,
    516         code VARCHAR(20) UNIQUE NOT NULL,
    517         description TEXT NOT NULL,
    518         price DECIMAL(10,2) NOT NULL,
    519         availability INTEGER NOT NULL DEFAULT 0,
    520         weight DECIMAL(10,2),
    521         dimensions VARCHAR(50),
    522         production_time INTEGER,
    523         category_id INTEGER REFERENCES category(category_id) ON DELETE SET NULL,
    524         store_id VARCHAR(10) REFERENCES store(store_id) ON DELETE CASCADE,
    525         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    526       )`,
     659                id VARCHAR(50) PRIMARY KEY,
     660                code VARCHAR(20) UNIQUE NOT NULL,
     661                description TEXT NOT NULL,
     662                price DECIMAL(10,2) NOT NULL,
     663                availability INTEGER NOT NULL DEFAULT 0,
     664                weight DECIMAL(10,2),
     665                dimensions VARCHAR(50),
     666                production_time INTEGER,
     667                category_id INTEGER REFERENCES category(category_id) ON DELETE SET NULL,
     668                store_id VARCHAR(10) REFERENCES store(store_id) ON DELETE CASCADE,
     669                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     670            )`,
    527671
    528672            // Boss table (VARCHAR ID - references personal.id)
    529673            `CREATE TABLE IF NOT EXISTS boss (
    530         boss_id VARCHAR(10) PRIMARY KEY REFERENCES personal(id) ON DELETE CASCADE,
    531         signature TEXT NOT NULL,
    532         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    533       )`,
     674                boss_id VARCHAR(10) PRIMARY KEY REFERENCES personal(id) ON DELETE CASCADE,
     675                signature TEXT NOT NULL,
     676                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     677            )`,
    534678
    535679            // Employees table (VARCHAR ID - references personal.id)
    536680            `CREATE TABLE IF NOT EXISTS employees (
    537         employee_id VARCHAR(10) PRIMARY KEY REFERENCES personal(id) ON DELETE CASCADE,
    538         date_of_hire DATE NOT NULL,
    539         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    540       )`,
     681                employee_id VARCHAR(10) PRIMARY KEY REFERENCES personal(id) ON DELETE CASCADE,
     682                date_of_hire DATE NOT NULL,
     683                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     684            )`,
    541685
    542686            // Works_in_store table (junction)
    543687            `CREATE TABLE IF NOT EXISTS works_in_store (
    544         personal_id VARCHAR(10) REFERENCES personal(id) ON DELETE CASCADE,
    545         store_id VARCHAR(10) REFERENCES store(store_id) ON DELETE CASCADE,
    546         PRIMARY KEY (personal_id, store_id)
    547       )`,
     688                personal_id VARCHAR(10) REFERENCES personal(id) ON DELETE CASCADE,
     689                store_id VARCHAR(10) REFERENCES store(store_id) ON DELETE CASCADE,
     690                PRIMARY KEY (personal_id, store_id)
     691            )`,
    548692
    549693            // Permissions table
    550694            `CREATE TABLE IF NOT EXISTS permissions (
    551         permission_id INTEGER PRIMARY KEY AUTOINCREMENT,
    552         personal_id VARCHAR(10) REFERENCES personal(id) ON DELETE CASCADE,
    553         type VARCHAR(50) NOT NULL,
    554         authorisation TEXT,
    555         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    556       )`,
     695                permission_id INTEGER PRIMARY KEY AUTOINCREMENT,
     696                personal_id VARCHAR(10) REFERENCES personal(id) ON DELETE CASCADE,
     697                type VARCHAR(50) NOT NULL,
     698                authorisation TEXT,
     699                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     700            )`,
    557701
    558702            // Order table (VARCHAR ID)
    559703            `CREATE TABLE IF NOT EXISTS "order" (
    560         order_num VARCHAR(20) PRIMARY KEY,
    561         client_id INTEGER REFERENCES client(client_id) ON DELETE SET NULL,
    562         order_date TIMESTAMP NOT NULL,
    563         quantity INTEGER NOT NULL,
    564         payment_method VARCHAR(50) NOT NULL,
    565         discount DECIMAL(10,2) DEFAULT 0,
    566         delivery_address TEXT NOT NULL,
    567         store_id VARCHAR(10) REFERENCES store(store_id) ON DELETE SET NULL,
    568         status VARCHAR(50) DEFAULT 'pending',
    569         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    570       )`,
     704                order_num VARCHAR(20) PRIMARY KEY,
     705                client_id INTEGER REFERENCES client(client_id) ON DELETE SET NULL,
     706                order_date TIMESTAMP NOT NULL,
     707                quantity INTEGER NOT NULL,
     708                payment_method VARCHAR(50) NOT NULL,
     709                discount DECIMAL(10,2) DEFAULT 0,
     710                delivery_address TEXT NOT NULL,
     711                store_id VARCHAR(10) REFERENCES store(store_id) ON DELETE SET NULL,
     712                status VARCHAR(50) DEFAULT 'pending',
     713                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     714            )`,
    571715
    572716            // Order_items table
    573717            `CREATE TABLE IF NOT EXISTS order_items (
    574         item_id INTEGER PRIMARY KEY AUTOINCREMENT,
    575         order_num VARCHAR(20) REFERENCES "order"(order_num) ON DELETE CASCADE,
    576         product_code VARCHAR(20) REFERENCES product(code) ON DELETE SET NULL,
    577         quantity INTEGER NOT NULL,
    578         price DECIMAL(10,2) NOT NULL,
    579         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    580       )`,
     718                item_id INTEGER PRIMARY KEY AUTOINCREMENT,
     719                order_num VARCHAR(20) REFERENCES "order"(order_num) ON DELETE CASCADE,
     720                product_code VARCHAR(20) REFERENCES product(code) ON DELETE SET NULL,
     721                quantity INTEGER NOT NULL,
     722                price DECIMAL(10,2) NOT NULL,
     723                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     724            )`,
    581725
    582726            // Review table (VARCHAR ID)
    583727            `CREATE TABLE IF NOT EXISTS review (
    584         review_id VARCHAR(20) PRIMARY KEY,
    585         client_id INTEGER REFERENCES client(client_id) ON DELETE SET NULL,
    586         product_code VARCHAR(20) REFERENCES product(code) ON DELETE CASCADE,
    587         rating INTEGER NOT NULL CHECK (rating >= 1 AND rating <= 5),
    588         comment TEXT,
    589         review_date TIMESTAMP NOT NULL,
    590         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    591       )`,
     728                review_id VARCHAR(20) PRIMARY KEY,
     729                client_id INTEGER REFERENCES client(client_id) ON DELETE SET NULL,
     730                product_code VARCHAR(20) REFERENCES product(code) ON DELETE CASCADE,
     731                rating INTEGER NOT NULL CHECK (rating >= 1 AND rating <= 5),
     732                comment TEXT,
     733                review_date TIMESTAMP NOT NULL,
     734                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     735            )`,
    592736
    593737            // Request table (VARCHAR ID)
    594738            `CREATE TABLE IF NOT EXISTS request (
    595         request_num VARCHAR(50) PRIMARY KEY,
    596         date_and_time TIMESTAMP NOT NULL,
    597         problem TEXT NOT NULL,
    598         client_id INTEGER REFERENCES client(client_id) ON DELETE SET NULL,
    599         store_id VARCHAR(10) REFERENCES store(store_id) ON DELETE CASCADE,
    600         status VARCHAR(50) DEFAULT 'pending',
    601         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    602       )`,
     739                request_num VARCHAR(50) PRIMARY KEY,
     740                date_and_time TIMESTAMP NOT NULL,
     741                problem TEXT NOT NULL,
     742                client_id INTEGER REFERENCES client(client_id) ON DELETE SET NULL,
     743                store_id VARCHAR(10) REFERENCES store(store_id) ON DELETE CASCADE,
     744                status VARCHAR(50) DEFAULT 'pending',
     745                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     746            )`,
    603747
    604748            // Refund table (VARCHAR ID)
    605749            `CREATE TABLE IF NOT EXISTS refund (
    606         refund_id VARCHAR(50) PRIMARY KEY,
    607         order_num VARCHAR(20) REFERENCES "order"(order_num) ON DELETE CASCADE,
    608         amount DECIMAL(10,2) NOT NULL,
    609         reason TEXT NOT NULL,
    610         status VARCHAR(50) DEFAULT 'pending',
    611         request_date TIMESTAMP NOT NULL,
    612         processed_date TIMESTAMP,
    613         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    614       )`,
     750                refund_id VARCHAR(50) PRIMARY KEY,
     751                order_num VARCHAR(20) REFERENCES "order"(order_num) ON DELETE CASCADE,
     752                amount DECIMAL(10,2) NOT NULL,
     753                reason TEXT NOT NULL,
     754                status VARCHAR(50) DEFAULT 'pending',
     755                request_date TIMESTAMP NOT NULL,
     756                processed_date TIMESTAMP,
     757                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     758            )`,
    615759
    616760            // Report table (VARCHAR ID)
    617761            `CREATE TABLE IF NOT EXISTS report (
    618         id VARCHAR(50) PRIMARY KEY,
    619         store_id VARCHAR(10) REFERENCES store(store_id) ON DELETE CASCADE,
    620         period VARCHAR(50) NOT NULL,
    621         start_date DATE NOT NULL,
    622         end_date DATE NOT NULL,
    623         type VARCHAR(50) NOT NULL,
    624         generated_by VARCHAR(10) REFERENCES personal(id) ON DELETE SET NULL,
    625         generated_at TIMESTAMP NOT NULL,
    626         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    627       )`,
     762                id VARCHAR(50) PRIMARY KEY,
     763                store_id VARCHAR(10) REFERENCES store(store_id) ON DELETE CASCADE,
     764                period VARCHAR(50) NOT NULL,
     765                start_date DATE NOT NULL,
     766                end_date DATE NOT NULL,
     767                type VARCHAR(50) NOT NULL,
     768                generated_by VARCHAR(10) REFERENCES personal(id) ON DELETE SET NULL,
     769                generated_at TIMESTAMP NOT NULL,
     770                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     771            )`,
    628772
    629773            // Audit_log table (SERIAL ID)
    630774            `CREATE TABLE IF NOT EXISTS audit_log (
    631         log_id INTEGER PRIMARY KEY AUTOINCREMENT,
    632         user_id VARCHAR(50),
    633         action VARCHAR(100) NOT NULL,
    634         resource_type VARCHAR(50),
    635         resource_id VARCHAR(50),
    636         details TEXT,
    637         ip_address VARCHAR(45),
    638         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    639       )`,
     775                log_id INTEGER PRIMARY KEY AUTOINCREMENT,
     776                user_id VARCHAR(50),
     777                action VARCHAR(100) NOT NULL,
     778                resource_type VARCHAR(50),
     779                resource_id VARCHAR(50),
     780                details TEXT,
     781                ip_address VARCHAR(45),
     782                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     783            )`,
    640784
    641785            // Color table (SERIAL ID)
    642786            `CREATE TABLE IF NOT EXISTS color (
    643         color_id INTEGER PRIMARY KEY AUTOINCREMENT,
    644         name VARCHAR(50) NOT NULL,
    645         hex_code VARCHAR(7) NOT NULL,
    646         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    647       )`,
     787                color_id INTEGER PRIMARY KEY AUTOINCREMENT,
     788                name VARCHAR(50) NOT NULL,
     789                hex_code VARCHAR(7) NOT NULL,
     790                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     791            )`,
    648792
    649793            // Image table (SERIAL ID)
    650794            `CREATE TABLE IF NOT EXISTS image (
    651         image_id INTEGER PRIMARY KEY AUTOINCREMENT,
    652         product_code VARCHAR(20) REFERENCES product(code) ON DELETE CASCADE,
    653         image_url TEXT NOT NULL,
    654         is_primary BOOLEAN DEFAULT FALSE,
    655         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    656       )`,
     795                image_id INTEGER PRIMARY KEY AUTOINCREMENT,
     796                product_code VARCHAR(20) REFERENCES product(code) ON DELETE CASCADE,
     797                image_url TEXT NOT NULL,
     798                is_primary BOOLEAN DEFAULT FALSE,
     799                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     800            )`,
    657801
    658802            // Delivery_address table (SERIAL ID)
    659803            `CREATE TABLE IF NOT EXISTS delivery_address (
    660         address_id INTEGER PRIMARY KEY AUTOINCREMENT,
    661         client_id INTEGER REFERENCES client(client_id) ON DELETE CASCADE,
    662         address TEXT NOT NULL,
    663         city VARCHAR(100) NOT NULL,
    664         postcode VARCHAR(20) NOT NULL,
    665         country VARCHAR(100) NOT NULL,
    666         is_default BOOLEAN DEFAULT FALSE,
    667         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    668       )`,
     804                address_id INTEGER PRIMARY KEY AUTOINCREMENT,
     805                client_id INTEGER REFERENCES client(client_id) ON DELETE CASCADE,
     806                address TEXT NOT NULL,
     807                city VARCHAR(100) NOT NULL,
     808                postcode VARCHAR(20) NOT NULL,
     809                country VARCHAR(100) NOT NULL,
     810                is_default BOOLEAN DEFAULT FALSE,
     811                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     812            )`,
    669813
    670814            // Roles table (SERIAL ID)
    671815            `CREATE TABLE IF NOT EXISTS roles (
    672         role_id INTEGER PRIMARY KEY AUTOINCREMENT,
    673         name VARCHAR(50) UNIQUE NOT NULL,
    674         description TEXT,
    675         created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    676       )`,
     816                role_id INTEGER PRIMARY KEY AUTOINCREMENT,
     817                name VARCHAR(50) UNIQUE NOT NULL,
     818                description TEXT,
     819                created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
     820            )`,
    677821
    678822            // User_roles table (junction)
    679823            `CREATE TABLE IF NOT EXISTS user_roles (
    680         user_id VARCHAR(50) REFERENCES users(id) ON DELETE CASCADE,
    681         role_id INTEGER REFERENCES roles(role_id) ON DELETE CASCADE,
    682         PRIMARY KEY (user_id, role_id)
    683       )`
     824                user_id VARCHAR(50) REFERENCES users(id) ON DELETE CASCADE,
     825                role_id INTEGER REFERENCES roles(role_id) ON DELETE CASCADE,
     826                PRIMARY KEY (user_id, role_id)
     827            )`
    684828        ];
    685829
    … …  
    766910        console.log('📝 Inserting initial data...');
    767911
    768         // REMOVED: Category insertion - now handled by database.ensureGeneralCategory()
    769 
    770         // Insert admin user
    771         const adminId = 'admin_' + Date.now().toString().slice(-6);
    772         const adminPassword = bcrypt.hashSync('Admin123!', 10);
    773 
    774         database.database.run(
    775             `INSERT INTO users (id, username, email, password, user_type, force_password_change)
    776        VALUES ($1, $2, $3, $4, $5, $6)
    777        ON CONFLICT DO NOTHING`,
    778             [adminId, 'admin', 'admin@handcraft.com', adminPassword, 'admin', 1],
    779             (err) => {
    780                 if (err) {
    781                     console.error('Error inserting admin user:', err.message);
    782                 } else {
    783                     console.log('✅ Admin user created');
    784                 }
    785             }
    786         );
    787 
    788912        // Insert default roles
    789913        const roles = [
    … …  
    800924            database.database.run(
    801925                `INSERT INTO roles (name, description)
    802          VALUES ($1, $2)
    803          ON CONFLICT DO NOTHING`,
     926                 VALUES (?, ?)
     927                 ON CONFLICT DO NOTHING`,
    804928                [role.name, role.description],
    805929                (err) => {
    … …  
    810934                    if (rolesInserted === roles.length) {
    811935                        console.log('✅ Roles inserted');
     936
     937                        // Create admin user with ID 000000
     938                        createAdminUser();
    812939
    813940                        // Ensure General category exists
    … …  
    825952        });
    826953    });
     954}
     955
     956// Function to create admin user with ID 000000
     957function createAdminUser() {
     958    const adminId = '000000';
     959    const adminPassword = bcrypt.hashSync('Admin123!', 10);
     960
     961    database.database.get(
     962        'SELECT * FROM users WHERE id = ? OR username = ? OR email = ?',
     963        [adminId, 'admin', 'admin@handcraft.com'],
     964        (err, existingAdmin) => {
     965            if (err) {
     966                console.error('Error checking for existing admin:', err.message);
     967                return;
     968            }
     969
     970            if (!existingAdmin) {
     971                // Start a transaction
     972                database.database.run('BEGIN TRANSACTION', (err) => {
     973                    if (err) {
     974                        console.error('Error beginning transaction:', err);
     975                        return;
     976                    }
     977
     978                    // Insert into users table
     979                    database.database.run(
     980                        `INSERT INTO users (id, username, email, password, user_type, force_password_change)
     981                         VALUES (?, ?, ?, ?, ?, ?)`,
     982                        [adminId, 'admin', 'admin@handcraft.com', adminPassword, 'admin', 1],
     983                        function(err) {
     984                            if (err) {
     985                                database.database.run('ROLLBACK');
     986                                console.error('Error inserting admin user:', err.message);
     987                                return;
     988                            }
     989
     990                            // Insert into personal table (required for boss table)
     991                            database.database.run(
     992                                `INSERT INTO personal (id, first_name, last_name, ssn, email, password)
     993                                 VALUES (?, ?, ?, ?, ?, ?)`,
     994                                [adminId, 'Admin', 'User', '0000000000000', 'admin@handcraft.com', adminPassword],
     995                                function(err) {
     996                                    if (err) {
     997                                        database.database.run('ROLLBACK');
     998                                        console.error('Error inserting admin personal:', err.message);
     999                                        return;
     1000                                    }
     1001
     1002                                    // Insert into boss table (store owner)
     1003                                    database.database.run(
     1004                                        `INSERT INTO boss (boss_id, signature)
     1005                                         VALUES (?, ?)`,
     1006                                        [adminId, 'Admin Signature'],
     1007                                        function(err) {
     1008                                            if (err) {
     1009                                                database.database.run('ROLLBACK');
     1010                                                console.error('Error inserting admin boss:', err.message);
     1011                                                return;
     1012                                            }
     1013
     1014                                            // Insert into permissions
     1015                                            database.database.run(
     1016                                                `INSERT INTO permissions (personal_id, type, authorisation)
     1017                                                 VALUES (?, ?, ?)`,
     1018                                                [adminId, 'ADMIN', 'full_access'],
     1019                                                function(err) {
     1020                                                    if (err) {
     1021                                                        console.error('Error inserting admin permissions:', err.message);
     1022                                                        // Continue even if this fails
     1023                                                    }
     1024
     1025                                                    // Assign admin role
     1026                                                    database.database.get(
     1027                                                        'SELECT role_id FROM roles WHERE name = ?',
     1028                                                        ['admin'],
     1029                                                        (err, adminRole) => {
     1030                                                            if (!err && adminRole) {
     1031                                                                database.database.run(
     1032                                                                    'INSERT OR IGNORE INTO user_roles (user_id, role_id) VALUES (?, ?)',
     1033                                                                    [adminId, adminRole.role_id],
     1034                                                                    (err) => {
     1035                                                                        if (err) {
     1036                                                                            console.error('Error assigning admin role:', err.message);
     1037                                                                        }
     1038                                                                    }
     1039                                                                );
     1040                                                            }
     1041
     1042                                                            database.database.run('COMMIT', (commitErr) => {
     1043                                                                if (commitErr) {
     1044                                                                    console.error('Error committing transaction:', commitErr);
     1045                                                                    database.database.run('ROLLBACK');
     1046                                                                } else {
     1047                                                                    console.log('\n');
     1048                                                                    console.log('🔐 ===== ADMIN CREDENTIALS =====');
     1049                                                                    console.log('🆔 ID: 000000');
     1050                                                                    console.log('👤 Username: admin');
     1051                                                                    console.log('📧 Email: admin@handcraft.com');
     1052                                                                    console.log('🔑 Password: Admin123!');
     1053                                                                    console.log('⚠️ This is a first-time login. You will be required to change your password after 2FA verification.');
     1054                                                                    console.log('================================\n');
     1055                                                                }
     1056                                                            });
     1057                                                        }
     1058                                                    );
     1059                                                }
     1060                                            );
     1061                                        }
     1062                                    );
     1063                                }
     1064                            );
     1065                        }
     1066                    );
     1067                });
     1068            } else {
     1069                console.log('✅ Admin user already exists with ID:', existingAdmin.id);
     1070            }
     1071        }
     1072    );
    8271073}
    8281074
    … …  
    8841130        serveStaticFile(res, 'verify-2fa.html', 'text/html');
    8851131    } else if (pathname === '/admin.html') {
     1132        // Check if user is authenticated
     1133        const cookies = parseCookies(req);
     1134        const sessionId = cookies.sessionId;
     1135
     1136        if (!sessionId || !sessions.has(sessionId)) {
     1137            res.writeHead(302, { 'Location': '/login.html' });
     1138            res.end();
     1139            return;
     1140        }
     1141
     1142        // Get user from session
     1143        const userId = sessions.get(sessionId);
     1144
     1145        // Check if this is the admin user
     1146        if (userId !== '000000') {
     1147            // Not admin, redirect to appropriate dashboard
     1148            if (userId.startsWith('client_')) {
     1149                res.writeHead(302, { 'Location': '/client-dashboard.html' });
     1150            } else if (userId.startsWith('personal_')) {
     1151                // Check if store owner or employee
     1152                const personalId = userId.replace('personal_', '');
     1153                database.database.get(
     1154                    'SELECT boss_id FROM boss WHERE boss_id = ?',
     1155                    [personalId],
     1156                    (err, boss) => {
     1157                        if (boss) {
     1158                            res.writeHead(302, { 'Location': '/store-owner.html' });
     1159                        } else {
     1160                            res.writeHead(302, { 'Location': '/store-employee.html' });
     1161                        }
     1162                        res.end();
     1163                    }
     1164                );
     1165                return;
     1166            } else {
     1167                res.writeHead(302, { 'Location': '/dashboard.html' });
     1168            }
     1169            res.end();
     1170            return;
     1171        }
     1172
    8861173        serveStaticFile(res, 'admin.html', 'text/html');
    8871174    } else if (pathname === '/store-owner.html') {
    … …  
    10891376
    10901377                database.database.get(
    1091                     'SELECT store_id FROM store WHERE store_email = $1',
     1378                    'SELECT store_id FROM store WHERE store_email = ?',
    10921379                    [formData.storeEmail],
    10931380                    (err, existingStore) => {
    … …  
    14731760                    // Insert into store table (store_id is VARCHAR)
    14741761                    database.database.run(
    1475                         'INSERT INTO store (store_id, name, date_of_founding, physical_address, store_email, rating) VALUES ($1, $2, $3, $4, $5, $6)',
     1762                        'INSERT INTO store (store_id, name, date_of_founding, physical_address, store_email, rating) VALUES (?, ?, ?, ?, ?, ?)',
    14761763                        [
    14771764                            tempStoreData.storeId,
    … …  
    14931780                            // Insert into personal table (id is VARCHAR)
    14941781                            database.database.run(
    1495                                 'INSERT INTO personal (id, first_name, last_name, ssn, email, password) VALUES ($1, $2, $3, $4, $5, $6)',
     1782                                'INSERT INTO personal (id, first_name, last_name, ssn, email, password) VALUES (?, ?, ?, ?, ?, ?)',
    14961783                                [
    14971784                                    tempStoreData.personalId,
    … …  
    15211808                                    // Insert into boss table (boss_id is VARCHAR, references personal.id)
    15221809                                    database.database.run(
    1523                                         'INSERT INTO boss (boss_id, signature) VALUES ($1, $2)',
     1810                                        'INSERT INTO boss (boss_id, signature) VALUES (?, ?)',
    15241811                                        [tempStoreData.personalId, tempStoreData.signature],
    15251812                                        (err) => {
    … …  
    15341821                                            // Insert into works_in_store table (personal_id is VARCHAR, store_id is VARCHAR)
    15351822                                            database.database.run(
    1536                                                 'INSERT INTO works_in_store (personal_id, store_id) VALUES ($1, $2)',
     1823                                                'INSERT INTO works_in_store (personal_id, store_id) VALUES (?, ?)',
    15371824                                                [tempStoreData.personalId, tempStoreData.storeId],
    15381825                                                (err) => {
    … …  
    15471834                                                    // Insert into permissions table (personal_id is VARCHAR)
    15481835                                                    database.database.run(
    1549                                                         'INSERT INTO permissions (personal_id, type, authorisation) VALUES ($1, $2, $3)',
     1836                                                        'INSERT INTO permissions (personal_id, type, authorisation) VALUES (?, ?, ?)',
    15501837                                                        [tempStoreData.personalId, 'BOSS', 'full_access'],
    15511838                                                        (err) => {
    … …  
    16311918                        if (tempUserData.address && tempUserData.city && tempUserData.postcode && tempUserData.country) {
    16321919                            database.database.run(
    1633                                 'INSERT INTO delivery_address (client_id, address, city, postcode, country, is_default) VALUES ($1, $2, $3, $4, $5, $6)',
     1920                                'INSERT INTO delivery_address (client_id, address, city, postcode, country, is_default) VALUES (?, ?, ?, ?, ?, ?)',
    16341921                                [
    16351922                                    clientId,
    … …  
    16651952            } else {
    16661953                const userId = 'user_' + Date.now().toString().slice(-8);
    1667 
    16681954                database.createUser(userId, tempUserData.username, tempUserData.email, tempUserData.password, tempUserData.userType, (err, userId) => {
    16691955                    if (err) {
    … …  
    17011987
    17021988            console.log(`🔍 Login attempt for email: ${email}`);
     1989
     1990            // First check if it's the admin user (special case)
     1991            if (email === 'admin@handcraft.com') {
     1992                database.getUserByUsername('admin', (err, adminUser) => {
     1993                    if (err || !adminUser) {
     1994                        console.error('Admin user not found');
     1995                        database.logAudit(null, 'LOGIN_FAILED', 'auth', null, `Admin login failed - user not found`, ipAddress);
     1996                        res.writeHead(401, { 'Content-Type': 'application/json' });
     1997                        res.end(JSON.stringify({ success: false, message: 'Invalid email or password' }));
     1998                        return;
     1999                    }
     2000
     2001                    if (database.verifyPassword(password, adminUser.password)) {
     2002                        const isFirstTimeLogin = adminUser.force_password_change === 1;
     2003
     2004                        const twoFACode = generateVerificationCode();
     2005
     2006                        verificationCodes.set(adminUser.email, {
     2007                            code: twoFACode,
     2008                            timestamp: Date.now(),
     2009                            userId: adminUser.id,
     2010                            isFirstTimeLogin: isFirstTimeLogin,
     2011                            userType: 'admin',
     2012                            needsPasswordChange: isFirstTimeLogin
     2013                        });
     2014
     2015                        console.log(`⏰ Generated 2FA code for admin ${adminUser.email}`);
     2016
     2017                        send2FACode(adminUser.email, twoFACode)
     2018                            .then(() => {
     2019                                res.writeHead(200, { 'Content-Type': 'application/json' });
     2020                                res.end(JSON.stringify({
     2021                                    success: true,
     2022                                    message: 'Two-factor authentication code sent to your email',
     2023                                    requires2FA: true,
     2024                                    email: adminUser.email,
     2025                                    username: adminUser.username,
     2026                                    isFirstTimeLogin: isFirstTimeLogin,
     2027                                    userType: 'admin'
     2028                                }));
     2029                            })
     2030                            .catch(error => {
     2031                                console.error('Error sending 2FA email:', error);
     2032                                res.writeHead(200, { 'Content-Type': 'application/json' });
     2033                                res.end(JSON.stringify({
     2034                                    success: true,
     2035                                    message: 'Two-factor authentication required',
     2036                                    requires2FA: true,
     2037                                    email: adminUser.email,
     2038                                    username: adminUser.username,
     2039                                    isFirstTimeLogin: isFirstTimeLogin,
     2040                                    userType: 'admin',
     2041                                    developmentCode: twoFACode
     2042                                }));
     2043                            });
     2044                    } else {
     2045                        database.logAudit(adminUser.id, 'LOGIN_FAILED', 'auth', adminUser.id.toString(), 'Invalid password for admin', ipAddress);
     2046                        res.writeHead(401, { 'Content-Type': 'application/json' });
     2047                        res.end(JSON.stringify({ success: false, message: 'Invalid email or password' }));
     2048                    }
     2049                });
     2050                return;
     2051            }
    17032052
    17042053            // First check if it's a client
    … …  
    17332082                        const sessionId = generateSessionId();
    17342083                        const clientId = client.client_ID;
    1735 
    17362084                        sessions.set(sessionId, `client_${clientId}`);
    17372085
    … …  
    17592107                        }));
    17602108                    });
     2109
    17612110                    return;
    17622111                }
    … …  
    18452194                                            }
    18462195                                        );
     2196
    18472197                                        return;
    18482198                                    }
    … …  
    19052255                                                    }
    19062256                                                );
     2257
    19072258                                                return;
    19082259                                            }
    … …  
    19242275
    19252276                                                            if (database.verifyPassword(password, userByUsername.password)) {
    1926                                                                 const isAdminUser = userByUsername.username === 'admin';
    1927                                                                 const isFirstTimeLogin = isAdminUser && userByUsername.force_password_change === 1;
     2277                                                                const isFirstTimeLogin = userByUsername.force_password_change === 1;
    19282278
    19292279                                                                const twoFACode = generateVerificationCode();
    … …  
    19342284                                                                    userId: userByUsername.id,
    19352285                                                                    isFirstTimeLogin: isFirstTimeLogin,
    1936                                                                     userType: isAdminUser ? 'admin' : userByUsername.user_type,
     2286                                                                    userType: userByUsername.user_type,
    19372287                                                                    needsPasswordChange: isFirstTimeLogin
    19382288                                                                });
    … …  
    19482298                                                                            username: userByUsername.username,
    19492299                                                                            isFirstTimeLogin: isFirstTimeLogin,
    1950                                                                             userType: isAdminUser ? 'admin' : userByUsername.user_type
     2300                                                                            userType: userByUsername.user_type
    19512301                                                                        }));
    19522302                                                                    })
    … …  
    19612311                                                                            username: userByUsername.username,
    19622312                                                                            isFirstTimeLogin: isFirstTimeLogin,
    1963                                                                             userType: isAdminUser ? 'admin' : userByUsername.user_type,
     2313                                                                            userType: userByUsername.user_type,
    19642314                                                                            developmentCode: twoFACode
    19652315                                                                        }));
    … …  
    19712321                                                            }
    19722322                                                        });
     2323
    19732324                                                        return;
    19742325                                                    }
    19752326
    19762327                                                    if (database.verifyPassword(password, user.password)) {
    1977                                                         const isAdminUser = user.username === 'admin';
    1978                                                         const isFirstTimeLogin = isAdminUser && user.force_password_change === 1;
     2328                                                        const isFirstTimeLogin = user.force_password_change === 1;
    19792329
    19802330                                                        const twoFACode = generateVerificationCode();
    … …  
    19852335                                                            userId: user.id,
    19862336                                                            isFirstTimeLogin: isFirstTimeLogin,
    1987                                                             userType: isAdminUser ? 'admin' : user.user_type,
     2337                                                            userType: user.user_type,
    19882338                                                            needsPasswordChange: isFirstTimeLogin
    19892339                                                        });
    … …  
    19992349                                                                    username: user.username,
    20002350                                                                    isFirstTimeLogin: isFirstTimeLogin,
    2001                                                                     userType: isAdminUser ? 'admin' : user.user_type
     2351                                                                    userType: user.user_type
    20022352                                                                }));
    20032353                                                            })
    … …  
    20122362                                                                    username: user.username,
    20132363                                                                    isFirstTimeLogin: isFirstTimeLogin,
    2014                                                                     userType: isAdminUser ? 'admin' : user.user_type,
     2364                                                                    userType: user.user_type,
    20152365                                                                    developmentCode: twoFACode
    20162366                                                                }));
    … …  
    20282378                            );
    20292379                        });
     2380
    20302381                        return;
    20312382                    }
    … …  
    20562407
    20572408            database.database.get(
    2058                 'SELECT * FROM users WHERE email = $1',
     2409                'SELECT * FROM users WHERE email = ?',
    20592410                [email],
    20602411                (err, user) => {
    … …  
    20732424                                timestamp: Date.now(),
    20742425                                userId: userByUsername.id,
    2075                                 isAdmin: userByUsername.username === 'admin' && userByUsername.force_password_change === 1,
    2076                                 needsPasswordChange: userByUsername.username === 'admin' && userByUsername.force_password_change === 1,
     2426                                isFirstTimeLogin: userByUsername.force_password_change === 1,
     2427                                needsPasswordChange: userByUsername.force_password_change === 1,
    20772428                                userType: userByUsername.user_type
    20782429                            });
    … …  
    21002451                                });
    21012452                        });
     2453
    21022454                        return;
    21032455                    }
    … …  
    21092461                        timestamp: Date.now(),
    21102462                        userId: user.id,
    2111                         isAdmin: user.username === 'admin' && user.force_password_change === 1,
    2112                         needsPasswordChange: user.username === 'admin' && user.force_password_change === 1,
     2463                        isFirstTimeLogin: user.force_password_change === 1,
     2464                        needsPasswordChange: user.force_password_change === 1,
    21132465                        userType: user.user_type
    21142466                    });
    … …  
    21912543                    redirectTo: 'change-password.html?forced=true'
    21922544                }));
     2545
    21932546                return;
    21942547            }
    … …  
    22722625
    22732626            if (tempAdminSessions.has(sessionId)) {
    2274                 res.writeHead(200, { 'Content-Type': 'application/json' });
    2275                 res.end(JSON.stringify({
    2276                     success: true,
    2277                     user: {
    2278                         id: userId,
    2279                         username: 'admin',
    2280                         needsPasswordChange: true
    2281                     },
    2282                     isTempSession: true
    2283                 }));
    2284                 return;
    2285             }
    2286 
     2627                // This is a temporary session (password change required)
     2628                // Get user info to determine type
     2629                database.getUserById(userId, (err, user) => {
     2630                    if (err || !user) {
     2631                        // Check if it's a personal user
     2632                        database.getPersonalById(userId, (err, personal) => {
     2633                            if (err || !personal) {
     2634                                res.writeHead(200, { 'Content-Type': 'application/json' });
     2635                                res.end(JSON.stringify({
     2636                                    success: true,
     2637                                    user: {
     2638                                        id: userId,
     2639                                        username: 'admin',
     2640                                        userType: 'admin',
     2641                                        needsPasswordChange: true
     2642                                    },
     2643                                    isTempSession: true
     2644                                }));
     2645                            } else {
     2646                                // Personal user (store owner/employee)
     2647                                database.database.get(
     2648                                    'SELECT boss_id FROM boss WHERE boss_id = ?',
     2649                                    [userId],
     2650                                    (err, boss) => {
     2651                                        let userType = 'store_employee';
     2652                                        if (boss) {
     2653                                            userType = 'store_owner';
     2654                                        }
     2655
     2656                                        res.writeHead(200, { 'Content-Type': 'application/json' });
     2657                                        res.end(JSON.stringify({
     2658                                            success: true,
     2659                                            user: {
     2660                                                id: personal.id,
     2661                                                firstName: personal.first_name,
     2662                                                lastName: personal.last_name,
     2663                                                email: personal.email,
     2664                                                userType: userType,
     2665                                                needsPasswordChange: true
     2666                                            },
     2667                                            isTempSession: true
     2668                                        }));
     2669                                    }
     2670                                );
     2671                            }
     2672                        });
     2673                    } else {
     2674                        // Regular user (admin)
     2675                        res.writeHead(200, { 'Content-Type': 'application/json' });
     2676                        res.end(JSON.stringify({
     2677                            success: true,
     2678                            user: {
     2679                                id: user.id,
     2680                                username: user.username,
     2681                                email: user.email,
     2682                                userType: user.user_type || 'admin',
     2683                                needsPasswordChange: true
     2684                            },
     2685                            isTempSession: true
     2686                        }));
     2687                    }
     2688                });
     2689
     2690                return;
     2691            }
     2692
     2693            // Regular session
    22872694            const userIdStr = String(userId);
    22882695
    2289             if (userIdStr.startsWith('client_')) {
     2696            if (userIdStr === '000000') {
     2697                // Admin user
     2698                database.getUserById(userIdStr, (err, user) => {
     2699                    if (err || !user) {
     2700                        res.writeHead(404, { 'Content-Type': 'application/json' });
     2701                        res.end(JSON.stringify({ success: false, message: 'User not found' }));
     2702                    } else {
     2703                        res.writeHead(200, { 'Content-Type': 'application/json' });
     2704                        res.end(JSON.stringify({
     2705                            success: true,
     2706                            user: {
     2707                                id: user.id,
     2708                                username: user.username,
     2709                                email: user.email,
     2710                                userType: 'admin'
     2711                            }
     2712                        }));
     2713                    }
     2714                });
     2715            }
     2716            else if (userIdStr.startsWith('client_')) {
    22902717                const clientId = parseInt(userIdStr.replace('client_', ''));
    22912718
    … …  
    23212748
    23222749                    database.database.get(
    2323                         'SELECT boss_id FROM boss WHERE boss_id = $1',
     2750                        'SELECT boss_id FROM boss WHERE boss_id = ?',
    23242751                        [personalId],
    23252752                        (err, boss) => {
    … …  
    23312758                                database.database.all(
    23322759                                    `SELECT s.* FROM store s
    2333                    JOIN works_in_store w ON s.store_id = w.store_id
    2334                    WHERE w.personal_id = $1`,
     2760                                     JOIN works_in_store w ON s.store_id = w.store_id
     2761                                     WHERE w.personal_id = ?`,
    23352762                                    [personalId],
    23362763                                    (err, stores) => {
    … …  
    23562783                            } else {
    23572784                                database.database.get(
    2358                                     'SELECT employee_id FROM employees WHERE employee_id = $1',
     2785                                    'SELECT employee_id FROM employees WHERE employee_id = ?',
    23592786                                    [personalId],
    23602787                                    (err, employee) => {
    … …  
    23662793                                            database.database.all(
    23672794                                                `SELECT s.* FROM store s
    2368                          JOIN works_in_store w ON s.store_id = w.store_id
    2369                          WHERE w.personal_id = $1`,
     2795                                                 JOIN works_in_store w ON s.store_id = w.store_id
     2796                                                 WHERE w.personal_id = ?`,
    23702797                                                [personalId],
    23712798                                                (err, stores) => {
    … …  
    25592986
    25602987                    database.database.get(
    2561                         'SELECT COUNT(*) as order_count FROM "order" WHERE store_id = $1 AND EXTRACT(YEAR FROM order_date) = $2',
    2562                         [storeId, new Date().getFullYear()],
     2988                        'SELECT COUNT(*) as order_count FROM "order" WHERE store_id = ? AND strftime("%Y", order_date) = ?',
     2989                        [storeId, new Date().getFullYear().toString()],
    25632990                        (err, result) => {
    25642991                            if (err) {
    … …  
    25692996                            }
    25702997
    2571                             const orderCount = result && result[0] ? parseInt(result[0].order_count) + 1 : 1;
     2998                            const orderCount = result ? result.order_count + 1 : 1;
    25722999                            const orderNumPadded = orderCount.toString().padStart(5, '0');
    25733000
    … …  
    26933120
    26943121                    database.database.get(
    2695                         'SELECT COUNT(*) as request_count FROM request WHERE store_id = $1 AND EXTRACT(YEAR FROM date_and_time) = $2 AND EXTRACT(MONTH FROM date_and_time) = $3',
    2696                         [storeId, now.getFullYear(), now.getMonth() + 1],
     3122                        'SELECT COUNT(*) as request_count FROM request WHERE store_id = ? AND strftime("%Y", date_and_time) = ? AND strftime("%m", date_and_time) = ?',
     3123                        [storeId, now.getFullYear().toString(), (now.getMonth() + 1).toString().padStart(2, '0')],
    26973124                        (err, result) => {
    26983125                            if (err) {
    … …  
    27033130                            }
    27043131
    2705                             const requestCount = result && result[0] ? parseInt(result[0].request_count) + 1 : 1;
     3132                            const requestCount = result ? result.request_count + 1 : 1;
    27063133                            const requestSeqPadded = requestCount.toString().padStart(2, '0');
    27073134
    … …  
    27523179
    27533180                    database.database.get(
    2754                         'SELECT store_id FROM "order" WHERE order_num = $1',
     3181                        'SELECT store_id FROM "order" WHERE order_num = ?',
    27553182                        [refundData.order_num],
    27563183                        (err, result) => {
    2757                             if (err || !result || result.length === 0) {
     3184                            if (err || !result) {
    27583185                                res.writeHead(404, { 'Content-Type': 'application/json' });
    27593186                                res.end(JSON.stringify({ success: false, message: 'Order not found' }));
    … …  
    27613188                            }
    27623189
    2763                             const storeId = result[0].store_id;
     3190                            const storeId = result.store_id;
    27643191                            const now = new Date();
    27653192                            const month = (now.getMonth() + 1).toString().padStart(2, '0');
    … …  
    27673194
    27683195                            database.database.get(
    2769                                 'SELECT COUNT(*) as refund_count FROM refund WHERE EXTRACT(YEAR FROM request_date) = $1 AND EXTRACT(MONTH FROM request_date) = $2',
    2770                                 [now.getFullYear(), now.getMonth() + 1],
     3196                                'SELECT COUNT(*) as refund_count FROM refund WHERE strftime("%Y", request_date) = ? AND strftime("%m", request_date) = ?',
     3197                                [now.getFullYear().toString(), (now.getMonth() + 1).toString().padStart(2, '0')],
    27713198                                (err, result) => {
    27723199                                    if (err) {
    … …  
    27773204                                    }
    27783205
    2779                                     const refundCount = result && result[0] ? parseInt(result[0].refund_count) + 1 : 1;
     3206                                    const refundCount = result ? result.refund_count + 1 : 1;
    27803207                                    const refundSeqPadded = refundCount.toString().padStart(2, '0');
    27813208
    … …  
    28183245
    28193246                database.database.get(
    2820                     'SELECT store_id FROM works_in_store WHERE personal_id = $1',
     3247                    'SELECT store_id FROM works_in_store WHERE personal_id = ?',
    28213248                    [personalId],
    28223249                    (err, bossStore) => {
    … …  
    28363263
    28373264                        database.database.get(
    2838                             'SELECT store_id FROM works_in_store WHERE personal_id = $1 AND store_id = $2',
     3265                            'SELECT store_id FROM works_in_store WHERE personal_id = ? AND store_id = ?',
    28393266                            [personalId, storeId],
    28403267                            (err, ownsStore) => {
    … …  
    28473274                                // FIXED: Changed SQL syntax from SUBSTRING(code FROM 4) to SUBSTR(code, 4) for SQLite compatibility
    28483275                                database.database.get(
    2849                                     'SELECT MAX(CAST(SUBSTR(code, 4) AS INTEGER)) as max_product_num FROM product WHERE store_id = $1',
     3276                                    'SELECT MAX(CAST(SUBSTR(code, 4) AS INTEGER)) as max_product_num FROM product WHERE store_id = ?',
    28503277                                    [storeId],
    28513278                                    (err, result) => {
    … …  
    28813308                                            } else {
    28823309                                                database.logAudit(personalId, 'PRODUCT_ADDED', 'product', productId.toString(), 'New product added', ipAddress);
    2883 
    28843310                                                res.writeHead(200, { 'Content-Type': 'application/json' });
    28853311                                                res.end(JSON.stringify({
    … …  
    29183344
    29193345                database.database.get(
    2920                     'SELECT store_id FROM product WHERE code = $1',
     3346                    'SELECT store_id FROM product WHERE code = ?',
    29213347                    [productData.code],
    29223348                    (err, product) => {
    … …  
    29283354
    29293355                        database.database.get(
    2930                             'SELECT store_id FROM works_in_store WHERE personal_id = $1 AND store_id = $2',
     3356                            'SELECT store_id FROM works_in_store WHERE personal_id = ? AND store_id = ?',
    29313357                            [personalId, product.store_id],
    29323358                            (err, ownsStore) => {
    … …  
    30133439
    30143440        let body = '';
     3441
    30153442        req.on('data', chunk => {
    30163443            body += chunk.toString();
    … …  
    30183445
    30193446        req.on('end', () => {
    3020             const { currentPassword, newPassword, confirmPassword } = JSON.parse(body);
    3021 
    3022             if (!currentPassword || !newPassword || !confirmPassword) {
    3023                 res.writeHead(400, { 'Content-Type': 'application/json' });
    3024                 res.end(JSON.stringify({ success: false, message: 'All fields are required' }));
    3025                 return;
    3026             }
    3027 
    3028             if (newPassword !== confirmPassword) {
    3029                 res.writeHead(400, { 'Content-Type': 'application/json' });
    3030                 res.end(JSON.stringify({ success: false, message: 'New passwords do not match' }));
    3031                 return;
    3032             }
    3033 
    3034             if (!validatePassword(newPassword)) {
    3035                 res.writeHead(400, { 'Content-Type': 'application/json' });
    3036                 res.end(JSON.stringify({
    3037                     success: false,
    3038                     message: 'Password must have at least 8 characters, including uppercase, lowercase, number and special character'
    3039                 }));
    3040                 return;
    3041             }
    3042 
    3043             database.getUserByUsername('admin', (err, user) => {
    3044                 if (err || !user) {
    3045                     res.writeHead(404, { 'Content-Type': 'application/json' });
    3046                     res.end(JSON.stringify({ success: false, message: 'User not found' }));
     3447            try {
     3448                const { newPassword, confirmPassword } = JSON.parse(body);
     3449
     3450                if (!newPassword || !confirmPassword) {
     3451                    res.writeHead(400, { 'Content-Type': 'application/json' });
     3452                    res.end(JSON.stringify({ success: false, message: 'All fields are required' }));
    30473453                    return;
    30483454                }
    30493455
    3050                 database.verifyPassword(currentPassword, user.password, (err, isValid) => {
    3051                     if (err || !isValid) {
    3052                         res.writeHead(400, { 'Content-Type': 'application/json' });
    3053                         res.end(JSON.stringify({ success: false, message: 'Current password is incorrect' }));
    3054                         return;
    3055                     }
    3056 
    3057                     database.updatePasswordAndClearForce(userId, newPassword, (err) => {
    3058                         if (err) {
    3059                             res.writeHead(500, { 'Content-Type': 'application/json' });
    3060                             res.end(JSON.stringify({ success: false, message: 'Failed to update password' }));
    3061                         } else {
    3062                             tempAdminSessions.delete(sessionId);
    3063 
    3064                             const newSessionId = generateSessionId();
    3065                             sessions.set(newSessionId, String(userId));
    3066 
    3067                             database.logAudit(userId, 'FORCED_PASSWORD_CHANGE', 'auth', userId.toString(),
    3068                                 'Admin forced password change completed', ipAddress);
    3069 
    3070                             res.writeHead(200, {
    3071                                 'Content-Type': 'application/json',
    3072                                 'Set-Cookie': `sessionId=${newSessionId}; HttpOnly; Path=/; Max-Age=3600; SameSite=Strict`
    3073                             });
    3074                             res.end(JSON.stringify({
    3075                                 success: true,
    3076                                 message: 'Password changed successfully. You can now access the dashboard.',
    3077                                 redirectTo: 'admin.html'
    3078                             }));
    3079                         }
    3080                     });
     3456                if (newPassword !== confirmPassword) {
     3457                    res.writeHead(400, { 'Content-Type': 'application/json' });
     3458                    res.end(JSON.stringify({ success: false, message: 'New passwords do not match' }));
     3459                    return;
     3460                }
     3461
     3462                if (!validatePassword(newPassword)) {
     3463                    res.writeHead(400, { 'Content-Type': 'application/json' });
     3464                    res.end(JSON.stringify({
     3465                        success: false,
     3466                        message: 'Password must have at least 8 characters, including uppercase, lowercase, number and special character'
     3467                    }));
     3468                    return;
     3469                }
     3470
     3471                // First, try to find the user in the users table (for admin)
     3472                database.getUserById(userId, (err, user) => {
     3473                    if (err) {
     3474                        console.error('Error finding user by ID:', err);
     3475                    }
     3476
     3477                    if (user) {
     3478                        // Found in users table (admin or regular user)
     3479                        console.log('Found user in users table:', user);
     3480
     3481                        const hashedPassword = bcrypt.hashSync(newPassword, 10);
     3482
     3483                        database.database.run(
     3484                            'UPDATE users SET password = ?, force_password_change = 0 WHERE id = ?',
     3485                            [hashedPassword, userId],
     3486                            function(err) {
     3487                                if (err) {
     3488                                    console.error('Error updating password:', err);
     3489                                    res.writeHead(500, { 'Content-Type': 'application/json' });
     3490                                    res.end(JSON.stringify({ success: false, message: 'Failed to update password' }));
     3491                                    return;
     3492                                }
     3493
     3494                                // Also update password in personal table if it exists (for admin)
     3495                                database.database.run(
     3496                                    'UPDATE personal SET password = ? WHERE id = ?',
     3497                                    [hashedPassword, userId],
     3498                                    function(err) {
     3499                                        if (err) {
     3500                                            console.log('No personal record to update for ID:', userId);
     3501                                        }
     3502                                    }
     3503                                );
     3504
     3505                                // Clear temp session
     3506                                tempAdminSessions.delete(sessionId);
     3507
     3508                                // Create new permanent session
     3509                                const newSessionId = generateSessionId();
     3510                                sessions.set(newSessionId, String(userId));
     3511
     3512                                // Determine redirect based on user type
     3513                                let redirectTo = 'dashboard.html';
     3514
     3515                                if (user.username === 'admin' || user.user_type === 'admin') {
     3516                                    redirectTo = 'admin.html';
     3517                                } else if (user.user_type === 'store_owner') {
     3518                                    redirectTo = 'store-owner.html';
     3519                                } else if (user.user_type === 'store_employee') {
     3520                                    redirectTo = 'store-employee.html';
     3521                                } else if (user.user_type === 'client') {
     3522                                    redirectTo = 'client-dashboard.html';
     3523                                }
     3524
     3525                                console.log(`Password changed successfully for user ${userId}, redirecting to ${redirectTo}`);
     3526
     3527                                database.logAudit(userId, 'FORCED_PASSWORD_CHANGE', 'auth', userId.toString(),
     3528                                    `${user.user_type || 'user'} forced password change completed`, ipAddress);
     3529
     3530                                // Set the cookie with proper options
     3531                                res.writeHead(200, {
     3532                                    'Content-Type': 'application/json',
     3533                                    'Set-Cookie': `sessionId=${newSessionId}; HttpOnly; Path=/; Max-Age=3600; SameSite=Strict`
     3534                                });
     3535                                res.end(JSON.stringify({
     3536                                    success: true,
     3537                                    message: 'Password changed successfully.',
     3538                                    redirectTo: redirectTo,
     3539                                    userType: user.user_type || 'user'
     3540                                }));
     3541                            }
     3542                        );
     3543                    } else {
     3544                        // Not found in users table, check personal table (for store owners/employees)
     3545                        console.log('User not found in users table, checking personal table for ID:', userId);
     3546
     3547                        database.getPersonalById(userId, (err, personal) => {
     3548                            if (err) {
     3549                                console.error('Error finding personal by ID:', err);
     3550                            }
     3551
     3552                            if (personal) {
     3553                                console.log('Found user in personal table:', personal);
     3554
     3555                                // Update password in personal table
     3556                                const hashedPassword = bcrypt.hashSync(newPassword, 10);
     3557
     3558                                database.database.run(
     3559                                    'UPDATE personal SET password = ? WHERE id = ?',
     3560                                    [hashedPassword, userId],
     3561                                    function(err) {
     3562                                        if (err) {
     3563                                            console.error('Error updating personal password:', err);
     3564                                            res.writeHead(500, { 'Content-Type': 'application/json' });
     3565                                            res.end(JSON.stringify({ success: false, message: 'Failed to update password' }));
     3566                                            return;
     3567                                        }
     3568
     3569                                        // Also update in users table if exists
     3570                                        database.database.run(
     3571                                            'UPDATE users SET password = ?, force_password_change = 0 WHERE email = ?',
     3572                                            [hashedPassword, personal.email],
     3573                                            function(err) {
     3574                                                if (err) {
     3575                                                    console.log('No users record to update for email:', personal.email);
     3576                                                }
     3577                                            }
     3578                                        );
     3579
     3580                                        // Determine user type (boss/owner or employee)
     3581                                        database.database.get(
     3582                                            'SELECT boss_id FROM boss WHERE boss_id = ?',
     3583                                            [userId],
     3584                                            (err, boss) => {
     3585                                                let userType = 'store_employee';
     3586                                                let redirectTo = 'store-employee.html';
     3587
     3588                                                if (boss) {
     3589                                                    userType = 'store_owner';
     3590                                                    redirectTo = 'store-owner.html';
     3591                                                }
     3592
     3593                                                // Clear temp session
     3594                                                tempAdminSessions.delete(sessionId);
     3595
     3596                                                // Create new permanent session
     3597                                                const newSessionId = generateSessionId();
     3598                                                sessions.set(newSessionId, `personal_${userId}`);
     3599
     3600                                                console.log(`Password changed successfully for ${userType} ${userId}, redirecting to ${redirectTo}`);
     3601
     3602                                                database.logAudit(userId, 'FORCED_PASSWORD_CHANGE', 'auth', userId.toString(),
     3603                                                    `${userType} forced password change completed`, ipAddress);
     3604
     3605                                                // Set the cookie with proper options
     3606                                                res.writeHead(200, {
     3607                                                    'Content-Type': 'application/json',
     3608                                                    'Set-Cookie': `sessionId=${newSessionId}; HttpOnly; Path=/; Max-Age=3600; SameSite=Strict`
     3609                                                });
     3610                                                res.end(JSON.stringify({
     3611                                                    success: true,
     3612                                                    message: 'Password changed successfully.',
     3613                                                    redirectTo: redirectTo,
     3614                                                    userType: userType
     3615                                                }));
     3616                                            }
     3617                                        );
     3618                                    }
     3619                                );
     3620                            } else {
     3621                                // User not found in any table
     3622                                console.error('User not found in any table with ID:', userId);
     3623                                res.writeHead(404, { 'Content-Type': 'application/json' });
     3624                                res.end(JSON.stringify({ success: false, message: 'User not found' }));
     3625                            }
     3626                        });
     3627                    }
    30813628                });
    3082             });
     3629            } catch (parseError) {
     3630                console.error('JSON parse error:', parseError);
     3631                res.writeHead(400, { 'Content-Type': 'application/json' });
     3632                res.end(JSON.stringify({ success: false, message: 'Invalid request format' }));
     3633            }
    30833634        });
    30843635    }
    … …  
    30883639            const userIdStr = String(userId);
    30893640
     3641            // Check if this is the admin user
     3642            if (userIdStr === '000000') {
     3643                res.writeHead(403, { 'Content-Type': 'application/json' });
     3644                res.end(JSON.stringify({ success: false, message: 'Only store owners can register employees' }));
     3645                return;
     3646            }
     3647
    30903648            if (!userIdStr.startsWith('personal_')) {
    30913649                res.writeHead(403, { 'Content-Type': 'application/json' });
    … …  
    30973655
    30983656            database.database.get(
    3099                 'SELECT boss_id FROM boss WHERE boss_id = $1',
     3657                'SELECT boss_id FROM boss WHERE boss_id = ?',
    31003658                [personalId],
    31013659                (err, boss) => {
    … …  
    32043762
    32053763                                        database.database.run(
    3206                                             'INSERT INTO personal (id, first_name, last_name, ssn, email, password) VALUES ($1, $2, $3, $4, $5, $6)',
     3764                                            'INSERT INTO personal (id, first_name, last_name, ssn, email, password) VALUES (?, ?, ?, ?, ?, ?)',
    32073765                                            [
    32083766                                                newPersonalId,
    … …  
    32283786
    32293787                                                database.database.run(
    3230                                                     'INSERT INTO employees (employee_id, date_of_hire) VALUES ($1, $2)',
     3788                                                    'INSERT INTO employees (employee_id, date_of_hire) VALUES (?, ?)',
    32313789                                                    [newPersonalId, dateOfHire],
    32323790                                                    (err) => {
    … …  
    32403798
    32413799                                                        database.database.run(
    3242                                                             'INSERT INTO works_in_store (personal_id, store_id) VALUES ($1, $2)',
     3800                                                            'INSERT INTO works_in_store (personal_id, store_id) VALUES (?, ?)',
    32433801                                                            [newPersonalId, storeId],
    32443802                                                            (err) => {
    … …  
    32523810
    32533811                                                                database.database.run(
    3254                                                                     'INSERT INTO permissions (personal_id, type, authorisation) VALUES ($1, $2, $3)',
     3812                                                                    'INSERT INTO permissions (personal_id, type, authorisation) VALUES (?, ?, ?)',
    32553813                                                                    [newPersonalId, 'EMPLOYEE', 'limited_access'],
    32563814                                                                    (err) => {
    … …  
    33003858            const userIdStr = String(userId);
    33013859
     3860            // Check if this is the admin user
     3861            if (userIdStr === '000000') {
     3862                res.writeHead(403, { 'Content-Type': 'application/json' });
     3863                res.end(JSON.stringify({ success: false, message: 'Only store owners can delete employees' }));
     3864                return;
     3865            }
     3866
    33023867            if (!userIdStr.startsWith('personal_')) {
    33033868                res.writeHead(403, { 'Content-Type': 'application/json' });
    … …  
    33093874
    33103875            database.database.get(
    3311                 'SELECT boss_id FROM boss WHERE boss_id = $1',
     3876                'SELECT boss_id FROM boss WHERE boss_id = ?',
    33123877                [personalId],
    33133878                (err, boss) => {
    … …  
    33333898
    33343899                        database.database.get(
    3335                             'SELECT store_id FROM works_in_store WHERE personal_id = $1 AND store_id = $2',
     3900                            'SELECT store_id FROM works_in_store WHERE personal_id = ? AND store_id = ?',
    33363901                            [personalId, storeId],
    33373902                            (err, bossStore) => {
    … …  
    33433908
    33443909                                database.database.get(
    3345                                     'SELECT personal_id FROM works_in_store WHERE personal_id = $1 AND store_id = $2',
     3910                                    'SELECT personal_id FROM works_in_store WHERE personal_id = ? AND store_id = ?',
    33463911                                    [employeeId, storeId],
    33473912                                    (err, employeeStore) => {
    … …  
    33533918
    33543919                                        database.database.get(
    3355                                             'SELECT boss_id FROM boss WHERE boss_id = $1',
     3920                                            'SELECT boss_id FROM boss WHERE boss_id = ?',
    33563921                                            [employeeId],
    33573922                                            (err, isBoss) => {
    … …  
    33753940
    33763941                                                    database.database.run(
    3377                                                         'DELETE FROM works_in_store WHERE personal_id = $1 AND store_id = $2',
     3942                                                        'DELETE FROM works_in_store WHERE personal_id = ? AND store_id = ?',
    33783943                                                        [employeeId, storeId],
    33793944                                                        (err) => {
    … …  
    33873952
    33883953                                                            database.database.run(
    3389                                                                 'DELETE FROM employees WHERE employee_id = $1',
     3954                                                                'DELETE FROM employees WHERE employee_id = ?',
    33903955                                                                [employeeId],
    33913956                                                                (err) => {
    … …  
    33953960
    33963961                                                                    database.database.run(
    3397                                                                         'DELETE FROM permissions WHERE personal_id = $1',
     3962                                                                        'DELETE FROM permissions WHERE personal_id = ?',
    33983963                                                                        [employeeId],
    33993964                                                                        (err) => {
    … …  
    34033968
    34043969                                                                            database.database.run(
    3405                                                                                 'DELETE FROM personal WHERE id = $1',
     3970                                                                                'DELETE FROM personal WHERE id = ?',
    34063971                                                                                [employeeId],
    34073972                                                                                (err) => {
    … …  
    34524017            const userIdStr = String(userId);
    34534018
     4019            // Check if this is the admin user
     4020            if (userIdStr === '000000') {
     4021                res.writeHead(403, { 'Content-Type': 'application/json' });
     4022                res.end(JSON.stringify({ success: false, message: 'Only store owners can update employee status' }));
     4023                return;
     4024            }
     4025
    34544026            if (!userIdStr.startsWith('personal_')) {
    34554027                res.writeHead(403, { 'Content-Type': 'application/json' });
    … …  
    34614033
    34624034            database.database.get(
    3463                 'SELECT boss_id FROM boss WHERE boss_id = $1',
     4035                'SELECT boss_id FROM boss WHERE boss_id = ?',
    34644036                [personalId],
    34654037                (err, boss) => {
    … …  
    34854057
    34864058                        database.database.get(
    3487                             'SELECT store_id FROM works_in_store WHERE personal_id = $1 AND store_id = $2',
     4059                            'SELECT store_id FROM works_in_store WHERE personal_id = ? AND store_id = ?',
    34884060                            [personalId, storeId],
    34894061                            (err, bossStore) => {
    … …  
    34954067
    34964068                                database.database.get(
    3497                                     'SELECT personal_id FROM works_in_store WHERE personal_id = $1 AND store_id = $2',
     4069                                    'SELECT personal_id FROM works_in_store WHERE personal_id = ? AND store_id = ?',
    34984070                                    [employeeId, storeId],
    34994071                                    (err, employeeStore) => {
    … …  
    35194091
    35204092                                        database.database.run(
    3521                                             'UPDATE permissions SET type = $1, authorisation = $2 WHERE personal_id = $3',
     4093                                            'UPDATE permissions SET type = ?, authorisation = ? WHERE personal_id = ?',
    35224094                                            [permissionType, authorization, employeeId],
    35234095                                            function(err) {
    … …  
    35524124            const userIdStr = String(userId);
    35534125
     4126            // Check if this is the admin user
     4127            if (userIdStr === '000000') {
     4128                res.writeHead(403, { 'Content-Type': 'application/json' });
     4129                res.end(JSON.stringify({ success: false, message: 'Only store owners can update employees' }));
     4130                return;
     4131            }
     4132
    35544133            if (!userIdStr.startsWith('personal_')) {
    35554134                res.writeHead(403, { 'Content-Type': 'application/json' });
    … …  
    35614140
    35624141            database.database.get(
    3563                 'SELECT boss_id FROM boss WHERE boss_id = $1',
     4142                'SELECT boss_id FROM boss WHERE boss_id = ?',
    35644143                [personalId],
    35654144                (err, boss) => {
    … …  
    35854164
    35864165                        database.database.get(
    3587                             'SELECT store_id FROM works_in_store WHERE personal_id = $1 AND store_id = $2',
     4166                            'SELECT store_id FROM works_in_store WHERE personal_id = ? AND store_id = ?',
    35884167                            [personalId, storeId],
    35894168                            (err, bossStore) => {
    … …  
    35954174
    35964175                                database.database.get(
    3597                                     'SELECT personal_id FROM works_in_store WHERE personal_id = $1 AND store_id = $2',
     4176                                    'SELECT personal_id FROM works_in_store WHERE personal_id = ? AND store_id = ?',
    35984177                                    [employeeId, storeId],
    35994178                                    (err, employeeStore) => {
    … …  
    36084187
    36094188                                        if (firstName) {
    3610                                             updates.push('first_name = $' + (params.length + 1));
     4189                                            updates.push('first_name = ?');
    36114190                                            params.push(firstName);
    36124191                                        }
    36134192
    36144193                                        if (lastName) {
    3615                                             updates.push('last_name = $' + (params.length + 1));
     4194                                            updates.push('last_name = ?');
    36164195                                            params.push(lastName);
    36174196                                        }
    … …  
    36234202                                                return;
    36244203                                            }
    3625                                             updates.push('email = $' + (params.length + 1));
     4204                                            updates.push('email = ?');
    36264205                                            params.push(email);
    36274206                                        }
    … …  
    36364215
    36374216                                        database.database.run(
    3638                                             `UPDATE personal SET ${updates.join(', ')} WHERE id = $${params.length}`,
     4217                                            `UPDATE personal SET ${updates.join(', ')} WHERE id = ?`,
    36394218                                            params,
    36404219                                            function(err) {
    … …  
    36714250            if (!storeId) {
    36724251                database.database.get(
    3673                     'SELECT store_id FROM works_in_store WHERE personal_id = $1 LIMIT 1',
     4252                    'SELECT store_id FROM works_in_store WHERE personal_id = ? LIMIT 1',
    36744253                    [personalId],
    36754254                    (err, store) => {
    … …  
    36914270                    }
    36924271                );
     4272
    36934273                return;
    36944274            }
    36954275
    36964276            database.database.get(
    3697                 'SELECT store_id FROM works_in_store WHERE personal_id = $1 AND store_id = $2',
     4277                'SELECT store_id FROM works_in_store WHERE personal_id = ? AND store_id = ?',
    36984278                [personalId, storeId],
    36994279                (err, ownsStore) => {
    … …  
    37244304            if (!storeId) {
    37254305                database.database.get(
    3726                     'SELECT store_id FROM works_in_store WHERE personal_id = $1 LIMIT 1',
     4306                    'SELECT store_id FROM works_in_store WHERE personal_id = ? LIMIT 1',
    37274307                    [personalId],
    37284308                    (err, store) => {
    … …  
    37444324                    }
    37454325                );
     4326
    37464327                return;
    37474328            }
    37484329
    37494330            database.database.get(
    3750                 'SELECT store_id FROM works_in_store WHERE personal_id = $1 AND store_id = $2',
     4331                'SELECT store_id FROM works_in_store WHERE personal_id = ? AND store_id = ?',
    37514332                [personalId, storeId],
    37524333                (err, ownsStore) => {
    … …  
    37774358            if (!storeId) {
    37784359                database.database.get(
    3779                     'SELECT store_id FROM works_in_store WHERE personal_id = $1 LIMIT 1',
     4360                    'SELECT store_id FROM works_in_store WHERE personal_id = ? LIMIT 1',
    37804361                    [personalId],
    37814362                    (err, store) => {
    … …  
    37974378                    }
    37984379                );
     4380
    37994381                return;
    38004382            }
    38014383
    38024384            database.database.get(
    3803                 'SELECT store_id FROM works_in_store WHERE personal_id = $1 AND store_id = $2',
     4385                'SELECT store_id FROM works_in_store WHERE personal_id = ? AND store_id = ?',
    38044386                [personalId, storeId],
    38054387                (err, ownsStore) => {
    … …  
    38304412            if (!storeId) {
    38314413                database.database.get(
    3832                     'SELECT store_id FROM works_in_store WHERE personal_id = $1 LIMIT 1',
     4414                    'SELECT store_id FROM works_in_store WHERE personal_id = ? LIMIT 1',
    38334415                    [personalId],
    38344416                    (err, store) => {
    … …  
    38504432                    }
    38514433                );
     4434
    38524435                return;
    38534436            }
    38544437
    38554438            database.database.get(
    3856                 'SELECT store_id FROM works_in_store WHERE personal_id = $1 AND store_id = $2',
     4439                'SELECT store_id FROM works_in_store WHERE personal_id = ? AND store_id = ?',
    38574440                [personalId, storeId],
    38584441                (err, ownsStore) => {
    … …  
    38834466            if (!storeId) {
    38844467                database.database.get(
    3885                     'SELECT store_id FROM works_in_store WHERE personal_id = $1 LIMIT 1',
     4468                    'SELECT store_id FROM works_in_store WHERE personal_id = ? LIMIT 1',
    38864469                    [personalId],
    38874470                    (err, store) => {
    … …  
    39034486                    }
    39044487                );
     4488
    39054489                return;
    39064490            }
    39074491
    39084492            database.database.get(
    3909                 'SELECT store_id FROM works_in_store WHERE personal_id = $1 AND store_id = $2',
     4493                'SELECT store_id FROM works_in_store WHERE personal_id = ? AND store_id = ?',
    39104494                [personalId, storeId],
    39114495                (err, ownsStore) => {
    … …  
    39344518            const userIdStr = String(userId);
    39354519
     4520            // Check if this is the admin user
     4521            if (userIdStr === '000000') {
     4522                res.writeHead(403, { 'Content-Type': 'application/json' });
     4523                res.end(JSON.stringify({ success: false, message: 'Only store employees can access this endpoint' }));
     4524                return;
     4525            }
     4526
    39364527            if (!userIdStr.startsWith('personal_')) {
    39374528                res.writeHead(403, { 'Content-Type': 'application/json' });
    … …  
    40024593
    40034594                database.database.get(
    4004                     'SELECT store_id FROM works_in_store WHERE personal_id = $1 AND store_id = $2',
     4595                    'SELECT store_id FROM works_in_store WHERE personal_id = ? AND store_id = ?',
    40054596                    [personalId, storeId],
    40064597                    (err, ownsStore) => {
    … …  
    40724663
    40734664                database.database.get(
    4074                     'SELECT store_id FROM works_in_store WHERE personal_id = $1 AND store_id = $2',
     4665                    'SELECT store_id FROM works_in_store WHERE personal_id = ? AND store_id = ?',
    40754666                    [personalId, storeId],
    40764667                    (err, ownsStore) => {
    … …  
    40844675
    40854676                        database.database.run(
    4086                             'INSERT INTO report (id, store_id, period, start_date, end_date, type, generated_by, generated_at) VALUES ($1, $2, $3, $4, $5, $6, $7, CURRENT_TIMESTAMP)',
     4677                            'INSERT INTO report (id, store_id, period, start_date, end_date, type, generated_by, generated_at) VALUES (?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)',
    40874678                            [reportId, storeId, period, startDate, endDate, type, personalId],
    40884679                            function(err) {
Note: See TracChangeset for help on using the changeset viewer.