403Webshell
Server IP : 167.235.67.158  /  Your IP : 216.73.216.95
Web Server : Apache
System : Linux ubuntu-8gb-nbg1-1 6.8.0-111-generic #111-Ubuntu SMP PREEMPT_DYNAMIC Sat Apr 11 23:16:02 UTC 2026 x86_64
User : root ( 0)
PHP Version : 8.3.6
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : OFF
Directory :  /var/www/api.pda.the-word.com/common/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/api.pda.the-word.com/common/sqlDB.js
const crypto = require('node:crypto');
const mysql = require('mysql2');

const pool = mysql.createPool({
  host: process.env.MYSQL_HOST,
  port: Number(process.env.MYSQL_PORT || 3306),
  user: process.env.MYSQL_USER,
  password: process.env.MYSQL_PASSWORD,
  database: process.env.MYSQL_DB,
  charset: 'utf8mb4',
  waitForConnections: true,
  connectionLimit: 10,
  queueLimit: 0
});

function queryDatabase(sql, values = []) {
  return new Promise((resolve, reject) => {
    pool.query(sql, values, (error, results) => {
      if (error) {
        reject(error);
        return;
      }
      resolve(results);
    });
  });
}

function getConnection() {
  return new Promise((resolve, reject) => {
    pool.getConnection((error, connection) => {
      if (error) {
        reject(error);
        return;
      }
      resolve(connection);
    });
  });
}

async function withTransaction(work) {
  const connection = await getConnection();

  const tx = {
    query(sql, values = []) {
      return new Promise((resolve, reject) => {
        connection.query(sql, values, (error, results) => {
          if (error) {
            reject(error);
            return;
          }
          resolve(results);
        });
      });
    },
    async insertRow(table, data) {
      const keys = Object.keys(data);
      const values = Object.values(data);
      const placeholders = keys.map(() => '?').join(', ');
      const columns = keys.map((key) => `\`${key}\``).join(', ');
      const sql = `INSERT INTO \`${table}\` (${columns}) VALUES (${placeholders})`;
      const result = await this.query(sql, values);
      return result.insertId;
    },
    async updateRows(table, data, whereClause, whereValues = []) {
      const keys = Object.keys(data);
      const values = Object.values(data);
      const setClause = keys.map((key) => `\`${key}\` = ?`).join(', ');
      const sql = `UPDATE \`${table}\` SET ${setClause} WHERE ${whereClause}`;
      const result = await this.query(sql, [...values, ...whereValues]);
      return result.affectedRows;
    }
  };

  try {
    await tx.query('START TRANSACTION');
    const result = await work(tx);
    await tx.query('COMMIT');
    connection.release();
    return result;
  } catch (error) {
    try {
      await tx.query('ROLLBACK');
    } finally {
      connection.release();
    }
    throw error;
  }
}

async function insertRow(table, data) {
  const keys = Object.keys(data);
  const values = Object.values(data);
  const placeholders = keys.map(() => '?').join(', ');
  const columns = keys.map((key) => `\`${key}\``).join(', ');
  const sql = `INSERT INTO \`${table}\` (${columns}) VALUES (${placeholders})`;
  const result = await queryDatabase(sql, values);
  return result.insertId;
}

async function updateRows(table, data, whereClause, whereValues = []) {
  const keys = Object.keys(data);
  const values = Object.values(data);
  const setClause = keys.map((key) => `\`${key}\` = ?`).join(', ');
  const sql = `UPDATE \`${table}\` SET ${setClause} WHERE ${whereClause}`;
  const result = await queryDatabase(sql, [...values, ...whereValues]);
  return result.affectedRows;
}

async function deleteRows(table, whereClause, whereValues = []) {
  const sql = `DELETE FROM \`${table}\` WHERE ${whereClause}`;
  const result = await queryDatabase(sql, whereValues);
  return result.affectedRows;
}

async function insertOrUpdateRow(table, data, whereClause, whereValues = []) {
  const updatedRows = await updateRows(table, data, whereClause, whereValues);
  if (updatedRows > 0) {
    return updatedRows;
  }
  return insertRow(table, data);
}

let ensurePromise;

function isUuidLike(value) {
  return typeof value === 'string' && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
}

async function columnExists(tableName, columnName) {
  const rows = await queryDatabase(
    `SELECT COUNT(*) AS count
     FROM INFORMATION_SCHEMA.COLUMNS
     WHERE TABLE_SCHEMA = DATABASE()
       AND TABLE_NAME = ?
       AND COLUMN_NAME = ?`,
    [tableName, columnName]
  );
  return Number(rows[0]?.count || 0) > 0;
}

async function indexExists(tableName, indexName) {
  const rows = await queryDatabase(
    `SELECT COUNT(*) AS count
     FROM INFORMATION_SCHEMA.STATISTICS
     WHERE TABLE_SCHEMA = DATABASE()
       AND TABLE_NAME = ?
       AND INDEX_NAME = ?`,
    [tableName, indexName]
  );
  return Number(rows[0]?.count || 0) > 0;
}

async function ensureSyncUuid(tableName, indexName) {
  if (!await columnExists(tableName, 'SyncUUID')) {
    await queryDatabase(`ALTER TABLE \`${tableName}\` ADD COLUMN SyncUUID VARCHAR(36) NULL`);
  }

  await ensureEntitySyncUuids(tableName);

  if (!await indexExists(tableName, indexName)) {
    await queryDatabase(`CREATE UNIQUE INDEX \`${indexName}\` ON \`${tableName}\` (Instructor, SyncUUID)`);
  }
}

