diff --git a/app/classes/config.php b/app/classes/config.php
index dff2866..330b247 100644
--- a/app/classes/config.php
+++ b/app/classes/config.php
@@ -74,7 +74,7 @@ class Config extends BedrockConfig {
$html .= '
';
diff --git a/app/classes/email.php b/app/classes/email.php
index 142c6a8..1ac110e 100644
--- a/app/classes/email.php
+++ b/app/classes/email.php
@@ -164,7 +164,7 @@ class Email {
}
}
$data->MAIL_FOOT = Views::simpleView( 'email.foot' );
- $data->MAIL_TITLE = self::$title;
+ $data->MAIL_TITLE = Template::parse( self::$title );
$data->MAIL_BODY = Template::parse( self::$message, $data );
$subject = Template::parse( self::$subject, $data );
$body = Views::simpleView( 'email.template', $data );
diff --git a/app/classes/forms.php b/app/classes/forms.php
index 28201a2..728adac 100644
--- a/app/classes/forms.php
+++ b/app/classes/forms.php
@@ -358,6 +358,10 @@ class Forms extends Check {
self::addUserError( 'Invalid Email.' );
return false;
}
+ if ( $user->usernameExists( Input::post( 'username' ) ) ) {
+ self::addUserError( 'A user with that username is already registered.' );
+ return false;
+ }
if ( !$user->noEmailExists( Input::post( 'email' ) ) ) {
self::addUserError( 'A user with that email is already registered.' );
return false;
@@ -374,7 +378,7 @@ class Forms extends Check {
self::addUserError( 'You must agree to the terms of service.' );
return false;
}
- if ( !self::token() ) {
+ if ( ! self::token() ) {
return false;
}
return true;
diff --git a/app/controllers/register.php b/app/controllers/register.php
index c04e6ca..f8ecbe3 100644
--- a/app/controllers/register.php
+++ b/app/controllers/register.php
@@ -25,6 +25,7 @@ use TheTempusProject\TheTempusProject as App;
use TheTempusProject\Classes\Controller;
use TheTempusProject\Classes\Forms;
use TheTempusProject\Bedrock\Classes\Config;
+use TheTempusProject\Plugins\Turnstile;
class Register extends Controller {
public function confirm( $code = null ) {
@@ -47,22 +48,40 @@ class Register extends Controller {
public function index() {
self::$title = '{SITENAME} Sign Up';
self::$pageDescription = 'Many features of {SITENAME} are disabled or hidden from unregistered users. On this page you can sign up for an account to access all the app has to offer.';
-
if ( ! Config::getValue( 'main/registrationEnabled' ) ) {
return Issues::add( 'notice', 'The site administrator has disable the ability to register a new account.' );
}
-
+ $turnstile = '';
+ if ( class_exists( 'TheTempusProject\Plugins\Turnstile' ) ) {
+ $turnstile = new Turnstile;
+ if ( ! $turnstile->checkEnabled() ) {
+ Components::set( 'TURNSTILE_WIDGET', '' );
+ $turnstile = '';
+ }
+ } else {
+ Components::set( 'TURNSTILE_WIDGET', '' );
+ }
Components::set( 'TERMS', Views::simpleView( 'auth.terms' ) );
if ( App::$isLoggedIn ) {
return Issues::add( 'notice', 'You are currently logged in.' );
}
- if ( !Input::exists() ) {
+ if ( ! Input::exists() ) {
return Views::view( 'auth.register' );
}
- if ( !Forms::check( 'register' ) ) {
+ if ( Input::exists( 'userEmail' ) ) {
+ // for the really bad AI / headless bots
+ Session::flash( 'success', 'Thank you for registering! Please check your email to confirm your account.' );
+ Redirect::to( 'home/index' );
+ }
+ if ( ! Forms::check( 'register' ) ) {
Issues::add( 'error', [ 'There was an error with your registration.' => Check::userErrors() ] );
return Views::view( 'auth.register' );
}
+ if ( ! empty( $turnstile ) ) {
+ if ( empty( $turnstile->verify() ) ) {
+ return Views::view( 'auth.register' );
+ }
+ }
self::$user->create( [
'username' => Input::post( 'username' ),
'password' => Hash::make( Input::post( 'password' ) ),
diff --git a/app/css/main-dark.css b/app/css/main-dark.css
index f6306ae..eb01391 100644
--- a/app/css/main-dark.css
+++ b/app/css/main-dark.css
@@ -8,6 +8,7 @@
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
+
.context-popover {
background-color: #383838;
color: white;
diff --git a/app/css/main.css b/app/css/main.css
index 86cd59f..19640bb 100644
--- a/app/css/main.css
+++ b/app/css/main.css
@@ -8,40 +8,40 @@
* @link https://TheTempusProject.com
* @license https://opensource.org/licenses/MIT [MIT LICENSE]
*/
-.facebook {
+ .facebook {
border-color: #1877F2 !important; /* Facebook Blue */
color: #1877F2 !important;
-}
-
-.x-black {
+ }
+
+ .x-black {
border-color: #000000 !important; /* X (formerly Twitter) Black */
color: #000000 !important;
-}
-
-.reddit {
+ }
+
+ .reddit {
border-color: #FF4500 !important; /* Reddit Orange */
color: #FF4500 !important;
-}
-
-.opera {
+ }
+
+ .opera {
border-color: #FF1B2D !important; /* Opera Red */
color: #FF1B2D !important;
-}
-
-.firefox {
+ }
+
+ .firefox {
border-color: #FF7139 !important; /* Firefox Orange */
color: #FF7139 !important;
-}
-
-.edge {
+ }
+
+ .edge {
border-color: #0078D7 !important; /* Microsoft Edge Blue */
color: #0078D7 !important;
-}
-
-.safari {
+ }
+
+ .safari {
border-color: #0B78E3 !important; /* Safari Blue */
color: #0B78E3 !important;
-}
+ }
.context-main-border {
border-color: #1e1e1e!important;
diff --git a/app/js/main.js b/app/js/main.js
index 95869a2..42bc568 100644
--- a/app/js/main.js
+++ b/app/js/main.js
@@ -25,26 +25,28 @@ if ( ! localStorage.getItem("pwaInstallDismissed") ) {
deferredPrompt = event;
installPrompt.classList.remove("d-none");
installPrompt.classList.add("d-block"); // Show the alert
- chromeMessage.classList.remove("d-none");
- chromeMessage.classList.add("d-block"); // Show the prompt
+ if ( chromeMessage ) {
+ chromeMessage.classList.remove("d-none");
+ chromeMessage.classList.add("d-block"); // Show the prompt
+ }
});
if ( isIos() && ! isInStandaloneMode() ) {
installPrompt.classList.remove("d-none");
installPrompt.classList.add("d-block"); // Show the alert
- iosMessage.classList.remove("d-none");
- iosMessage.classList.add("d-block"); // Show the prompt
+
+ if ( iosMessage ) {
+ iosMessage.classList.remove("d-none");
+ iosMessage.classList.add("d-block"); // Show the prompt
+ }
}
}
// ios REQUIRES a service worker
-if ( 'serviceWorker' in navigator ) {
- navigator.serviceWorker.register('app/js/sw.js')
+if ('serviceWorker' in navigator) {
+ navigator.serviceWorker.register('/sw.js')
.then(() => console.log('Service Worker Registered'));
}
-// self.addEventListener('install', () => self.skipWaiting());
-// self.addEventListener('activate', () => self.clients.claim());
-// self.addEventListener('fetch', () => {}); // No file interception
// Handle Install Button Click
if ( installButton ) {
@@ -299,6 +301,7 @@ document.querySelectorAll('[data-bs-toggle="collapse"]').forEach(button => {
});
+
// this should load all popovers
document.addEventListener("DOMContentLoaded", function () {
var popoverTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]'));
diff --git a/app/models/user.php b/app/models/user.php
index 0bbf75a..7d07d12 100644
--- a/app/models/user.php
+++ b/app/models/user.php
@@ -641,7 +641,7 @@ class User extends DatabaseModel {
Debug::error( 'User not created.' );
return false;
}
- return true;
+ return self::$db->lastId();
}
/**
diff --git a/app/plugins/comments/plugin.php b/app/plugins/comments/plugin.php
index 61fb325..752c021 100644
--- a/app/plugins/comments/plugin.php
+++ b/app/plugins/comments/plugin.php
@@ -65,7 +65,7 @@ class Comments extends Plugin {
public function __construct( $load = false ) {
if ( !empty(App::$activePerms) ) {
- App::$isMod = !empty(App::$activePerms['modAccess']);
+ App::$isMod = ! empty( App::$activePerms['modAccess'] );
} else {
App::$isMod = false;
}
diff --git a/app/plugins/contact/controllers/contact.php b/app/plugins/contact/controllers/contact.php
index 7cb5969..68050a6 100644
--- a/app/plugins/contact/controllers/contact.php
+++ b/app/plugins/contact/controllers/contact.php
@@ -21,6 +21,7 @@ use TheTempusProject\Bedrock\Functions\Input;
use TheTempusProject\Bedrock\Functions\Session;
use TheTempusProject\Hermes\Functions\Redirect;
use TheTempusProject\Models\Contact as ContactModel;
+use TheTempusProject\Plugins\Turnstile;
class Contact extends Controller {
protected static $contact;
@@ -29,13 +30,28 @@ class Contact extends Controller {
self::$contact = new ContactModel;
self::$title = 'Contact - {SITENAME}';
self::$pageDescription = 'At {SITENAME}, we value our users\' input. You can provide any contact or suggestions using this form.';
- if ( !Input::exists() ) {
+ $turnstile = '';
+ if ( class_exists( 'TheTempusProject\Plugins\Turnstile' ) ) {
+ $turnstile = new Turnstile;
+ if ( ! $turnstile->checkEnabled() ) {
+ Components::set( 'TURNSTILE_WIDGET', '' );
+ $turnstile = '';
+ }
+ } else {
+ Components::set( 'TURNSTILE_WIDGET', '' );
+ }
+ if ( ! Input::exists() ) {
return Views::view( 'contact.create' );
}
- if ( !Forms::check( 'contact' ) ) {
+ if ( ! Forms::check( 'contact' ) ) {
Issues::add( 'error', [ 'There was an error with your form, please check your submission and try again.' => Check::userErrors() ] );
return Views::view( 'contact.create' );
}
+ if ( ! empty( $turnstile ) ) {
+ if ( empty( $turnstile->verify() ) ) {
+ return Views::view( 'contact.create' );
+ }
+ }
$result = self::$contact->create( Input::post( 'name' ), Input::post( 'contactEmail' ), Input::post( 'entry' ) );
if ( $result ) {
Session::flash( 'success', 'Thank you! Your contact has been received.' );
diff --git a/app/plugins/contact/views/create.html b/app/plugins/contact/views/create.html
index c4783ba..1d17811 100644
--- a/app/plugins/contact/views/create.html
+++ b/app/plugins/contact/views/create.html
@@ -40,6 +40,7 @@
+ {TURNSTILE_WIDGET}
Submit
diff --git a/app/plugins/notifications/controllers/admin/notifications.php b/app/plugins/notifications/controllers/admin/notifications.php
index ac935f1..b14fd0a 100644
--- a/app/plugins/notifications/controllers/admin/notifications.php
+++ b/app/plugins/notifications/controllers/admin/notifications.php
@@ -35,8 +35,6 @@ class Notifications extends AdminController {
self::$notifications = new NotificationsModel;
self::$user = new User;
self::$group = new Group;
- $view = Navigation::activePageSelect( 'nav.admin', '/admin/Notifications' );
- Components::set( 'ADMINNAV', $view );
}
public function index( $data = null ) {
diff --git a/app/plugins/notifications/models/notification.php b/app/plugins/notifications/models/notification.php
index d9f939c..db8fc6f 100644
--- a/app/plugins/notifications/models/notification.php
+++ b/app/plugins/notifications/models/notification.php
@@ -121,21 +121,21 @@ class Notification extends DatabaseModel {
return true;
}
- public function filter( $messageArray, $filters = [] ) {
+ public function filter( $entities, $filters = [] ) {
$out = [];
- foreach ( $messageArray as $message ) {
- if ( !is_object( $message ) ) {
- $message = $messageArray;
+ foreach ( $entities as $entity ) {
+ if ( !is_object( $entity ) ) {
+ $entity = $entities;
$end = true;
}
- if ( $message->seenAt == 0 ) {
- $message->unseenBadge = Views::simpleView( 'notifications.unseenBadge' );
- $message->markReadLink = '
';
+ if ( $entity->seenAt == 0 ) {
+ $entity->unseenBadge = Views::simpleView( 'notifications.unseenBadge' );
+ $entity->markReadLink = '
';
} else {
- $message->unseenBadge = '';
- $message->markReadLink = '';
+ $entity->unseenBadge = '';
+ $entity->markReadLink = '';
}
- $out[] = (object) $message;
+ $out[] = (object) $entity;
if ( !empty( $end ) ) {
$out = $out[0];
break;
diff --git a/app/plugins/turnstile/plugin.php b/app/plugins/turnstile/plugin.php
new file mode 100644
index 0000000..d2a6e4d
--- /dev/null
+++ b/app/plugins/turnstile/plugin.php
@@ -0,0 +1,85 @@
+
+ * @link https://TheTempusProject.com
+ * @license https://opensource.org/licenses/MIT [MIT LICENSE]
+ */
+namespace TheTempusProject\Plugins;
+
+use TheTempusProject\TheTempusProject as App;
+use TheTempusProject\Classes\Plugin;
+use TheTempusProject\Models\Notification;
+use TheTempusProject\Houdini\Classes\Components;
+use TheTempusProject\Houdini\Classes\Views;
+use TheTempusProject\Bedrock\Classes\Config;
+use TheTempusProject\Bedrock\Functions\Input;
+use TheTempusProject\Houdini\Classes\Issues;
+
+class Turnstile extends Plugin {
+ private static $loaded = false;
+ public $pluginName = 'TP Turnstile';
+ public $pluginAuthor = 'JoeyK';
+ public $pluginWebsite = 'https://TheTempusProject.com';
+ public $modelVersion = '1.0';
+ public $pluginVersion = '3.0';
+ public $pluginDescription = 'A simple plugin which adds a site wide cloudflare turnstile integration.';
+ public $configName = 'turnstile';
+ public $configMatrix = [
+ 'secretKey' => [
+ 'type' => 'text',
+ 'pretty' => 'Turnstile Secret Key',
+ 'default' => 'xxxxxxxxxxxxx',
+ ],
+ 'apiKey' => [
+ 'type' => 'text',
+ 'pretty' => 'Turnstile API Key',
+ 'default' => 'xxxxxxxxxxxxxx',
+ ],
+ ];
+
+ public function __construct( $load = false ) {
+ parent::__construct( $load );
+ if ( ! self::$loaded ) {
+ if ( $this->checkEnabled() ) {
+ Components::set( 'TURNSTILE_API_KEY', Config::getValue( 'turnstile/apiKey' ) );
+ Components::set( 'TURNSTILE_WIDGET', Views::simpleView( 'turnstile.widget') );
+ Components::append( 'TEMPLATE_JS_INCLUDES', '' );
+ }
+ self::$loaded = true;
+ }
+ }
+
+ public function verify() {
+ if ( ! Input::exists('cf-turnstile-response') ) {
+ Issues::add( 'notice', 'Turnstile verification failed. Please try again.' );
+ return false;
+ }
+ $verify_url = "https://challenges.cloudflare.com/turnstile/v0/siteverify";
+ $data = [
+ "secret" => Config::getValue( 'turnstile/secretKey' ),
+ "response" => Input::post('cf-turnstile-response'),
+ "remoteip" => $_SERVER["REMOTE_ADDR"] // Optional, helps detect abuse
+ ];
+ $options = [
+ "http" => [
+ "header" => "Content-Type: application/x-www-form-urlencoded",
+ "method" => "POST",
+ "content" => http_build_query($data)
+ ]
+ ];
+ $context = stream_context_create($options);
+ $response = file_get_contents($verify_url, false, $context);
+ $result = json_decode($response, true);
+ if ( ! $result["success"]) {
+ Issues::add( 'notice', 'Turnstile verification failed. Please try again. If the issue persists, please contact the site administrator.' );
+ return false;
+ }
+ return true;
+ }
+}
diff --git a/app/plugins/turnstile/views/widget.html b/app/plugins/turnstile/views/widget.html
new file mode 100644
index 0000000..b129fc9
--- /dev/null
+++ b/app/plugins/turnstile/views/widget.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/app/templates/default/default.inc.php b/app/templates/default/default.inc.php
index 6747556..d84b00d 100644
--- a/app/templates/default/default.inc.php
+++ b/app/templates/default/default.inc.php
@@ -49,6 +49,7 @@ class DefaultLoader extends Loader {
Components::set( 'FONT_AWESOME_URL', self::FONT_AWESOME_URL );
}
$this->addJs( '' );
+ $this->addJs( '' );
Components::setIfNull( 'LOGO', Config::getValue( 'main/logo' ) ?? TP_DEFAULT_LOGO );
if ( ! empty( Config::getValue( 'share/enabled' ) ) ) {
diff --git a/app/views/admin/users/list.html b/app/views/admin/users/list.html
index 79110bd..430afe2 100644
--- a/app/views/admin/users/list.html
+++ b/app/views/admin/users/list.html
@@ -19,7 +19,7 @@
{LOOP}
- {ID}
+ {ID}
{usernamePretty}
{DTC date}{registered}{/DTC}
@@ -31,7 +31,7 @@
{/LOOP}
{ALT}
-
+
No results to show.
diff --git a/app/views/auth/register.html b/app/views/auth/register.html
index 23281cd..79a407f 100644
--- a/app/views/auth/register.html
+++ b/app/views/auth/register.html
@@ -15,6 +15,7 @@
Email:
+
@@ -42,6 +43,13 @@
+
+
+
+ {TURNSTILE_WIDGET}
+
+
+
diff --git a/app/views/faq.html b/app/views/faq.html
index b914758..956f2b6 100644
--- a/app/views/faq.html
+++ b/app/views/faq.html
@@ -56,8 +56,8 @@
- {SITENAME} is open source and available free of charge through GitLab and Packagist .
- The developer behind the project is Joey Kimsey and he can be contacted through his website for development services.
+ {SITENAME} is open source and available free of charge through GitLab and Packagist .
+ The developer behind the project is Joey Kimsey and he can be contacted through his website for development services.
diff --git a/app/views/pwa.html b/app/views/pwa.html
index 45bfae8..360088a 100644
--- a/app/views/pwa.html
+++ b/app/views/pwa.html
@@ -10,9 +10,9 @@
- {SITENAME} is now available as a Progressive-Web-App, tap the share icon and then "Add to Home Screen".
+ {SITENAME} is now available as a Progressive-Web-App, tap
and then "Add to Home Screen".
-
+
\ No newline at end of file
diff --git a/app/views/start.html b/app/views/start.html
index 3afa8a8..4ff8e7b 100644
--- a/app/views/start.html
+++ b/app/views/start.html
@@ -9,13 +9,13 @@
At this time, the best recommendation available is to contact us for more information.
The site here is actively maintained so feel free to utilize any of our available resources for contact.
- In addition to the site here, you can contact the lead developer (me) directly through JoeyKimsey.com .
+ In addition to the site here, you can contact the lead developer (me) directly through JoeyKimsey.com .
Right now, this entire system was built and managed by myself. As stated, I have used my own version of this for years, but translating it to a publicly available product is not a 1-to-1 job. There may be bugs or issues encountered while you use the product. I can't guarantee a fix for every need in every case immediately, but I do actively keep track of bugs and work hard to ensure everyone has a great experience using the app.
- If you encounter any bugs, feel free to report them here . Likewise, there are forms for feedback, reviews, suggestions, and a general contact form. Thanks for taking the time to check out the product!
+ If you encounter any bugs, feel free to report them here . Likewise, there are forms for feedback, reviews, suggestions, and a general contact form. Thanks for taking the time to check out the product!
{loggedin}