Advertisement
Guest User

Untitled

a guest
Oct 5th, 2016
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 46.50 KB | None | 0 0
  1. <?php
  2. namespace Fr;
  3.  
  4. class LS {
  5.  
  6. /**
  7. * ------------
  8. * BEGIN CONFIG
  9. * ------------
  10. * Edit the configuraion
  11. */
  12.  
  13. public static $default_config = array(
  14. /**
  15. * Basic Config of logSys
  16. */
  17. "basic" => array(
  18. "company" => "My Site",
  19. "email" => "email@mysite.com",
  20. "email_callback" => 0
  21. ),
  22.  
  23. /**
  24. * Database Configuration
  25. */
  26. "db" => array(
  27. "host" => "",
  28. "port" => 3306,
  29. "username" => "",
  30. "password" => "",
  31. "name" => "",
  32. "table" => "users",
  33. "token_table" => "resetTokens"
  34. ),
  35.  
  36. /**
  37. * Keys used for encryption
  38. * DONT MAKE THIS PUBLIC
  39. */
  40. "keys" => array(
  41. /**
  42. * Changing cookie key will expire all current active login sessions
  43. */
  44. "cookie" => "ckxc436jd*^30f840v*9!@#$",
  45. /**
  46. * `salt` should not be changed after users are created
  47. */
  48. "salt" => "^#$4%9f+1^p9)M@4M)V$"
  49. ),
  50.  
  51. /**
  52. * Enable/Disable certain features
  53. */
  54. "features" => array(
  55. /**
  56. * Should I Call session_start();
  57. */
  58. "start_session" => true,
  59. /**
  60. * Enable/Disable Login using Username & E-Mail
  61. */
  62. "email_login" => true,
  63. /**
  64. * Enable/Disable `Remember Me` feature
  65. */
  66. "remember_me" => true,
  67. /**
  68. * Should FrLS::init() be called automatically
  69. */
  70. "auto_init" => false,
  71.  
  72. /**
  73. * Prevent Brute Forcing
  74. * ---------------------
  75. * By enabling this, logSys will deny login for the time mentioned
  76. * in the "brute_force"->"time_limit" seconds after "brute_force"->"tries"
  77. * number of incorrect login tries.
  78. */
  79. "block_brute_force" => true,
  80.  
  81. /**
  82. * Two Step Login
  83. * --------------
  84. * By enabling this, a checking is done when user visits
  85. * whether the device he/she uses is approved by the user.
  86. * Allows the original user to revoke logins in other devices/places
  87. * Useful if the user forgot to logout in some place.
  88. */
  89. "two_step_login" => false
  90. ),
  91.  
  92. /**
  93. * `Blocking Brute Force Attacks` options
  94. */
  95. "brute_force" => array(
  96. /**
  97. * No of tries alloted to each user
  98. */
  99. "tries" => 5,
  100. /**
  101. * The time IN SECONDS for which block from login action should be done after
  102. * incorrect login attempts. Use http://www.easysurf.cc/utime.htm#m60s
  103. * for converting minutes to seconds. Default : 5 minutes
  104. */
  105. "time_limit" => 300
  106. ),
  107.  
  108. /**
  109. * Information about pages
  110. */
  111. "pages" => array(
  112. /**
  113. * Pages that doesn't require logging in.
  114. * Exclude login page, but include REGISTER page.
  115. * Use RELATIVE links. To find the relative link of
  116. * a page, do var_dump(FrLS::curPage());
  117. */
  118. "no_login" => array(),
  119.  
  120. /**
  121. * Pages that both logged in and not logged in users can access
  122. */
  123. "everyone" => array(),
  124.  
  125. /**
  126. * The login page. ex : /login.php or /accounts/login.php
  127. */
  128. "login_page" => "",
  129.  
  130. /**
  131. * The home page. The main page for logged in users.
  132. * logSys redirects to here after user logs in
  133. */
  134. "home_page" => ""
  135. ),
  136.  
  137. /**
  138. * Settings about cookie creation
  139. */
  140. "cookies" => array(
  141. /**
  142. * Default : cookies expire in 30 days. The value is
  143. * for setting in strtotime() function
  144. * http://php.net/manual/en/function.strtotime.php
  145. */
  146. "expire" => "+30 days",
  147. "path" => "/",
  148. "domain" => "",
  149. ),
  150.  
  151. /**
  152. * 2 Step Login
  153. */
  154. 'two_step_login' => array(
  155. /**
  156. * Message to show before displaying "Enter Token" form.
  157. */
  158. 'instruction' => '',
  159.  
  160. /**
  161. * Callback when token is generated.
  162. * Used to send message to user (Phone/E-Mail)
  163. */
  164. 'send_callback' => '',
  165.  
  166. /**
  167. * The table to stoe user's sessions
  168. */
  169. 'devices_table' => 'user_devices',
  170.  
  171. /**
  172. * The length of token generated.
  173. * A low value is better for tokens sent via Mobile SMS
  174. */
  175. 'token_length' => 4,
  176.  
  177. /**
  178. * Whether the token should be numeric only ?
  179. * Default Token : Alphabetic + Numeric mixed strings
  180. */
  181. 'numeric' => false,
  182.  
  183. /**
  184. * The expire time of cookie that authorizes the device
  185. * to login using the user's account with 2 Step Verification
  186. * The value is for setting in strtotime() function
  187. * http://php.net/manual/en/function.strtotime.php
  188. */
  189. 'expire' => '+45 days',
  190.  
  191. /**
  192. * Should logSys checks if device is valid, everytime
  193. * logSys is initiated ie everytime a page loads
  194. * If you want to check only the first time a user loads
  195. * a page, then set the value to TRUE, else FALSE
  196. */
  197. 'first_check_only' => true
  198. )
  199. );
  200.  
  201. /* ------------
  202. * END Config.
  203. * ------------
  204. * No more editing after this line.
  205. */
  206.  
  207. public static $config = array();
  208. private static $constructed = false;
  209.  
  210. /**
  211. * Merge user config and default config
  212. * $direct is for knowing whether the function is called by self::construct()
  213. */
  214. public static function config($config = null, $direct = true){
  215. if($config != null){
  216. self::$config = $config;
  217. }
  218. self::$config = array_replace_recursive(self::$default_config, self::$config);
  219. if($direct == true){
  220. self::construct();
  221. }
  222. }
  223.  
  224. /**
  225. * Log something in the Francium.log file.
  226. * To enable logging, make a file called "Francium.log" in the directory
  227. * where "class.logsys.php" file is situated
  228. */
  229. public static function log($msg = ""){
  230. $log_file = __DIR__ . "/Francium.log";
  231. if(file_exists($log_file)){
  232. if($msg != ""){
  233. $message = "[" . date("Y-m-d H:i:s") . "] $msg";
  234. $fh = fopen($log_file, 'a');
  235. fwrite($fh, $message . "n");
  236. fclose($fh);
  237. }
  238. }
  239. }
  240.  
  241. public static $loggedIn = false;
  242. public static $db = true;
  243. public static $user = false;
  244. private static $init_called = false;
  245. private static $cookie, $session, $remember_cookie, $dbh;
  246.  
  247. public static function construct($called_from = ""){
  248. if(self::$constructed === false){
  249. self::config(null, false);
  250. self::$constructed = true;
  251.  
  252. if(self::$config['features']['start_session'] === true){
  253. session_start();
  254. }
  255. /**
  256. * Try connecting to Database Server
  257. */
  258. try{
  259. /**
  260. * Add the login page to the array of pages that doesn't need logging in
  261. */
  262. array_push(self::$config['pages']['no_login'], self::$config['pages']['login_page']);
  263.  
  264. self::$dbh = new PDO("mysql:dbname=". self::$config['db']['name'] .";host=". self::$config['db']['host'] .";port=". self::$config['db']['port']. ";charset=utf8", self::$config['db']['username'], self::$config['db']['password']);
  265. self::$db = true;
  266.  
  267. self::$cookie = isset($_COOKIE['logSyslogin']) ? $_COOKIE['logSyslogin'] : false;
  268. self::$session = isset($_SESSION['logSyscuruser']) ? $_SESSION['logSyscuruser'] : false;
  269. self::$remember_cookie = isset($_COOKIE['logSysrememberMe']) ? $_COOKIE['logSysrememberMe'] : false;
  270.  
  271. $encUserID = hash("sha256", self::$config['keys']['cookie'] . self::$session . self::$config['keys']['cookie']);
  272.  
  273. if(self::$cookie == $encUserID){
  274. self::$loggedIn = true;
  275. }else{
  276. self::$loggedIn = false;
  277. }
  278.  
  279. /**
  280. * If there is a Remember Me Cookie and the user is not logged in,
  281. * then log in the user with the ID in the remember cookie, if it
  282. * matches with the decrypted value in `logSyslogin` cookie
  283. */
  284. if(self::$config['features']['remember_me'] === true && self::$remember_cookie !== false && self::$loggedIn === false){
  285. $encUserID = hash("sha256", self::$config['keys']['cookie']. self::$remember_cookie . self::$config['keys']['cookie']);
  286. if(self::$cookie == $encUserID){
  287. self::$loggedIn = true;
  288. }else{
  289. self::$loggedIn = false;
  290. }
  291.  
  292. if(self::$loggedIn === true){
  293. $_SESSION['logSyscuruser'] = self::$remember_cookie;
  294. self::$session = self::$remember_cookie;
  295. }
  296. }
  297.  
  298. self::$user = self::$session;
  299.  
  300. /**
  301. * Check if devices is authorized to use the account
  302. */
  303. if(self::$config['features']['two_step_login'] === true && self::$loggedIn){
  304. $login_page = self::curPage() === self::$config['pages']['login_page'];
  305.  
  306. if(!isset($_SESSION['device_check']) && !isset($_COOKIE['logSysdevice']) && $login_page === false){
  307. /**
  308. * The device cookie is not even set. So, logout
  309. */
  310. self::logout();
  311. $called_from = "login";
  312. }else if(self::$config['two_step_login']['first_check_only'] === false || (self::$config['two_step_login']['first_check_only'] === true && !isset($_SESSION['device_check']))){
  313. $sql = self::$dbh->prepare("SELECT '1' FROM `". self::$config['two_step_login']['devices_table'] ."` WHERE `uid` = ? AND `token` = ?");
  314. $sql->execute(array(self::$user, $_COOKIE['logSysdevice']));
  315.  
  316. /**
  317. * Device not authorized, so remove device cookie & logout
  318. */
  319. if($sql->fetchColumn() !== '1' && $login_page === false){
  320. setcookie("logSysdevice", "", time() - 10);
  321. self::logout();
  322. $called_from = "login";
  323. }else{
  324. /**
  325. * This session has been checked and verified
  326. */
  327. $_SESSION['device_check'] = 1;
  328. }
  329. }
  330. }
  331.  
  332. if(self::$config['features']['auto_init'] === true && $called_from != "logout" && $called_from != "login"){
  333. self::init();
  334. }
  335. return true;
  336. }catch(PDOException $e) {
  337. /**
  338. * Couldn't connect to Database
  339. */
  340. self::log('Couldn't connect to database. Check FrLS::$config["db"] credentials');
  341. return false;
  342. }
  343. }
  344. }
  345.  
  346. /**
  347. * A function that will automatically redirect user according to his/her login status
  348. */
  349. public static function init() {
  350. self::construct();
  351. if(in_array(self::curPage(), self::$config['pages']['everyone'])){
  352. /**
  353. * No redirects as this page can be accessed
  354. * by anyone whether he/she is logged in or not
  355. */
  356. }else if(self::$loggedIn === true && in_array(self::curPage(), self::$config['pages']['no_login'])){
  357. self::redirect(self::$config['pages']['home_page']);
  358. }else if(self::$loggedIn === false && array_search(self::curPage(), self::$config['pages']['no_login']) === false){
  359. self::redirect(self::$config['pages']['login_page']);
  360. }
  361. self::$init_called = true;
  362. }
  363.  
  364. /**
  365. * A function to login the user with the username and password.
  366. * As of version 0.4, it is required to include the remember_me parameter
  367. * when calling this function to avail the "Remember Me" feature.
  368. */
  369. public static function login($username, $password, $remember_me = false, $cookies = true){
  370. self::construct("login");
  371. if(self::$db === true){
  372. /**
  373. * We Add LIMIT to 1 in SQL query because to
  374. * get an array with key as the column name.
  375. */
  376. if(self::$config['features']['email_login'] === true){
  377. $query = "SELECT `id`, `password`, `attempt` FROM `". self::$config['db']['table'] ."` WHERE `username`=:login OR `email`=:login ORDER BY `id` LIMIT 1";
  378. }else{
  379. $query = "SELECT `id`, `password`, `attempt` FROM `". self::$config['db']['table'] ."` WHERE `username`=:login ORDER BY `id` LIMIT 1";
  380. }
  381.  
  382. $sql = self::$dbh->prepare($query);
  383. $sql->bindValue(":login", $username);
  384.  
  385. $sql->execute();
  386. $cols = $sql->fetch(PDO::FETCH_ASSOC);
  387.  
  388. if(empty($cols)){
  389. // No such user like that
  390. return false;
  391. }else{
  392. /**
  393. * Get the user details
  394. */
  395. $us_id = $cols['id'];
  396. $us_pass = $cols['password'];
  397. $status = $cols['attempt'];
  398.  
  399. if(substr($status, 0, 2) == "b-"){
  400. $blockedTime = substr($status, 2);
  401. if(time() < $blockedTime){
  402. $blocked = true;
  403. return array(
  404. "status" => "blocked",
  405. "minutes" => round(abs($blockedTime - time()) / 60, 0),
  406. "seconds" => round(abs($blockedTime - time()) / 60*60, 2)
  407. );
  408. }else{
  409. // remove the block, because the time limit is over
  410. self::updateUser(array(
  411. "attempt" => "" // No tries at all
  412. ), $us_id);
  413. }
  414. }
  415. /**
  416. * Why login if password is empty ?
  417. * --------------------------------
  418. * If using OAuth, you have to login someone without knowing their password,
  419. * this usage is helpful. But, it makes a serious security problem too.
  420. * Hence, before calling FrLS::login() in the login page, it is
  421. * required to check whether the password fieldis left blank
  422. */
  423. if(!isset($blocked) && ($password === "" || password_verify($password . self::$config['keys']['salt'], $us_pass) )){
  424. if($cookies === true){
  425.  
  426. $_SESSION['logSyscuruser'] = $us_id;
  427.  
  428. setcookie("logSyslogin", hash("sha256", self::$config['keys']['cookie'] . $us_id . self::$config['keys']['cookie']), strtotime(self::$config['cookies']['expire']), self::$config['cookies']['path'], self::$config['cookies']['domain']);
  429.  
  430. if( $remember_me === true && self::$config['features']['remember_me'] === true ){
  431. setcookie("logSysrememberMe", $us_id, strtotime(self::$config['cookies']['expire']), self::$config['cookies']['path'], self::$config['cookies']['domain']);
  432. }
  433. self::$loggedIn = true;
  434.  
  435. if(self::$config['features']['block_brute_force'] === true){
  436. /**
  437. * If Brute Force Protection is Enabled,
  438. * Reset the attempt status
  439. */
  440. self::updateUser(array(
  441. "attempt" => "0"
  442. ), $us_id);
  443. }
  444.  
  445. // Redirect
  446. if(self::$init_called){
  447. self::redirect(self::$config['pages']['home_page']);
  448. }
  449. return true;
  450. }else{
  451. /**
  452. * If cookies shouldn't be set,
  453. * it means login() was called
  454. * to get the user's ID. So, return it
  455. */
  456. return $us_id;
  457. }
  458. }else{
  459. /**
  460. * Incorrect password
  461. * ------------------
  462. * Check if brute force protection is enabled
  463. */
  464. if(self::$config['features']['block_brute_force'] === true){
  465. $max_tries = self::$config['brute_force']['tries'];
  466.  
  467. if($status == ""){
  468. // User was not logged in before
  469. self::updateUser(array(
  470. "attempt" => "1" // Tried 1 time
  471. ), $us_id);
  472. }else if($status == $max_tries){
  473. /**
  474. * Account Blocked. User will be only able to
  475. * re-login at the time in UNIX timestamp
  476. */
  477. $eligible_for_next_login_time = strtotime("+". self::$config['brute_force']['time_limit'] ." seconds", time());
  478. self::updateUser(array(
  479. "attempt" => "b-" . $eligible_for_next_login_time
  480. ), $us_id);
  481. return array(
  482. "status" => "blocked",
  483. "minutes" => round(abs($eligible_for_next_login_time - time()) / 60, 0),
  484. "seconds" => round(abs($eligible_for_next_login_time - time()) / 60*60, 2)
  485. );
  486. }else if($status < $max_tries){
  487. // If the attempts are less than Max and not Max
  488. self::updateUser(array(
  489. "attempt" => $status + 1 // Increase the no of tries by +1.
  490. ), $us_id);
  491. }
  492. }
  493. return false;
  494. }
  495. }
  496. }
  497. }
  498.  
  499. /**
  500. * A function to register a user with passing the username, password
  501. * and optionally any other additional fields.
  502. */
  503. public static function register( $id, $password, $other = array() ){
  504. self::construct();
  505. if( self::userExists($id) || (isset($other['email']) && self::userExists($other['email'])) ){
  506. return "exists";
  507. }else{
  508. $hashedPass = password_hash($password. self::$config['keys']['salt'], PASSWORD_DEFAULT);
  509.  
  510. if( count($other) == 0 ){
  511. /* If there is no other fields mentioned, make the default query */
  512. $sql = self::$dbh->prepare("INSERT INTO `". self::$config['db']['table'] ."` (`username`, `password`) VALUES(:username, :password)");
  513. }else{
  514. /* if there are other fields to add value to, make the query and bind values according to it */
  515. $keys = array_keys($other);
  516. $columns = implode(",", $keys);
  517. $colVals = implode(",:", $keys);
  518. $sql = self::$dbh->prepare("INSERT INTO `". self::$config['db']['table'] ."` (`username`, `password`, $columns) VALUES(:username, :password, :$colVals)");
  519. foreach($other as $key => $value){
  520. $value = htmlspecialchars($value);
  521. $sql->bindValue(":$key", $value);
  522. }
  523. }
  524. /* Bind the default values */
  525. $sql->bindValue(":username", $id);
  526. $sql->bindValue(":password", $hashedPass);
  527. $sql->execute();
  528. return true;
  529. }
  530. }
  531.  
  532. /**
  533. * Logout the current logged in user by deleting the cookies and destroying session
  534. */
  535. public static function logout(){
  536. self::construct("logout");
  537. session_destroy();
  538. setcookie("logSyslogin", "", time() - 10, self::$config['cookies']['path'], self::$config['cookies']['domain']);
  539. setcookie("logSysrememberMe", "", time() - 10, self::$config['cookies']['path'], self::$config['cookies']['domain']);
  540.  
  541. /**
  542. * Wait for the cookies to be removed, then redirect
  543. */
  544. usleep(2000);
  545. self::redirect(self::$config['pages']['login_page']);
  546. return true;
  547. }
  548.  
  549. /**
  550. * A function to handle the Forgot Password process
  551. */
  552. public static function forgotPassword(){
  553. self::construct();
  554. $curStatus = "initial"; // The Current Status of Forgot Password process
  555. $identName = self::$config['features']['email_login'] === false ? "Username" : "Username / E-Mail";
  556.  
  557. if( !isset($_POST['logSysForgotPass']) && !isset($_GET['resetPassToken']) && !isset($_POST['logSysForgotPassChange']) ){
  558. $html = '<form action="'. self::curPageURL() .'" method="POST">';
  559. $html .= "<label>";
  560. $html .= "<p>{$identName}</p>";
  561. $html .= "<input type='text' id='logSysIdentification' placeholder='Enter your {$identName}' size='25' name='identification' />";
  562. $html .= "</label>";
  563. $html .= "<p><button name='logSysForgotPass' type='submit'>Reset Password</button></p>";
  564. $html .= "</form>";
  565. echo $html;
  566. /**
  567. * The user had moved to the reset password form ie she/he is currently seeing the forgot password form
  568. */
  569. $curStatus = "resetPasswordForm";
  570. }elseif( isset($_GET['resetPassToken']) && !isset($_POST['logSysForgotPassChange']) ){
  571. /**
  572. * The user gave the password reset token. Check if the token is valid.
  573. */
  574. $reset_pass_token = urldecode($_GET['resetPassToken']);
  575. $sql = self::$dbh->prepare("SELECT COUNT(1) FROM `". self::$config['db']['token_table'] ."` WHERE `token` = ?");
  576. $sql->execute(array($reset_pass_token));
  577.  
  578. if($sql->fetchColumn() == 0 || $reset_pass_token == ""){
  579. echo "<h3>Error : Wrong/Invalid Token</h3>";
  580. $curStatus = "invalidToken"; // The token user gave was not valid
  581. }else{
  582. /**
  583. * The token is valid, display the new password form
  584. */
  585. $html = "<p>The Token key was Authorized. Now, you can change the password</p>";
  586. $html .= "<form action='".self::curPageURL()."' method='POST'>";
  587. $html .= "<input type='hidden' name='token' value='{$reset_pass_token}' />";
  588. $html .= "<label>";
  589. $html .= "<p>New Password</p>";
  590. $html .= "<input type='password' name='logSysForgotPassNewPassword' />";
  591. $html .= "</label><br/>";
  592. $html .= "<label>";
  593. $html .= "<p>Retype Password</p>";
  594. $html .= "<input type='password' name='logSysForgotPassRetypedPassword'/>";
  595. $html .= "</label><br/>";
  596. $html .= "<p><button name='logSysForgotPassChange'>Reset Password</button></p>";
  597. $html .= "</form>";
  598. echo $html;
  599. /**
  600. * The token was correct, displayed the change/new password form
  601. */
  602. $curStatus = "changePasswordForm";
  603. }
  604. }elseif(isset($_POST['logSysForgotPassChange']) && isset($_POST['logSysForgotPassNewPassword']) && isset($_POST['logSysForgotPassRetypedPassword'])){
  605. $reset_pass_token = urldecode($_POST['token']);
  606. $sql = self::$dbh->prepare("SELECT `uid` FROM `". self::$config['db']['token_table'] ."` WHERE `token` = ?");
  607. $sql->execute(array($reset_pass_token));
  608.  
  609. $user = $sql->fetchColumn();
  610.  
  611. if( $user == null || $reset_pass_token == null ){
  612. echo "<h3>Error : Wrong/Invalid Token</h3>";
  613. $curStatus = "invalidToken"; // The token user gave was not valid
  614. }else{
  615. if($_POST['logSysForgotPassNewPassword'] == "" || $_POST['logSysForgotPassRetypedPassword'] == ""){
  616. echo "<h3>Error : Passwords Fields Left Blank</h3>";
  617. $curStatus = "fieldsLeftBlank";
  618. }elseif( $_POST['logSysForgotPassNewPassword'] != $_POST['logSysForgotPassRetypedPassword'] ){
  619. echo "<h3>Error : Passwords Don't Match</h3>";
  620. $curStatus = "passwordDontMatch"; // The new password and retype password submitted didn't match
  621. }else{
  622. /**
  623. * We must create a fake assumption that the user is logged in to
  624. * change the password as FrLS::changePassword()
  625. * requires the user to be logged in.
  626. */
  627. self::$user = $user;
  628. self::$loggedIn = true;
  629.  
  630. if(self::changePassword($_POST['logSysForgotPassNewPassword'])){
  631. self::$user = false;
  632. self::$loggedIn = false;
  633.  
  634. /**
  635. * The token shall not be used again, so remove it.
  636. */
  637. $sql = self::$dbh->prepare("DELETE FROM `". self::$config['db']['token_table'] ."` WHERE `token` = ?");
  638. $sql->execute(array($reset_pass_token));
  639.  
  640. echo "<h3>Success : Password Reset Successful</h3><p>You may now login with your new password.</p>";
  641. $curStatus = "passwordChanged"; // The password was successfully changed
  642. }
  643. }
  644. }
  645. }elseif(isset($_POST['identification'])){
  646. /**
  647. * Check if username/email is provided and if it's valid and exists
  648. */
  649. $identification = $_POST['identification'];
  650. if($identification == ""){
  651. echo "<h3>Error : {$identName} not provided</h3>";
  652. $curStatus = "identityNotProvided"; // The identity was not given
  653. }else{
  654. $sql = self::$dbh->prepare("SELECT `email`, `id` FROM `". self::$config['db']['table'] ."` WHERE `username`=:login OR `email`=:login");
  655. $sql->bindValue(":login", $identification);
  656.  
  657. $sql->execute();
  658. $cols = $sql->fetch(PDO::FETCH_ASSOC);
  659.  
  660. if(empty($cols)){
  661. echo "<h3>Error : User Not Found</h3>";
  662. $curStatus = "userNotFound"; // The user with the identity given was not found in the users database
  663. }else{
  664. $email = $cols['email'];
  665. $uid = $cols['id'];
  666.  
  667. /**
  668. * Make token and insert into the table
  669. */
  670. $token = self::rand_string(40);
  671. $sql = self::$dbh->prepare("INSERT INTO `". self::$config['db']['token_table'] ."` (`token`, `uid`, `requested`) VALUES (?, ?, NOW())");
  672. $sql->execute(array($token, $uid));
  673. $encodedToken = urlencode($token);
  674.  
  675. /**
  676. * Prepare the email to be sent
  677. */
  678. $subject = "Reset Password";
  679. $body = "You requested for resetting your password on ". self::$config['basic']['company'] .". For this, please click the following link :
  680. <blockquote>
  681. <a href='". self::curPageURL() ."?resetPassToken={$encodedToken}'>Reset Password : {$token}</a>
  682. </blockquote>";
  683. self::sendMail($email, $subject, $body);
  684.  
  685. echo "<p>An email has been sent to your email inbox with instructions. Check Your Mail Inbox and SPAM Folders.</p><p>You can close this window.</p>";
  686. $curStatus = "emailSent"; // E-Mail has been sent
  687. }
  688. }
  689. }
  690. return $curStatus;
  691. }
  692.  
  693. /**
  694. * A function that handles the logged in user to change her/his password
  695. */
  696. public static function changePassword($newpass){
  697. self::construct();
  698. if(self::$loggedIn){
  699. $hashedPass = password_hash($newpass . self::$config['keys']['salt'], PASSWORD_DEFAULT);
  700. $sql = self::$dbh->prepare("UPDATE `". self::$config['db']['table'] ."` SET `password` = ? WHERE `id` = ?");
  701. $sql->execute(array($hashedPass, self::$user));
  702. return true;
  703. }else{
  704. echo "<h3>Error : Not Logged In</h3>";
  705. return "notLoggedIn";
  706. }
  707. }
  708.  
  709. /**
  710. * Check if user exists with ther username/email given
  711. * $identification - Either email/username
  712. */
  713. public static function userExists($identification){
  714. self::construct();
  715. if(self::$config['features']['email_login'] === true){
  716. $query = "SELECT COUNT(1) FROM `". self::$config['db']['table'] ."` WHERE `username`=:login OR `email`=:login";
  717. }else{
  718. $query = "SELECT COUNT(1) FROM `". self::$config['db']['table'] ."` WHERE `username`=:login";
  719. }
  720. $sql = self::$dbh->prepare($query);
  721. $sql->execute(array(
  722. ":login" => $identification
  723. ));
  724. return $sql->fetchColumn() == "0" ? false : true;
  725. }
  726.  
  727. /**
  728. * Fetches data of user in database. Returns a single value or an
  729. * array of value according to parameteres given to the function
  730. */
  731. public static function getUser($what = "*", $user = null){
  732. self::construct();
  733. if($user == null){
  734. $user = self::$user;
  735. }
  736. if( is_array($what) ){
  737. $columns = implode("`,`", $what);
  738. $columns = "`{$columns}`";
  739. }else{
  740. $columns = $what != "*" ? "`$what`" : "*";
  741. }
  742.  
  743. $sql = self::$dbh->prepare("SELECT {$columns} FROM `". self::$config['db']['table'] ."` WHERE `id` = ? ORDER BY `id` LIMIT 1");
  744. $sql->execute(array($user));
  745.  
  746. $data = $sql->fetch(PDO::FETCH_ASSOC);
  747. if( !is_array($what) ){
  748. $data = $what == "*" ? $data : $data[$what];
  749. }
  750. return $data;
  751. }
  752.  
  753. /**
  754. * Updates the info of user in DB
  755. */
  756. public static function updateUser($toUpdate = array(), $user = null){
  757. self::construct();
  758. if( is_array($toUpdate) && !isset($toUpdate['id']) ){
  759. if($user == null){
  760. $user = self::$user;
  761. }
  762. $columns = "";
  763. foreach($toUpdate as $k => $v){
  764. $columns .= "`$k` = :$k, ";
  765. }
  766. $columns = substr($columns, 0, -2); // Remove last ","
  767.  
  768. $sql = self::$dbh->prepare("UPDATE `". self::$config['db']['table'] ."` SET {$columns} WHERE `id`=:id");
  769. $sql->bindValue(":id", $user);
  770. foreach($toUpdate as $key => $value){
  771. $value = htmlspecialchars($value);
  772. $sql->bindValue(":$key", $value);
  773. }
  774. $sql->execute();
  775.  
  776. }else{
  777. return false;
  778. }
  779. }
  780.  
  781. /**
  782. * Returns a string which shows the time since the user has joined
  783. */
  784. public static function joinedSince($user = null){
  785. self::construct();
  786. if($user == null){
  787. $user = self::$user;
  788. }
  789. $created = self::getUser("created");
  790. $timeFirst = strtotime($created);
  791. $timeSecond = strtotime("now");
  792. $memsince = $timeSecond - strtotime($created);
  793. $regged = date("n/j/Y", strtotime($created));
  794.  
  795. if($memsince < 60) {
  796. $memfor = $memsince . " Seconds";
  797. }else if($memsince < 120){
  798. $memfor = floor ($memsince / 60) . " Minute";
  799. }else if($memsince < 3600 && $memsince > 120){
  800. $memfor = floor($memsince / 60) . " Minutes";
  801. }else if($memsince < 7200 && $memsince > 3600){
  802. $memfor = floor($memsince / 3600) . " Hour";
  803. }else if($memsince < 86400 && $memsince > 3600){
  804. $memfor = floor($memsince / 3600) . " Hours";
  805. }else if($memsince < 172800){
  806. $memfor = floor($memsince / 86400) . " Day";
  807. }else if($memsince < 604800 && $memsince > 172800){
  808. $memfor = floor($memsince / 86400) . " Days";
  809. }else if($memsince < 1209600 && $memsince > 604800){
  810. $memfor = floor($memsince / 604800) . " Week";
  811. }else if($memsince < 2419200 && $memsince > 1209600){
  812. $memfor = floor($memsince / 604800) . " Weeks";
  813. }else if($memsince < 4838400){
  814. $memfor = floor($memsince / 2419200) . " Month";
  815. }else if($memsince < 31536000 && $memsince > 4838400){
  816. $memfor = floor($memsince / 2419200) . " Months";
  817. }else if($memsince < 63072000){
  818. $memfor = floor($memsince / 31536000) . " Year";
  819. }else if($memsince > 63072000){
  820. $memfor = floor($memsince / 31536000) . " Years";
  821. }
  822. return (string) $memfor;
  823. }
  824.  
  825. /**
  826. * 2 Step Verification Login Process
  827. * ---------------------------------
  828. * When user logs in, it checks whether there is a cookie named "logSysdevice" and if there is :
  829. * 1. Checks `config` -> `two_step_login` -> `devices_table` table in DB whethere there is a token with value as that of $_COOKIES['logSysdevice']
  830. * 2. If there is a row in table, then the "Enter Received Token" form is not shown and is directly logged in if username & pass is correct
  831. * If there is not a cookie, then :
  832. * 1. The "Enter Received token" form is shown
  833. * 2. If the token entered is correct, then a unique string is set as $_COOKIE['logSysdevice'] value and inserted to `config` -> `two_step_login` -> `devices_table` table in DB
  834. * 3. The $_COOKIE['logSysdevice'] is set to be stored for 4 months
  835. * ---------------------
  836. * ^ In the above instructions, the token sending to E-Mail/SMS is not mentioned. Assume that it is done
  837. */
  838. public static function twoStepLogin($identification = "", $password = "", $remember_me = false){
  839. if(isset($_POST['logSys_two_step_login-token']) && isset($_POST['logSys_two_step_login-uid']) && $_SESSION['logSys_two_step_login-first_step'] === '1'){
  840. /**
  841. * The user's ID and token is got through the form
  842. * User = One who is about to log in and is stuck at 2 step verification
  843. */
  844. $uid = $_POST['logSys_two_step_login-uid'];
  845. $token = $_POST['logSys_two_step_login-token'];
  846.  
  847. $sql = self::$dbh->prepare("SELECT COUNT(1) FROM `". self::$config['db']['token_table'] ."` WHERE `token` = ? AND `uid` = ?");
  848. $sql->execute(array($token, $uid));
  849.  
  850. if($sql->fetchColumn() == 0){
  851. /**
  852. * To prevent user from Brute Forcing the token, we set the
  853. * status of the first login step to false,
  854. * so that the user would have to login again
  855. */
  856. $_SESSION['logSys_two_step_login-first_step'] = '0';
  857. echo "<h3>Error : Wrong/Invalid Token</h3>";
  858. return "invalidToken";
  859. }else{
  860. /**
  861. * Register User's new device if and only if
  862. * the user wants to remember the device from
  863. * which the user is logging in
  864. */
  865. if(isset($_POST['logSys_two_step_login-dontask'])){
  866. $device_token = self::rand_string(10);
  867. $sql = self::$dbh->prepare("INSERT INTO `". self::$config['two_step_login']['devices_table'] ."` (`uid`, `token`, `last_access`) VALUES (?, ?, NOW())");
  868. $sql->execute(array($uid, $device_token));
  869. setcookie("logSysdevice", $device_token, strtotime(self::$config['two_step_login']['expire']), self::$config['cookies']['path'], self::$config['cookies']['domain']);
  870. }else{
  871. /**
  872. * Verify login for this session
  873. */
  874. $_SESSION["device_check"] = "1";
  875. }
  876.  
  877. /**
  878. * Revoke token from reusing
  879. */
  880. $sql = self::$dbh->prepare("DELETE FROM `". self::$config['db']['token_table'] ."` WHERE `token` = ? AND `uid` = ?");
  881. $sql->execute(array($token, $uid));
  882. self::login(self::getUser("username", $uid), "", isset($_POST['logSys_two_step_login-remember_me']));
  883. }
  884. return true;
  885. }else if($identification != "" && $password != ""){
  886. $login = self::login($identification, $password, $remember_me, false);
  887. if($login === false){
  888. /**
  889. * Username/Password wrong
  890. */
  891. return false;
  892. }else if(is_array($login) && $login['status'] == "blocked"){
  893. return $login;
  894. }else{
  895. /**
  896. * Get the user ID from FrLS::login()
  897. */
  898. $uid = $login;
  899.  
  900. /**
  901. * Check if device is verfied so that 2 Step Verification can be skipped
  902. */
  903. if(isset($_COOKIE['logSysdevice'])){
  904. $sql = self::$dbh->prepare("SELECT 1 FROM `". self::$config['two_step_login']['devices_table'] ."` WHERE `uid` = ? AND `token` = ?");
  905. $sql->execute(array($uid, $_COOKIE['logSysdevice']));
  906. if($sql->fetchColumn() == "1"){
  907. $verfied = true;
  908. /**
  909. * Update last accessed time
  910. */
  911. $sql = self::$dbh->prepare("UPDATE `". self::$config['two_step_login']['devices_table'] ."` SET `last_access` = NOW() WHERE `uid` = ? AND `token` = ?");
  912. $sql->execute(array($uid, $_COOKIE['logSysdevice']));
  913.  
  914. self::login(self::getUser("username", $uid), "", $remember_me);
  915. return true;
  916. }
  917. }
  918. /**
  919. * Start the 2 Step Verification Process
  920. * Do only if callback is present and if
  921. * the device is not verified
  922. */
  923. if(is_callable(self::$config['two_step_login']['send_callback']) && !isset($verified)){
  924. /**
  925. * The first part of 2 Step Login is completed
  926. */
  927. $_SESSION['logSys_two_step_login-first_step'] = '1';
  928.  
  929. /**
  930. * The 2nd parameter depends on `config` -> `two_step_login` -> `numeric`
  931. */
  932. $token = self::rand_string(self::$config['two_step_login']['token_length'], self::$config['two_step_login']['numeric']);
  933.  
  934. /**
  935. * Save the token in DB
  936. */
  937. $sql = self::$dbh->prepare("INSERT INTO `". self::$config['db']['token_table'] ."` (`token`, `uid`, `requested`) VALUES (?, ?, NOW())");
  938. $sql->execute(array($token, $uid));
  939.  
  940. call_user_func_array(self::$config['two_step_login']['send_callback'], array($uid, $token));
  941.  
  942. /**
  943. * Display the form
  944. */
  945. $html = "<form action='". self::curPageURL() ."' method='POST'>
  946. <p>". self::$config['two_step_login']['instruction'] ."</p>
  947. <label>
  948. <p>Token Received</p>
  949. <input type='text' name='logSys_two_step_login-token' placeholder='Paste the token here... (case sensitive)' />
  950. </label>
  951. <label style='display: block;'>
  952. <span>Remember this device ?</span>
  953. <input type='checkbox' name='logSys_two_step_login-dontask' />
  954. </label>
  955. <input type='hidden' name='logSys_two_step_login-uid' value='". $uid ."' />
  956. ". ($remember_me === true ? "<input type='hidden' name='logSys_two_step_login-remember_me' />" : "") ."
  957. <label>
  958. <button>Verify</button>
  959. </label>
  960. </form>";
  961. echo $html;
  962. return "formDisplay";
  963. }else{
  964. self::log("two_step_login: Token Callback not present");
  965. }
  966. }
  967. }
  968. /**
  969. * 2 Step Login is not doing any actions or
  970. * hasn't returned anything before. If so,
  971. * then return false to indicate that the
  972. * function is not doing anything
  973. */
  974. return false;
  975. }
  976.  
  977. /**
  978. * Returns array of devices that are authorized
  979. * to login by user's account credentials
  980. */
  981. public static function getDevices(){
  982. if(self::$loggedIn){
  983. $sql = self::$dbh->prepare("SELECT * FROM `". self::$config['two_step_login']['devices_table'] ."` WHERE `uid` = ?");
  984. $sql->execute(array(self::$user));
  985. return $sql->fetchAll(PDO::FETCH_ASSOC);
  986. }else{
  987. return false;
  988. }
  989. }
  990.  
  991. /**
  992. * Revoke a device
  993. */
  994. public static function revokeDevice($device_token){
  995. if(self::$loggedIn){
  996. $sql = self::$dbh->prepare("DELETE FROM `". self::$config['two_step_login']['devices_table'] ."` WHERE `uid` = ? AND `token` = ?");
  997. $sql->execute(array(self::$user, $device_token));
  998. if(isset($_SESSION['device_check'])){
  999. unset($_SESSION['device_check']);
  1000. }
  1001. return $sql->rowCount() == 1;
  1002. }
  1003. }
  1004.  
  1005. /**
  1006. * ---------------------
  1007. * Extra Tools/Functions
  1008. * ---------------------
  1009. */
  1010.  
  1011. /**
  1012. * Check if E-Mail is valid
  1013. */
  1014. public static function validEmail($email = ""){
  1015. return filter_var($email, FILTER_VALIDATE_EMAIL);
  1016. }
  1017.  
  1018. /**
  1019. * Get the current page URL
  1020. */
  1021. public static function curPageURL() {
  1022. $pageURL = 'http';
  1023. if(isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on"){$pageURL .= "s";}
  1024. $pageURL .= "://";
  1025. if($_SERVER["SERVER_PORT"] != "80") {
  1026. $pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
  1027. }else{
  1028. $pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
  1029. }
  1030. return $pageURL;
  1031. }
  1032.  
  1033. /**
  1034. * Generate a Random String
  1035. * $int - Whether numeric string should be output
  1036. */
  1037. public static function rand_string($length, $int = false) {
  1038. $random_str = "";
  1039. $chars = $int ? "0516243741506927589" : "subinsblogabcdefghijklmanopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  1040. $size = strlen($chars) - 1;
  1041. for($i = 0;$i < $length;$i++) {
  1042. $random_str .= $chars[rand(0, $size)];
  1043. }
  1044. return $random_str;
  1045. }
  1046.  
  1047. /**
  1048. * Get the current page path.
  1049. * Eg: /mypage, /folder/mypage.php
  1050. */
  1051. public static function curPage(){
  1052. $parts = parse_url(self::curPageURL());
  1053. return $parts["path"];
  1054. }
  1055.  
  1056. /**
  1057. * Do a redirect
  1058. */
  1059. public static function redirect($url, $status = 302){
  1060. header("Location: $url", true, $status);
  1061. exit;
  1062. }
  1063.  
  1064. /**
  1065. * Any mails need to be sent by logSys goes to here
  1066. */
  1067. public static function sendMail($email, $subject, $body){
  1068. /**
  1069. * If there is a callback for email sending, use it else PHP's mail()
  1070. */
  1071. if(is_callable(self::$config['basic']['email_callback'])){
  1072. call_user_func_array(self::$config['basic']['email_callback'], array($email, $subject, $body));
  1073. }else{
  1074. $headers = array();
  1075. $headers[] = "MIME-Version: 1.0";
  1076. $headers[] = "Content-type: text/html; charset=iso-8859-1";
  1077. $headers[] = "From: ". self::$config['basic']['email'];
  1078. $headers[] = "Reply-To: ". self::$config['basic']['email'];
  1079. mail($email, $subject, $body, implode("rn", $headers));
  1080. }
  1081. }
  1082.  
  1083. /**
  1084. * CSRF Protection
  1085. */
  1086. public static function csrf($type = ""){
  1087. if(!isset($_COOKIE['csrf_token'])){
  1088. $csrf_token = self::rand_string(5);
  1089. setcookie("csrf_token", $csrf_token, 0, self::$config['cookies']['path'], self::$config['cookies']['domain']);
  1090. }else{
  1091. $csrf_token = $_COOKIE['csrf_token'];
  1092. }
  1093. if($type == "s"){
  1094. /**
  1095. * Output as string
  1096. */
  1097. return urlencode($csrf_token);
  1098. }elseif($type == "g"){
  1099. /**
  1100. * Output as a GET parameter
  1101. */
  1102. return "&csrf_token=" . urlencode($csrf_token);
  1103. }elseif($type == "i"){
  1104. /**
  1105. * Output as an input field
  1106. */
  1107. echo "<input type='hidden' name='csrf_token' value='{$csrf_token}' />";
  1108. }else{
  1109. /**
  1110. * Check CSRF validity
  1111. */
  1112. if((isset($_POST['csrf_token']) && $_COOKIE['csrf_token'] == $_POST['csrf_token']) || (isset($_GET['csrf_token']) && $_COOKIE['csrf_token'] == $_GET['csrf_token'])){
  1113. return true;
  1114. }else{
  1115. /**
  1116. * CSRF Token doesn't match.
  1117. */
  1118. return false;
  1119. }
  1120. }
  1121. }
  1122.  
  1123. /**
  1124. * -------------------------
  1125. * End Extra Tools/Functions
  1126. * -------------------------
  1127. */
  1128. }
  1129.  
  1130. <?php
  1131. require "config.php";
  1132. ?>
  1133. <!DOCTYPE html>
  1134. <html>
  1135. <head>
  1136. <title>Change Password</title>
  1137. </head>
  1138. <body>
  1139. <?php
  1140. if(isset($_POST['change_password'])){
  1141. if(isset($_POST['current_password']) && $_POST['current_password'] != "" && isset($_POST['new_password']) && $_POST['new_password'] != "" && isset($_POST['retype_password']) && $_POST['retype_password'] != "" && isset($_POST['current_password']) && $_POST['current_password'] != ""){
  1142.  
  1143. $curpass = $_POST['current_password'];
  1144. $new_password = $_POST['new_password'];
  1145. $retype_password = $_POST['retype_password'];
  1146.  
  1147. if($new_password != $retype_password){
  1148. echo "<p><h2>Passwords Doesn't match</h2><p>The passwords you entered didn't match. Try again.</p></p>";
  1149. }else if(FrLS::login(FrLS::getUser("username"), "", false, false) == false){
  1150. echo "<h2>Current Password Wrong!</h2><p>The password you entered for your account is wrong.</p>";
  1151. }else{
  1152. $change_password = FrLS::changePassword($new_password);
  1153. if($change_password === true){
  1154. echo "<h2>Password Changed Successfully</h2>";
  1155. }
  1156. }
  1157. }else{
  1158. echo "<p><h2>Password Fields was blank</h2><p>Form fields were left blank</p></p>";
  1159. }
  1160. }
  1161. ?>
  1162. <form action="<?php echo FrLS::curPageURL();?>" method='POST'>
  1163. <label>
  1164. <p>Current Password</p>
  1165. <input type='password' name='current_password' />
  1166. </label>
  1167. <label>
  1168. <p>New Password</p>
  1169. <input type='password' name='new_password' />
  1170. </label>
  1171. <label>
  1172. <p>Retype New Password</p>
  1173. <input type='password' name='retype_password' />
  1174. </label>
  1175. <button style="display: block;margin-top: 10px;" name='change_password' type='submit'>Change Password</button>
  1176. </form>
  1177. </body>
  1178. </html>
  1179.  
  1180. <?php
  1181. /**
  1182. * For Development Purposes
  1183. */
  1184. ini_set("display_errors", "on");
  1185.  
  1186. require __DIR__ . "/../../src/class.logsys.php";
  1187. FrLS::config(array(
  1188. "db" => array(
  1189. "host" => "localhost",
  1190. "port" => 3306,
  1191. "username" => "root",
  1192. "password" => "backstreetboys",
  1193. "name" => "test",
  1194. "table" => "users"
  1195. ),
  1196. "features" => array(
  1197. "auto_init" => true
  1198. ),
  1199. "pages" => array(
  1200. "no_login" => array(
  1201. "/Francium/logSys/",
  1202. "/Francium/logSys/examples/basic/reset.php",
  1203. "/Francium/logSys/examples/basic/register.php"
  1204. ),
  1205. "everyone" => array(
  1206. "/Francium/logSys/examples/two-step-login/status.php"
  1207. ),
  1208. "login_page" => "/Francium/logSys/examples/basic/login.php",
  1209. "home_page" => "/Francium/logSys/examples/basic/home.php"
  1210. )
  1211. ));
  1212.  
  1213. <?php
  1214. require "config.php";
  1215. if(isset($_POST['action_login'])){
  1216. $identification = $_POST['login'];
  1217. $password = $_POST['password'];
  1218. if($identification == "" || $password == ""){
  1219. $msg = array("Error", "Username / Password Wrong !");
  1220. }else{
  1221. $login = FrLS::login($identification, $password, isset($_POST['remember_me']));
  1222. if($login === false){
  1223. $msg = array("Error", "Username / Password Wrong !");
  1224. }else if(is_array($login) && $login['status'] == "blocked"){
  1225. $msg = array("Error", "Too many login attempts. You can attempt login after ". $login['minutes'] ." minutes (". $login['seconds'] ." seconds)");
  1226. }
  1227. }
  1228. }
  1229. ?>
  1230. <html>
  1231. <head>
  1232. <title>Log In</title>
  1233. </head>
  1234. <body>
  1235. <div class="content">
  1236. <h2>Log In</h2>
  1237. <?php
  1238. if(isset($msg)){
  1239. echo "<h2>{$msg[0]}</h2><p>{$msg[1]}</p>";
  1240. }
  1241. ?>
  1242. <form action="login.php" method="POST" style="margin:0px auto;display:table;">
  1243. <label>
  1244. <p>Username / E-Mail</p>
  1245. <input name="login" type="text"/>
  1246. </label><br/>
  1247. <label>
  1248. <p>Password</p>
  1249. <input name="password" type="password"/>
  1250. </label><br/>
  1251. <label>
  1252. <p>
  1253. <input type="checkbox" name="remember_me"/> Remember Me
  1254. </p>
  1255. </label>
  1256. <div clear></div>
  1257. <button style="width:150px;" name="action_login">Log In</button>
  1258. </form>
  1259. <style>
  1260. input[type=text], input[type=password]{
  1261. width: 230px;
  1262. }
  1263. </style>
  1264. <p>
  1265. <p>Don't have an account ?</p>
  1266. <a class="button" href="register.php">Register</a>
  1267. </p>
  1268. <p>
  1269. <p>Forgot Your Password ?</p>
  1270. <a class="button" href="reset.php">Reset Password</a>
  1271. </p>
  1272. </div>
  1273. </body>
  1274. </html>
  1275.  
  1276. <?php
  1277. require "config.php";
  1278. FrLS::logout();
  1279. ?>
  1280.  
  1281. <?php
  1282. include "config.php";
  1283. ?>
  1284. <!DOCTYPE html>
  1285. <html>
  1286. <head></head>
  1287. <body>
  1288. <div class="content">
  1289. <h1>Register</h1>
  1290. <form action="register.php" method="POST">
  1291. <label>
  1292. <input name="username" placeholder="Username" />
  1293. </label>
  1294. <label>
  1295. <input name="email" placeholder="E-Mail" />
  1296. </label>
  1297. <label>
  1298. <input name="pass" type="password" placeholder="Password" />
  1299. </label>
  1300. <label>
  1301. <input name="retyped_password" type="password" placeholder="Retype Password" />
  1302. </label>
  1303. <label>
  1304. <input name="name" placeholder="Name" />
  1305. </label>
  1306. <label>
  1307. <button name="submit">Register</button>
  1308. </label>
  1309. </form>
  1310. <?php
  1311. if( isset($_POST['submit']) ){
  1312. $username = $_POST['username'];
  1313. $email = $_POST['email'];
  1314. $password = $_POST['pass'];
  1315. $retyped_password = $_POST['retyped_password'];
  1316. $name = $_POST['name'];
  1317. if( $username == "" || $email == "" || $password == '' || $retyped_password == '' || $name == '' ){
  1318. echo "<h2>Fields Left Blank</h2>", "<p>Some Fields were left blank. Please fill up all fields.</p>";
  1319. }elseif( !FrLS::validEmail($email) ){
  1320. echo "<h2>E-Mail Is Not Valid</h2>", "<p>The E-Mail you gave is not valid</p>";
  1321. }elseif( !ctype_alnum($username) ){
  1322. echo "<h2>Invalid Username</h2>", "<p>The Username is not valid. Only ALPHANUMERIC characters are allowed and shouldn't exceed 10 characters.</p>";
  1323. }elseif($password != $retyped_password){
  1324. echo "<h2>Passwords Don't Match</h2>", "<p>The Passwords you entered didn't match</p>";
  1325. }else{
  1326. $createAccount = FrLS::register($username, $password,
  1327. array(
  1328. "email" => $email,
  1329. "name" => $name,
  1330. "created" => date("Y-m-d H:i:s") // Just for testing
  1331. )
  1332. );
  1333. if($createAccount === "exists"){
  1334. echo "<label>User Exists.</label>";
  1335. }elseif($createAccount === true){
  1336. echo "<label>Success. Created account. <a href='login.php'>Log In</a></label>";
  1337. }
  1338. }
  1339. }
  1340. ?>
  1341. <style>
  1342. label{
  1343. display: block;
  1344. margin-bottom: 5px;
  1345. }
  1346. </style>
  1347. </div>
  1348. </body>
  1349. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement