diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..c28aea0
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,3 @@
+# These are supported funding model platforms
+
+github: ['Nephiaust']
diff --git a/.github/workflows/psalm.yml b/.github/workflows/psalm.yml
new file mode 100644
index 0000000..931deb7
--- /dev/null
+++ b/.github/workflows/psalm.yml
@@ -0,0 +1,35 @@
+name: Psalm Static analysis
+
+on: [push, pull_request]
+
+jobs:
+ psalm:
+ name: Psalm
+ permissions:
+ actions: read
+ checks: read
+ contents: read
+ deployments: none
+ id-token: none
+ issues: write
+ discussions: read
+ packages: read
+ pages: none
+ pull-requests: write
+ repository-projects: read
+ security-events: write
+ statuses: write
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v3
+
+ - name: Psalm
+ uses: docker://ghcr.io/psalm/psalm-github-actions:5.7.7
+ with:
+ security_analysis: true
+ report_file: results.sarif
+ - name: Upload Security Analysis results to GitHub
+ uses: github/codeql-action/upload-sarif@v2
+ with:
+ sarif_file: results.sarif
diff --git a/.gitignore b/.gitignore
index 485dee6..8ea58cf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,44 @@
.idea
+/uploads/*
+
+# General Apple files
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Apple Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# VS Code files for those working on multiple tools
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+*.code-workspace
+
+# Local History for Visual Studio Code
+.history/
+
+# Built Visual Studio Code Extensions
+*.vsix
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..6c2ff60
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+ "githubPullRequests.ignoredPullRequestBranches": [
+ "master"
+ ]
+}
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..ea64188
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1 @@
+//TODO
\ No newline at end of file
diff --git a/README.md b/README.md
index 758e35a..4e4c566 100644
--- a/README.md
+++ b/README.md
@@ -1,25 +1,32 @@
# Simple-PHP-Blog
-Simple blog system for personal development using procedural PHP and MYSQL.
+Simple blog system for personal development using procedural PHP and MySQLi. It allows you to create, edit, delete posts to get you started on your journey. If you are building your own from scratch this will give the head start that you need.
For educational purposes only.
-# Setup
+**__Security is not guaranteed with this system, best efforts have been made to make it secure__**
-Update the `connect.php` file with your database credentials.
-Import the `database.sql` file.
+Setup
+===
-If installed on a sub-folder, edit the `config.php` and replace the empty constant with the folder's name.
-
-The pagination results per page can be set on the `config.php` file.
+1. Create a MySQL database on your MySQL server, take note of the details (username, password, database name, server name)
+2. Import the `database.sql` file into the new database you created
+3. Edit the `config.php` file
+ 1. Edit the MySQL details to match your SQL server login details (e.g. server name, username, password, database)
+ 2. Edit the `SITE_ROOT` if you are putting it in a folder/sub-directory (e.g. www.example.com/myblog/, you would enter 'myblog' there)
+ 3. _OPTIONAL_ Change the number of blog posts to show per page with the `PAGINATION` option
+ 4. _OPTIONAL_ Set the `DEBUG_MODE` option to `true` if you want/need to see any and all errors
+4. Upload all the files to your web server
+5. Go to your new site (e.g. www.example.com/myblog/)
### URL Rewrite
-The latest update introduces 'slugs', also known as 'SEO URLs'.
-After you update to the latest version, click on the "Generate slugs (SEO URLs)" button on the admin dashboard and slugs will be generated for all existing posts.
+The system now uses **slugs**, also known as **SEO URLs**
-The blog posts URL structure is like this: `http://localhost/p/4/apple-reveals-apple-watch-series-7`
+The blog posts URL structure is like this: `http://www.example.com/myblog/p/4/apple-reveals-apple-watch-series-7`, where the `p/4/apple-reveals-apple-watch-series-7` is the slug
-If you use Apache, enable the Apache rewrite module for the .htaccess rewrite rule to work.
+#### Apache servers
+There is an .htaccess file that has the required rewrite module and rule in the files.
+#### Nginx servers
If you use NGINX, you can insert something similar to the code below in your NGINX configuration block.
```
location / {
@@ -27,14 +34,19 @@ location / {
}
```
-# Default Admin Login
+Using the Simple-PHP-Blog
+===
+
+The system is quite easy to use, as there isnt much work required to do a simple blog.
+
+## Default Admin Login
Username: admin
Password: 12345
-There is no way to update the admin password through the dashboard yet.
-To change your password, hash your password with PHP's `password_hash()` function. Then update the database value with the new password hash.
+**__There is no way to update the admin password through the dashboard yet.__**
+**__To change your password, hash your password with PHP's `password_hash()` function. Then update the database value with the new password hash.__**
-# Screenshots
+## Screenshots


diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..61335f7
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,18 @@
+# Security Policy
+
+## Supported Versions
+
+Use this section to tell people about which versions of your project are
+currently being supported with security updates.
+
+| Version | Supported |
+| ------- | ------------------ |
+| 4.x.x | :white_check_mark: |
+
+## Reporting a Vulnerability
+
+Use this section to tell people how to report a vulnerability.
+
+Tell them where to go, how often they can expect to get an update on a
+reported vulnerability, what to expect if the vulnerability is accepted or
+declined, etc.
diff --git a/_config.yml b/_config.yml
deleted file mode 100644
index c419263..0000000
--- a/_config.yml
+++ /dev/null
@@ -1 +0,0 @@
-theme: jekyll-theme-cayman
\ No newline at end of file
diff --git a/admin.php b/admin.php
index 6a0163e..5d45f66 100644
--- a/admin.php
+++ b/admin.php
@@ -1,16 +1,21 @@
-
";
}
include("categories.php");
diff --git a/login.php b/login.php
index 09265c4..8fed782 100644
--- a/login.php
+++ b/login.php
@@ -1,37 +1,72 @@
Login';
-if (isset($_POST['log'])) {
- $username = mysqli_real_escape_string($dbcon, $_POST['username']);
- $password = mysqli_real_escape_string($dbcon, $_POST['password']);
+if (isset($_POST['username'])) {$CurrentUser = htmlentities(strip_tags($_POST['username']), ENT_SUBSTITUTE);}
- $sql = "SELECT * FROM admin WHERE username = '$username'";
+// Lets check to see if the call was a HTTP POST request
+// If it is, display the admin page
+// If it is NOT, display the login page
+if ($_SERVER["REQUEST_METHOD"] == "POST") {
+ // Now to check if the username field is not empty, otherwise throw an error.
+ if (empty(trim($_POST["username"]))) {
+ echo "
Username or password not supplied.
";
+ } else {
+ // We have data for a username, now lets save it in a SQL safe string (e.g. automatically add escape characters, etc.)
+ $username = mysqli_real_escape_string($dbcon, $_POST['username']);
+ }
+
+ // Do the same for the password field.
+ if (empty(trim($_POST["password"]))) {
+ echo "
Username or password not supplied!
";
+ } else {
+ // And again save the password in a SQL safe string
+ $password = mysqli_real_escape_string($dbcon, $_POST['password']);
+ }
+
+ // Build the SQL statement to get the user details (so we can then verify the user exists AND that the password is valid)
+ $sql = "SELECT `id`, `username`, `password`, `displayname` FROM users WHERE username = '$username'";
+
+ // Request the data from the SQL server, process it AND count the number of rows.
$result = mysqli_query($dbcon, $sql);
$row = mysqli_fetch_assoc($result);
$row_count = mysqli_num_rows($result);
-
+ // Check that the user only exists once in the SQL database AND that the password is matching.
if ($row_count == 1 && password_verify($password, $row['password'])) {
+ // This part we store some information in the PHP session information, so we can use it as a later time (e.g. the user ID)
+ $_SESSION['displayname'] = $row['displayname'];
+ $_SESSION['userid'] = $row['id'];
$_SESSION['username'] = $username;
+ $_SESSION["loggedin"] = true;
+
+ // Now we redirect the user to the admin portal.
header("location: admin.php");
} else {
echo "