CatPtain commited on
Commit
5186047
·
verified ·
1 Parent(s): d35d407

Upload 5 files

Browse files
Files changed (5) hide show
  1. config.php +53 -60
  2. index.html +187 -91
  3. save.php +10 -24
  4. storage.php +10 -544
  5. user-manager.php +49 -25
config.php CHANGED
@@ -1,16 +1,15 @@
1
  <?php
2
  require_once __DIR__ . '/storage.php';
 
3
 
4
- // Try GitHub user management first
5
- $githubUserManager = new GitHubUserManager();
6
- $useGitHubAuth = true;
7
-
8
- // Check authentication - prioritize GitHub user management
9
  $authenticated = false;
10
- if ($githubUserManager->isLoggedIn()) {
 
11
  $authenticated = true;
12
  } else {
13
- // Fallback to environment variable authentication
14
  if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
15
  $users = StorageConfig::getUsers();
16
  $username = $_SERVER['PHP_AUTH_USER'];
@@ -18,7 +17,6 @@ if ($githubUserManager->isLoggedIn()) {
18
 
19
  if (isset($users[$username]) && $users[$username] === $password) {
20
  $authenticated = true;
21
- $useGitHubAuth = false;
22
  }
23
  }
24
  }
@@ -53,33 +51,34 @@ if (!$authenticated) {
53
  <!-- User Management Section -->
54
  <div class="config-section">
55
  <h2>👥 用户管理系统</h2>
56
- <?php if ($useGitHubAuth): ?>
57
- <div class="status-item status-ok">✅ 使用 GitHub 用户管理</div>
58
- <div class="status-item status-ok">👤 当前用户: <?= htmlspecialchars($githubUserManager->getCurrentUser()) ?></div>
 
 
 
 
 
59
 
60
- <div class="mt-3">
61
- <h4>💡 GitHub 用户管理特性</h4>
62
- <ul>
63
- <li>✅ 用户数据存储在 GitHub 仓库中,永不丢失</li>
64
- <li>✅ 多实例间自动同步用户数据</li>
65
- <li>✅ 每次登录都从 GitHub 加载最新数据</li>
66
- <li>✅ 支持登录和密码修改功能</li>
67
- </ul>
68
- </div>
69
- <?php else: ?>
70
- <div class="status-item status-warning">⚠️ 使用环境变量用户管理 (基础模式)</div>
71
- <?php
72
- $envUsers = StorageConfig::getUsers();
73
- if (!empty($envUsers)) {
74
- echo '<div class="status-item status-ok">✅ ' . count($envUsers) . ' 个环境变量用户</div>';
75
- foreach ($envUsers as $username => $password) {
76
- echo '<div class="status-item status-ok">👤 User: ' . htmlspecialchars($username) . '</div>';
77
- }
78
- } else {
79
- echo '<div class="status-item status-error">❌ 未找到用户配置</div>';
80
  }
81
- ?>
82
- <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  </div>
84
 
85
  <!-- Storage Configuration -->
@@ -112,6 +111,7 @@ if (!$authenticated) {
112
  echo '<div class="status-item status-ok">✅ Repository: ' . htmlspecialchars($github['owner']) . '/' . htmlspecialchars($github['repo']) . '</div>';
113
  echo '<div class="status-item status-ok">🌿 Branch: ' . htmlspecialchars($github['branch']) . '</div>';
114
  echo '<div class="status-item status-ok">📂 Path: ' . htmlspecialchars($github['path']) . '</div>';
 
115
  }
116
  }
117
 
@@ -140,22 +140,6 @@ if (!$authenticated) {
140
  echo '<div class="status-item status-error"> - ' . htmlspecialchars($error) . '</div>';
141
  }
142
  }
143
-
144
- // Test GitHub connectivity if configured
145
- if (!empty($github['token']) && !empty($github['owner']) && !empty($github['repo'])) {
146
- echo '<h4>🔗 GitHub 连接测试</h4>';
147
- try {
148
- $branchCheck = StorageConfig::checkGitHubBranch();
149
- if ($branchCheck['success']) {
150
- echo '<div class="status-item status-ok">✅ GitHub 连接正常</div>';
151
- echo '<div class="status-item status-ok">🌿 分支检查: ' . htmlspecialchars($branchCheck['message']) . '</div>';
152
- } else {
153
- echo '<div class="status-item status-error">❌ GitHub 连接失败: ' . htmlspecialchars($branchCheck['message']) . '</div>';
154
- }
155
- } catch (Exception $e) {
156
- echo '<div class="status-item status-error">❌ GitHub 测试异常: ' . htmlspecialchars($e->getMessage()) . '</div>';
157
- }
158
- }
159
  ?>
160
  </div>
161
 
@@ -164,29 +148,38 @@ if (!$authenticated) {
164
  <h2>🚀 快速操作</h2>
165
  <div class="row">
166
  <div class="col-md-6">
167
- <a href="editor.html" class="btn btn-primary btn-lg w-100">
168
- 📝 启动编辑器
169
  </a>
170
  </div>
171
  <div class="col-md-6">
172
- <a href="login.html" class="btn btn-success btn-lg w-100">
173
- 🔐 用户登录
174
  </a>
175
  </div>
176
  </div>
177
  </div>
178
 
179
- <!-- User Data Migration Notice -->
180
- <?php if (file_exists(__DIR__ . '/user-data/users.json')): ?>
181
  <div class="config-section">
 
182
  <div class="alert alert-info">
183
- <h4>📋 数据迁移提示</h4>
184
- <p>检测到本地用户数据文件 <code>user-data/users.json</code>。</p>
185
- <p>现在系统已升级为从 GitHub 仓库加载用户数据,确保多实例间数据同步。</p>
186
- <p>如需迁移现有用户数据,请联系管理员。</p>
 
 
 
 
 
 
 
 
 
 
187
  </div>
188
  </div>
189
- <?php endif; ?>
190
  </div>
191
  </div>
192
  </div>
 
1
  <?php
2
  require_once __DIR__ . '/storage.php';
3
+ require_once __DIR__ . '/user-manager.php';
4
 
5
+ // Check authentication
6
+ $userManager = new UserManager();
 
 
 
7
  $authenticated = false;
8
+
9
+ if ($userManager->isLoggedIn()) {
10
  $authenticated = true;
11
  } else {
12
+ // Fallback to Basic Auth for environment variables
13
  if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
14
  $users = StorageConfig::getUsers();
15
  $username = $_SERVER['PHP_AUTH_USER'];
 
17
 
18
  if (isset($users[$username]) && $users[$username] === $password) {
19
  $authenticated = true;
 
20
  }
21
  }
22
  }
 
