diff --git a/.gitignore b/.gitignore index 591c5c1..a72b4e4 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ config/pages.json config/tags.json *.DS_Store config.codekit3 +/config/backups \ No newline at end of file diff --git a/brain/api/v1/SettingsAPI.inc.php b/brain/api/v1/SettingsAPI.inc.php index d9e502c..f8fa99b 100644 --- a/brain/api/v1/SettingsAPI.inc.php +++ b/brain/api/v1/SettingsAPI.inc.php @@ -54,4 +54,10 @@ class SettingsAPI return $result; } + + public static function createBackup() + { + $result = Settings::makeBackup(); + return $result; + } } diff --git a/brain/controller/APIControl.inc.php b/brain/controller/APIControl.inc.php index 92a0ff7..60735d2 100644 --- a/brain/controller/APIControl.inc.php +++ b/brain/controller/APIControl.inc.php @@ -15,15 +15,57 @@ class APIControl ResponseInterface $response, array $args ): ResponseInterface { + $filename = ""; switch (isset($args["third"]) ? $args["third"] : "none") { case "status": $result = AuthAPI::status(); break; + case "files": + if (Session::active()) { + if ($args["third"] == "backup") { + $filename = "../config/backups/latest_backup.zip"; + if (file_exists($filename)) { + header("Content-Type: application/zip"); + header( + 'Content-Disposition: attachment; filename="' . + basename($filename) . + '"' + ); + header("Content-Length: " . filesize($filename)); + + flush(); + // return readfile($filename); + //readfile($filename); + // delete file + //unlink($filename); + } + } + } else { + $result = [ + "message" => "API access denied, homie", + "type" => "API_ERROR", + ]; + } default: break; } - $response->getBody()->write(json_encode($result)); - return $response->withHeader("Content-Type", "application/json"); + + $freshResponse = $response; + + if ($args["third"] == "files") { + $freshResponse + ->getBody() + ->write(file_get_contents("../config/backups/latest_back.zip")); + + $freshResponse->withHeader("Content-Type", "application/zip"); + return $freshResponse->withAddedHeader( + "Content-Disposition", + "attachment; filename=latest_backup.zip" + ); + } else { + $response->getBody()->write(json_encode($result)); + return $response->withHeader("Content-Type", "application/json"); + } } public static function post( ServerRequestInterface $request, @@ -48,7 +90,18 @@ class APIControl $task == "init" ? $body : $request ); break; - + case "backup": + $token = $request->getHeader("fipamo-access-token"); + //Verify token for admin tasks + if (Session::verifyToken($token[0])) { + $result = SettingsAPI::createBackup(); + } else { + $result = [ + "message" => "API access denied, homie", + "type" => "API_ERROR", + ]; + } + break; case "login": $result = AuthAPI::login($body); break; diff --git a/brain/controller/DashControl.inc.php b/brain/controller/DashControl.inc.php index 69ba850..532cc88 100644 --- a/brain/controller/DashControl.inc.php +++ b/brain/controller/DashControl.inc.php @@ -24,6 +24,7 @@ class DashControl $themes = $config->getThemes(); $template = "dash/settings.twig"; $member = Session::get("member"); + $updated = new \Moment\Moment($settings["global"]["last_backup"]); $pageOptions = [ "title" => "Dash Settings", "private" => $settings["global"]["private"], @@ -33,7 +34,7 @@ class DashControl "siteTitle" => $settings["global"]["title"], "baseUrl" => $settings["global"]["base_url"], "desc" => $settings["global"]["descriptions"], - "lastBackup" => $settings["global"]["last_backup"], + "lastBackup" => $updated->format("Y M D d"), "currentTheme" => $settings["global"]["theme"], "themes" => $themes, "mailOption" => $settings["email"]["active"], @@ -115,6 +116,7 @@ class DashControl header("Location: /dashboard"); die(); break; + default: //$secret = ; $template = "dash/start.twig"; diff --git a/brain/data/Settings.inc.php b/brain/data/Settings.inc.php index 4917c1e..535a5a9 100644 --- a/brain/data/Settings.inc.php +++ b/brain/data/Settings.inc.php @@ -168,6 +168,77 @@ class Settings DocTools::writeSettings("../config/settings.json", $settings); } + public static function makeBackup() + { + //make sure back directory is there + if (!is_dir("../config/backups")) { + mkdir("../config/backups", 0755, true); + } + //creat backup zip + $zip = new ZipArchive(); + $zip->open( + "../config/backups/latest_back.zip", + ZipArchive::CREATE | ZipArchive::OVERWRITE + ); + //gather data and path info for md pages + $pagePath = "../content/pages"; + $yearPaths = glob($pagePath . "/*", GLOB_ONLYDIR); + foreach ($yearPaths as $years) { + $year = explode("/", $years); + //grap the index and save it + if (trim($year[3]) == "start") { + $options = [ + "add_path" => "content/pages/" . $year[3] . "/", + "remove_all_path" => true, + ]; + $zip->addGlob($years . "/*.md", GLOB_BRACE, $options); + } + $monthsPath = glob($pagePath . "/" . $year[3] . "/*", GLOB_ONLYDIR); + foreach ($monthsPath as $months) { + $month = explode("/", $months); + //once info is collected, add md pages to zip + $options = [ + "add_path" => "content/pages/" . $year[3] . "/" . $month[4] . "/", + "remove_all_path" => true, + ]; + $zip->addGlob($months . "/*.md", GLOB_BRACE, $options); + } + } + + //tather data and path info for blog images + $blogImagesPath = "../public/assets/images/blog"; + $yearPaths = glob($blogImagesPath . "/*", GLOB_ONLYDIR); + foreach ($yearPaths as $years) { + $year = explode("/", $years); + $monthsPath = glob($blogImagesPath . "/" . $year[5] . "/*", GLOB_ONLYDIR); + foreach ($monthsPath as $months) { + $month = explode("/", $months); + //once info is collected, add images pages to zip + $options = [ + "add_path" => + "public/assets/images/blog/" . $year[5] . "/" . $month[6] . "/", + "remove_all_path" => true, + ]; + $zip->addGlob($months . "/*.*", GLOB_BRACE, $options); + } + } + + //add directory for settings and save them + $zip->addEmptyDir("settings"); + $zip->addFile("../config/settings.json", "settings/settings.json"); + $zip->addFile("../config/folks.json", "settings/folks.json"); + $zip->addFile("../config/tags.json", "settings/tags.json"); + //save zip file + $zip->close(); + + //update settings file with latest back up date + $updated = new \Moment\Moment(); + self::updateGlobalData("last_backup", $updated->format("Y-m-d\TH:i:sP")); + + $result = ["message" => "Backup created. THIS IS A SAFE SPACE!"]; + return $result; + } + public static function updateTags() { $tags = Sorting::tags(); diff --git a/brain/views/dash/settings.twig b/brain/views/dash/settings.twig index 39b5b45..79a91e2 100644 --- a/brain/views/dash/settings.twig +++ b/brain/views/dash/settings.twig @@ -64,7 +64,7 @@
{% if lastBackup != '' %}
- The last back up was created {{lastBackup}}
+ The last back up was created {{lastBackup}}
{% else %} span No back ups. Frowny face. diff --git a/src/libraries/FipamoAdminAPI.js b/src/libraries/FipamoAdminAPI.js index 55b05d7..195bb5b 100644 --- a/src/libraries/FipamoAdminAPI.js +++ b/src/libraries/FipamoAdminAPI.js @@ -19,7 +19,7 @@ export const API_UPLOAD_BACKGROUND = "/api/v1/settings/add-feature-background"; export const API_PUBLISH_PAGES = "/api/v1/settings/publish"; export const API_NAV_SYNC = "/api/v1/settings/nav-sync"; export const API_REINDEX_PAGES = "/api/v1/settings/reindex"; -export const API_CREATE_BACKUP = "/api/v1/backup/create"; +export const API_CREATE_BACKUP = "/api/v1/backup"; export const API_DOWNLOAD_BACKUP = "/api/v1/backup/download"; export const API_RESTORE_BACKUP = "/api/v1/backup/restore"; export const API_SEND_MAIL = "/api/v1/mailer";