diff --git a/components/active/class.active.php b/components/active/class.active.php index b515cae..77dcd11 100755 --- a/components/active/class.active.php +++ b/components/active/class.active.php @@ -1,173 +1,194 @@ actives = getJSON('active.php'); - } - - ////////////////////////////////////////////////////////////////// - // List User's Active Files - ////////////////////////////////////////////////////////////////// - - public function ListActive() - { - $active_list = array(); - $tainted = false; - $root = WORKSPACE; - if ($this->actives) { - foreach ($this->actives as $active => $data) { - if (is_array($data) && isset($data['username']) && $data['username']==$this->username) { - if ($this->isAbsPath($data['path'])) { - $root = ""; - } else { - $root = $root.'/'; - } - if (file_exists($root.$data['path'])) { - $focused = isset($data['focused']) ? $data['focused'] : false; - $active_list[] = array('path'=>$data['path'], 'focused'=>$focused); - } else { - unset($this->actives[$active]); - $tainted = true; - } - } - } - } - if ($tainted) { - saveJSON('active.php', $this->actives); - } - echo formatJSEND("success", $active_list); - } - - ////////////////////////////////////////////////////////////////// - // Check File - ////////////////////////////////////////////////////////////////// - - public function Check() - { - $cur_users = array(); - foreach ($this->actives as $active => $data) { - if (is_array($data) && isset($data['username']) && $data['username']!=$this->username && $data['path']==$this->path) { - $cur_users[] = $data['username']; - } - } - if (count($cur_users)!=0) { - //echo formatJSEND("error", "Warning: File ".substr($this->path, strrpos($this->path, "/")+1)." Currently Opened By: " . implode(", ", $cur_users)); - } else { - echo formatJSEND("success"); - } - } - - ////////////////////////////////////////////////////////////////// - // Add File - ////////////////////////////////////////////////////////////////// - - public function Add() - { - $process_add = true; - foreach ($this->actives as $active => $data) { - if (is_array($data) && isset($data['username']) && $data['username']==$this->username && $data['path']==$this->path) { - $process_add = false; - } - } - if ($process_add) { - $this->actives[] = array("username"=>$this->username,"path"=>$this->path); - saveJSON('active.php', $this->actives); - echo formatJSEND("success"); - } - } - - ////////////////////////////////////////////////////////////////// - // Rename File - ////////////////////////////////////////////////////////////////// - - public function Rename() - { - $revised_actives = array(); - foreach ($this->actives as $active => $data) { - if (is_array($data) && isset($data['username'])) { - $revised_actives[] = array("username"=>$data['username'],"path"=>str_replace($this->path, $this->new_path, $data['path'])); - } - } - saveJSON('active.php', $revised_actives); - echo formatJSEND("success"); - } - - ////////////////////////////////////////////////////////////////// - // Remove File - ////////////////////////////////////////////////////////////////// - - public function Remove() - { - foreach ($this->actives as $active => $data) { - if (is_array($data) && isset($data['username']) && $this->username==$data['username'] && $this->path==$data['path']) { - unset($this->actives[$active]); - } - } - saveJSON('active.php', $this->actives); - echo formatJSEND("success"); - } - - ////////////////////////////////////////////////////////////////// - // Remove All Files - ////////////////////////////////////////////////////////////////// - - public function RemoveAll() - { - foreach ($this->actives as $active => $data) { - if (is_array($data) && isset($data['username']) && $this->username==$data['username']) { - unset($this->actives[$active]); - } - } - saveJSON('active.php', $this->actives); - echo formatJSEND("success"); - } - - ////////////////////////////////////////////////////////////////// - // Mark File As Focused - // All other files will be marked as non-focused. - ////////////////////////////////////////////////////////////////// - - public function MarkFileAsFocused() - { - foreach ($this->actives as $active => $data) { - if (is_array($data) && isset($data['username']) && $this->username==$data['username']) { - $this->actives[$active]['focused']=false; - if ($this->path==$data['path']) { - $this->actives[$active]['focused']=true; - } - } - } - saveJSON('active.php', $this->actives); - echo formatJSEND("success"); - } +class Active extends Common { + + ////////////////////////////////////////////////////////////////// + // PROPERTIES + ////////////////////////////////////////////////////////////////// + + public $username = ""; + public $path = ""; + public $new_path = ""; + + ////////////////////////////////////////////////////////////////// + // METHODS + ////////////////////////////////////////////////////////////////// + + // -----------------------------||----------------------------- // + + ////////////////////////////////////////////////////////////////// + // Construct + ////////////////////////////////////////////////////////////////// + + public function __construct() { + } + + ////////////////////////////////////////////////////////////////// + // List User's Active Files + ////////////////////////////////////////////////////////////////// + + public function ListActive() { + + global $sql; + $query = "SELECT path,focused FROM active WHERE username=?"; + $bind_variables = array( $this->username ); + $result = $sql->query( $query, $bind_variables, array() ); + $tainted = false; + $root = WORKSPACE; + $active_list = $result; + + if( ! empty( $return ) ) { + + foreach ( $result as $id => $data ) { + + if ( $this->isAbsPath( $data['path'] ) ) { + + $root = ""; + } else { + + $root = $root.'/'; + } + + if ( ! file_exists( $root . $data['path'] ) ) { + + $tainted = true; + unset( $active_list[$id] ); + } + } + } + + if( $tainted ) { + + $this->update_active( $active_list ); + } + + echo formatJSEND( "success", $active_list ); + } + + ////////////////////////////////////////////////////////////////// + // Check File + ////////////////////////////////////////////////////////////////// + + public function Check() { + + global $sql; + $query = "SELECT username FROM active WHERE path=?"; + $bind_variables = array( $this->path ); + $result = $sql->query( $query, $bind_variables, array() ); + $tainted = false; + $user = false; + $users = array(); + $root = WORKSPACE; + + foreach( $result as $id => $data ) { + + array_push( $users, $data["username"] ); + if( $data["username"] == $this->username ) { + + $user = true; + } + } + + if ( ( count( $result ) == 1 && ! $user ) || count( $result ) > 1 ) { + + echo formatJSEND( "warning", "Warning: File " . substr( $this->path, strrpos( $this->path, "/" ) +1 ) . " Currently Opened By: " . implode( ", ", $users ) ); + } else { + + echo formatJSEND("success"); + } + } + + ////////////////////////////////////////////////////////////////// + // Add File + ////////////////////////////////////////////////////////////////// + + public function Add() { + + global $sql; + $query = "INSERT INTO active( username, path, focused ) VALUES ( ?, ?, ? );"; + $bind_variables = array( $this->username, $this->path, false ); + $return = $sql->query( $query, $bind_variables, 0, "rowCount" ); + + if( $return > 0 ) { + + echo formatJSEND( "success" ); + } + } + + ////////////////////////////////////////////////////////////////// + // Rename File + ////////////////////////////////////////////////////////////////// + + public function Rename() { + + global $sql; + $query = "UPDATE active SET path=? WHERE path=?;"; + $bind_variables = array( $this->new_path, $this->path ); + $return = $sql->query( $query, $bind_variables, 0, "rowCount" ); + + if( $return > 0 ) { + + echo formatJSEND( "success" ); + } + } + + ////////////////////////////////////////////////////////////////// + // Remove File + ////////////////////////////////////////////////////////////////// + + public function Remove() { + + global $sql; + $query = "DELETE FROM active WHERE path=? AND username=?;"; + $bind_variables = array( $this->path, $this->username ); + $return = $sql->query( $query, $bind_variables, 0, "rowCount" ); + + if( $return > 0 ) { + + echo formatJSEND( "success" ); + } + } + + ////////////////////////////////////////////////////////////////// + // Remove All Files + ////////////////////////////////////////////////////////////////// + + public function RemoveAll() { + + global $sql; + $query = "DELETE FROM active WHERE username=?;"; + $bind_variables = array( $this->username ); + $return = $sql->query( $query, $bind_variables, 0, "rowCount" ); + + if( $return > 0 ) { + + echo formatJSEND( "success" ); + } + } + + ////////////////////////////////////////////////////////////////// + // Mark File As Focused + // All other files will be marked as non-focused. + ////////////////////////////////////////////////////////////////// + + public function MarkFileAsFocused() { + + global $sql; + $query = "UPDATE active SET focused=? WHERE username=?;UPDATE active SET focused=? WHERE path=? AND username=?;"; + $bind_variables = array( false, $this->username, true, $this->path, $this->username ); + $return = $sql->query( $query, $bind_variables, 0, "rowCount" ); + + if( $return > 0 ) { + + echo formatJSEND( "success" ); + } + } } diff --git a/components/active/init.js b/components/active/init.js index b3b138b..b721657 100755 --- a/components/active/init.js +++ b/components/active/init.js @@ -669,9 +669,8 @@ var newSession = this.sessions[newPath]; // Change Editor Mode - var ext = codiad.filemanager.getExtension(newPath); - var mode = codiad.editor.selectMode(ext); - + var mode = codiad.editor.selectMode(newPath); + // handle async mode change var fn = function() { codiad.editor.setModeDisplay(newSession); diff --git a/components/autosave/init.js b/components/autosave/init.js index 8133009..e3889f3 100755 --- a/components/autosave/init.js +++ b/components/autosave/init.js @@ -99,7 +99,17 @@ amplify.subscribe( 'active.onClose', function( path ) { let _this = codiad.auto_save; - _this.editor.removeEventListener( "change", _this.change ); + try { + + _this.editor.removeEventListener( "change", _this.change ); + } catch( e ) { + + /** + * If the listener is not currently on file and we + * try to close it, the program will throw an exception and + * stop you from closing the file + */ + } }); /* Subscribe to know when a file become active. */ diff --git a/components/editor/init.js b/components/editor/init.js index fe1427b..681a421 100755 --- a/components/editor/init.js +++ b/components/editor/init.js @@ -321,18 +321,18 @@ // ////////////////////////////////////////////////////////////////// - getSettings: function() { + getSettings: async function() { - var boolVal = null; - var _this = this; - var options = [ + let boolVal = null; + let _this = this; + let options = [ 'editor.fontSize', 'editor.overScroll', 'editor.printMarginColumn', 'editor.tabSize', 'editor.theme', ]; - var bool_options = [ + let bool_options = [ 'editor.autocomplete', 'settings.autosave', 'editor.printMargin', @@ -345,9 +345,11 @@ 'editor.persistentModal', ]; - $.each( options, async function( idx, key ) { + let user_settings = await codiad.settings.get_options(); + + $.each( options, function( idx, key ) { - let localValue = await codiad.settings.get_option( 'codiad.' + key ); + let localValue = user_settings['codiad.' + key]; if ( localValue != null ) { _this.settings[key.split('.').pop()] = localValue; @@ -356,7 +358,7 @@ $.each( bool_options, async function(idx, key) { - let localValue = await codiad.settings.get_option( 'codiad.' + key ); + let localValue = user_settings['codiad.' + key]; if ( localValue != null ) { _this.settings[key.split('.').pop()] = (localValue == 'true'); diff --git a/components/install/install.php b/components/install/install.php index 7388155..df94187 100644 --- a/components/install/install.php +++ b/components/install/install.php @@ -1,5 +1,12 @@ active = $path . "/data/active.php"; - $this->config = $path . "/config.php"; - $this->projects = $path . "/data/projects.php"; - $this->path = $path; - $this->sessions = $path . "/data/sessions"; - $this->users = $path . "/data/users.php"; - $this->rel = $rel; - $this->workspace = $path . "/workspace"; - $this->db_types = sql::db_types; - - $this->check(); - - require_once( "../sql/class.sql.php" ); - $this->sql = new sql(); - $this->install(); + if( isset( $_POST["path"] ) ) { + + $path = $_POST['path']; + $rel = str_replace( '/components/install/install.php', '', $_SERVER['REQUEST_URI'] ); + + $this->active = $path . "/data/active.php"; + $this->config = $path . "/config.php"; + $this->projects = $path . "/data/projects.php"; + $this->path = $path; + $this->sessions = $path . "/data/sessions"; + $this->users = $path . "/data/users.php"; + $this->rel = $rel; + $this->workspace = $path . "/workspace"; + $this->db_types = sql::DB_TYPES; + $this->project_name = $_POST["project_name"]; + $this->project_path = $this->clean_path( $_POST["project_path"] ); + $this->username = $this->clean_username( $_POST["username"] ); + $this->password = $this->encrypt_password( $_POST["password"] ); + + $this->check(); + $this->sql = new sql(); + $this->install(); + exit; + } } function check() { @@ -51,7 +64,12 @@ class Install { if( ! in_array( DBTYPE, $this->db_types ) ) { - $this->JSEND( "Invalid database. Please select one of the following: " . implode( ", ", $db_types ), addslashes( json_encode( array( $dbtype, $db_types ) ) ) ); + $this->JSEND( "Invalid database. Please select one of the following: " . implode( ", ", $db_types ), json_encode( array( $dbtype, $db_types ) ) ); + } + + if( ! is_dir( $this->sessions ) ) { + + mkdir( $this->sessions, 00755 ); } } @@ -134,20 +152,20 @@ define("WSURL", BASE_URL . "/workspace"); // Marketplace //define("MARKETURL", "http://market.codiad.com/json"); '; - saveFile( $config, $config_data ); + $this->save_file( $this->config, $config_data ); echo( "success" ); } function create_project() { - $project_path = $this->clean_path( $project_path ); + $project_path = $this->project_path; if ( ! $this->is_abs_path( $project_path ) ) { $project_path = str_replace( " ", "_", preg_replace( '/[^\w-\.]/', '', $project_path ) ); - if( ! is_dir( $workspace . "/" . $project_path ) ) { + if( ! is_dir( $this->workspace . "/" . $project_path ) ) { - mkdir( $workspace . "/" . $project_path ); + mkdir( $this->workspace . "/" . $project_path ); } } else { @@ -171,11 +189,12 @@ define("WSURL", BASE_URL . "/workspace"); } $bind_variables = array( - $project_name, + $this->project_name, $project_path, - $username + $this->username ); $query = "INSERT INTO projects(name, path, owner) VALUES (?,?,?);"; + $connection = $this->sql->connect(); $statement = $connection->prepare( $query ); $statement->execute( $bind_variables ); $error = $statement->errorInfo(); @@ -190,6 +209,18 @@ define("WSURL", BASE_URL . "/workspace"); $this->sql->create_tables( array( + "active" => array( + "fields" => array( + "username" => "string", + "path" => "text", + "focused" => "string" + ), + "attributes" => array( + "username" => array( "not null", "unique" ), + "path" => array( "not null", "unique" ), + "focused" => array( "not null" ), + ) + ), "options" => array( "fields" => array( "id" => "int", @@ -216,7 +247,7 @@ define("WSURL", BASE_URL . "/workspace"); "name" => array( "not null" ), "path" => array( "not null", "unique" ), "owner" => array( "not null", "unique" ), - "access" => array( "not null" ), + "access" => array(), ) ), "users" => array( @@ -262,15 +293,16 @@ define("WSURL", BASE_URL . "/workspace"); $bind_variables = array( "", "", - $username, - $password, + $this->username, + $this->password, "", - $project_path, + $this->project_path, "admin", "", "" ); $query = "INSERT INTO users(first_name, last_name, username, password, email, project, access, groups, token) VALUES (?,?,?,?,?,?,?,?,?)"; + $connection = $this->sql->connect(); $statement = $connection->prepare( $query ); $statement->execute( $bind_variables ); $error = $statement->errorInfo(); @@ -279,6 +311,13 @@ define("WSURL", BASE_URL . "/workspace"); die( '{"message":"Could not create user in database.","error":"' . addslashes(json_encode( $error )) .'"}' ); } + + $this->set_default_options(); + } + + function encrypt_password( $string ) { + + return sha1( md5( $string ) ); } function is_abs_path( $path ) { @@ -309,6 +348,7 @@ define("WSURL", BASE_URL . "/workspace"); $this->create_tables(); $this->create_project(); $this->create_user(); + //exit( "stop" ); $this->create_config(); } @@ -325,6 +365,37 @@ define("WSURL", BASE_URL . "/workspace"); exit( json_encode( $message ) ); } + function save_file( $file, $data ) { + + $write = fopen( $file, 'w' ) or die( '{"message": "can\'t open file"}' ); + fwrite( $write, $data ); + fclose( $write ); + } + + public function set_default_options() { + + foreach( Settings::DEFAULT_OPTIONS as $id => $option ) { + + $query = "INSERT INTO user_options ( name, username, value ) VALUES ( ?, ?, ? );"; + $bind_variables = array( + $option["name"], + $this->username, + $option["value"], + ); + $result = $this->sql->query( $query, $bind_variables, 0, "rowCount" ); + + if( $result == 0 ) { + + $query = "UPDATE user_options SET value=? WHERE name=? AND username=?;"; + $bind_variables = array( + $option["value"], + $option["name"], + $this->username, + ); + $result = $this->sql->query( $query, $bind_variables, 0, "rowCount" ); + } + } + } } $Install = new Install(); diff --git a/components/install/process.php b/components/install/process.php deleted file mode 100755 index 5eaa186..0000000 --- a/components/install/process.php +++ /dev/null @@ -1,295 +0,0 @@ -"; - saveFile( $file, $data ); -} - -function encryptPassword( $p ) { - - return sha1( md5( $p ) ); -} - -function cleanUsername( $username ) { - - return preg_replace( '#[^A-Za-z0-9' . preg_quote( '-_@. ' ). ']#', '', $username ); -} - -function isAbsPath( $path ) { - - return $path[0] === '/'; -} - -function cleanPath( $path ) { - - // prevent Poison Null Byte injections - $path = str_replace( chr( 0 ), '', $path ); - - // prevent go out of the workspace - while ( strpos( $path, '../' ) !== false ) { - - $path = str_replace( '../', '', $path ); - } - return $path; -} - -////////////////////////////////////////////////////////////////////// -// Verify no overwrites -////////////////////////////////////////////////////////////////////// - -if ( ! ( defined( 'DBHOST' ) && defined( 'DBNAME' ) && defined( 'DBUSER' ) && defined( 'DBPASS' ) && defined( 'DBTYPE' ) ) ) { - - ////////////////////////////////////////////////////////////////// - // Get POST responses - ////////////////////////////////////////////////////////////////// - - $username = cleanUsername( $_POST['username'] ); - $password = encryptPassword( $_POST['password'] ); - $project_name = $_POST['project_name']; - if ( isset( $_POST['project_path'] ) ) { - - $project_path = $_POST['project_path']; - } else { - - $project_path = $project_name; - } - $timezone = $_POST['timezone']; - - $dbtype = $_POST['dbtype']; - $dbhost = $_POST['dbhost']; - $dbname = $_POST['dbname']; - $dbuser = $_POST['dbuser']; - $dbpass = $_POST['dbpass']; - - //Valid databases Codiad is able to use - $db_types = [ - 'mysql', - 'pgsql', - //'sqlite', - ]; - - //Is selected database type valid? - if( ! in_array( $dbtype, $db_types ) ) { - - die( '{"message": "Invalid database. Please select one of the following: ' . implode( ", ", $db_types ) . '.", "error": "' . addslashes(json_encode( array( $dbtype, $db_types ) ) ) . '"}' ); - } - - try { - - $connection = new PDO( "{$dbtype}:host={$dbhost};dbname={$dbname}", $dbuser, $dbpass ); - } catch( PDOException $e ) { - - die( '{"message":"Could not connect to database.","error":"' . addslashes( json_encode( $e->getMessage() ) ) .'"}' ); - } - $bind_vars = array(); - $bind = ""; - $database_sql_fullpath = $path . '/components/install/sql/' . $dbtype . '.sql'; - if( ! is_file( $database_sql_fullpath ) ) { - - die( '{"message":"Could not find the sql script for the database type: ' . $dbtype . '","error":"' . addslashes( json_encode( array( "path" => $database_sql_fullpath, "dbtype" => $dbtype ) ) ) .'"}' ); - } - $sql = file_get_contents( $database_sql_fullpath ); - - try { - - //Create the database - $result = $connection->exec( $sql ); - } catch( PDOException $e ) { - - die( '{"message":"Could not create initial tables in database.","error":"' . addslashes( json_encode( $e->getMessage() ) ) .'"}' ); - } - - $error = $connection->errorInfo(); - if( ! $error[0] == "00000" ) { - - die( '{"message":"Could not create initial tables in database.","error":"' . addslashes( json_encode( $error ) ) .'"}' ); - } - - ////////////////////////////////////////////////////////////////// - // Create Projects files - ////////////////////////////////////////////////////////////////// - - $project_path = cleanPath( $project_path ); - - if ( ! isAbsPath( $project_path ) ) { - - $project_path = str_replace( " ", "_", preg_replace( '/[^\w-\.]/', '', $project_path ) ); - if( ! is_dir( $workspace . "/" . $project_path ) ) { - - mkdir( $workspace . "/" . $project_path ); - } - } else { - - $project_path = cleanPath( $project_path ); - if ( substr( $project_path, -1 ) == '/' ) { - - $project_path = substr( $project_path, 0, strlen( $project_path ) - 1 ); - } - if ( ! file_exists( $project_path ) ) { - - if ( ! mkdir( $project_path . '/', 0755, true ) ) { - - die( '{"message": "Unable to create Absolute Path"}' ); - } - } else { - - if ( ! is_writable( $project_path ) || ! is_readable( $project_path ) ) { - - die( '{"message": "No Read/Write Permission"}' ); - } - } - } - - $bind_variables = array( - $project_name, - $project_path, - $username - ); - $query = "INSERT INTO projects(name, path, owner) VALUES (?,?,?);"; - $statement = $connection->prepare( $query ); - $statement->execute( $bind_variables ); - $error = $statement->errorInfo(); - - if( ! $error[0] == "00000" ) { - - die( '{"message":"Could not create project in database.","error":"' . addslashes(json_encode( $error )) .'"}' ); - } - - $bind_variables = array( - "", - "", - $username, - $password, - "", - $project_path, - "admin", - "", - "" - ); - $query = "INSERT INTO users(first_name, last_name, username, password, email, project, access, groups, token) VALUES (?,?,?,?,?,?,?,?,?)"; - $statement = $connection->prepare( $query ); - $statement->execute( $bind_variables ); - $error = $statement->errorInfo(); - - if( ! $error[0] == "00000" ) { - - die( '{"message":"Could not create user in database.","error":"' . addslashes(json_encode( $error )) .'"}' ); - } - - - /** - * Create sessions path. - */ - - if ( ! is_dir( $sessions ) ) { - - mkdir( $sessions, 00755 ); - } - - ////////////////////////////////////////////////////////////////// - // Create Active file - ////////////////////////////////////////////////////////////////// - - saveJSON( $active, array( '' ) ); - - ////////////////////////////////////////////////////////////////// - // Create Config - ////////////////////////////////////////////////////////////////// - - - $config_data = '