51
  <!-- User Management Section -->
52
  <div class="config-section">
53
  <h2>👥 用户管理系统</h2>
54
+ <?php
55
+ $envUsers = StorageConfig::getUsers();
56
+ if (!empty($envUsers)) {
57
+ echo '<div class="status-item status-ok">✅ 环境变量用户系统 (简单高效)</div>';
58
+ echo '<div class="status-item status-ok">📊 已配置 ' . count($envUsers) . ' 个用户账号</div>';
59
+ foreach ($envUsers as $username => $password) {
60
+ echo '<div class="status-item status-ok">👤 用户: ' . htmlspecialchars($username) . '</div>';
61
+ }
62
 
63
+ if ($userManager->isLoggedIn()) {
64
+ echo '<div class="status-item status-ok">🔐 当前登录用户: ' . htmlspecialchars($userManager->getCurrentUser()) . '</div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  }
66
+ } else {
67
+ echo '<div class="status-item status-error">❌ 未找到用户配置</div>';
68
+ echo '<div class="status-item status-warning">请检查环境变量 USER_1_NAME, USER_1_PASSWORD 等设置</div>';
69
+ }
70
+ ?>
71
+
72
+ <div class="mt-3">
73
+ <h4>💡 用户管理特性</h4>
74
+ <ul>
75
+ <li>✅ 基于环境变量配置,安全可靠</li>
76
+ <li>✅ 用户数据按账号隔离存储</li>
77
+ <li>✅ GitHub仓库按用户目录分类</li>
78
+ <li>✅ 支持session登录,用户体验良好</li>
79
+ <li>✅ 无注册功能,管理员完全控制</li>
80
+ </ul>
81
+ </div>
82
  </div>
83
 
84
  <!-- Storage Configuration -->
 
111
  echo '<div class="status-item status-ok">✅ Repository: ' . htmlspecialchars($github['owner']) . '/' . htmlspecialchars($github['repo']) . '</div>';
112
  echo '<div class="status-item status-ok">🌿 Branch: ' . htmlspecialchars($github['branch']) . '</div>';
113
  echo '<div class="status-item status-ok">📂 Path: ' . htmlspecialchars($github['path']) . '</div>';
114
+ echo '<div class="status-item status-ok">🔗 用户文件存储结构: <code>' . htmlspecialchars($github['path']) . 'users/{username}/*.html</code></div>';
115
  }
116
  }
117
 
 
140
  echo '<div class="status-item status-error"> - ' . htmlspecialchars($error) . '</div>';
141
  }
142
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  ?>
144
  </div>
145
 
 
148
  <h2>🚀 快速操作</h2>
149
  <div class="row">
150
  <div class="col-md-6">
151
+ <a href="/" class="btn btn-success btn-lg w-100">
152
+ 🔐 用户登录
153
  </a>
154
  </div>
155
  <div class="col-md-6">
156
+ <a href="editor.html" class="btn btn-primary btn-lg w-100">
157
+ 📝 启动编辑器
158
  </a>
159
  </div>
160
  </div>
161
  </div>
162
 
163
+ <!-- File Structure Info -->
 
164
  <div class="config-section">
165
+ <h2>📁 文件结构说明</h2>
166
  <div class="alert alert-info">
167
+ <h5>GitHub 存储结构</h5>
168
+ <pre><code>pages/
169
+ ├── users/
170
+ │ ├── PS01/
171
+ │ │ ├── index.html
172
+ │ │ └── about.html
173
+ │ ├── PS02/
174
+ │ │ ├── portfolio.html
175
+ │ │ └── contact.html
176
+ │ ├── PS03/
177
+ │ │ └── blog.html
178
+ │ └── PS04/
179
+ │ └── products.html</code></pre>
180
+ <p><strong>说明:</strong> 每个用户只能访问和编辑自己目录下的文件,实现完全的数据隔离。</p>
181
  </div>
182
  </div>
 
183
  </div>
184
  </div>
185
  </div>
index.html CHANGED
@@ -1,127 +1,223 @@
1
  <!DOCTYPE html>
2
- <html lang="en">
3
  <head>
4
- <meta charset="utf-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1">
6
  <title>VvvebJs - Visual Website Builder</title>
 
7
  <style>
8
  body {
9
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
10
  min-height: 100vh;
11
  display: flex;
12
- flex-direction: column;
13
- justify-content: center;
14
  align-items: center;
15
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
16
- margin: 0;
17
- padding: 20px;
18
  }
19
-
20
- .cyber-card {
21
- background: rgba(255, 255, 255, 0.1);
22
- backdrop-filter: blur(20px);
23
- border: 1px solid rgba(255, 255, 255, 0.2);
24
  border-radius: 20px;
 
25
  padding: 40px;
26
- text-align: center;
27
- box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
28
- margin-bottom: 30px;
29
  min-width: 400px;
 
30
  }
31
-
32
- .repo-title {
33
- color: #fff;
34
- font-size: 2.5em;
35
- font-weight: 700;
36
- margin: 0 0 10px 0;
37
- text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
38
  }
39
-
40
- .repo-subtitle {
41
- color: rgba(255, 255, 255, 0.8);
42
- font-size: 1.2em;
43
- margin: 0 0 20px 0;
44
  }
45
-
46
- .repo-info {
47
- display: flex;
48
- justify-content: space-around;
49
- margin: 20px 0;
50
  }
51
-
52
- .info-item {
53
- color: rgba(255, 255, 255, 0.9);
54
- font-size: 0.9em;
 
55
  }
