installer

This commit is contained in:
crispycat 2023-12-07 17:10:41 -05:00
parent c1a57c64f2
commit cd05d9d4e8
20 changed files with 506 additions and 4 deletions

2
.gitignore vendored Normal file → Executable file
View File

@ -1,4 +1,4 @@
build
cache
source
lite
patch/config.php

0
LICENSE Normal file → Executable file
View File

0
README Normal file → Executable file
View File

View File

@ -1,11 +1,11 @@
#!/bin/bash
rm -rf build;
if [[ -d cache ]]; then
cp -r cache build;
if [[ -d source ]]; then
cp -r source build;
else
git clone https://git.calitabby.com/crispage/crispage.git build;
cp -r build cache;
cp -r build source;
fi;
while IFS= read -r line; do

0
delete.list Normal file → Executable file
View File

0
patch/core/app/assets/Asset.php Normal file → Executable file
View File

0
patch/core/app/assets/AssetManager.php Normal file → Executable file
View File

0
patch/core/app/assets/class/Module.php Normal file → Executable file
View File

0
patch/core/app/assets/class/Plugin.php Normal file → Executable file
View File

0
patch/core/app/assets/class/Role.php Normal file → Executable file
View File

0
patch/core/app/assets/class/User.php Normal file → Executable file
View File

0
patch/core/app/extensions/CoreExtensions.php Normal file → Executable file
View File

0
patch/core/templates/default/layouts/api.php Normal file → Executable file
View File

2
patch/core/templates/default/layouts/default.php Normal file → Executable file
View File

@ -31,6 +31,8 @@
);
$this->app->page->renderComponent($com_msgs);
$this->app->page->renderMainComponent();
echo "<p>v" . VERSION . "</p>";
?>
</body>
</html>

1
patch/packages/.htaccess Executable file
View File

@ -0,0 +1 @@
Require all denied

View File

