This commit is contained in:
+35
-1
@@ -23,7 +23,7 @@ $path = str_replace('/api/', '', $path);
|
||||
$segments = explode('/', trim($path, '/'));
|
||||
$resource = $segments[0] ?? '';
|
||||
|
||||
if ($resource !== 'session' && $resource !== 'login' && $resource !== 'logout') {
|
||||
if ($resource !== 'session' && $resource !== 'login' && $resource !== 'logout' && $resource !== 'registration') {
|
||||
$loggedin = isset($_SESSION['neptune_loggedin']) && $_SESSION['neptune_loggedin'] === true;
|
||||
if (!$loggedin) {
|
||||
http_response_code(401);
|
||||
@@ -70,6 +70,9 @@ try {
|
||||
case 'shapes':
|
||||
handleShapes($method, $id, $db);
|
||||
break;
|
||||
case 'registration':
|
||||
handleRegistration($method, $db);
|
||||
break;
|
||||
default:
|
||||
http_response_code(404);
|
||||
echo json_encode(['error' => 'Not found']);
|
||||
@@ -79,6 +82,28 @@ try {
|
||||
echo json_encode(['error' => $e->getMessage()]);
|
||||
}
|
||||
|
||||
function handleRegistration($method, $db) {
|
||||
if ($method === 'GET') {
|
||||
$stmt = $db->prepare("SELECT setting_value FROM neptune_settings WHERE setting_key = 'registration_enabled'");
|
||||
$stmt->execute();
|
||||
$row = $stmt->fetch();
|
||||
$enabled = $row ? $row['setting_value'] !== '0' : true;
|
||||
echo json_encode(['registration_enabled' => $enabled]);
|
||||
} elseif ($method === 'POST') {
|
||||
$role = $_SESSION['neptune_role'] ?? 'user';
|
||||
if ($role !== 'admin') {
|
||||
http_response_code(403);
|
||||
echo json_encode(['error' => 'Admins only']);
|
||||
return;
|
||||
}
|
||||
$data = json_decode(file_get_contents('php://input'), true);
|
||||
$enabled = isset($data['registration_enabled']) ? ($data['registration_enabled'] ? '1' : '0') : '1';
|
||||
$stmt = $db->prepare("INSERT INTO neptune_settings (setting_key, setting_value) VALUES ('registration_enabled', ?) ON DUPLICATE KEY UPDATE setting_value = ?");
|
||||
$stmt->execute([$enabled, $enabled]);
|
||||
echo json_encode(['status' => 'success', 'registration_enabled' => $enabled === '1']);
|
||||
}
|
||||
}
|
||||
|
||||
function handleSession($method, $db) {
|
||||
$loggedin = isset($_SESSION['neptune_loggedin']) && $_SESSION['neptune_loggedin'] === true;
|
||||
if (!$loggedin && $method === 'GET') {
|
||||
@@ -152,6 +177,15 @@ function handleLogin($method, $db) {
|
||||
$_SESSION['neptune_username'] = $user['username'];
|
||||
$_SESSION['neptune_role'] = $user['role'];
|
||||
} else {
|
||||
$stmt = $db->prepare("SELECT setting_value FROM neptune_settings WHERE setting_key = 'registration_enabled'");
|
||||
$stmt->execute();
|
||||
$regSetting = $stmt->fetch();
|
||||
$registrationEnabled = $regSetting ? $regSetting['setting_value'] !== '0' : true;
|
||||
if (!$registrationEnabled) {
|
||||
http_response_code(403);
|
||||
echo json_encode(['error' => 'Registration is disabled by admin']);
|
||||
return;
|
||||
}
|
||||
$count = $db->query("SELECT COUNT(*) as c FROM neptune_users")->fetch()['c'];
|
||||
$role = ($count == 0) ? 'admin' : 'user';
|
||||
$stmt = $db->prepare("INSERT INTO neptune_users (user_token, username, email, role) VALUES (?, ?, ?, ?)");
|
||||
|
||||
@@ -54,4 +54,15 @@ function migrate($db) {
|
||||
$rootDb->exec("ALTER TABLE neptune.network_nodes ADD COLUMN IF NOT EXISTS notes VARCHAR(1000) DEFAULT '' AFTER group_name");
|
||||
} catch (Exception $e) {
|
||||
}
|
||||
$db->exec("CREATE TABLE IF NOT EXISTS neptune_settings (
|
||||
setting_key VARCHAR(100) PRIMARY KEY,
|
||||
setting_value TEXT NOT NULL
|
||||
)");
|
||||
try {
|
||||
$stmt = $db->prepare("SELECT COUNT(*) as c FROM neptune_settings WHERE setting_key = 'registration_enabled'");
|
||||
$stmt->execute();
|
||||
if ($stmt->fetch()['c'] == 0) {
|
||||
$db->exec("INSERT INTO neptune_settings (setting_key, setting_value) VALUES ('registration_enabled', '1')");
|
||||
}
|
||||
} catch (Exception $e) {}
|
||||
}
|
||||
@@ -1033,6 +1033,13 @@ function esc(s) {
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
async function loadRegistrationSetting() {
|
||||
try {
|
||||
const res = await apiFetch('registration');
|
||||
document.getElementById('registrationToggle').checked = res.registration_enabled === true;
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
async function loadUsers() {
|
||||
const list = document.getElementById('userList');
|
||||
try {
|
||||
@@ -1076,7 +1083,11 @@ async function removeUser(id) {
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('settingsModal').addEventListener('show.bs.modal', loadUsers);
|
||||
document.getElementById('settingsModal').addEventListener('show.bs.modal', () => {
|
||||
loadUsers();
|
||||
loadRegistrationSetting();
|
||||
});
|
||||
document.getElementById('registrationToggle').addEventListener('change', saveRegistrationSetting);
|
||||
|
||||
// ==================== DOCUMENTS ====================
|
||||
const DOC_TYPE_ICONS = {
|
||||
|
||||
@@ -480,6 +480,16 @@
|
||||
<button class="btn btn-primary" id="addUserBtn"><i class="fas fa-plus"></i> Add</button>
|
||||
</div>
|
||||
<small class="text-secondary">Get the user token from the user's Jakach Auth profile or ask them to log in once.</small>
|
||||
<hr class="border-secondary">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<h6 class="text-secondary mb-0"><i class="fas fa-user-plus me-1"></i> New User Registration</h6>
|
||||
<small class="text-secondary">Allow new users to register via login link</small>
|
||||
</div>
|
||||
<div class="form-check form-switch mb-0">
|
||||
<input class="form-check-input" type="checkbox" id="registrationToggle" style="cursor:pointer;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user