56
-
57
- .info-value {
58
- display: block;
59
- color: #fff;
60
- font-weight: 600;
61
- margin-top: 5px;
62
  }
63
-
64
- .login-btn {
65
- background: linear-gradient(45deg, #ff6b6b, #4ecdc4);
66
- color: white;
67
  border: none;
68
- padding: 15px 40px;
69
- font-size: 1.1em;
70
  font-weight: 600;
71
- border-radius: 50px;
72
- cursor: pointer;
73
- text-decoration: none;
74
- display: inline-block;
75
- transition: all 0.3s ease;
76
- box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
77
  }
78
-
79
- .login-btn:hover {
80
  transform: translateY(-2px);
81
- box-shadow: 0 15px 30px rgba(0, 0, 0, 0.3);
 
82
  }
83
-
84
- @media (max-width: 480px) {
85
- .cyber-card {
86
- min-width: auto;
87
- margin: 0 10px 30px 10px;
88
- padding: 30px 20px;
89
- }
90
- .repo-title {
91
- font-size: 2em;
92
- }
93
- .repo-info {
94
- flex-direction: column;
95
- gap: 15px;
96
- }
 
 
 
 
 
97
  }
98
  </style>
99
  </head>
100
  <body>
101
- <!-- 赛博信息卡片仓库 -->
102
- <div class="cyber-card">
103
- <h1 class="repo-title">🔮 VvvebJs</h1>
104
- <p class="repo-subtitle">赛博网站构建器</p>
 
105
 
106
- <div class="repo-info">
107
- <div class="info-item">
108
- <span>存储类型</span>
109
- <span class="info-value">GitHub</span>
110
- </div>
111
- <div class="info-item">
112
- <span>认证状态</span>
113
- <span class="info-value">🔐 安全</span>
114
  </div>
115
- <div class="info-item">
116
- <span>版本</span>
117
- <span class="info-value">v2.0</span>
 
118
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  </div>
120
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
 
122
- <!-- 登录按钮 -->
123
- <a href="editor.html" class="login-btn">
124
- 🚀 进入编辑器
125
- </a>
126
  </body>
127
  </html>
 
1
  <!DOCTYPE html>
2
+ <html lang="zh-CN">
3
  <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>VvvebJs - Visual Website Builder</title>
7
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
8
  <style>
9
  body {
10
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
11
  min-height: 100vh;
12
  display: flex;
 
 
13
  align-items: center;
14
+ justify-content: center;
15
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 
16
  }
17
+ .login-container {
18
+ background: rgba(255, 255, 255, 0.95);
 
 
 
19
  border-radius: 20px;
20
+ box-shadow: 0 20px 40px rgba(0,0,0,0.1);
21
  padding: 40px;
 
 
 
22
  min-width: 400px;
23
+ backdrop-filter: blur(10px);
24
  }
25
+ .login-header {
26
+ text-align: center;
27
+ margin-bottom: 30px;
 
 
 
 
28
  }
29
+ .login-header h1 {
30
+ color: #333;
31
+ font-weight: 600;
32
+ margin-bottom: 10px;
 
33
  }
34
+ .login-header p {
35
+ color: #666;
36
+ margin: 0;
 
 
37
  }
38
+ .form-control {
39
+ border-radius: 10px;
40
+ padding: 12px 16px;
41
+ border: 2px solid #e1e5e9;
42
+ margin-bottom: 20px;
43
  }
44
+ .form-control:focus {
45
+ border-color: #667eea;
46
+ box-shadow: 0 0 0 0.2rem rgba(102, 126, 234, 0.25);
 
 
 
47
  }
48
+ .btn-login {
49
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
 
 
50
  border: none;
51
+ border-radius: 10px;
52
+ padding: 12px;
53
  font-weight: 600;
54
+ color: white;
55
+ width: 100%;
56
+ margin-top: 10px;
 
 
 
57
  }
58
+ .btn-login:hover {
 
59
  transform: translateY(-2px);
60
+ box-shadow: 0 10px 25px rgba(102, 126, 234, 0.3);
61
+ color: white;
62
  }
63
+ .alert {
64
+ border-radius: 10px;
65
+ margin-bottom: 20px;
66
+ }
67
+ .features {
68
+ margin-top: 30px;
69
+ padding-top: 20px;
70
+ border-top: 1px solid #e1e5e9;
71
+ }
72
+ .features h6 {
73
+ color: #333;
74
+ margin-bottom: 15px;
75
+ }
76
+ .features ul {
77
+ color: #666;
78
+ font-size: 14px;
79
+ }
80
+ .features ul li {
81
+ margin-bottom: 8px;
82
  }
83
  </style>
84
  </head>
85
  <body>
86
+ <div class="login-container">
87
+ <div class="login-header">
88
+ <h1>🎨 VvvebJs Editor</h1>
89
+ <p>请登录以继续使用可网站编辑器</p>
90
+ </div>
91
 
92
+ <div id="alert-container"></div>
93
+
94
+ <form id="loginForm">
95
+ <div class="form-group">
96
+ <label for="username" class="form-label">用户名</label>
97
+ <input type="text" class="form-control" id="username" name="username" placeholder="请输入用户名" required>
 
 
98
  </div>
99
+
100
+ <div class="form-group">
101
+ <label for="password" class="form-label">密码</label>
102
+ <input type="password" class="form-control" id="password" name="password" placeholder="请输入密码" required>
103
  </div>
104
+
105
+ <button type="submit" class="btn btn-login">
106
+ <span id="loginText">登录</span>
107
+ <span id="loginSpinner" class="spinner-border spinner-border-sm d-none" role="status"></span>
108
+ </button>
109
+ </form>
110
+
111
+ <div class="features">
112
+ <h6>🚀 主要功能</h6>
113
+ <ul>
114
+ <li>🎨 可视化拖拽编辑器</li>
115
+ <li>📱 Bootstrap 5 响应式组件</li>
116
+ <li>💾 GitHub 云端存储,数据按用户隔离</li>
117
+ <li>🔄 实时保存,多实例同步</li>
118
+ <li>🔒 用户权限隔离,只能访问自己的文件</li>
119
+ </ul>
120
  </div>
121
  </div>
122
+
123
+ <script>
124
+ // Check if already logged in
125
+ window.onload = function() {
126
+ fetch('user-manager.php', {
127
+ method: 'POST',
128
+ headers: {
129
+ 'Content-Type': 'application/x-www-form-urlencoded',
130
+ },
131
+ body: 'action=check_login'
132
+ })
133
+ .then(response => response.json())
134
+ .then(data => {
135
+ if (data.logged_in) {
136
+ // Already logged in, redirect to editor
137
+ window.location.href = 'editor.html';
138
+ }
139
+ })
140
+ .catch(error => {
141
+ console.log('Auth check failed:', error);
142
+ });
143
+ };
144
+
145
+ function showAlert(message, type = 'danger') {
146
+ const alertContainer = document.getElementById('alert-container');
147
+ alertContainer.innerHTML = `
148
+ <div class="alert alert-${type} alert-dismissible fade show" role="alert">
149
+ ${message}
150
+ <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
151
+ </div>
152
+ `;
153
+ }
154
+
155
+ function setLoading(loading) {
156
+ const loginText = document.getElementById('loginText');
157
+ const loginSpinner = document.getElementById('loginSpinner');
158
+ const submitBtn = document.querySelector('.btn-login');
159
+
160
+ if (loading) {
161
+ loginText.classList.add('d-none');
162
+ loginSpinner.classList.remove('d-none');
163
+ submitBtn.disabled = true;
164
+ } else {
165
+ loginText.classList.remove('d-none');
166
+ loginSpinner.classList.add('d-none');
167
+ submitBtn.disabled = false;
168
+ }
169
+ }
170
+
171
+ document.getElementById('loginForm').addEventListener('submit', async function(e) {
172
+ e.preventDefault();
173
+
174
+ const username = document.getElementById('username').value;
175
+ const password = document.getElementById('password').value;
176
+
177
+ if (!username || !password) {
178
+ showAlert('请填写用户名和密码');
179
+ return;
180
+ }
181
+
182
+ setLoading(true);
183
+
184
+ try {
185
+ const response = await fetch('user-manager.php', {
186
+ method: 'POST',
187
+ headers: {
188
+ 'Content-Type': 'application/x-www-form-urlencoded',
189
+ },
190
+ body: `action=login&username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}`
191
+ });
192
+
193
+ const result = await response.json();
194
+
195
+ if (result.success) {
196
+ showAlert('登录成功!正在跳转...', 'success');
197
+ setTimeout(() => {
198
+ window.location.href = 'editor.html';
199
+ }, 1000);
200
+ } else {
201
+ showAlert(result.message || '登录失败');
202
+ setLoading(false);
203
+ }
204
+ } catch (error) {
205
+ showAlert('网络错误,请重试');
206
+ setLoading(false);
207
+ }
208
+ });
209
+
210
+ // Auto focus on username field
211
+ document.getElementById('username').focus();
212
+
213
+ // Allow Enter key to submit
214
+ document.addEventListener('keypress', function(e) {
215
+ if (e.key === 'Enter') {
216
+ document.getElementById('loginForm').dispatchEvent(new Event('submit'));
217
+ }
218
+ });
219
+ </script>
220
 
221
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
 
 
 
222
  </body>
223
  </html>
save.php CHANGED
@@ -18,34 +18,20 @@ https://github.com/givanz/VvvebJs
18
 
19
  // Include storage classes
20
  require_once __DIR__ . '/storage.php';
 
21
 
22
- // Authentication check using GitHub-based user management
23
  function checkAuth() {
24
- // Try GitHub user management first
25
- $githubUserManager = new GitHubUserManager();
26
 
27
  // Check if user is logged in via session
28
- if ($githubUserManager->isLoggedIn()) {
29
  return true;
30
  }
31
 
32
- // Fallback to Basic Auth for environment variables
33
- if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW'])) {
34
- header('WWW-Authenticate: Basic realm="VvvebJs"');
35
- header('HTTP/1.0 401 Unauthorized');
36
- die('Authentication required');
37
- }
38
-
39
- $users = StorageConfig::getUsers();
40
- $username = $_SERVER['PHP_AUTH_USER'];
41
- $password = $_SERVER['PHP_AUTH_PW'];
42
-
43
- if (!isset($users[$username]) || $users[$username] !== $password) {
44
- header('HTTP/1.0 401 Unauthorized');
45
- die('Invalid credentials');
46
- }
47
-
48
- return true;
49
  }