@ -0,0 +1,314 @@
<?php
/*
Crispage CMS
crispycat <the@crispy.cat>
https://crispy.cat/software/crispage
Crispage is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
*/
use \Crispage\Auth\CorePermissions;
use \Crispage\CoreSettings;
use \Crispage\Utils\FileUtils;
use \Crispage\Request\Route;
if (IS_INSTALLED) throw new Exception("Crispage is already installed");
$this->log("Starting Crispage Lite Installation");
// Check PHP
if (PHP_VERSION_ID < 80100)
throw new Exception("PHP version 8.1 or higher is required to install Crispage!");
$exts = [
"bz2",
"fileinfo",
"filter",
"json",
"mcrypt",
"openssl",
"PDO",
"pdo_mysql",
"Phar",
"random",
"zip",
"zlib"
];
foreach ($exts as $ext) {
if (!extension_loaded($ext))
$this->log("Extension $ext is not loaded. Please enable it to ensure proper functionality.", $this::L_WARNING);
}
// Get installation options
$iopts = $this->app->request->params["iopts"] ?? [];
if (!is_array($iopts) || empty($iopts)) {
$this->log("Please continue after providing the following information:", $this::L_ERROR);
?>
<form method="post" action="<?php echo WROOT; ?>/package.php">
<input type="hidden" name="mode" value="install" />
<label for="iopts[SITE_DOMAIN]">Site domain:</label>
<input type="text" name="iopts[SITE_DOMAIN]" value="<?php echo $_SERVER["SERVER_NAME"]; ?>" required />
<br />
<label for="iopts[ENABLE_USER_REGISTRATION]">Enable User Registration</label>
<input type="checkbox" name="iopts[ENABLE_USER_REGISTRATION]" value="0" />
<br />
<hr />
<label for="iopts[DB_LOC]">Database host:</label>
<input type="text" name="iopts[DB_LOC]" value="localhost" required />
<br />
<label for="iopts[DB_PORT]">Database Port:</label>
<input type="number" name="iopts[DB_PORT]" value="3306" min="1" max="65535" required />
<br />
<label for="iopts[DB_NAME]">Database name:</label>
<input type="text" name="iopts[DB_NAME]" required />
<br />
<label for="iopts[DB_USER]">Database user:</label>
<input type="text" name="iopts[DB_USER]" required />
<br />
<label for="iopts[DB_PASSWD]">Database password:</label>
<input type="password" name="iopts[DB_PASSWD]" required />
<br />
<label for="iopts[DB_PREFIX]">Table prefix:</label>
<input type="text" name="iopts[DB_PREFIX]" value="lite_" required />
<br />
<hr />
<label for="iopts[ADMIN_ACCOUNT]">Admin Username:</label>
<input type="text" name="iopts[ADMIN_ACCOUNT]" required />
<br />
<label for="iopts[ADMIN_EMAIL]">Admin Email:</label>
<input type="text" name="iopts[ADMIN_EMAIL]" required />
<br />
<label for="admpasswd">Admin Password:</label>
<input type="password" name="admpasswd" required />
<br />
<hr />
<button type="submit">Continue</button>
</form>
<?php
throw new Exception("User input required");
}
$iopts["CONFIG_VERSION"] = explode("-", VERSION)[0];
// Connect to database
$this->log("Connecting to database");
$db_type = "\\Crispage\\Database\\MySQLDatabase";
$db_loc = strval($iopts["DB_LOC"] ?? "localhost");
$db_port = intval($iopts["DB_PORT"] ?? 3306);
$db_name = strval($iopts["DB_NAME"] ?? "");
$db_user = strval($iopts["DB_USER"] ?? "");
$db_passwd = strval($iopts["DB_PASSWD"] ?? "");
$db_prefix = strval($iopts["DB_PREFIX"] ?? "cspg_");
$db_opts = [];
if (!class_exists($db_type))
throw new Exception("DB type $db_type not available");
$this->app->database = new $db_type([
"location" => $db_loc,
"port" => $db_port,
"username" => $db_user,
"password" => $db_passwd,
"dbname" => $db_name,
"prefix" => $db_prefix,
"options" => $db_opts
]);
$this->app->database->connect();
// Create database tables
$this->log("Creating database tables");
$this->app->database->createTable("system", [
"iid" => $this->app->database::TYPE_STRING,
"version" => $this->app->database::TYPE_STRING,
"next_asset_id" => $this->app->database::TYPE_INT
]);
$this->app->database->createTable("settings", [
"setting" => $this->app->database::TYPE_STRING,
"value" => [$this->app->database::TYPE_STRING, true],
"component" => [$this->app->database::TYPE_STRING, true],
"com_data" => [$this->app->database::TYPE_STRING, true]
]);
$this->app->database->addUnique("settings", "setting");
$this->app->database->createTable("routes", [
"id" => $this->app->database::TYPE_STRING,
"action" => $this->app->database::TYPE_STRING,
"data" => $this->app->database::TYPE_STRING
]);
$this->app->database->addUnique("routes", "id");
$this->app->database->createTable("extensions", [
"id" => $this->app->database::TYPE_STRING,
"version" => $this->app->database::TYPE_STRING,
"package" => $this->app->database::TYPE_STRING,
"classname" => $this->app->database::TYPE_STRING,
"type" => $this->app->database::TYPE_STRING,
"data" => $this->app->database::TYPE_STRING
]);
$this->app->database->addUnique("extensions", "id");
$this->app->database->createTable("assets", [
"id" => $this->app->database::TYPE_INT,
"classname" => $this->app->database::TYPE_STRING,
"tablename" => $this->app->database::TYPE_STRING,
"slug" => $this->app->database::TYPE_STRING
]);
$this->app->database->addPrimaryKey("assets", "id");
$this->app->assets->createTable("\\Crispage\\Assets\\Module");
$this->app->assets->createTable("\\Crispage\\Assets\\Plugin");
$this->app->assets->createTable("\\Crispage\\Assets\\Role");
$this->app->assets->createTable("\\Crispage\\Assets\\User");
$this->app->database->createTable("sessions", [
"id" => $this->app->database::TYPE_STRING,
"token_hash" => $this->app->database::TYPE_STRING,
"user_id" => $this->app->database::TYPE_INT,
"expire_time" => $this->app->database::TYPE_INT,
"ip_hash" => $this->app->database::TYPE_STRING
]);
$this->app->database->addUnique("sessions", "id");
$this->app->database->createTable("passwd", [
"user_id" => $this->app->database::TYPE_INT,
"password_hash" => $this->app->database::TYPE_STRING,
"expire_time" => $this->app->database::TYPE_INT
]);
$this->app->database->addPrimaryKey("passwd", "user_id");
$this->app->database->createTable("rme", [
"id" => $this->app->database::TYPE_STRING,
"token_hash" => $this->app->database::TYPE_STRING,
"user_id" => $this->app->database::TYPE_INT,
"expire_time" => $this->app->database::TYPE_INT
]);
$this->app->database->addUnique("rme", "id");
$this->app->database->createTable("userconfirmation", [
"user_id" => $this->app->database::TYPE_INT,
"token_hash" => $this->app->database::TYPE_STRING,
"expire_time" => $this->app->database::TYPE_INT
]);
$this->app->database->addPrimaryKey("userconfirmation", "user_id");
$this->app->database->createTable("passwdreset", [
"user_id" => $this->app->database::TYPE_INT,
"token_hash" => $this->app->database::TYPE_STRING,
"expire_time" => $this->app->database::TYPE_INT
]);
$this->app->database->addPrimaryKey("passwdreset", "user_id");
// Create system table
$this->log("Filling system table");
$this->app->database->insert("system", [
"iid" => uniqid("crispage_lite\${$db_prefix}$", true),
"version" => VERSION,
"next_asset_id" => 1
]);
$this->log("Setting defaults");
$drole = $this->app->assets->create("\\Crispage\\Assets\\Role", [
"slug" => "default",
"name" => "Default",
"rank" => "255",
"permissions" => CorePermissions::LOG_IN | CorePermissions::POST_COMMENT
]);
$settings = [
"crispage.page.default_template" => "default",
"crispage.page.default_layout" => "default",
"crispage.date_format_short" => "Y-m-d",
"crispage.date_format_long" => "Y F j",
"crispage.time_format_short" => "H:i T",
"crispage.time_format_long" => "H:i:s T",
"crispage.timezone" => "Etc/UTC",
"crispage.auth.default_roles" => "[$drole->id]"
];
foreach (CoreSettings::get() as $key => $_)
$this->app->settings->set($key, $settings[$key] ?? "");
$this->log("Creating super user");
$username = strval($iopts["ADMIN_ACCOUNT"] ?? "admin");
$email = strval($iopts["ADMIN_EMAIL"] ?? "");
$password = strval($this->app->request->params["admpasswd"] ?? "");
$role = $this->app->assets->create("\\Crispage\\Assets\\Role", [
"slug" => "superuser",
"name" => "Super User",
"rank" => 0,
"permissions" => CorePermissions::ALL
]);
$user = $this->app->assets->create("\\Crispage\\Assets\\User", [
"slug" => $username,
"displayname" => $username,
"email" => $email,
"state" => \Crispage\Assets\User::ACTIVATED,
"role_ids" => "[$role->id]"
]);
$this->app->auth->setPassword($user, $password);
$this->app->router->setRoute(new Route("/", "\\CrispageLite\\DefaultAction", []));
// Create config
$this->log("Creating configuration file");
$template = file_get_contents(PACKAGE_PATH . "/config_template.php");
$nmatches = preg_match_all(\Crispage\Text\I18n::TS_REGEX, $template, $matches, PREG_OFFSET_CAPTURE);
$pos = 0;
$config = "";
for ($i = 0; $i < $nmatches; $i++) {
$start = $matches[0][$i][1];
$length = strlen($matches[0][$i][0]);
$key = $matches[1][$i][0];
$config .= substr($template, $pos, $start - $pos);
$config .= $iopts[$key] ?? $key;
$pos = $start + $length;
}
$config .= substr($template, $pos);
if (file_put_contents(ROOT . "/config.php", $config) === false)
throw new Exception("Could not write configuration file! Is `" . ROOT . "/config.php` writable?");
$this->log("Removing update files");
if (file_exists(ROOT . "/_crispage")) FileUtils::emptyDirectory(ROOT . "/_crispage");
rmdir(ROOT . "/_crispage");
file_put_contents(PACKAGE_PATH . "/version", VERSION);
// Finish
$this->log("Crispage has been installed successfully!", $this::L_SUCCESS);
?>
<a href="<?php echo WROOT; ?>"><button>View Site</button></a>
<a href="<?php echo WROOT; ?>/backend"><button>View Backend</button></a>
<a href=""><button>Install Sample Data</button></a>
<?php
?>

