diff --git a/Application/Controllers/AccountController.php b/Application/Controllers/AccountController.php index a3d3b1c..f7ace42 100644 --- a/Application/Controllers/AccountController.php +++ b/Application/Controllers/AccountController.php @@ -6,6 +6,9 @@ use Application\HTTP\Response; use Application\Services\ServiceContainer; use Application\Models\User; use Application\Models\UserChange; +use Application\Models\UserConfirmation; +use Application\Foundations\MailBuilder; +use Application\Foundations\QueryBuilder; class AccountController { public function __construct() { @@ -15,6 +18,66 @@ class AccountController { $user = User::find($request->id); return $response->view('profile', [ 'user' => $user ] ); } + public function update_account(Request $request, Response $response) { + $user = ServiceContainer::Authentication()->user(); + $hash = $user->password; + $verify = password_verify($request->password,$hash); + if(!$verify) { + return $response->redirect("/me")->with([ "me_error" => "Incorrect password"]); + } + if($request->newpassword) { + if($request->newpassword != $request->confirmpassword) { + return $response->redirect("/me")->with([ "me_error" => "Password and confirm password don't match"]); + } + $confirmator = UserChange::create([ + 'user_id' => $user->id, + 'action_type' => 'password', + 'best_before' => date('Y-m-d H:i:s',strtotime("+6 hours")), + 'data' => password_hash($request->newpassword,PASSWORD_DEFAULT), + 'confirm_key' => hash('sha256',$user->username.time()), + 'is_confirmed' => 0, + ]); + $email = new MailBuilder(); + $body = "Someone, hopefully you, has requested to change your password.\n"; + $body .= "To finish the change, use the URL below:\n\n"; + $body .= $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'].'/me/confirm?'.$confirmator->confirm_key; + $email->from("metaforums@nanao.moe")->to($user->email)->subject("Confirm important changes to your account")->body($body); + ServiceContainer::Email()->send($email); + } + if (isset($request->email) && $request->email != $user->email) { + $confirmator = UserChange::create([ + 'user_id' => $user->id, + 'action_type' => 'email', + 'best_before' => date('Y-m-d H:i:s',strtotime("+6 hours")), + 'data' => $request->email, + 'confirm_key' => hash('sha256',$user->username.time()), + 'is_confirmed' => 0, + ]); + $email = new MailBuilder(); + $body = "Someone, hopefully you, has requested to change your email.\n"; + $body .= "To finish the change, use the URL below:\n\n"; + $body .= $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'].'/me/confirm?'.$confirmator->confirm_key; + $body .= "\n\nAfter confirming this change, you need to reconfirm your email address."; + $email->from("metaforums@nanao.moe")->to($user->email)->subject("Confirm important changes to your account")->body($body); + ServiceContainer::Email()->send($email); + } + if (isset($request->delete) && $request->delete == $user->username) { + $confirmator = UserChange::create([ + 'user_id' => $user->id, + 'action_type' => 'delete', + 'best_before' => date('Y-m-d H:i:s',strtotime("+6 hours")), + 'confirm_key' => hash('sha256',$user->username.time()), + 'is_confirmed' => 0, + ]); + $email = new MailBuilder(); + $body = "Someone, hopefully you, has requested to delete your account.\n"; + $body .= "To confirm deletion, use the URL below:\n\n"; + $body .= $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'].'/me/confirm?'.$confirmator->confirm_key; + $email->from("metaforums@nanao.moe")->to($user->email)->subject("We are sad to see you leaving")->body($body); + ServiceContainer::Email()->send($email); + } + return $response->redirect("/me"); + } public function update(Request $request, Response $response) { $user = ServiceContainer::Authentication()->user(); $updateData = []; @@ -35,10 +98,41 @@ class AccountController { 'is_confirmed' => 1, ]); } + $user->update($updateData); return $response->redirect("/me"); } + public function confirm(Request $request, Response $response) { + $user = ServiceContainer::Authentication()->user(); + $query = new QueryBuilder(); + $query = $query->where('confirm_key',$request->queryString())->where('is_confirmed',0); + $change = UserChange::selectOne($query); + if($change) { + if($change->action_type == 'password') { + $user->update(['password' => $change->data]); + } else if($change->action_type == 'email') { + $user->update(['email' => $change->data, 'is_confirmed' => 0]); + $confirmator = UserConfirmation::create([ + 'confirm_key' => hash('sha256',$user->username.time()), + 'user_id' => $user->id, + 'best_before' => date('Y-m-d H:i:s', strtotime('+6 hours', time())), + ]); + $email = new MailBuilder(); + $body = "You have recently changed your email address.\n"; + $body .= "You will need to confirm this new address using the URL below:\n\n"; + $body .= $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'].'/email/confirm?'.$confirmator->confirm_key; + $email->from("metaforums@nanao.moe")->to($user->email)->subject("Please reconfirm your email address")->body($body); + ServiceContainer::Email()->send($email); + } else if($change->action_type == 'delete') { + $user->update(['is_deactivated' => 1]); + return $response->redirect("/logout"); + } + $change->update(['is_confirmed' => 1]); + } + return $response->redirect("/me"); + } public function me(Request $request, Response $response) { + if(!ServiceContainer::Authentication()->isLoggedIn()) return $response->redirect('/login'); $user = ServiceContainer::Authentication()->user(); return $response->view('me', [ 'user' => $user ] ); } diff --git a/Application/Controllers/ApiController.php b/Application/Controllers/ApiController.php index 97544b7..862503a 100644 --- a/Application/Controllers/ApiController.php +++ b/Application/Controllers/ApiController.php @@ -32,10 +32,10 @@ class ApiController { $bans = $this->getBans(); $where = new QueryBuilder(); $where = $where->where('group_id',$request->id); - $categories = Category::select($where); if(count($bans) > 0) { $where = $where->whereNotIn('id',$bans); } + $categories = Category::select($where); return $response->json()->data($categories); } public function threads(Request $request, Response $response) { diff --git a/Application/Controllers/AuthController.php b/Application/Controllers/AuthController.php index 3fd412f..3c131d7 100644 --- a/Application/Controllers/AuthController.php +++ b/Application/Controllers/AuthController.php @@ -78,7 +78,7 @@ class AuthController { $email = new MailBuilder(); $body = "Thank you for registering with metaforums.\n"; $body .= "To be able to explore the vast forum, use the URL below:\n\n"; - $body .= $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'].'/signup/confirm?'.$confirmator->confirm_key; + $body .= $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['SERVER_NAME'].'/email/confirm?'.$confirmator->confirm_key; $email->from("metaforums@nanao.moe")->to($data->email)->subject("Complete your registration on Metaforums")->body($body); ServiceContainer::Email()->send($email); if($confirmator != null) { diff --git a/Application/Controllers/ForumThreadController.php b/Application/Controllers/ForumThreadController.php index 438fdc0..44b0ef2 100644 --- a/Application/Controllers/ForumThreadController.php +++ b/Application/Controllers/ForumThreadController.php @@ -9,6 +9,7 @@ use Application\Models\Post; use Application\Models\Thread; use Application\Models\UserAction; use Application\Models\UserReport; +use Application\Models\User; use Application\Foundations\QueryBuilder; use Application\Foundations\MailBuilder; @@ -82,18 +83,18 @@ class ForumThreadController { 'post_id' => $request->report, 'report_date' => date('Y-m-d H:i:s'), ]); - if($user->didIModerateThis($category->id)) { + if($report->user()->didIModerateThis($category->id)) { $query = new QueryBuilder(); $query = $query->where('role','>=','100000'); $admins = User::select($query); foreach($admins as $moderator) { $email = new MailBuilder(); $body = "Dear ".$moderator->username."\n"; - $body .= "Someone reported ".$report->user()->username.", a moderator for ".$category->category_name." for alleged violation of the rules.\n\n"; + $body .= $user->username." reported ".$report->user()->username.", a moderator for ".$category->category_name." for alleged violation of the rules.\n\n"; $body .= "Reason:\n\n"; $body .= $request->content."\n\n"; $body .= "Please resolve this via the moderation interface.\n"; - $email->from("metaforums@nanao.moe")->to($moderator->email)->subject("New report: ".$user->username)->body($body); + $email->from("metaforums@nanao.moe")->to($moderator->email)->subject("New report: ".$report->user()->username)->body($body); ServiceContainer::Email()->send($email); } } else { diff --git a/Application/Views/editor.php b/Application/Views/editor.php index ea43534..19164c2 100644 --- a/Application/Views/editor.php +++ b/Application/Views/editor.php @@ -12,7 +12,7 @@

You cannot delete this post.

user()->is_confirmed == 0 ) { ?>

Please confirm your email address to create threads

-isLocked() ) { ?> +isLocked() && !isset($report) ) { ?> This thread has been locked.
diff --git a/Application/Views/me.php b/Application/Views/me.php index 21982a7..7997c67 100644 --- a/Application/Views/me.php +++ b/Application/Views/me.php @@ -29,6 +29,28 @@ $view->include('layouts/head');
+
+
+ + + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
diff --git a/Application/Views/moderation.php b/Application/Views/moderation.php index aa76e79..8f6710f 100644 --- a/Application/Views/moderation.php +++ b/Application/Views/moderation.php @@ -42,7 +42,7 @@ var selectapp = new Vue({ this.current_category = id; this.current_report = 0; this.reports = []; - window.history.pushState('category-'+id,'','/moderation?category='+id+window.location.hash); + if(id != 0) window.history.pushState('category-'+id,'','/moderation?category='+id+window.location.hash); $.ajax("/api/get_reports?id="+id) .done(function(data) { this.reports = data; diff --git a/Application/Views/profile.php b/Application/Views/profile.php index 4e5cc5a..8b0ac77 100644 --- a/Application/Views/profile.php +++ b/Application/Views/profile.php @@ -5,8 +5,8 @@ $view->include('layouts/head');

username ?>'s profile

- isLoggedIn() && $auth->user()->id == $user->id) { ?> -

Edit

+ isLoggedIn() && ($auth->user()->id == $user->id) ) { ?> +

Edit

@@ -50,7 +50,7 @@ $view->include('layouts/head'); Most Active In - most_active()->category_name ?> (most_active()->group()->group_name ?>) + most_active()->category_name ?? "None" ?> (most_active() ? $user->most_active()->group()->group_name : "None" ?>) Number of Hearts diff --git a/Application/Views/thread.php b/Application/Views/thread.php index dfff170..1a2c190 100644 --- a/Application/Views/thread.php +++ b/Application/Views/thread.php @@ -1,7 +1,7 @@ isLocked()) { ?>
This thread has been locked for lock()->duration ?>. See the last post for reason why. -user()->didIModerateThis($thread->category_id) ) { ?> +isLoggedIn() && $auth->user()->didIModerateThis($thread->category_id) ) { ?> Unlock this thread
@@ -71,7 +71,7 @@ This thread has been locked for lock()->duration ?>. See the - user()->didIModerateThis($thread->category()->id) ) { ?> + user()->didIModerateThis($thread->category()->id) || $auth->user()->is_admin ) { ?> @@ -92,16 +92,19 @@ var threadapp = new Vue({ $.ajax("/thread/editor?thread=id ?>&reply="+post_id).done(function(data) { $("#editor").html(data); }); + window.location.hash = "#editor"; }, edit(post_id) { $.ajax("/thread/editor?thread=id ?>&edit="+post_id).done(function(data) { $("#editor").html(data); }); + window.location.hash = "#editor"; }, delete_post(post_id) { $.ajax("/thread/editor?thread=id ?>&delete="+post_id).done(function(data) { $("#editor").html(data); }); + window.location.hash = "#editor"; }, favorite(post_id) { $.ajax("/api/favorite?id="+post_id).done(function(data) { @@ -113,11 +116,13 @@ var threadapp = new Vue({ $.ajax("/thread/editor?thread=id ?>&report="+post_id).done(function(data) { $("#editor").html(data); }); + window.location.hash = "#editor"; }, moderate(post_id) { $.ajax("/thread/moderating_editor?id="+post_id).done(function(data) { $("#editor").html(data); }); + window.location.hash = "#editor"; } }, }); diff --git a/README.md b/README.md index 13c47b6..966441e 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,9 @@ An online web-based discussion forum application 4. Point the browser to `localhost` ## Sample database data + ### Users + 1. Username: Administrator Password: yuikaadmin Role: Site Admin @@ -32,6 +34,10 @@ An online web-based discussion forum application 7. Username: MusubiTendouji Password: nanasisters Role: User +8. Username: BadEnd + Password: communicate + Role: User + ### Post sources diff --git a/routes.php b/routes.php index 0e8261d..e86dddf 100644 --- a/routes.php +++ b/routes.php @@ -9,7 +9,7 @@ return [ 'POST:/signup' => [ 'controller' => 'AuthController@create_user', ], - 'GET:/signup/confirm' => [ + 'GET:/email/confirm' => [ 'controller' => 'AuthController@sign_up_confirm', ], 'GET:/login' => [ @@ -75,6 +75,12 @@ return [ 'POST:/me/update' => [ 'controller' => 'AccountController@update', ], + 'POST:/me/update-account' => [ + 'controller' => 'AccountController@update_account', + ], + 'GET:/me/confirm' => [ + 'controller' => 'AccountController@confirm', + ], 'GET:/moderation' => [ 'controller' => 'IndexController@moderation', ],