From 9cb35f2bf2127cc8ac077aae17514a57e576217d Mon Sep 17 00:00:00 2001 From: George Halkiadakis Date: Wed, 26 Apr 2023 04:43:12 +0300 Subject: alfa.2 version; seceral optimizations; added support for mail-relay --- public/app/config/app_constants.php | 14 +- public/app/controllers/Auth.php | 10 +- public/app/controllers/cms/Course.php | 4 +- public/app/extends/Send_mail.php | 254 +++++++++++++----------- public/app/models/admin/User_model.php | 38 +++- public/app/models/cms/Course_model.php | 2 +- public/app/routes/user.php | 6 +- public/app/views/components/user-management.php | 4 +- public/app/views/user/login.php | 4 +- public/app/views/user/registration.php | 2 +- 10 files changed, 203 insertions(+), 135 deletions(-) (limited to 'public/app') diff --git a/public/app/config/app_constants.php b/public/app/config/app_constants.php index 529d04a..b46bc51 100644 --- a/public/app/config/app_constants.php +++ b/public/app/config/app_constants.php @@ -27,21 +27,25 @@ define('SITE_URL', 'http://localhost'); // email setup // --- -- -- - - - + // SMTP define('MAIL_MAILER', $env['MAIL_MAILER']); define('MAIL_HOST', $env['MAIL_HOST']); define('MAIL_PORT', $env['MAIL_PORT']); define('MAIL_USERNAME', $env['MAIL_USERNAME']); define('MAIL_PASSWORD', $env['MAIL_PASSWORD']); define('MAIL_ENCRYPTION', $env['MAIL_ENCRYPTION']); + // Mailjet +define('MAILJET_APIKEY', $env['MAILJET_APIKEY']); // apikey +define('MAILJET_SECRET', $env['MAILJET_SECRET']); // secret +define('MAILJET_TICKET', $env['MAILJET_TICKET']); // apikey:secret + // sender info define('MAIL_FROM_NAME', $env['MAIL_FROM_NAME']); define('NO_REPLY_EMAIL', $env['NO_REPLY_EMAIL']); define('REPLY_TO_EMAIL', $env['REPLY_TO_EMAIL']); -// mailjet setup -// --- -- -- - - - -define('MJ_API_KEY', $env['MJ_API_KEY']); -define('MJ_SECRET_KEY', $env['MJ_SECRET_KEY']); -define('MJ_SMTP', $env['MJ_SMTP']); +// default mail service; options so far: [ mailjet | phpmailer ] +define('DEFAULT_MAIL_SERVICE', 'mailjet'); + // DEFAULT VALUES ////////////////////////////////////////////////////////////// // ----------------------------------------------------------------------------- diff --git a/public/app/controllers/Auth.php b/public/app/controllers/Auth.php index 8af7513..32ff07a 100644 --- a/public/app/controllers/Auth.php +++ b/public/app/controllers/Auth.php @@ -52,8 +52,9 @@ class Auth { // get user's security attributes $attributes = User_Model::getUser($record['id']); + $roles = json_decode($attributes['Roles_json']); $user - ->setRoles(json_decode($attributes['Roles_json'])) + ->setRoles($roles) ->setPrivileges( array_merge( json_decode($attributes['RootPrivileges_json']), @@ -73,10 +74,15 @@ class Auth { '/' ); + // check if admin (and redirect differently) + $is_admin = (!empty(array_intersect([1,2,3], $roles))); // login OK, set Token in session $userManager->createUserToken($user); - return true; + return [ + 'success' => true, + 'goto' => $is_admin ? '/admin/lessons' : '/user/profile', + ]; } else { return false; diff --git a/public/app/controllers/cms/Course.php b/public/app/controllers/cms/Course.php index 0edc832..a1de9c1 100644 --- a/public/app/controllers/cms/Course.php +++ b/public/app/controllers/cms/Course.php @@ -31,7 +31,7 @@ class Course { * * @return true|false */ - private static function is_admin_or_permited( $privilege_id) + private static function is_admin_or_permited( $privilege_id ) { return ( Auth::in_admin_group() @@ -56,7 +56,7 @@ class Course { $file = self::get_file_attributes($file_path); // if user is authorized - if (is_admin_or_permited($file['privilege_id'])) { + if (self::is_admin_or_permited($file['privilege_id'])) { $media_type = Registry::get('REQUEST')->GET['type']; // get media-type $real_path = MEDIA_STORAGE_ROOT . $file_path; // construct real path diff --git a/public/app/extends/Send_mail.php b/public/app/extends/Send_mail.php index fa0d8d3..52eab53 100644 --- a/public/app/extends/Send_mail.php +++ b/public/app/extends/Send_mail.php @@ -8,96 +8,179 @@ use PHPMailer\PHPMailer\Exception; class Send_mail { + /** send_activation_code + * + * construct the envelope = [ + * email => user email + * name => user full name + * subject => subject + * body => email message body + * ] + * + * then send the email; + * + * @param $activator (array): [ + * email => user email, + * name => user full name, + * code => activation code + * ] + * + * @return success_starus (boolean) + * + * TODO: + * check for email templating: + * + https://stackoverflow.com/questions/2391171/how-to-get-output-from-local-script-in-php + * + https://stackoverflow.com/questions/171318/how-do-i-capture-php-output-into-a-variable + */ + public static function send_activation_code($activator) + { + $activation_url = SITE_URL ."/account/activate?ticket=". $activator['code']; + $envelope = [ + 'email' => $activator['email'], + 'name' => $activator['name'], + 'subject' => 'Εγγραφή στο Classroom', + 'body' => "Χαίρετε,
+ το παρόν αυτοποιημένο email σάς έχει σταλεί + γιατί έχει γίνει αίτημα εγγραφής σας στο Classroom.
+
+ Όνομα επαφής: ". $activator['name'] ."
+ Email : ". $activator['email'] ."
+
+ Για να ενεργοποιήσετε την πρόσβασή σας στο site + θα πρέπει ακολουθήσετε τον παρακάτω σύνδεσμο: + ". $activation_url .". +
+
+ Μετά την ενεργοποίηση θα έχετε πρόσσβαση + στο περιεχόμενο του site.
+ Μην απαντήσετε στο email, + δεν υπάρχει φυσική επαφή η οποία να λαμβάνει τυχόν replies." + ]; + + switch (DEFAULT_MAIL_SERVICE) { + case 'mailjet': + $reply = self::send_mailjet($envelope); + break; + + case 'phpMailer': + $reply = self::send_phpMailer($envelope); + break; + } - private static function init_mail() + return $reply; + + } + + + /** send phpMailer + * + * send email using phpMailer class; + * optional SMTP server configuration; + * + * @param $envelope + * @return success_starus (boolean) + */ + public static function send_phpMailer($envelope) { $mail = new PHPMailer(); - // setup smpt + # // setup smpt $mail->SMTPDebug = 3; $mail->IsSMTP(); $mail->Host = MAIL_HOST; - $mail->SMPTAuth = false; + # $mail->SMPTAuth = false; $mail->SMTPSecure = MAIL_ENCRYPTION; - // $mail->Protocol = 'mail'; + # // $mail->Protocol = 'mail'; $mail->Mailer = MAIL_MAILER; $mail->Port = MAIL_PORT; $mail->Username = MAIL_USERNAME; $mail->Password = MAIL_PASSWORD; - return $mail; - } + // setup format + $mail->CharSet = 'utf-8'; + $mail->IsHTML(true); + // setup THE mail + // --- -- -- - - - + // It's important not to use the submitter's address as the from address + // as it's forgery, which will cause your messages to fail SPF checks. + // Use an address in your own domain as the from address; + // put the submitter's address in a reply-to - /** - * - */ - private static function init_slack() - { + $mail->setFrom(NO_REPLY_EMAIL, MAIL_FROM_NAME); + $mail->addAddress($envelope['email'], $envelope['name']); + $mail->addReplyTo(REPLY_TO_EMAIL, MAIL_FROM_NAME); + $mail->Subject = $envelope['subject']; + $mail->Body = $envelope['body']; + + return (!$mail->send()) ? false : true; } - /** + /** send_mailjet * - * @param $envelope (array): mail from/to and activation code + * send email using CURL mail-relay of Mailjet * - * TODO: - * check for email templating: - * + https://stackoverflow.com/questions/2391171/how-to-get-output-from-local-script-in-php - * + https://stackoverflow.com/questions/171318/how-do-i-capture-php-output-into-a-variable + * @param $envelope + * @return success_starus (boolean) */ - public static function send_activation_code($envelope) + public static function send_mailjet($envelope) { - $mail = self::init_mail(); + $body = [ + 'Messages' => [ + [ + 'From' => [ + 'Email' => REPLY_TO_EMAIL, + 'Name' => MAIL_FROM_NAME + ], + 'To' => [ + [ + 'Email' => $envelope['email'], + 'Name' => $envelope['name'] + ] + ], + 'Subject' => $envelope['subject'], + 'HTMLPart' => $envelope['body'] + ] + ] + ]; + + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, "https://api.mailjet.com/v3.1/send"); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body)); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_HTTPHEADER, array( + 'Content-Type: application/json') + ); + curl_setopt( + $ch, + CURLOPT_USERPWD, + MAILJET_APIKEY. ':'. MAILJET_SECRET + ); + $server_output = curl_exec($ch); + curl_close ($ch); + + $response = json_decode($server_output); - // setup format - $mail->CharSet = 'utf-8'; - $mail->IsHTML(true); + return ($response->Messages[0]->Status == 'success'); - // setup THE mail - // --- -- -- - - - - // It's important not to use the submitter's address as the from address as it's forgery, - // which will cause your messages to fail SPF checks. - // Use an address in your own domain as the from address, put the submitter's address in a reply-to - $mail->setFrom(NO_REPLY_EMAIL, MAIL_FROM_NAME); - $mail->addAddress($envelope['email'], $envelope['name']); - $mail->addReplyTo(REPLY_TO_EMAIL, MAIL_FROM_NAME); - $mail->Subject = 'Εγγραφή στο Classroom'; - $mail->Body = "Χαίρετε,
- το παρόν αυτοποιημένο email σάς έχει σταλεί γιατί έχει γίνει αίτημα εγγραφής σας στο Classroom.
-
- Όνομα επαφής: ". $envelope['name'] ."
- Email : ". $envelope['email'] ."
-
- Για να ενεργοποιήσετε την πρόσβασή σας στο site θα πρέπει να παρακαλώ πατήστε στον - παρακάτω σύνδεσμο url - . -
-
- Μετά την ενεργοποίηση θα έχετε πρόσσβαση στο περιεχόμενο του site.
-
- Μην απαντήσετε στο email γιατί δεν υπάρχει φυσική επαφή η οποία να λαμβάνει τυχόν replies.
"; - if (!$mail->send()) { - return false; - } else { - return true; - } - } - } -/** - * +/** NOTE: + * ----------------------------------------------------------------------------- + * (brainstorming) * Optimization per concept alternative technologies @@ -125,66 +208,5 @@ Database Log Log event to Slack Log event to Email - * - * - */ - -/** custom email api - * - * host : https://api.roptron.gr - * apikey : md5(hash)-substring(0,5, md5(service)) 8668d1c4a8f5aba236a8f821d148340f-0c83f - * message : serialize([ - * from[email] => from name - * replyTo[email] => reply-to-Name - * to => [ - * email => email-name - * secondemail => another email name - * ] - * type => html - * charset => utf8 - * subject => mail subject - * mailBody => html string - * ]) - * - */ - -/** Several custom APIs - * - * Mailer - * - * sendpulse - * rU8WEmcHsRcEQaH - * rU8WEmcHsRcEQaH - * - * mailjet - * piipiis@g - * EN6Xg8!99ZTKaYp7 - * - * - * sendGrid - * piipiis - * EN6Xg899ZTKU8WEmcHsR54321 - * - * - * time4vps... - * https://community.time4vps.com/discussion/75/are-any-ports-blocked-by-time4vps - * - * test activation code: - * ca42d68cfba5fbbafeacc010b8e3a551 - * - * - * - * MAIL API - * --- -- -- - - - - * client = ip/mp5(IP) or domain/md5(ref_domain) - * token = md5(client + timestamp + rand(0,10000)) - * - * api : auth_content : client : token - * --- : --- : --- : --- - * mail : ip|domain : md5(*) : md5(...) -> send an email - * image : ip|domain : md5(*) : md5(...) -> proccess an image (resize|crop|convert) - * slack : ip|domain : md5(*) : md5(...) -> send a slack message to channel - * database : ip|domain : md5(*) : md5(...) -> - * + * ----------------------------------------------------------------------------- */ - \ No newline at end of file diff --git a/public/app/models/admin/User_model.php b/public/app/models/admin/User_model.php index 62d99db..2885dc1 100644 --- a/public/app/models/admin/User_model.php +++ b/public/app/models/admin/User_model.php @@ -159,7 +159,10 @@ class User_model )->lastInsertID(); // set default privileges - // self::set_user_privileges($new_user_id, $privileges); + self::set_user_privileges($new_user_id, $privileges); + + // set reader role + self::set_user_role($new_user_id, 5); // update history History::trackUserAccess($new_user_id, TRACK_ACCOUNT, 'Create User Account'); @@ -173,6 +176,39 @@ class User_model } + /** set_user_privileges + * + * @param $privileges (array) + */ + public static function set_user_privileges($user, $privileges) + { + $db = Registry::use('database'); // database connection + foreach($privileges as $pri) { // pri = privilege id + $db->runQuery( + "INSERT INTO user_privilege (user_id, privilege_id) VALUES (:user, :pri)", + [ ':user' => $user, ":pri" => $pri ] + ); + } + return true; + } + + + /** set_user_role + * + * user, role are (int) IDs + */ + public static function set_user_role($user, $role) + { + + Registry::use('database')->runQuery( + "INSERT INTO user_role (user_id, role_id) VALUES (:user, :role)", + [ ':user' => $user, ":role" => $role ] + ); + + return true; + } + + /** activate * * check if activation code is valid; diff --git a/public/app/models/cms/Course_model.php b/public/app/models/cms/Course_model.php index 6378226..54f49cf 100644 --- a/public/app/models/cms/Course_model.php +++ b/public/app/models/cms/Course_model.php @@ -18,7 +18,7 @@ class Course_model { public static function get_categories() { return Registry::use('database')->runQuery( - "SELECT * FROM course ORDER BY `order`", + "SELECT * FROM course ORDER BY label", [] ); } diff --git a/public/app/routes/user.php b/public/app/routes/user.php index d419a5b..7ad0fa6 100644 --- a/public/app/routes/user.php +++ b/public/app/routes/user.php @@ -10,10 +10,10 @@ use app\controllers\Classroom_user; // common requests (GET method) // --- -- -- - - - -// request login ... -> sends to POST:/account/check-login +// request login ... -> then sends to POST:/account/check-login Route::add('/login', function() { Render::view('user/login'); }); -// request registration ... -> sends to POST:/account/register +// request registration ... -> then sends to POST:/account/register Route::add('/registration', function() { Render::view('user/registration'); }); // request logout @@ -65,7 +65,7 @@ Route::add('/account/profile', function() { ); } else { - print_r($user); + Render::json(['success' => true, 'status' => 'user is connected']); } } ); diff --git a/public/app/views/components/user-management.php b/public/app/views/components/user-management.php index 9f95af8..636f2ff 100644 --- a/public/app/views/components/user-management.php +++ b/public/app/views/components/user-management.php @@ -11,8 +11,8 @@
  • -
  • Εγγραφή
  • -
  • Επαναφορά password
  • +
  • Εγγραφή
  • +
  • Επαναφορά password
  • diff --git a/public/app/views/user/login.php b/public/app/views/user/login.php index ba29158..1a59d43 100644 --- a/public/app/views/user/login.php +++ b/public/app/views/user/login.php @@ -76,8 +76,8 @@ // send POST request $.post(request, data) .done(function( data ) { - if (data.status) { - window.location.href = '/account/profile'; + if (data.status !== false) { + window.location.href = data.status.goto; } else { alert('Wrong credentials; please try again'); diff --git a/public/app/views/user/registration.php b/public/app/views/user/registration.php index e3527f0..f0a110c 100644 --- a/public/app/views/user/registration.php +++ b/public/app/views/user/registration.php @@ -110,7 +110,7 @@ // send POST request $.post(request, data) .done(function( data ) { - console.log(data); + $('.classroom .content-form').html(data.message) }); } -- cgit v1.2.3