This commit is contained in:
Joshua Ashton
2025-03-15 21:45:14 -06:00
parent ce6984622c
commit ab50339a32
24 changed files with 33 additions and 1354 deletions
-19
View File
@@ -1,19 +0,0 @@
{
"name": "quaxlyqueen/vintagecoding.net",
"description": "A blog and tutorial site.",
"type": "project",
"autoload": {
"psr-4": {
"Quaxlyqueen\\VintagecodingNet\\": "src/"
}
},
"authors": [
{
"name": "Josh Ashton",
"email": "me@joshashton.dev"
}
],
"require": {
"vlucas/phpdotenv": "^5.6"
}
}
Generated
-479
View File
@@ -1,479 +0,0 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "221cfbdaafd7336c85eb46b3ae913379",
"packages": [
{
"name": "graham-campbell/result-type",
"version": "v1.1.3",
"source": {
"type": "git",
"url": "https://github.com/GrahamCampbell/Result-Type.git",
"reference": "3ba905c11371512af9d9bdd27d99b782216b6945"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/3ba905c11371512af9d9bdd27d99b782216b6945",
"reference": "3ba905c11371512af9d9bdd27d99b782216b6945",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0",
"phpoption/phpoption": "^1.9.3"
},
"require-dev": {
"phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28"
},
"type": "library",
"autoload": {
"psr-4": {
"GrahamCampbell\\ResultType\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
}
],
"description": "An Implementation Of The Result Type",
"keywords": [
"Graham Campbell",
"GrahamCampbell",
"Result Type",
"Result-Type",
"result"
],
"support": {
"issues": "https://github.com/GrahamCampbell/Result-Type/issues",
"source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.3"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type",
"type": "tidelift"
}
],
"time": "2024-07-20T21:45:45+00:00"
},
{
"name": "phpoption/phpoption",
"version": "1.9.3",
"source": {
"type": "git",
"url": "https://github.com/schmittjoh/php-option.git",
"reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/schmittjoh/php-option/zipball/e3fac8b24f56113f7cb96af14958c0dd16330f54",
"reference": "e3fac8b24f56113f7cb96af14958c0dd16330f54",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"phpunit/phpunit": "^8.5.39 || ^9.6.20 || ^10.5.28"
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": false
},
"branch-alias": {
"dev-master": "1.9-dev"
}
},
"autoload": {
"psr-4": {
"PhpOption\\": "src/PhpOption/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "Johannes M. Schmitt",
"email": "schmittjoh@gmail.com",
"homepage": "https://github.com/schmittjoh"
},
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
}
],
"description": "Option Type for PHP",
"keywords": [
"language",
"option",
"php",
"type"
],
"support": {
"issues": "https://github.com/schmittjoh/php-option/issues",
"source": "https://github.com/schmittjoh/php-option/tree/1.9.3"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption",
"type": "tidelift"
}
],
"time": "2024-07-20T21:41:07+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638",
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",
"shasum": ""
},
"require": {
"php": ">=7.2"
},
"provide": {
"ext-ctype": "*"
},
"suggest": {
"ext-ctype": "For best performance"
},
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gert de Pagter",
"email": "BackEndTea@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for ctype functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"ctype",
"polyfill",
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341",
"reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341",
"shasum": ""
},
"require": {
"php": ">=7.2"
},
"provide": {
"ext-mbstring": "*"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-09-09T11:45:10+00:00"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.31.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
"reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8",
"shasum": ""
},
"require": {
"php": ">=7.2"
},
"type": "library",
"extra": {
"thanks": {
"url": "https://github.com/symfony/polyfill",
"name": "symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php80\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ion Bazan",
"email": "ion.bazan@gmail.com"
},
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-09-09T11:45:10+00:00"
},
{
"name": "vlucas/phpdotenv",
"version": "v5.6.1",
"source": {
"type": "git",
"url": "https://github.com/vlucas/phpdotenv.git",
"reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/a59a13791077fe3d44f90e7133eb68e7d22eaff2",
"reference": "a59a13791077fe3d44f90e7133eb68e7d22eaff2",
"shasum": ""
},
"require": {
"ext-pcre": "*",
"graham-campbell/result-type": "^1.1.3",
"php": "^7.2.5 || ^8.0",
"phpoption/phpoption": "^1.9.3",
"symfony/polyfill-ctype": "^1.24",
"symfony/polyfill-mbstring": "^1.24",
"symfony/polyfill-php80": "^1.24"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"ext-filter": "*",
"phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
},
"suggest": {
"ext-filter": "Required to use the boolean validator."
},
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": false
},
"branch-alias": {
"dev-master": "5.6-dev"
}
},
"autoload": {
"psr-4": {
"Dotenv\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
},
{
"name": "Vance Lucas",
"email": "vance@vancelucas.com",
"homepage": "https://github.com/vlucas"
}
],
"description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.",
"keywords": [
"dotenv",
"env",
"environment"
],
"support": {
"issues": "https://github.com/vlucas/phpdotenv/issues",
"source": "https://github.com/vlucas/phpdotenv/tree/v5.6.1"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv",
"type": "tidelift"
}
],
"time": "2024-07-20T21:52:34+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {},
"platform-dev": {},
"plugin-api-version": "2.6.0"
}
View File
+16
View File
@@ -0,0 +1,16 @@
* {
padding: 0;
margin: 0;
}
body {
background-color: black;
}
.center-abs {
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
View File
+4
View File
@@ -0,0 +1,4 @@
h1 {
font-size: clamp(4vw, 6vw, 8vw);
color: #00ee00;
}
View File
-22
View File
@@ -1,22 +0,0 @@
<?php
/*
* Given some article data, create a card or thumbnail of the article with the
* following:
* - A thumbnail image,
* - The article heading,
* - A brief description,
* - A call to action button.
*/
function generate_article_card($data) {
$article = '
<div class="box shadow">
<img class="shadow thumbnail" src="' . $data['thumbnail'] . '">
<h3 class="card_heading">' . $data['heading'] . '</h3>
<p class="">' . $data['description'] . '</p>
<button href="' . $data['path'] . '">Read Article</button>
</div>
';
return $article;
}
?>
-5
View File
@@ -1,5 +0,0 @@
<?php
echo '
</body>
</html>
';
-46
View File
@@ -1,46 +0,0 @@
<?php
include_once('includes/functions.php');
/*
* Creates a form from an associative array of fields.
*
* See includes/input_validation.php for the structure of a fields array.
*/
function generate_form($fields, $error)
{
$form = '
<div class="standard_box outer_shadow form_container">
<form method="' . $fields['method'] . '" action="' . $fields['action'] . '">
';
foreach ($fields as $field => $metadata) {
if ($field == 'method' || $field == 'action')
continue;
$form .= '
<div class="input_box inner_shadow">
<label for="' . $field . '">' . ucwords($metadata['label']) . '</label>
<input id="' . $field . '" name="' . $field . '" type="' . $metadata['type'] . '" placeholder="' . $metadata['placeholder'] . '">
</div>
';
}
$form .= '
<input type="submit" class="submit_button">
</form>
';
if (!empty($error)) {
$form .= '
<div class="standard_box inner_shadow error">
<p class="error">' . ucwords($error) . ' information!</p>
</div>
';
}
$form .= '
</div>
';
return $form;
}
-14
View File
@@ -1,14 +0,0 @@
<?php
echo '
<!doctype html>
<html lang="en">
<head>
<title>Vintage Coding</title>
<link href="css/styles.css" type="text/css" rel="stylesheet">
<script src="js/index.js"></script>
</head>
<body>
';
include_once('nav.php');
-14
View File
@@ -1,14 +0,0 @@
<?php
$nav = '
<nav>
<ul>
<li><a href="home.php">Home</a></li>
<li><a href="account.php">Account</a></li>
<li><a href="admin.php">Admin</a></li>
<li><a href="articles.php">Articles</a></li>
</ul>
</nav>
';
echo $nav;
-65
View File
@@ -1,65 +0,0 @@
<?php
$create_account_fields = [
'method' => 'post',
'action' => 'process.php?action=create_account',
'create_account_username' => [
'label' => 'username',
'type' => 'text',
'placeholder' => 'e.g., jsmith',
'validators' => [
'no_spaces',
'check_sql',
],
],
'create_account_first_name' => [
'label' => 'first name',
'type' => 'text',
'placeholder' => 'e.g., John',
'validators' => [
'no_spaces',
'only_letters',
'check_sql',
],
],
'create_account_last_name' => [
'label' => 'last name',
'type' => 'text',
'placeholder' => 'e.g., Smith',
'validators' => [
'no_spaces',
'only_letters',
'check_sql',
],
],
'create_account_email' => [
'label' => 'email address',
'type' => 'text',
'placeholder' => 'e.g., jsmith@email.com',
'validators' => [
'valid_email',
'check_sql',
],
],
'create_account_password' => [
'label' => 'password',
'type' => 'password',
'placeholder' => '',
'validators' => [
'no_spaces',
'pw_strength',
'no_backslash',
'check_sql',
],
],
'verify_create_account_password' => [
'label' => 'password',
'type' => 'password',
'placeholder' => '',
'validators' => [
'no_spaces',
'pw_strength',
'no_backslash',
'check_sql',
],
],
];
-25
View File
@@ -1,25 +0,0 @@
<?php
$login_fields = [
'method' => 'post',
'action' => 'process.php?action=login',
'login_username' => [
'label' => 'username',
'type' => 'text',
'placeholder' => 'e.g., jsmith',
'validators' => [
'no_spaces',
'check_sql',
],
],
'login_password' => [
'label' => 'password',
'type' => 'password',
'placeholder' => '',
'validators' => [
'no_spaces',
'pw_strength',
'no_backslash',
'check_sql',
],
],
];
-30
View File
@@ -1,30 +0,0 @@
<?php
include_once('sql.php');
function authorize($username, $password_hash)
{
$pw_hash = get_account_login($username);
pretty_print($pw_hash);
if (!empty($pw_hash)) {
if ($password_hash == $pw_hash) {
$user = get_account_info($username);
pretty_print($user);
// $_SESSION['is_logged_in'] = true;
// $_SESSION['username'] = $username;
return true;
}
}
return false;
}
function pretty_print($input)
{
echo '
<pre>
' . print_r($input) . '
</pre>
';
}
-308
View File
@@ -1,308 +0,0 @@
<?php
/*
* Author: Joshua Ashton <me@joshashton.dev>
* Date: 06 March 2025
* Version: v0.1.0
*
*
* A data format standard for easily creating forms with input validation.
*
*
* This file provides functions for validating form input data. For any given
* field in an associative array, provide an array of validation requirements.
* This is to enable modular data fields while ensuring data integrity and
* safety from SQL injection.
*
*
* Each function accepts at least an input string, and will return either true
* or false. It is up to the client to interpret that and create error messages
* and ensure data format consistency accordingly.
*
*
* *****************************************************************************
*
*
* EXAMPLE LOGIN DATA IMPLEMENTATION
*
*
* $login_fields = [
* 'method' => 'post',
* 'action' => 'process.php?action=login',
* 'login_username' => [
* 'label' => 'username',
* 'type' => 'text',
* 'placeholder' => 'e.g., jsmith',
* 'validators' => [
* 'no_spaces',
* 'check_sql',
* ],
* ],
*
* 'login_password' => [
* 'label' => 'password',
* 'type' => 'password',
* 'placeholder' => '',
* 'validators' => [
* 'no_spaces',
* 'pw_strength',
* 'no_backslash',
* 'check_sql',
* ],
* ],
* ];
*
*
* *****************************************************************************
*
*
* CLIENT VALIDATION IMPLEMENTATION
*
*
* function validate($input, $validators)
* {
* include_once ('includes/input_validation.php');
*
* foreach ($validators as $v) {
* switch ($v) {
* case 'no_spaces':
* if (!no_spaces($input))
* return false;
* break;
* case 'no_digits':
* if (!no_digits($input))
* return false;
* break;
* case 'no_backslash':
* if (!no_backslash($input))
* return false;
* break;
* case 'no_special':
* if (!no_special($input))
* return false;
* break;
* case 'only_digits':
* if (!only_digits($input))
* return false;
* break;
* case 'only_digits_x':
* if (!only_digits_x($input, 5))
* return false;
* break;
* case 'only_letters':
* if (!only_letters($input))
* return false;
* break;
* case 'only_letters_x':
* if (!only_letters_x($input, 5))
* return false;
* break;
* case 'valid_email':
* if (!valid_email($input))
* return false;
* break;
* case 'valid_phone':
* if (!valid_phone($input))
* return false;
* break;
* case 'pw_strength':
* if (!pw_strength($input))
* return false;
* break;
* case 'check_sql':
* if (check_sql($input))
* return false;
* break;
* }
* }
* return true;
* }
*/
function no_spaces($input)
{
return !str_contains($input, ' ');
}
function no_digits($input)
{
for ($i = 0; $i < strlen($input); $i++)
if (is_numeric($input[$i]))
return false;
return true;
}
function no_backslash($input)
{
for ($i = 0; $i < strlen($input); $i++)
if ($input[$i] === '\\')
return false;
return true;
}
/*
* This checks for the following characters:
* ' ' ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [
* \ ] ^ _ ` { | } ~
*
* TODO: Add support for additional special characters available through
* other means.
*/
function no_special($input)
{
$special = [
'!',
'"',
'#',
'$',
'%',
'&',
"'",
'(',
')',
'*',
'+',
',',
'-',
'.',
'/',
':',
';',
'<',
'=',
'>',
'?',
'@',
'[',
'\\',
']',
'^',
'_',
'`',
'{',
'|',
'}',
'~',
];
for ($i = 0; $i < strlen($input); $i++)
if (in_array($input[$i], $special))
return false;
return true;
}
function only_digits($input)
{
for ($i = 0; $i < strlen($input); $i++)
if (!is_numeric($input[$i]))
return false;
return true;
}
function only_digits_x($input, $x)
{
if (strlen($input) != $x)
return false;
for ($i = 0; $i < strlen($input); $i++)
if (!is_numeric($input[$i]))
return false;
return true;
}
function only_letters($input)
{
return (preg_match('/[^A-Za-z]*/', $input) == 1 ? true : false);
}
function only_letters_x($input, $x)
{
if (strlen($input) != $x)
return false;
return (preg_match('/[^A-Za-z]*/', $input) ? true : false);
}
// TODO: Add additional step which tests if the email exists.
function valid_email($input)
{
if (!str_contains($input, '@'))
return false;
$email = explode('@', $input);
if (count($email) != 2)
return false;
return true;
}
/*
* Note: While this function handles the most common variations of a phone
* number (and potential missed or inconsistent entry), it does not apply
* any formatting. The client must handle data consistency themselves.
*/
function valid_phone($input)
{
$formats = [
'/^\d{10}$/', // xxxxxxxxxx
'/^\d{3}-\d{7}$/', // xxx-xxxxxxx
'/^\d{6}-\d{4}$/', // xxxxxx-xxxx
'/^\d{3}-\d{3}-\d{4}$/', // xxx-xxx-xxxx
'/^\(\d{3}\)\d{7}$/', // (xxx)xxxxxxx
'/^\(\d{3}\)\d{3}-\d{4}$/', // (xxx)xxx-xxxx
'/^\(\d{3}\) \d{3}-\d{4}$/', // (xxx) xxx-xxxx
'/^\(\d{3}\)\d{3} -\d{4}$/', // (xxx)xxx -xxxx
'/^\(\d{3}\)\d{3}- \d{4}$/', // (xxx)xxx- xxxx
'/^\(\d{3}\)\d{3} - \d{4}$/', // (xxx)xxx - xxxx
'/^\(\d{3}\) \d{3} -\d{4}$/', // (xxx) xxx -xxxx
'/^\(\d{3}\) \d{3}- \d{4}$/', // (xxx) xxx- xxxx
'/^\(\d{3}\) \d{3} - \d{4}$/', // (xxx) xxx - xxxx
'/^\d{3} \d{7}$/', // xxx xxxxxxx
'/^\d{6} \d{4}$/', // xxxxxx xxxx
'/^\d{3} \d{3} \d{4}$/', // xxx xxx xxxx
'/^\d{3} \d{3}-\d{4}$/', // xxx xxx-xxxx
'/^\d{3}-\d{3} \d{4}$/', // xxx-xxx xxxx
'/^\d{3}\.\d{7}$/', // xxx.xxxxxxx
'/^\d{6}\.\d{4}$/', // xxxxxx.xxxx
'/^\d{3}\.\d{3}\.\d{4}$/', // xxx.xxx.xxxx
];
foreach ($formats as $regex)
if (preg_match($regex, $input))
return true;
return false;
}
/*
* TODO: This should ensure the user's password consists of the following:
* - length > 8,
* - 1+ uppercase letters,
* - 1+ lowercase letters,
* - 1+ digits,
* - 1+ special characters
*/
function pw_strength($input)
{
return true;
}
/*
* TODO: Need to implement SQL Injection prevention.
*
* Note: This should have the additional step of blacklisting a user who
* attempts SQL Injection. At least adding any valid submitted information
* to a DB table in case they attempt to create a 'valid' account, or
* flagging a 'valid' account that attempts SQL Injection. This will require
* a lot of research and therefore time. For now, since this isn't public
* facing, I'll operate with some trust in the user.
*
* Also, this might be better in a database functions file instead.
*/
function check_sql($input)
{
return false;
}
-72
View File
@@ -1,72 +0,0 @@
<?php
// phpdotenv initialization
require_once 'vendor/autoload.php';
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/..');
$dotenv->safeLoad();
// Use environment variables for the database password and IP address.
$db_user = $_ENV['DATABASE_USER'];
$db_pass = $_ENV['DATABASE_PASSWORD'];
define('HOST', 'localhost');
define('USER', $db_user);
define('PASS', $db_pass);
define('DB', 'vintagecodingdotnet');
// **************** ACCOUNT QUERIES *************** //
/*
* IMPORTANT: This should only be called once a user has been authorized as an
* administrator.
*
* TODO: Use JOIN to get other columns like roles and profile pictures.
*/
function get_all_accounts()
{
$conn = mysqli_connect(HOST, USER, PASS, DB);
$query = 'SELECT * FROM accounts;';
$results = mysqli_query($conn, $query);
return $results;
}
function get_account_login($username)
{
$conn = mysqli_connect(HOST, USER, PASS, DB);
$query = 'SELECT password_hash FROM accounts WHERE username = "' . $username . '";';
$results = mysqli_query($conn, $query);
return $results;
}
function get_account_info($username)
{
$conn = mysqli_connect(HOST, USER, PASS, DB);
$query = 'SELECT * FROM accounts WHERE username = "' . $username . '";';
$results = mysqli_query($conn, $query);
return $results;
}
function get_account_role($username)
{
$conn = mysqli_connect(HOST, USER, PASS, DB);
$query = 'SELECT * FROM accounts WHERE username = "' . $username . '";';
$results = mysqli_query($conn, $query);
return $results;
}
// **************** ARTICLE QUERIES *************** //
function get_all_article_cards()
{
$conn = mysqli_connect(HOST, USER, PASS, DB);
$query = 'SELECT article_id, title, slug, featured_image, excerpt FROM articles;';
$results = mysqli_query($conn, $query);
return $results;
}
function get_new_article_cards()
{
$conn = mysqli_connect(HOST, USER, PASS, DB);
$query = 'SELECT article_id, title, slug, featured_image, excerpt FROM articles ORDER BY publish_date;';
$results = mysqli_query($conn, $query);
return $results;
}
Executable → Regular
+13 -4
View File
@@ -1,6 +1,15 @@
<?php
include_once('includes/components/head.php');
<!DOCTYPE html>
<html>
include_once('login.php');
<head>
<link href="css/base.css" rel="stylesheet" type="text/css">
<link href="css/text.css" rel="stylesheet" type="text/css">
</head>
include_once('includes/components/foot.php');
<body>
<div class="center-abs">
<h1>Under Construction</h1>
</div>
</body>
</html>
View File
View File
-8
View File
@@ -1,8 +0,0 @@
<?php
include_once('includes/fields/login_fields.php');
include_once('includes/components/form.php');
if (isset($_GET['error']))
echo generate_form($login_fields, $_GET['error']);
else
echo generate_form($login_fields, '');
-6
View File
@@ -1,6 +0,0 @@
<?php
include_once('../includes/components/head.php');
echo '<h1>Home</h1>';
include_once('../includes/components/foot.php');
-114
View File
@@ -1,114 +0,0 @@
<?php
if (!isset($_GET['action']))
header('Location: .');
include_once ('includes/functions.php');
$action = $_GET['action'];
switch ($action) {
case 'login':
$error_location = 'login.php?error=';
$success_location = 'pages/home.php';
// If fields are empty, redirect to login with error state.
if (empty($_POST['login_username']) || empty($_POST['login_password']))
header('Location: ' . $error_location . 'empty');
include_once ('fields/login_fields.php');
// If field inputs are invalid, redirect to login with error state.
foreach ($_POST as $field => $value) {
if (!validate($value, $login_fields[$field]['validators']))
header('Location: ' . $error_location . 'invalid');
}
$username = $_POST['login_username'];
$password_hash = hash('sha256', $_POST['login_password']);
// If username/password hash are incorrect, redirect to login with error state.
if (!authorize($username, $password_hash))
header('Location: ' . $error_location . 'incorrect');
unset($_POST['login_username']);
unset($_POST['login_password']);
// auth() handles setting $_SESSION variables, user is now OK to proceed to home.php.
header('Location: ' . $success_location);
default:
// code...
break;
}
function validate($input, $validators)
{
include_once ('includes/input_validation.php');
foreach ($validators as $v) {
switch ($v) {
case 'no_spaces':
if (!no_spaces($input))
return false;
break;
case 'no_digits':
if (!no_digits($input))
return false;
break;
case 'no_backslash':
if (!no_backslash($input))
return false;
break;
case 'no_special':
if (!no_special($input))
return false;
break;
case 'only_digits':
if (!only_digits($input))
return false;
break;
// TODO: Need to get x.
case 'only_digits_x':
if (!only_digits_x($input, 5))
return false;
break;
case 'only_letters':
if (!only_letters($input))
return false;
break;
// TODO: Need to get x.
case 'only_letters_x':
if (!only_letters_x($input, 5))
return false;
break;
case 'valid_email':
if (!valid_email($input))
return false;
break;
case 'valid_phone':
if (!valid_phone($input))
return false;
break;
case 'pw_strength':
if (!pw_strength($input))
return false;
break;
case 'check_sql':
if (check_sql($input))
return false;
break;
}
}
return true;
}
-123
View File
@@ -1,123 +0,0 @@
create_db() {
/opt/lampp/bin/mariadb -u violet -p -e "DROP DATABASE IF EXISTS vintagecodingdotnet;";
/opt/lampp/bin/mariadb -u violet -p -e "CREATE DATABASE vintagecodingdotnet;";
# Create file_types table.
/opt/lampp/bin/mariadb -u violet -p -e "
USE vintagecodingdotnet;
CREATE TABLE file_types (
file_type_id INT PRIMARY KEY AUTO_INCREMENT,
file_type VARCHAR(8)
);";
# Create the media table.
/opt/lampp/bin/mariadb -u violet -p -e "
USE vintagecodingdotnet;
CREATE TABLE media (
media_id INT PRIMARY KEY,
file_name TINYTEXT NOT NULL,
file_path VARCHAR(2048) NOT NULL,
file_type INT NOT NULL,
FOREIGN KEY (file_type) REFERENCES file_types(file_type_id)
);";
# Create the roles table.
/opt/lampp/bin/mariadb -u violet -p -e "
USE vintagecodingdotnet;
CREATE TABLE roles (
role_id INT PRIMARY KEY AUTO_INCREMENT,
role VARCHAR(32) NOT NULL
);";
# Create the accounts table.
/opt/lampp/bin/mariadb -u violet -p -e "
USE vintagecodingdotnet;
CREATE TABLE accounts (
account_id INT PRIMARY KEY,
username VARCHAR(32) UNIQUE NOT NULL,
first_name VARCHAR(64) NOT NULL,
last_name VARCHAR(64) NOT NULL,
email VARCHAR(64) UNIQUE NOT NULL,
password_hash VARCHAR(64) NOT NULL,
role INT NOT NULL,
registration_date DATETIME,
bio TINYTEXT,
profile_picture INT,
FOREIGN KEY (role) REFERENCES roles(role_id),
FOREIGN KEY (profile_picture) REFERENCES media(media_id)
);";
# Create the article_status table.
/opt/lampp/bin/mariadb -u violet -p -e "
USE vintagecodingdotnet;
CREATE TABLE article_status (
status_id INT PRIMARY KEY AUTO_INCREMENT,
status VARCHAR(16) NOT NULL
);";
# Create the articles table.
/opt/lampp/bin/mariadb -u violet -p -e "
USE vintagecodingdotnet;
CREATE TABLE articles (
article_id INT PRIMARY KEY AUTO_INCREMENT,
account_id INT NOT NULL,
title VARCHAR(128) UNIQUE NOT NULL,
slug VARCHAR(128) UNIQUE NOT NULL,
content LONGTEXT NOT NULL,
publish_date DATETIME,
last_modified DATETIME NOT NULL,
status INT NOT NULL,
featured_image INT,
excerpt VARCHAR(255),
FOREIGN KEY (account_id) REFERENCES accounts(account_id),
FOREIGN KEY (status) REFERENCES article_status(status_id)
);";
}
# Insert data constants into the database.
# Acceptable file types: png, jpg, jpeg, svg.
# Acceptable roles: administrator, contributor, commenter, guest.
# Acceptable article status: published, draft, archived.
#
# Also creates administrator user
const_data() {
# Insert the data to the file_types table.
# Acceptable file types are png, jpg, jpeg, svg
/opt/lampp/bin/mariadb -u violet -p -e "
USE vintagecodingdotnet;
INSERT INTO file_types (file_type) VALUES ('png'), ('jpg'), ('jpeg'), ('svg');
";
# Insert the data to the roles table.
/opt/lampp/bin/mariadb -u violet -p -e "
USE vintagecodingdotnet;
INSERT INTO roles (role) VALUES ('administrator'), ('contributor'), ('commenter'), ('guest');
";
# Insert the data to the article_status table.
/opt/lampp/bin/mariadb -u violet -p -e "
USE vintagecodingdotnet;
INSERT INTO article_status (status) VALUES ('published'), ('draft'), ('archived');
";
# Create an administrator user.
/opt/lampp/bin/mariadb -u violet -p -e "
USE vintagecodingdotnet;
INSERT INTO accounts
(account_id, username, email, password_hash, role, registration_date, bio, profile_picture) VALUES
(42, 'admin', 'me@joshashton.dev', 'e03b1a00caa6e8113a3bc3e7101ecbd0fea710f5e091e7b195bdba53bbeb004e', 1, CURDATE(), null, null);
";
}
insert_data() {
/opt/lampp/bin/mariadb -u violet -p -e "
USE vintagecodingdotnet;
INSERT INTO articles (article_name) VALUES
('test'),
('another test'),
('a third test');
";
}
create_db
const_data