50
 
51
  // Check authentication
@@ -53,10 +39,10 @@ $action = $_GET['action'] ?? $_POST['action'] ?? '';
53
 
54
  // Special handling for auth check
55
  if ($action === 'checkAuth') {
56
- $githubUserManager = new GitHubUserManager();
57
- if ($githubUserManager->isLoggedIn()) {
58
  http_response_code(200);
59
- echo json_encode(['authenticated' => true, 'user' => $githubUserManager->getCurrentUser()]);
60
  } else {
61
  http_response_code(401);
62
  echo json_encode(['authenticated' => false]);
 
18
 
19
  // Include storage classes
20
  require_once __DIR__ . '/storage.php';
21
+ require_once __DIR__ . '/user-manager.php';
22
 
23
+ // Authentication check
24
  function checkAuth() {
25
+ $userManager = new UserManager();
 
26
 
27
  // Check if user is logged in via session
28
+ if ($userManager->isLoggedIn()) {
29
  return true;
30
  }
31
 
32
+ // No authentication found
33
+ header('Location: login.html');
34
+ exit;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  }
36
 
37
  // Check authentication
 
39
 
40
  // Special handling for auth check
41
  if ($action === 'checkAuth') {
42
+ $userManager = new UserManager();
43
+ if ($userManager->isLoggedIn()) {
44
  http_response_code(200);
45
+ echo json_encode(['authenticated' => true, 'user' => $userManager->getCurrentUser()]);
46
  } else {
47
  http_response_code(401);
48
  echo json_encode(['authenticated' => false]);
storage.php CHANGED
@@ -43,6 +43,16 @@ class StorageConfig {
43
  }
44
 
45
  public static function getCurrentUser() {
 
 
 
 
 
 
 
 
 
 
46
  return $_SERVER['PHP_AUTH_USER'] ?? 'anonymous';
47
  }
48
 
@@ -54,550 +64,6 @@ class StorageConfig {
54
  $safeUsername = preg_replace('/[^a-zA-Z0-9_-]/', '_', $username);
55
  return "users/{$safeUsername}/";
56
  }
57
-
58
- private static function makeGitHubRequest($url, $method = 'GET', $data = null) {
59
- $config = self::getGitHubConfig();
60
-
61
- if (empty($config['token'])) {
62
- return [
63
- 'body' => false,
64
- 'http_code' => 401,
65
- 'headers' => [],
66
- 'error' => 'GitHub token not configured'
67
- ];
68
- }
69
-
70
- $headers = [
71
- 'Authorization: token ' . $config['token'],
72
- 'Accept: application/vnd.github.v3+json',
73
- 'User-Agent: VvvebJs-Visual-Editor/1.0',
74
- 'Content-Type: application/json'
75
- ];
76
-
77
- $contextOptions = [
78
- 'http' => [
79
- 'method' => $method,
80
- 'header' => implode("\r\n", $headers),
81
- 'ignore_errors' => true,
82
- 'timeout' => 30
83
- ]
84
- ];
85
-
86
- if ($data && in_array($method, ['POST', 'PUT', 'PATCH'])) {
87
- $contextOptions['http']['content'] = json_encode($data);
88
- }
89
-
90
- $context = stream_context_create($contextOptions);
91
- $response = @file_get_contents($url, false, $context);
92
- $httpCode = 0;
93
-
94
- if (isset($http_response_header)) {
95
- foreach ($http_response_header as $header) {
96
- if (preg_match('/HTTP\/\d\.\d\s+(\d+)/', $header, $matches)) {
97
- $httpCode = (int)$matches[1];
98
- break;
99
- }
100
- }
101
- }
102
-
103
- return [
104
- 'body' => $response,
105
- 'http_code' => $httpCode,
106
- 'headers' => $http_response_header ?? [],
107
- 'error' => $response === false ? 'Request failed' : null
108
- ];
109
- }
110
-
111
- public static function checkGitHubBranch() {
112
- $config = self::getGitHubConfig();
113
-
114
- if (empty($config['token']) || empty($config['owner']) || empty($config['repo'])) {
115
- return [
116
- 'success' => false,
117
- 'http_code' => 400,
118
- 'message' => 'GitHub configuration incomplete'
119
- ];
120
- }
121
-
122
- // First check if repository exists and get default branch
123
- $repoUrl = "https://api.github.com/repos/{$config['owner']}/{$config['repo']}";
124
- $repoResult = self::makeGitHubRequest($repoUrl);
125
-
126
- if ($repoResult['http_code'] !== 200) {
127
- return [
128
- 'success' => false,
129
- 'http_code' => $repoResult['http_code'],
130
- 'message' => 'Cannot access repository: ' . ($repoResult['error'] ?? 'Unknown error')
131
- ];
132
- }
133
-
134
- $repoData = json_decode($repoResult['body'], true);
135
- $defaultBranch = $repoData['default_branch'] ?? 'main';
136
-
137
- // If user specified branch matches default branch, use it
138
- if ($config['branch'] === $defaultBranch) {
139
- return [
140
- 'success' => true,
141
- 'http_code' => 200,
142
- 'message' => "Using default branch: {$defaultBranch}",
143
- 'branch' => $defaultBranch
144
- ];
145
- }
146
-
147
- // Check if specified branch exists
148
- $branchUrl = "https://api.github.com/repos/{$config['owner']}/{$config['repo']}/branches/{$config['branch']}";
149
- $branchResult = self::makeGitHubRequest($branchUrl);
150
-
151
- if ($branchResult['http_code'] === 200) {
152
- return [
153
- 'success' => true,
154
- 'http_code' => 200,
155
- 'message' => "Branch '{$config['branch']}' exists",
156
- 'branch' => $config['branch']
157
- ];
158
- }
159
-
160
- // If branch doesn't exist, try to create it
161
- if ($branchResult['http_code'] === 404) {
162
- return self::createGitHubBranch($defaultBranch);
163
- }
164
-
165
- return [
166
- 'success' => false,
167
- 'http_code' => $branchResult['http_code'],
168
- 'message' => "Branch check failed: " . ($branchResult['error'] ?? 'Unknown error')
169
- ];
170
- }
171
-
172
- private static function createGitHubBranch($defaultBranch = 'main') {
173
- $config = self::getGitHubConfig();
174
-
175
- // Get the default branch reference
176
- $refUrl = "https://api.github.com/repos/{$config['owner']}/{$config['repo']}/git/refs/heads/{$defaultBranch}";
177
- $refResult = self::makeGitHubRequest($refUrl);
178
-
179
- if ($refResult['http_code'] !== 200) {
180
- return [
181
- 'success' => false,
182
- 'http_code' => $refResult['http_code'],
183
- 'message' => "Cannot get {$defaultBranch} branch reference: " . ($refResult['error'] ?? 'Unknown error')
184
- ];
185
- }
186
-
187
- $refData = json_decode($refResult['body'], true);
188
- $sha = $refData['object']['sha'];
189
-
190
- // Create new branch
191
- $createUrl = "https://api.github.com/repos/{$config['owner']}/{$config['repo']}/git/refs";
192
- $createData = [
193
- 'ref' => "refs/heads/{$config['branch']}",
194
- 'sha' => $sha
195
- ];
196
-
197
- $createResult = self::makeGitHubRequest($createUrl, 'POST', $createData);
198
-
199
- if ($createResult['http_code'] === 201) {
200
- return [
201
- 'success' => true,
202
- 'http_code' => 201,
203
- 'message' => "Branch '{$config['branch']}' created successfully",
204
- 'branch' => $config['branch']
205
- ];
206
- }
207
-
208
- return [
209
- 'success' => false,
210
- 'http_code' => $createResult['http_code'],
211
- 'message' => "Failed to create branch: " . ($createResult['error'] ?? 'Unknown error')
212
- ];
213
- }
214
-
215
- public static function testGitHubPermissions() {
216
- $config = self::getGitHubConfig();
217
-
218
- // Test by creating a simple test file
219
- $testFile = '.vvvebjs-test-' . time() . '.txt';
220
- $testContent = 'VvvebJs test file - safe to delete';
221
-
222
- $result = self::saveToGitHub($testFile, $testContent);
223
-
224
- if ($result['success']) {
225
- // Try to delete the test file
226
- self::deleteFromGitHub($testFile);
227
- }
228
-
229
- return $result;
230
- }
231
-
232
- public static function saveToGitHub($filename, $content) {
233
- $config = self::getGitHubConfig();
234
- $path = rtrim($config['path'], '/') . '/' . ltrim($filename, '/');
235
-
236
- // Check if file exists first
237
- $fileUrl = "https://api.github.com/repos/{$config['owner']}/{$config['repo']}/contents/{$path}";
238
- $fileResult = self::makeGitHubRequest($fileUrl);
239
-
240
- $isUpdate = $fileResult['http_code'] === 200;
241
- $sha = null;
242
-
243
- if ($isUpdate) {
244
- $fileData = json_decode($fileResult['body'], true);
245
- $sha = $fileData['sha'] ?? null;
246
- }
247
-
248
- $commitData = [
249
- 'message' => $isUpdate ? "Update {$filename}" : "Create {$filename}",
250
- 'content' => base64_encode($content),
251
- 'branch' => $config['branch']
252
- ];
253
-
254
- if ($sha) {
255
- $commitData['sha'] = $sha;
256
- }
257
-
258
- $result = self::makeGitHubRequest($fileUrl, 'PUT', $commitData);
259
-
260
- return [
261
- 'success' => in_array($result['http_code'], [200, 201]),
262
- 'http_code' => $result['http_code'],
263
- 'message' => in_array($result['http_code'], [200, 201]) ?
264
- ($isUpdate ? 'File updated' : 'File created') :
265
- 'Save failed: ' . ($result['error'] ?? 'Unknown error')
266
- ];
267
- }
268
-
269
- public static function deleteFromGitHub($filename) {
270
- $config = self::getGitHubConfig();
271
- $path = rtrim($config['path'], '/') . '/' . ltrim($filename, '/');
272
-
273
- // Get file info first
274
- $fileUrl = "https://api.github.com/repos/{$config['owner']}/{$config['repo']}/contents/{$path}";
275
- $fileResult = self::makeGitHubRequest($fileUrl);
276
-
277
- if ($fileResult['http_code'] !== 200) {
278
- return [
279
- 'success' => false,
280
- 'http_code' => $fileResult['http_code'],
281
- 'message' => 'File not found or inaccessible'
282
- ];
283
- }
284
-
285
- $fileData = json_decode($fileResult['body'], true);
286
- $sha = $fileData['sha'];
287
-
288
- $deleteData = [
289
- 'message' => "Delete {$filename}",
290
- 'sha' => $sha,
291
- 'branch' => $config['branch']
292
- ];
293
-
294
- $result = self::makeGitHubRequest($fileUrl, 'DELETE', $deleteData);
295
-
296
- return [
297
- 'success' => $result['http_code'] === 200,
298
- 'http_code' => $result['http_code'],
299
- 'message' => $result['http_code'] === 200 ? 'File deleted' : 'Delete failed'
300
- ];
301
- }
302
- }
303
-
304
- // GitHub-based User Manager
305
- class GitHubUserManager {
306
- private $config;
307
- private $usersFilePath = 'system/users.json';
308
-
309
- public function __construct() {
310
- $this->config = StorageConfig::getGitHubConfig();
311
- session_start();
312
- }
313
-
314
- /**
315
- * Load user data from GitHub repository
316
- */
317
- private function loadUsersFromGitHub() {
318
- if (empty($this->config['token']) || empty($this->config['owner']) || empty($this->config['repo'])) {
319
- error_log("GitHub User Manager: Configuration incomplete");
320
- return [];
321
- }
322
-
323
- $url = "https://api.github.com/repos/{$this->config['owner']}/{$this->config['repo']}/contents/{$this->usersFilePath}";
324
-
325
- $result = $this->makeGitHubRequest($url, 'GET');
326
-
327
- if ($result['http_code'] === 200) {
328
- $fileData = json_decode($result['body'], true);
329
- if (isset($fileData['content'])) {
330
- $usersJson = base64_decode($fileData['content']);
331
- $users = json_decode($usersJson, true);
332
- if (json_last_error() === JSON_ERROR_NONE) {
333
- error_log("GitHub User Manager: Successfully loaded " . count($users) . " users from GitHub");
334
- return $users;
335
- }
336
- }
337
- } elseif ($result['http_code'] === 404) {
338
- // Users file doesn't exist yet, create empty structure
339
- error_log("GitHub User Manager: Users file not found, will create on first registration");
340
- return [];
341
- }
342
-
343
- error_log("GitHub User Manager: Failed to load users from GitHub. HTTP Code: " . $result['http_code']);
344
- return [];
345
- }
346
-
347
- /**
348
- * Save user data to GitHub repository
349
- */
350
- private function saveUsersToGitHub($users) {
351
- if (empty($this->config['token']) || empty($this->config['owner']) || empty($this->config['repo'])) {
352
- return false;
353
- }
354
-
355
- $url = "https://api.github.com/repos/{$this->config['owner']}/{$this->config['repo']}/contents/{$this->usersFilePath}";
356
-
357
- // Get current file SHA if exists
358
- $fileResult = $this->makeGitHubRequest($url, 'GET');
359
- $sha = null;
360
- $isUpdate = false;
361
-
362
- if ($fileResult['http_code'] === 200) {
363
- $fileData = json_decode($fileResult['body'], true);
364
- $sha = $fileData['sha'] ?? null;
365
- $isUpdate = true;
366
- }
367
-
368
- $usersJson = json_encode($users, JSON_PRETTY_PRINT);
369
- $commitData = [
370
- 'message' => $isUpdate ? 'Update user data' : 'Create user data file',
371
- 'content' => base64_encode($usersJson),
372
- 'branch' => $this->config['branch']
373
- ];
374
-
375
- if ($sha) {
376
- $commitData['sha'] = $sha;
377
- }
378
-
379
- $result = $this->makeGitHubRequest($url, 'PUT', $commitData);
380
-
381
- if (in_array($result['http_code'], [200, 201])) {
382
- error_log("GitHub User Manager: Successfully saved users to GitHub");
383
- return true;
384
- } else {
385
- error_log("GitHub User Manager: Failed to save users to GitHub. HTTP Code: " . $result['http_code']);
386
- return false;
387
- }
388
- }
389
-
390
- /**
391
- * Register a new user
392
- */
393
- public function registerUser($username, $password, $email = '') {
394
- // Load current users from GitHub
395
- $users = $this->loadUsersFromGitHub();
396
-
397
- // Check if user already exists
398
- if (isset($users[$username])) {
399
- return ['success' => false, 'message' => 'User already exists'];
400
- }
401
-
402
- // Validate username
403
- if (!preg_match('/^[a-zA-Z0-9_-]+$/', $username) || strlen($username) < 3) {
404
- return ['success' => false, 'message' => 'Username must be at least 3 characters and contain only letters, numbers, underscore, and dash'];
405
- }
406
-
407
- // Hash password
408
- $hashedPassword = password_hash($password, PASSWORD_DEFAULT);
409
-
410
- // Add user
411
- $users[$username] = [
412
- 'password' => $hashedPassword,
413
- 'email' => $email,
414
- 'created' => date('Y-m-d H:i:s'),
415
- 'last_login' => null
416
- ];
417
-
418
- // Save to GitHub
419
- if ($this->saveUsersToGitHub($users)) {
420
- return ['success' => true, 'message' => 'User registered successfully'];
421
- } else {
422
- return ['success' => false, 'message' => 'Failed to save user data to GitHub'];
423
- }
424
- }
425
-
426
- /**
427
- * Login user
428
- */
429
- public function loginUser($username, $password) {
430
- // Always load fresh user data from GitHub on login
431
- $users = $this->loadUsersFromGitHub();
432
-
433
- if (!isset($users[$username])) {
434
- return ['success' => false, 'message' => 'User not found'];
435
- }
436
-
437
- if (password_verify($password, $users[$username]['password'])) {
438
- $_SESSION['username'] = $username;
439
- $_SESSION['logged_in'] = true;
440
-
441
- // Update last login time
442
- $users[$username]['last_login'] = date('Y-m-d H:i:s');
443
- $this->saveUsersToGitHub($users);
444
-
445
- return ['success' => true, 'message' => 'Login successful'];
446
- } else {
447
- return ['success' => false, 'message' => 'Invalid password'];
448
- }
449
- }
450
-
451
- /**
452
- * Logout user
453
- */
454
- public function logoutUser() {
455
- session_destroy();
456
- return ['success' => true, 'message' => 'Logged out successfully'];
457
- }
458
-
459
- /**
460
- * Check if user is logged in
461
- */
462
- public function isLoggedIn() {
463
- return isset($_SESSION['logged_in']) && $_SESSION['logged_in'] === true;
464
- }
465
-
466
- /**
467
- * Get current logged in user
468
- */
469
- public function getCurrentUser() {
470
- if ($this->isLoggedIn()) {
471
- return $_SESSION['username'];
472
- }
473
- return null;
474
- }
475
-
476
- /**
477
- * Require login
478
- */
479
- public function requireLogin() {
480
- if (!$this->isLoggedIn()) {
481
- header('Location: login.html');
482
- exit;
483
- }
484
- }
485
-
486
- /**
487
- * Get user list (fresh from GitHub)
488
- */
489
- public function getUserList() {
490
- $users = $this->loadUsersFromGitHub();
491
- $userList = [];
492
- foreach ($users as $username => $data) {
493
- $userList[] = [
494
- 'username' => $username,
495
- 'email' => $data['email'],
496
- 'created' => $data['created'],
497
- 'last_login' => $data['last_login']
498
- ];
499
- }
500
- return $userList;
501
- }
502
-
503
- /**
504
- * Update user profile
505
- */
506
- public function updateUserProfile($username, $updates) {
507
- $users = $this->loadUsersFromGitHub();
508
-
509
- if (!isset($users[$username])) {
510
- return ['success' => false, 'message' => 'User not found'];
511
- }
512
-
513
- // Update allowed fields
514
- $allowedFields = ['email'];
515
- foreach ($allowedFields as $field) {
516
- if (isset($updates[$field])) {
517
- $users[$username][$field] = $updates[$field];
518
- }
519
- }
520
-
521
- // Update modified timestamp
522
- $users[$username]['modified'] = date('Y-m-d H:i:s');
523
-
524
- if ($this->saveUsersToGitHub($users)) {
525
- return ['success' => true, 'message' => 'Profile updated successfully'];
526
- } else {
527
- return ['success' => false, 'message' => 'Failed to update profile'];
528
- }
529
- }
530
-
531
- /**
532
- * Change user password
533
- */
534
- public function changePassword($username, $oldPassword, $newPassword) {
535
- $users = $this->loadUsersFromGitHub();
536
-
537
- if (!isset($users[$username])) {
538
- return ['success' => false, 'message' => 'User not found'];
539
- }
540
-
541
- // Verify old password
542
- if (!password_verify($oldPassword, $users[$username]['password'])) {
543
- return ['success' => false, 'message' => 'Invalid current password'];
544
- }
545
-
546
- // Update password
547
- $users[$username]['password'] = password_hash($newPassword, PASSWORD_DEFAULT);
548
- $users[$username]['modified'] = date('Y-m-d H:i:s');
549
-
550
- if ($this->saveUsersToGitHub($users)) {
551
- return ['success' => true, 'message' => 'Password changed successfully'];
552
- } else {
553
- return ['success' => false, 'message' => 'Failed to change password'];
554
- }
555
- }
556
-
557
- /**
558
- * Make GitHub API request
559
- */
560
- private function makeGitHubRequest($url, $method = 'GET', $data = null) {
561
- $headers = [
562
- 'Authorization: token ' . $this->config['token'],
563
- 'Accept: application/vnd.github.v3+json',
564
- 'User-Agent: VvvebJs-UserManager/1.0',
565
- 'Content-Type: application/json'
566
- ];
567
-
568
- $contextOptions = [
569
- 'http' => [
570
- 'method' => $method,
571
- 'header' => implode("\r\n", $headers),
572
- 'ignore_errors' => true,
573
- 'timeout' => 30
574
- ]
575
- ];
576
-
577
- if ($data && in_array($method, ['POST', 'PUT', 'PATCH'])) {
578
- $contextOptions['http']['content'] = json_encode($data);
579
- }
580
-
581
- $context = stream_context_create($contextOptions);
582
- $response = @file_get_contents($url, false, $context);
583
- $httpCode = 0;
584
-
585
- if (isset($http_response_header)) {
586
- foreach ($http_response_header as $header) {
587
- if (preg_match('/HTTP\/\d\.\d\s+(\d+)/', $header, $matches)) {
588
- $httpCode = (int)$matches[1];
589
- break;
590
- }
591
- }
592
- }
593
-
594
- return [
595
- 'body' => $response,
596
- 'http_code' => $httpCode,
597
- 'headers' => $http_response_header ?? [],
598
- 'error' => $response === false ? 'Request failed' : null
599
- ];
600
- }
601
  }
602
 
603
  // External storage handlers
 
43
  }
44
 
45
  public static function getCurrentUser() {
46
+ // Check session first
47
+ if (session_status() === PHP_SESSION_NONE) {
48
+ session_start();
49
+ }
50
+
51
+ if (isset($_SESSION['username'])) {
52
+ return $_SESSION['username'];
53
+ }
54
+
55
+ // Fallback to Basic Auth
56
  return $_SERVER['PHP_AUTH_USER'] ?? 'anonymous';
57
  }
58
 
 
64
  $safeUsername = preg_replace('/[^a-zA-Z0-9_-]/', '_', $username);
65
  return "users/{$safeUsername}/";
66
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  }
68
 
69
  // External storage handlers
user-manager.php CHANGED
@@ -1,13 +1,60 @@
1
  <?php
2
  require_once __DIR__ . '/storage.php';
3
 
4
- // Use GitHub-based user management
5
- $userManager = new GitHubUserManager();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
  // Handle AJAX requests
8
  if ($_SERVER['REQUEST_METHOD'] === 'POST') {
9
  header('Content-Type: application/json');
10
 
 
11
  $action = $_POST['action'] ?? '';
12
 
13
  switch ($action) {
@@ -28,29 +75,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
28
  ]);
29
  break;
30
 
31
- case 'update_profile':
32
- if (!$userManager->isLoggedIn()) {
33
- echo json_encode(['success' => false, 'message' => 'Not logged in']);
34
- break;
35
- }
36
- $username = $userManager->getCurrentUser();
37
- $updates = [
38
- 'email' => $_POST['email'] ?? ''
39
- ];
40
- echo json_encode($userManager->updateUserProfile($username, $updates));
41
- break;
42
-
43
- case 'change_password':
44
- if (!$userManager->isLoggedIn()) {
45
- echo json_encode(['success' => false, 'message' => 'Not logged in']);
46
- break;
47
- }
48
- $username = $userManager->getCurrentUser();
49
- $oldPassword = $_POST['old_password'] ?? '';
50
- $newPassword = $_POST['new_password'] ?? '';
51
- echo json_encode($userManager->changePassword($username, $oldPassword, $newPassword));
52
- break;
53
-
54
  default:
55
  echo json_encode(['success' => false, 'message' => 'Invalid action']);
56
  }
 