View File

@ -0,0 +1,13 @@
<?php
/*
Crispage CMS
crispycat <the@crispy.cat>
https://crispy.cat/software/crispage
Crispage is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
*/
$this->log("Crispage can't (and doesn't want to) uninstall itself!", $this::L_FATAL);
?>

View File

@ -0,0 +1,109 @@
<?php
namespace Crispage;
class Config {
// This should never need to be changed, except by the updater
public const _CONFIG_VERSION = "{%CONFIG_VERSION}";
/*
General settings
*/
// Your public-facing domain
public const SITE_DOMAIN = "{%SITE_DOMAIN}";
// Usernames of users who should have all privileges regardless of role
public const SUPERUSERS = ["{%ADMIN_ACCOUNT}"];
/*
Security settings
*/
// Enable API (req. for some functions) prod: true
public const API_ENABLED = true;
// password_hash() algorithm prod: PASSWORD_BCRYPT
public const PASSWD_ALGO = PASSWORD_BCRYPT;
// password_hash() options prod: ["cost" => {>=12}]
public const PASSWD_OPTS = ["cost" => 12];
// random token length in bytes prod: {>16}
public const TOKEN_BYTES = 16;
// Enable public user registration
public const ENABLE_USER_REGISTRATION = {%ENABLE_USER_REGISTRATION};
// Media folders to which users can upload and delete files
public const MEDIA_WRITABLE_PATHS = [
"/uploads",
"/assets"
];
// Mimetypes to disallow
public const MEDIA_MIMETYPE_BLACKLIST = [
"text/x-php"
];
/*
Database settings
*/
public const DB_TYPE = "\Crispage\Database\MySQLDatabase";
// Database location or host
public const DB_LOC = "{%DB_LOC}";
// Database port
public const DB_PORT = {%DB_PORT};
// Database name
public const DB_NAME = "{%DB_NAME}";
// Database credentials
public const DB_USER = "{%DB_USER}";
public const DB_PASSWD = "{%DB_PASSWD}";
// Database table prefix
public const DB_PREFIX = "{%DB_PREFIX}";
// Database PDO options
public const DB_OPTS = null;
/*
Development settings, modify at your own risk
*/
// Force error messages, even on 404 prod: false
public const DEV_FORCE_ERRMSGS = false;
// Disable output buffering prod: false
public const DEV_DISABLE_OB = false;
// Run modules in unsafe maode (debug) prod: false
public const DEV_MODULES_UNSAFE = false;
// PHP error level prod: E_ALL & ~E_DEPRECATED & ~E_STRICT
public const ERRLVL = E_ALL & ~E_DEPRECATED & ~E_STRICT;
// PHPMailer SMTP debug level <0-4> prod: 0
public const SMTP_DEBUG = 0;
// Show database errors (should never be enabled on production servers)
public const SHOW_DB_ERRORS = false;
// Paths are relative to ROOT
public const CLASS_PATHS = [
// Component paths
"\\Crispage\\Response\\Component" => [
"/user/components",
"/core/components"
],
// Action paths
"\\Crispage\\Response\\Action" => [
"/user/actions",
"/core/actions"
],
// Plugin paths
"\\Crispage\\PluginRunnable" => [
"/user/plugins",
"/core/plugins"
]
];
// Template path
public const TEMPLATE_PATH = [
"/user/templates",
"/core/templates"
];
// Translation path
public const TRANSLATION_PATH = [
"/user/translations",
"/core/translations",
];
// Media path
public const MEDIA_PATH = "/media";
// URL to media server; set to null to use MEDIA_PATH
public const MEDIA_CUSTOM_PREFIX= null;
// Packages path
public const PACKAGE_PATH = "/packages";
// Temporary files path
public const TEMP_PATH = "/temp";
}
?>

