@@ -73,6 +73,10 @@
Meus Arquivos
+
+
+ Compartilhamentos
+
isAdmin()): ?>
diff --git a/public/shares.php b/public/shares.php
index 53a9794..8a7abae 100644
--- a/public/shares.php
+++ b/public/shares.php
@@ -72,7 +72,7 @@ function formatExpiry($date) {
Meus Arquivos
-
+
Compartilhamentos
diff --git a/src/Auth.php b/src/Auth.php
index cb696ce..a0840f9 100755
--- a/src/Auth.php
+++ b/src/Auth.php
@@ -61,7 +61,7 @@ public function mustChangePassword(): bool {
return isset($_SESSION['must_change_password']) && $_SESSION['must_change_password'];
}
- public function getCurrentUserId(): ?int {
+ public function getCurrentUserId(): ?string {
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
diff --git a/src/FileManager.php b/src/FileManager.php
index 566cb27..0dd9b7f 100755
--- a/src/FileManager.php
+++ b/src/FileManager.php
@@ -7,9 +7,9 @@
class FileManager {
private StorageInterface $storage;
- private int $userId;
+ private string $userId;
- public function __construct(int $userId, StorageInterface $storage) {
+ public function __construct(string $userId, StorageInterface $storage) {
$this->userId = $userId;
$this->storage = $storage;
$this->storage->createDirectory($this->getUserPrefix());
diff --git a/src/ShareManager.php b/src/ShareManager.php
index 6544497..974747d 100644
--- a/src/ShareManager.php
+++ b/src/ShareManager.php
@@ -16,12 +16,12 @@ public function __construct(Database $db) {
/**
* Creates a new share link for a file.
*
- * @param int $userId The ID of the user who owns the file.
+ * @param string $userId The ID of the user who owns the file.
* @param string $filename The name of the file to share.
* @param string $duration The duration of the share ('1h', '1d', or 'forever').
* @return string The generated UUID for the share link.
*/
- public function createShare(int $userId, string $filename, string $duration): string {
+ public function createShare(string $userId, string $filename, string $duration): string {
$uuid = $this->generateUuidV4();
$expiresAt = null;
@@ -58,10 +58,10 @@ public function getShare(string $uuid): ?array {
/**
* Lists all shares for a specific user.
*
- * @param int $userId The ID of the user.
+ * @param string $userId The ID of the user.
* @return array List of shares.
*/
- public function listShares(int $userId): array {
+ public function listShares(string $userId): array {
$stmt = $this->pdo->prepare("
SELECT * FROM shared_files
WHERE user_id = ?
@@ -75,10 +75,10 @@ public function listShares(int $userId): array {
* Deletes a specific share.
*
* @param string $uuid The UUID of the share.
- * @param int $userId The ID of the user (for security).
+ * @param string $userId The ID of the user (for security).
* @return bool True on success.
*/
- public function deleteShare(string $uuid, int $userId): bool {
+ public function deleteShare(string $uuid, string $userId): bool {
$stmt = $this->pdo->prepare("
DELETE FROM shared_files
WHERE uuid = ? AND user_id = ?
diff --git a/src/UserManager.php b/src/UserManager.php
index cadf06f..2f62607 100755
--- a/src/UserManager.php
+++ b/src/UserManager.php
@@ -13,18 +13,19 @@ public function __construct(Database $database) {
$this->db = $database->getConnection();
}
- public function addUser(string $username, string $password, string $role = 'user'): int {
+ public function addUser(string $username, string $password, string $role = 'user'): string {
if ($this->getUserByUsername($username)) {
throw new Exception("Username already exists.");
}
$hash = password_hash($password, PASSWORD_DEFAULT);
- $stmt = $this->db->prepare("INSERT INTO users (username, password, role) VALUES (?, ?, ?)");
+ $stmt = $this->db->prepare("INSERT INTO users (username, password, role) VALUES (?, ?, ?) RETURNING id");
$stmt->execute([$username, $hash, $role]);
- return (int) $this->db->lastInsertId();
+ $result = $stmt->fetch(PDO::FETCH_ASSOC);
+ return (string) $result['id'];
}
- public function changePassword(int $userId, string $currentPassword, string $newPassword): bool {
+ public function changePassword(string $userId, string $currentPassword, string $newPassword): bool {
$stmt = $this->db->prepare("SELECT password FROM users WHERE id = ?");
$stmt->execute([$userId]);
$user = $stmt->fetch();
@@ -42,7 +43,7 @@ public function changePassword(int $userId, string $currentPassword, string $new
return $updateStmt->execute([$hash, $userId]);
}
- public function removeUser(int $id): bool {
+ public function removeUser(string $id): bool {
// Find user first to prevent removing the last admin (logic simplified for now)
$stmt = $this->db->prepare("DELETE FROM users WHERE id = ?");
return $stmt->execute([$id]);
@@ -60,7 +61,7 @@ public function getUserByUsername(string $username): ?array {
return $user ?: null;
}
- public function getUserById(int $id): ?array {
+ public function getUserById(string $id): ?array {
$stmt = $this->db->prepare("SELECT id, username, role, created_at FROM users WHERE id = ?");
$stmt->execute([$id]);
$user = $stmt->fetch();
diff --git a/src/init_db.php b/src/init_db.php
index 83f987b..e7b9d51 100755
--- a/src/init_db.php
+++ b/src/init_db.php
@@ -12,7 +12,7 @@
echo "Creating users table...\n";
$pdo->exec("
CREATE TABLE IF NOT EXISTS users (
- id SERIAL PRIMARY KEY,
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
username VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
role VARCHAR(50) DEFAULT 'user',
@@ -31,7 +31,7 @@
$pdo->exec("
CREATE TABLE IF NOT EXISTS shared_files (
uuid UUID PRIMARY KEY,
- user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
+ user_id uuid REFERENCES users(id) ON DELETE CASCADE,
filename TEXT NOT NULL,
expires_at TIMESTAMP NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
diff --git a/tests/AuthTest.php b/tests/AuthTest.php
index 3317686..9cc3b97 100755
--- a/tests/AuthTest.php
+++ b/tests/AuthTest.php
@@ -20,7 +20,7 @@ protected function setUp(): void {
$pdo->exec("DROP TABLE IF EXISTS users CASCADE;");
$pdo->exec("
CREATE TABLE users (
- id SERIAL PRIMARY KEY,
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
username VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
role VARCHAR(50) DEFAULT 'user',
@@ -47,7 +47,7 @@ public function testValidLogin() {
$this->assertTrue($this->auth->login('admin', 'adminpass'));
$this->assertTrue($this->auth->isLoggedIn());
$this->assertTrue($this->auth->isAdmin());
- $this->assertEquals(1, $this->auth->getCurrentUserId());
+ $this->assertMatchesRegularExpression('/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i', $this->auth->getCurrentUserId());
}
public function testInvalidLogin() {
diff --git a/tests/ShareManagerTest.php b/tests/ShareManagerTest.php
index 32ba818..fd39c0e 100644
--- a/tests/ShareManagerTest.php
+++ b/tests/ShareManagerTest.php
@@ -5,6 +5,7 @@
use App\Config\Database;
use App\ShareManager;
use PHPUnit\Framework\TestCase;
+use PDO;
class ShareManagerTest extends TestCase {
private Database $db;
@@ -22,7 +23,7 @@ protected function setUp(): void {
$pdo->exec("
CREATE TABLE users (
- id SERIAL PRIMARY KEY,
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
username VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
role VARCHAR(50) DEFAULT 'user',
@@ -34,7 +35,7 @@ protected function setUp(): void {
$pdo->exec("
CREATE TABLE shared_files (
uuid UUID PRIMARY KEY,
- user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
+ user_id UUID REFERENCES users(id) ON DELETE CASCADE,
filename TEXT NOT NULL,
expires_at TIMESTAMP NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
@@ -42,11 +43,14 @@ protected function setUp(): void {
");
// Create a default user for tests
- $pdo->exec("INSERT INTO users (id, username, password) VALUES (1, 'admin', 'admin')");
+ $pdo->exec("INSERT INTO users (username, password) VALUES ('admin', 'admin')");
}
public function testCreateShareForever() {
- $uuid = $this->shareManager->createShare(1, 'test_forever.txt', 'forever');
+ $stmt = $this->db->getConnection()->prepare("SELECT * FROM users WHERE username = ?");
+ $stmt->execute(['admin']);
+ $user = $stmt->fetch();
+ $uuid = $this->shareManager->createShare($user["id"], 'test_forever.txt', 'forever');
// UUID v4 regex
$this->assertMatchesRegularExpression('/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i', $uuid);
@@ -57,7 +61,10 @@ public function testCreateShareForever() {
}
public function testCreateShareWithExpiry() {
- $uuid = $this->shareManager->createShare(1, 'test_1h.txt', '1h');
+ $stmt = $this->db->getConnection()->prepare("SELECT * FROM users WHERE username = ?");
+ $stmt->execute(['admin']);
+ $user = $stmt->fetch();
+ $uuid = $this->shareManager->createShare($user["id"], 'test_1h.txt', '1h');
$share = $this->shareManager->getShare($uuid);
$this->assertNotNull($share);
@@ -70,7 +77,10 @@ public function testCreateShareWithExpiry() {
}
public function testGetExpiredShareReturnsNull() {
- $uuid = $this->shareManager->createShare(1, 'expired.txt', '1h');
+ $stmt = $this->db->getConnection()->prepare("SELECT * FROM users WHERE username = ?");
+ $stmt->execute(['admin']);
+ $user = $stmt->fetch();
+ $uuid = $this->shareManager->createShare($user["id"], 'expired.txt', '1h');
// Manually set expiry to the past
$stmt = $this->db->getConnection()->prepare("UPDATE shared_files SET expires_at = '2000-01-01 00:00:00' WHERE uuid = ?");
@@ -82,8 +92,11 @@ public function testGetExpiredShareReturnsNull() {
public function testCleanupExpiredShares() {
// Create one active and one expired share
- $uuidActive = $this->shareManager->createShare(1, 'active.txt', 'forever');
- $uuidExpired = $this->shareManager->createShare(1, 'to_cleanup.txt', '1h');
+ $stmt = $this->db->getConnection()->prepare("SELECT * FROM users WHERE username = ?");
+ $stmt->execute(['admin']);
+ $user = $stmt->fetch();
+ $uuidActive = $this->shareManager->createShare($user["id"], 'active.txt', 'forever');
+ $uuidExpired = $this->shareManager->createShare($user["id"], 'to_cleanup.txt', '1h');
$stmt = $this->db->getConnection()->prepare("UPDATE shared_files SET expires_at = '2000-01-01 00:00:00' WHERE uuid = ?");
$stmt->execute([$uuidExpired]);
@@ -104,12 +117,14 @@ public function testDeleteUserDeletesShares() {
// This tests the ON DELETE CASCADE constraint
$pdo = $this->db->getConnection();
// Ensure user 999 exists for test
- $pdo->exec("INSERT INTO users (id, username, password) VALUES (999, 'testuser_delete', 'pass') ON CONFLICT (id) DO UPDATE SET username = EXCLUDED.username");
-
- $uuid = $this->shareManager->createShare(999, 'cascadetest.txt', 'forever');
+ $stmt = $this->db->getConnection()->prepare("INSERT INTO users (username, password) VALUES (?, ?) RETURNING id");
+ $stmt->execute(['testuser_delete', 'pass']);
+ $result = $stmt->fetch(PDO::FETCH_ASSOC);
+
+ $uuid = $this->shareManager->createShare($result['id'], 'cascadetest.txt', 'forever');
$this->assertNotNull($this->shareManager->getShare($uuid));
- $pdo->exec("DELETE FROM users WHERE id = 999");
+ $pdo->exec("DELETE FROM users WHERE id = '" . $result['id'] . "'");
// The share should be gone
$stmt = $pdo->prepare("SELECT COUNT(*) FROM shared_files WHERE uuid = ?");
@@ -118,10 +133,13 @@ public function testDeleteUserDeletesShares() {
}
public function testListShares() {
- $this->shareManager->createShare(1, 'file1.txt', 'forever');
- $this->shareManager->createShare(1, 'file2.txt', '1h');
+ $stmt = $this->db->getConnection()->prepare("SELECT * FROM users WHERE username = ?");
+ $stmt->execute(['admin']);
+ $user = $stmt->fetch();
+ $this->shareManager->createShare($user['id'], 'file1.txt', 'forever');
+ $this->shareManager->createShare($user['id'], 'file2.txt', '1h');
- $shares = $this->shareManager->listShares(1);
+ $shares = $this->shareManager->listShares($user['id']);
$this->assertCount(2, $shares);
// Should be ordered by created_at DESC, so file2.txt is likely first if created after
$this->assertEquals('file2.txt', $shares[0]['filename']);
@@ -129,19 +147,25 @@ public function testListShares() {
}
public function testDeleteShare() {
- $uuid = $this->shareManager->createShare(1, 'todelete.txt', 'forever');
+ $stmt = $this->db->getConnection()->prepare("SELECT * FROM users WHERE username = ?");
+ $stmt->execute(['admin']);
+ $user = $stmt->fetch();
+ $uuid = $this->shareManager->createShare($user["id"], 'todelete.txt', 'forever');
$this->assertNotNull($this->shareManager->getShare($uuid));
- $result = $this->shareManager->deleteShare($uuid, 1);
+ $result = $this->shareManager->deleteShare($uuid, $user['id']);
$this->assertTrue($result);
$this->assertNull($this->shareManager->getShare($uuid));
}
public function testDeleteShareInvalidUser() {
- $uuid = $this->shareManager->createShare(1, 'notmine.txt', 'forever');
+ $stmt = $this->db->getConnection()->prepare("SELECT * FROM users WHERE username = ?");
+ $stmt->execute(['admin']);
+ $user = $stmt->fetch();
+ $uuid = $this->shareManager->createShare($user["id"], 'notmine.txt', 'forever');
// Try to delete with user 2 (which doesn't exist but we want to check user_id check)
- $result = $this->shareManager->deleteShare($uuid, 2);
+ $result = $this->shareManager->deleteShare($uuid, "38b6b309-74c3-4eab-88e1-64a2a0f9d4ac");
$this->assertFalse($result);
$this->assertNotNull($this->shareManager->getShare($uuid));
}
diff --git a/tests/UserManagerTest.php b/tests/UserManagerTest.php
index 261325d..fab8f55 100755
--- a/tests/UserManagerTest.php
+++ b/tests/UserManagerTest.php
@@ -19,7 +19,7 @@ protected function setUp(): void {
$pdo->exec("DROP TABLE IF EXISTS users CASCADE;");
$pdo->exec("
CREATE TABLE users (
- id SERIAL PRIMARY KEY,
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
username VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
role VARCHAR(50) DEFAULT 'user',