Compare commits
3 Commits
e8d324e89d
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 7937261925 | |||
| 7babef1372 | |||
| d7ca1abece |
@@ -10,6 +10,7 @@ session_start();
|
|||||||
while (ob_get_level() > 0) {
|
while (ob_get_level() > 0) {
|
||||||
ob_end_flush();
|
ob_end_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
ob_implicit_flush(true);
|
ob_implicit_flush(true);
|
||||||
|
|
||||||
// Send headers early
|
// Send headers early
|
||||||
@@ -33,11 +34,9 @@ $themeRemoteOrigin = ''; // e.g. 'git@github.com:your-org/client-theme-repo.git'
|
|||||||
$dbPath = __DIR__ . '/panel.sqlite';
|
$dbPath = __DIR__ . '/panel.sqlite';
|
||||||
|
|
||||||
// ---------- Init DB ----------
|
// ---------- Init DB ----------
|
||||||
|
|
||||||
$seedInfo = initDb();
|
$seedInfo = initDb();
|
||||||
|
|
||||||
// ---------- Routing / Auth Gate ----------
|
// ---------- Routing / Auth Gate ----------
|
||||||
|
|
||||||
$action = isset($_GET['action']) ? $_GET['action'] : 'list';
|
$action = isset($_GET['action']) ? $_GET['action'] : 'list';
|
||||||
|
|
||||||
// Logout handler
|
// Logout handler
|
||||||
@@ -52,9 +51,9 @@ requireLogin($action);
|
|||||||
$user = getCurrentUser();
|
$user = getCurrentUser();
|
||||||
|
|
||||||
// ---------- Login Action ----------
|
// ---------- Login Action ----------
|
||||||
|
|
||||||
if ($action === 'login') {
|
if ($action === 'login') {
|
||||||
$loginError = null;
|
$loginError = null;
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
$username = trim($_POST['username'] ?? '');
|
$username = trim($_POST['username'] ?? '');
|
||||||
$password = $_POST['password'] ?? '';
|
$password = $_POST['password'] ?? '';
|
||||||
@@ -79,8 +78,8 @@ if ($action === 'login') {
|
|||||||
$loginError = 'Username and password are required.';
|
$loginError = 'Username and password are required.';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
@@ -133,7 +132,6 @@ if ($action === 'login') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------- Self password change (processed for any authenticated action) ----------
|
// ---------- Self password change (processed for any authenticated action) ----------
|
||||||
|
|
||||||
$selfPasswordError = null;
|
$selfPasswordError = null;
|
||||||
$selfPasswordMessage = null;
|
$selfPasswordMessage = null;
|
||||||
$passwordDialogOpen = false;
|
$passwordDialogOpen = false;
|
||||||
@@ -172,10 +170,9 @@ if (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------- Page Layout (for authenticated users) ----------
|
// ---------- Page Layout (for authenticated users) ----------
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
@@ -216,11 +213,8 @@ if (
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
// ---------- Actions for authenticated users ----------
|
// ---------- Actions for authenticated users ----------
|
||||||
|
|
||||||
if ($action === 'create') {
|
if ($action === 'create') {
|
||||||
|
|
||||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && (!isset($_POST['op']) || $_POST['op'] !== 'self_change_password')) {
|
if ($_SERVER['REQUEST_METHOD'] === 'POST' && (!isset($_POST['op']) || $_POST['op'] !== 'self_change_password')) {
|
||||||
$rawDomain = $_POST['domain'] ?? '';
|
$rawDomain = $_POST['domain'] ?? '';
|
||||||
$domain = sanitizeDomain($rawDomain);
|
$domain = sanitizeDomain($rawDomain);
|
||||||
@@ -300,12 +294,14 @@ if ($action === 'create') {
|
|||||||
$bootstrapArgs[] = '--theme-starter-repo';
|
$bootstrapArgs[] = '--theme-starter-repo';
|
||||||
$bootstrapArgs[] = $themeStarterRepo;
|
$bootstrapArgs[] = $themeStarterRepo;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($themeRemoteOrigin !== '') {
|
if ($themeRemoteOrigin !== '') {
|
||||||
$bootstrapArgs[] = '--theme-remote-origin';
|
$bootstrapArgs[] = '--theme-remote-origin';
|
||||||
$bootstrapArgs[] = $themeRemoteOrigin;
|
$bootstrapArgs[] = $themeRemoteOrigin;
|
||||||
}
|
}
|
||||||
|
|
||||||
$bootstrapCmd = escapeshellcmd($bootstrapScript);
|
$bootstrapCmd = escapeshellcmd($bootstrapScript);
|
||||||
|
|
||||||
foreach ($bootstrapArgs as $arg) {
|
foreach ($bootstrapArgs as $arg) {
|
||||||
$bootstrapCmd .= ' ' . escapeshellarg($arg);
|
$bootstrapCmd .= ' ' . escapeshellarg($arg);
|
||||||
}
|
}
|
||||||
@@ -340,7 +336,6 @@ if ($action === 'create') {
|
|||||||
echo '</div>';
|
echo '</div>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
@@ -394,7 +389,6 @@ if ($action === 'create') {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
} elseif ($action === 'delete' && isset($_GET['domain'])) {
|
} elseif ($action === 'delete' && isset($_GET['domain'])) {
|
||||||
$domain = sanitizeDomain($_GET['domain']);
|
$domain = sanitizeDomain($_GET['domain']);
|
||||||
|
|
||||||
@@ -470,9 +464,7 @@ if ($action === 'create') {
|
|||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
|
|
||||||
} elseif ($action === 'users' && isAdmin()) {
|
} elseif ($action === 'users' && isAdmin()) {
|
||||||
|
|
||||||
$db = getDb();
|
$db = getDb();
|
||||||
$userMessage = null;
|
$userMessage = null;
|
||||||
$userError = null;
|
$userError = null;
|
||||||
@@ -501,6 +493,7 @@ if ($action === 'create') {
|
|||||||
// Check uniqueness
|
// Check uniqueness
|
||||||
$stmt = $db->prepare('SELECT COUNT(*) FROM users WHERE username = ?');
|
$stmt = $db->prepare('SELECT COUNT(*) FROM users WHERE username = ?');
|
||||||
$stmt->execute([$username]);
|
$stmt->execute([$username]);
|
||||||
|
|
||||||
if ((int)$stmt->fetchColumn() > 0) {
|
if ((int)$stmt->fetchColumn() > 0) {
|
||||||
$userError = 'Username already exists.';
|
$userError = 'Username already exists.';
|
||||||
} else {
|
} else {
|
||||||
@@ -512,6 +505,7 @@ if ($action === 'create') {
|
|||||||
}
|
}
|
||||||
} elseif ($op === 'reset_password') {
|
} elseif ($op === 'reset_password') {
|
||||||
$userId = (int)($_POST['user_id'] ?? 0);
|
$userId = (int)($_POST['user_id'] ?? 0);
|
||||||
|
|
||||||
if ($userId > 0) {
|
if ($userId > 0) {
|
||||||
$stmt = $db->prepare('SELECT username FROM users WHERE id = ?');
|
$stmt = $db->prepare('SELECT username FROM users WHERE id = ?');
|
||||||
$stmt->execute([$userId]);
|
$stmt->execute([$userId]);
|
||||||
@@ -529,6 +523,7 @@ if ($action === 'create') {
|
|||||||
'username' => $row['username'],
|
'username' => $row['username'],
|
||||||
'password' => $newPass,
|
'password' => $newPass,
|
||||||
];
|
];
|
||||||
|
|
||||||
$userMessage = 'Password reset for user "' . htmlspecialchars($row['username']) . '".';
|
$userMessage = 'Password reset for user "' . htmlspecialchars($row['username']) . '".';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -549,9 +544,11 @@ if ($action === 'create') {
|
|||||||
if ($userMessage) {
|
if ($userMessage) {
|
||||||
echo '<p><strong>' . $userMessage . '</strong></p>';
|
echo '<p><strong>' . $userMessage . '</strong></p>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($userError) {
|
if ($userError) {
|
||||||
echo '<p><strong>' . htmlspecialchars($userError) . '</strong></p>';
|
echo '<p><strong>' . htmlspecialchars($userError) . '</strong></p>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($generatedPasswordInfo) {
|
if ($generatedPasswordInfo) {
|
||||||
echo '<p class="muted">New password for <strong>' . htmlspecialchars($generatedPasswordInfo['username']) . '</strong>: ';
|
echo '<p class="muted">New password for <strong>' . htmlspecialchars($generatedPasswordInfo['username']) . '</strong>: ';
|
||||||
echo '<code>' . htmlspecialchars($generatedPasswordInfo['password']) . '</code></p>';
|
echo '<code>' . htmlspecialchars($generatedPasswordInfo['password']) . '</code></p>';
|
||||||
@@ -623,7 +620,6 @@ if ($action === 'create') {
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// Default: site list
|
// Default: site list
|
||||||
$cmd = sprintf('sudo %s site list', escapeshellcmd($woPath));
|
$cmd = sprintf('sudo %s site list', escapeshellcmd($woPath));
|
||||||
@@ -642,16 +638,19 @@ if ($action === 'create') {
|
|||||||
|
|
||||||
// Map of domain => [owner_id, username, role]
|
// Map of domain => [owner_id, username, role]
|
||||||
$meta = [];
|
$meta = [];
|
||||||
|
|
||||||
$stmt = $db->query('
|
$stmt = $db->query('
|
||||||
SELECT s.domain, s.owner_id, u.username, u.role
|
SELECT s.domain, s.owner_id, u.username, u.role
|
||||||
FROM sites s
|
FROM sites s
|
||||||
LEFT JOIN users u ON s.owner_id = u.id
|
LEFT JOIN users u ON s.owner_id = u.id
|
||||||
');
|
');
|
||||||
|
|
||||||
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
|
||||||
$meta[$row['domain']] = $row;
|
$meta[$row['domain']] = $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sites = [];
|
$sites = [];
|
||||||
|
|
||||||
foreach ($output as $line) {
|
foreach ($output as $line) {
|
||||||
$line = trim($line);
|
$line = trim($line);
|
||||||
|
|
||||||
@@ -668,11 +667,13 @@ if ($action === 'create') {
|
|||||||
|
|
||||||
// Take the first column as the domain
|
// Take the first column as the domain
|
||||||
$parts = preg_split('/\s+/', $line);
|
$parts = preg_split('/\s+/', $line);
|
||||||
|
|
||||||
if (!$parts || !isset($parts[0])) {
|
if (!$parts || !isset($parts[0])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$domain = sanitizeDomain($parts[0]);
|
$domain = sanitizeDomain($parts[0]);
|
||||||
|
|
||||||
if (!$domain) {
|
if (!$domain) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -712,24 +713,26 @@ if ($action === 'create') {
|
|||||||
echo '<li style="margin-bottom:0.75rem;">';
|
echo '<li style="margin-bottom:0.75rem;">';
|
||||||
echo '<strong>' . $siteEsc . '</strong>';
|
echo '<strong>' . $siteEsc . '</strong>';
|
||||||
echo ' <span class="tag">dev</span>';
|
echo ' <span class="tag">dev</span>';
|
||||||
|
|
||||||
if ($owner) {
|
if ($owner) {
|
||||||
echo ' <span class="muted" style="margin-left:0.5rem;">Owner: ' . htmlspecialchars($owner) . '</span>';
|
echo ' <span class="muted" style="margin-left:0.5rem;">Owner: ' . htmlspecialchars($owner) . '</span>';
|
||||||
} else {
|
} else {
|
||||||
echo ' <span class="muted" style="margin-left:0.5rem;">Owner: Unassigned</span>';
|
echo ' <span class="muted" style="margin-left:0.5rem;">Owner: Unassigned</span>';
|
||||||
}
|
}
|
||||||
|
|
||||||
echo '<br>';
|
echo '<br>';
|
||||||
echo '<a href="' . $url . '" target="_blank" rel="noopener">Open site</a> · ';
|
echo '<a href="' . $url . '" target="_blank" rel="noopener">Open site</a> · ';
|
||||||
echo '<a href="' . $adminUrl . '" target="_blank" rel="noopener">WP Admin</a> · ';
|
echo '<a href="' . $adminUrl . '" target="_blank" rel="noopener">WP Admin</a> · ';
|
||||||
echo '<a href="?action=delete&domain=' . urlencode($site) . '" class="muted danger">Delete…</a>';
|
echo '<a href="?action=delete&domain=' . urlencode($site) . '" class="muted danger">Delete…</a>';
|
||||||
echo '</li>';
|
echo '</li>';
|
||||||
}
|
}
|
||||||
|
|
||||||
echo '</ul>';
|
echo '</ul>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
echo '</div>';
|
echo '</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
||||||
<!-- Change Password Modal -->
|
<!-- Change Password Modal -->
|
||||||
@@ -832,6 +835,5 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
<?php phpinfo(); ?>
|
|
||||||
@@ -90,8 +90,10 @@ else
|
|||||||
if wp user list --field=user_email | grep -q "^${ADMIN_EMAIL}\$"; then
|
if wp user list --field=user_email | grep -q "^${ADMIN_EMAIL}\$"; then
|
||||||
echo "Admin email ${ADMIN_EMAIL} already in use; skipping user create."
|
echo "Admin email ${ADMIN_EMAIL} already in use; skipping user create."
|
||||||
else
|
else
|
||||||
wp user create "$ADMIN_USER" "$ADMIN_EMAIL" --role=administrator --user_pass="$(openssl rand -base64 16)"
|
PASS=$(openssl rand -base64 16)
|
||||||
echo "Admin user $ADMIN_USER created with email $ADMIN_EMAIL (random password)."
|
|
||||||
|
wp user create "$ADMIN_USER" "$ADMIN_EMAIL" --role=administrator --user_pass="$PASS"
|
||||||
|
echo "Admin user $ADMIN_USER created with email $ADMIN_EMAIL ($PASS)."
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -119,6 +121,12 @@ DEV_PLUGINS=(
|
|||||||
query-monitor
|
query-monitor
|
||||||
user-switching
|
user-switching
|
||||||
debug-bar
|
debug-bar
|
||||||
|
https://docs.vincentdevelopment.ca/files/advanced-custom-fields-pro.zip
|
||||||
|
https://docs.vincentdevelopment.ca/files/gravity-forms.zip
|
||||||
|
autodescription
|
||||||
|
better-search-replace
|
||||||
|
google-site-kit
|
||||||
|
simple-history
|
||||||
)
|
)
|
||||||
|
|
||||||
for PLUGIN in "${DEV_PLUGINS[@]}"; do
|
for PLUGIN in "${DEV_PLUGINS[@]}"; do
|
||||||
@@ -151,7 +159,7 @@ if [[ -n "$THEME_STARTER_REPO" ]]; then
|
|||||||
mkdir -p "$THEMES_DIR"
|
mkdir -p "$THEMES_DIR"
|
||||||
|
|
||||||
# Slug from project name
|
# Slug from project name
|
||||||
THEME_SLUG=$(echo "$PROJECT_NAME" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-')
|
THEME_SLUG=$(echo "$PROJECT_NAME" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-' | sed 's/-$//')
|
||||||
[[ -z "$THEME_SLUG" ]] && THEME_SLUG="custom-theme"
|
[[ -z "$THEME_SLUG" ]] && THEME_SLUG="custom-theme"
|
||||||
|
|
||||||
TARGET_THEME_DIR="${THEMES_DIR}/${THEME_SLUG}"
|
TARGET_THEME_DIR="${THEMES_DIR}/${THEME_SLUG}"
|
||||||
@@ -187,4 +195,15 @@ else
|
|||||||
echo "==> Theme starter repo not provided; skipping theme bootstrap."
|
echo "==> Theme starter repo not provided; skipping theme bootstrap."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "==> Installing dependencies..."
|
||||||
|
cd "$TARGET_THEME_DIR"
|
||||||
|
/usr/local/bin/composer install
|
||||||
|
/usr/bin/npm install
|
||||||
|
|
||||||
|
echo "==> Doing initial build..."
|
||||||
|
/usr/bin/npm run build
|
||||||
|
|
||||||
|
echo "==> Updating site permissions..."
|
||||||
|
sudo /usr/local/bin/wo-fix-perms.sh "$DOMAIN"
|
||||||
|
|
||||||
echo "==> Bootstrap complete."
|
echo "==> Bootstrap complete."
|
||||||
|
|||||||
Reference in New Issue
Block a user