View File

@ -0,0 +1,62 @@
<?php
namespace Crispage;
define("SERVER_NAME", $_SERVER["SERVER_NAME"]);
class Config {
public const _CONFIG_VERSION = VERSION;
public const SITE_DOMAIN = SERVER_NAME;
public const SUPERUSERS = [];
public const API_ENABLED = true;
public const PASSWD_ALGO = PASSWORD_BCRYPT;
public const PASSWD_OPTS = ["cost" => 12];
public const TOKEN_BYTES = 16;
public const ENABLE_USER_REGISTRATION = true;
public const MEDIA_WRITABLE_PATHS = ["/"];
public const MEDIA_MIMETYPE_BLACKLIST = [];
public const DB_TYPE = "\Crispage\Database\MySQLDatabase";
public const DB_LOC = "localhost";
public const DB_PORT = 3306;
public const DB_NAME = "molyb_crispage";
public const DB_USER = "crispage";
public const DB_PASSWD = "Crispage20221110$$";
public const DB_PREFIX = "cspg_";
public const DB_OPTS = null;
public const DEV_FORCE_ERRMSGS = true;
public const DEV_DISABLE_OB = true;
public const DEV_MODULES_UNSAFE = true;
public const ERRLVL = E_ALL;
public const SMTP_DEBUG = 1;
public const SHOW_DB_ERRORS = true;
public const CLASS_PATHS = [
"\\Crispage\\Response\\Component" => [
"/user/components",
"/core/components"
],
"\\Crispage\\Response\\Action" => [
"/user/actions",
"/core/actions"
],
"\\Crispage\\PluginRunnable" => [
"/user/plugins",
"/core/plugins"
]
];
public const TEMPLATE_PATH = [
"/user/templates",
"/core/templates"
];
public const TRANSLATION_PATH = [
"/user/translations",
"/core/translations",
];
public const MEDIA_PATH = "/media";
public const MEDIA_CUSTOM_PREFIX= null;
public const PACKAGE_PATH = "/packages";
public const TEMP_PATH = "/temp";
}
?>

View File

@ -0,0 +1 @@
lite_0.20.1a_1