async function ensureEntitySyncUuids(tableName, instructorId = null) {
  const where = instructorId ? 'WHERE Instructor = ?' : '';
  const values = instructorId ? [instructorId] : [];
  const rows = await queryDatabase(
    `SELECT ID, Instructor, SyncUUID FROM \`${tableName}\` ${where} ORDER BY Instructor ASC, ID ASC`,
    values
  );
  const seen = new Set();

  for (const row of rows) {
    const instructor = Number(row.Instructor || 0);
    const existingUuid = String(row.SyncUUID || '').trim().toLowerCase();
    const existingKey = `${instructor}:${existingUuid}`;

    if (isUuidLike(existingUuid) && !seen.has(existingKey)) {
      seen.add(existingKey);
      if (existingUuid !== row.SyncUUID) {
        await queryDatabase(`UPDATE \`${tableName}\` SET SyncUUID = ? WHERE ID = ? AND Instructor = ?`, [existingUuid, row.ID, instructor]);
      }
      continue;
    }

    let replacementUuid;
    do {
      replacementUuid = crypto.randomUUID();
    } while (seen.has(`${instructor}:${replacementUuid}`));

    seen.add(`${instructor}:${replacementUuid}`);
    await queryDatabase(`UPDATE \`${tableName}\` SET SyncUUID = ? WHERE ID = ? AND Instructor = ?`, [replacementUuid, row.ID, instructor]);
  }
}

function ensureApiTables() {
  if (ensurePromise) {
    return ensurePromise;
  }

  const statements = [
    `CREATE TABLE IF NOT EXISTS api_user_tokens (
      id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
      user_id BIGINT NOT NULL,
      token_hash VARCHAR(64) NOT NULL,
      created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
      last_used_at DATETIME(3) NULL,
      revoked_at DATETIME(3) NULL,
      UNIQUE KEY uq_api_user_tokens_hash (token_hash),
      KEY idx_api_user_tokens_user (user_id)
    )`,
    `CREATE TABLE IF NOT EXISTS api_refresh_tokens (
      id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
      user_id BIGINT NOT NULL,
      token_hash VARCHAR(64) NOT NULL,
      expires_at DATETIME(3) NOT NULL,
      revoked_at DATETIME(3) NULL,
      created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
      replaced_by_id BIGINT NULL,
      UNIQUE KEY uq_api_refresh_tokens_hash (token_hash),
      KEY idx_api_refresh_tokens_user (user_id)
    )`,
    `CREATE TABLE IF NOT EXISTS sync_operations (
      id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
      user_id BIGINT NOT NULL,
      action_id VARCHAR(128) NOT NULL,
      entity_type VARCHAR(64) NOT NULL,
      entity_id BIGINT NULL,
      status VARCHAR(32) NOT NULL,
      request_payload LONGTEXT NOT NULL,
      response_payload LONGTEXT NOT NULL,
      created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
      UNIQUE KEY uq_sync_operations_user_action (user_id, action_id)
    )`,
    `CREATE TABLE IF NOT EXISTS sync_entity_keys (
      id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
      user_id BIGINT NOT NULL,
      device_id VARCHAR(128) NOT NULL,
      entity_type VARCHAR(64) NOT NULL,
      local_id VARCHAR(128) NOT NULL,
      entity_id BIGINT NOT NULL,
      created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
      UNIQUE KEY uq_sync_entity_keys_lookup (user_id, device_id, entity_type, local_id),
      KEY idx_sync_entity_keys_entity (entity_type, entity_id)
    )`,
    `CREATE TABLE IF NOT EXISTS sync_entity_state (
      id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
      user_id BIGINT NOT NULL,
      entity_type VARCHAR(64) NOT NULL,
      entity_id BIGINT NOT NULL,
      last_client_edited_at_utc DATETIME(3) NOT NULL,
      last_device_id VARCHAR(128) NOT NULL,
      updated_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
      UNIQUE KEY uq_sync_entity_state_entity (user_id, entity_type, entity_id)
    )`,
    `CREATE TABLE IF NOT EXISTS sync_change_log (
      cursor_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
      user_id BIGINT NOT NULL,
      entity_type VARCHAR(64) NOT NULL,
      entity_id BIGINT NOT NULL,
      operation VARCHAR(32) NOT NULL,
      changed_at_utc DATETIME(3) NOT NULL,
      KEY idx_sync_change_log_user_cursor (user_id, cursor_id),
      KEY idx_sync_change_log_entity (entity_type, entity_id)
    )`
  ];

  ensurePromise = (async () => {
    for (const statement of statements) {
      await queryDatabase(statement);
    }

    await ensureSyncUuid('Students', 'uq_students_instructor_syncuuid');
    await ensureSyncUuid('Lessons', 'uq_lessons_instructor_syncuuid');
  })().catch((error) => {
    ensurePromise = null;
    throw error;
  });

  return ensurePromise;
}

module.exports = {
  deleteRows,
  ensureEntitySyncUuids,
  ensureApiTables,
  insertOrUpdateRow,
  insertRow,
  queryDatabase,
  updateRows,
  withTransaction
};

Youez - 2016 - github.com/yon3zu
LinuXploit