1
  <?php
2
  require_once __DIR__ . '/storage.php';
3
 
4
+ // Simple user manager - only login, no registration
5
+ class UserManager {
6
+ public function __construct() {
7
+ if (session_status() === PHP_SESSION_NONE) {
8
+ session_start();
9
+ }
10
+ }
11
+
12
+ public function loginUser($username, $password) {
13
+ $users = StorageConfig::getUsers();
14
+
15
+ if (!isset($users[$username])) {
16
+ return ['success' => false, 'message' => 'User not found'];
17
+ }
18
+
19
+ if ($users[$username] === $password) {
20
+ $_SESSION['username'] = $username;
21
+ $_SESSION['logged_in'] = true;
22
+
23
+ return ['success' => true, 'message' => 'Login successful'];
24
+ } else {
25
+ return ['success' => false, 'message' => 'Invalid password'];
26
+ }
27
+ }
28
+
29
+ public function logoutUser() {
30
+ session_destroy();
31
+ return ['success' => true, 'message' => 'Logged out successfully'];
32
+ }
33
+
34
+ public function isLoggedIn() {
35
+ return isset($_SESSION['logged_in']) && $_SESSION['logged_in'] === true;
36
+ }
37
+
38
+ public function getCurrentUser() {
39
+ if ($this->isLoggedIn()) {
40
+ return $_SESSION['username'];
41
+ }
42
+ return null;
43
+ }
44
+
45
+ public function requireLogin() {
46
+ if (!$this->isLoggedIn()) {
47
+ header('Location: login.html');
48
+ exit;
49
+ }
50
+ }
51
+ }
52
 
53
  // Handle AJAX requests
54
  if ($_SERVER['REQUEST_METHOD'] === 'POST') {
55
  header('Content-Type: application/json');
56
 
57
+ $userManager = new UserManager();
58
  $action = $_POST['action'] ?? '';
59
 
60
  switch ($action) {
 
75
  ]);
76
  break;
77
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  default:
79
  echo json_encode(['success' => false, 'message' => 'Invalid action']);
80
  }