diff --git a/.env.example b/.env.example index f720f0b1c..2c91c78fb 100644 --- a/.env.example +++ b/.env.example @@ -12,6 +12,15 @@ EXTENSION_DEVELOPER_MODE=false QUEUE_DRIVER=database NAV_EXTENSION_HIDE_COUNT=10 BRAND_NAME="Havelsan © 2020" + +MAIL_ENABLED=false +MAIL_MAILER=smtp +MAIL_HOST=smtp.mailtrap.io +MAIL_PORT=2525 +MAIL_USERNAME= +MAIL_PASSWORD= +MAIL_ENCRYPTION=tls + MARKET_URL=https://market.liman.dev MARKET_CLIENT_ID= MARKET_CLIENT_SECRET= \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 67716ad44..8345a3add 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -16,6 +16,8 @@ jobs: repository: limanmys/php-sandbox path: package/liman/sandbox/php token: ${{ secrets.CI_TOKEN }} + ref: "1.4-dev" + - uses: actions/cache@v2 with: path: ~/.npm @@ -39,22 +41,6 @@ jobs: key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: | ${{ runner.os }}-composer- - - name: Create Docs - run: | - sudo apt install npm -y - cd package/liman/server/ - npm install - npm run docs - echo "api.liman.dev" > storage/docs/CNAME - - name: Push Docs to APIDOCS Repository - uses: cpina/github-action-push-to-another-repository@master - env: - API_TOKEN_GITHUB: ${{ secrets.CI_TOKEN }} - with: - source-directory: 'package/liman/server/storage/docs' - destination-github-username: 'limanmys' - destination-repository-name: 'apidocs' - user-email: mcelen94@gmail.com - name: Set up Liman Environment uses: shivammathur/setup-php@v2 with: @@ -97,7 +83,7 @@ jobs: Architecture: amd64 Priority: important Description: Liman MYS - Depends: gpg, zip, unzip, dnsutils, nginx, redis, php-redis, php7.3-fpm, php7.3-curl, php7.3, php7.3-sqlite3, php7.3-ldap, php7.3-snmp, php7.3-mbstring, php7.3-xml, php7.3-zip, php7.3-ssh2, php7.3-posix, libnginx-mod-http-headers-more-filter, php7.3-smbclient, krb5-user, smbclient, libssl1.1, acl, novnc, supervisor, expect, php-mongodb, php7.3-gd, rsyslog, python3.7, python3-jinja2, python3-requests, python3-crypto, python3-paramiko, python3-tornado + Depends: gpg, zip, unzip, nginx, redis, php-redis, php7.3-fpm, php7.3-curl, php7.3, php7.3-sqlite3, php7.3-snmp, php7.3-mbstring, php7.3-xml, php7.3-zip, php7.3-posix, libnginx-mod-http-headers-more-filter, libssl1.1, supervisor """ > DEBIAN/control cd ../ dpkg-deb -Zgzip --build package diff --git a/app/Connectors/GenericConnector.php b/app/Connectors/GenericConnector.php new file mode 100644 index 000000000..300ca6757 --- /dev/null +++ b/app/Connectors/GenericConnector.php @@ -0,0 +1,126 @@ +server = $server; + $this->user = $user; + } + + public function execute($command) + { + return trim( + self::request('runCommand', [ + "command" => $command, + ]) + ); + } + + public function sendFile($localPath, $remotePath, $permissions = 0644) + { + return trim( + self::request('putFile', [ + "localPath" => $localPath, + "remotePath" => $remotePath, + ]) + ); + } + + public function receiveFile($localPath, $remotePath) + { + return trim( + self::request('getFile', [ + "localPath" => $localPath, + "remotePath" => $remotePath, + ]) + ); + } + + public function runScript($script, $parameters, $runAsRoot = false) + { + return trim( + self::request('getFile', [ + "script" => $script, + "parameters" => $parameters, + "runAsRoot" => $runAsRoot, + ]) + ); + $remotePath = "/tmp/" . Str::random(); + + $this->sendFile($script, $remotePath); + $output = $this->execute("[ -f '$remotePath' ] && echo 1 || echo 0"); + if ($output != "1") { + abort(504, "Betik gönderilemedi"); + } + $this->execute("chmod +x " . $remotePath); + + // Run Part Of The Script + $query = $runAsRoot ? sudo() : ''; + $query = $query . $remotePath . " " . $parameters . " 2>&1"; + $output = $this->execute($query); + + return $output; + } + + public function verify($ip_address, $username, $password, $port, $type) + { + return trim( + self::request('verify', [ + "ip_address" => $ip_address, + "username" => $username, + "password" => $password, + "port" => $port, + "keyType" => $type, + ]) + ); + } + + public function create( + \App\Models\Server $server, + $username, + $password, + $user_id, + $key, + $port = null + ) { + } + + public function request($url, $params, $retry = 3) + { + $client = new Client(['verify' => false]); + + if ($this->server != null) { + $params["server_id"] = $this->server->id; + } + + if ($this->user == null) { + $params["token"] = Token::create(user()->id); + } else { + $params["token"] = Token::create($this->user->id); + } + + try { + $response = $client->request( + 'POST', + "https://127.0.0.1:5454/$url", + [ + "form_params" => $params, + ] + ); + return $response->getBody()->getContents(); + } catch (GuzzleException $exception) { + return $exception->getMessage(); + } + $json = json_decode((string) $res->getBody()); + return $json->output; + } +} diff --git a/app/Connectors/SNMPConnector.php b/app/Connectors/SNMPConnector.php index 58e90b74c..2d376fb5a 100644 --- a/app/Connectors/SNMPConnector.php +++ b/app/Connectors/SNMPConnector.php @@ -34,13 +34,14 @@ class SNMPConnector implements Connector */ public function __construct(\App\Models\Server $server, $user_id) { + list($username, $password, $port) = self::retrieveCredentials(); $this->server = $server; - $this->username = $this->getCredential("username"); - $this->securityLevel = $this->getCredential("SNMPsecurityLevel"); - $this->authProtocol = $this->getCredential("SNMPauthProtocol"); - $this->authPassword = $this->getCredential("SNMPauthPassword"); - $this->privacyProtocol = $this->getCredential("SNMPprivacyProtocol"); - $this->privacyPassword = $this->getCredential("SNMPprivacyPassword"); + $this->username = $username; + $this->securityLevel = 'authPriv'; + $this->authProtocol = 'SHA'; + $this->authPassword = $password; + $this->privacyProtocol = 'AES'; + $this->privacyPassword = $password; } public function execute($command, $flag = true) @@ -102,25 +103,18 @@ public static function createSnmp() return true; } - public static function verifySnmp( - $ip_address, - $username, - $securityLevel, - $authProtocol, - $authPassword, - $privacyProtocol, - $privacyPassword - ) { + public static function verifySnmp($ip_address, $username, $authPassword) + { foreach (SNMPConnector::$verifyCommands as $command) { try { $flag = snmp3_get( $ip_address, $username, - $securityLevel, - $authProtocol, + 'authPriv', + 'SHA', + $authPassword, + 'DES', $authPassword, - $privacyProtocol, - $privacyPassword, $command ); } catch (\Exception $e) { @@ -129,28 +123,27 @@ public static function verifySnmp( } if (isset($flag)) { - return respond("SNMP bağlantısı doğrulandı.", 200); + return "ok"; } - return respond( - "$username,$securityLevel,$authProtocol,$authPassword,$privacyProtocol,$privacyPassword,$ip_address", - 201 - ); - return isset($flag); + return "nok"; } - private function getCredential($name) + public static function retrieveCredentials() { - $object = UserSettings::where([ - 'user_id' => user()->id, - 'server_id' => server()->id, - 'name' => $name, - ])->first(); - if (!$object) { + if (server()->key() == null) { abort( 504, "Bu sunucu için SNMP anahtarınız yok. Kasa üzerinden bir anahtar ekleyebilirsiniz." ); } - return lDecrypt($object["value"]); + $data = json_decode(server()->key()->data, true); + + return [ + lDecrypt($data["clientUsername"]), + lDecrypt($data["clientPassword"]), + array_key_exists("key_port", $data) + ? intval($data["key_port"]) + : 161, + ]; } } diff --git a/app/Connectors/SSHCertificateConnector.php b/app/Connectors/SSHCertificateConnector.php deleted file mode 100644 index 314279c20..000000000 --- a/app/Connectors/SSHCertificateConnector.php +++ /dev/null @@ -1,171 +0,0 @@ -ip_address, - $server->key_port ? $server->key_port : 22 - ); - return true; - } - - public function execute($command, $flag = true) - { - return trim($this->shell->exec($command)); - } - - /** - * @param $script - * @param $parameters - * @param null $extra - * @return string - */ - public function runScript($script, $parameters, $runAsRoot = false) - { - $remotePath = "/tmp/" . Str::random(); - - $this->sendFile($script, $remotePath); - $output = $this->execute("[ -f '$remotePath' ] && echo 1 || echo 0"); - if ($output != "1") { - abort(504, "Betik gönderilemedi"); - } - $this->execute("chmod +x " . $remotePath); - - // Run Part Of The Script - $query = $runAsRoot ? sudo() : ''; - $query = $query . $remotePath . " " . $parameters . " 2>&1"; - $output = $this->execute($query); - - return $output; - } - - public function sendFile($localPath, $remotePath, $permissions = 0644) - { - if ($this->sftp == null) { - $sftp = new SFTP(server()->ip_address, server()->key_port); - list($username, $password) = self::retrieveCredentials(); - if (!$sftp->login($username, $password)) { - return false; - } - - $this->sftp = $sftp; - } - return $this->sftp->put( - $remotePath, - $localPath, - SFTP::SOURCE_LOCAL_FILE - ); - } - - public static function verify($ip_address, $username, $password, $port) - { - $ssh = new SSH2($ip_address, $port); - $key = new RSA(); - $key->loadKey($password); - if (!$ssh->login($username, $key)) { - return respond( - "Bu Kullanıcı adı ve anahtar ile bağlanılamadı.", - 201 - ); - } - - return respond("Kullanıcı adı ve anahtar doğrulandı.", 200); - } - - public function receiveFile($localPath, $remotePath) - { - if ($this->sftp == null) { - $sftp = new SFTP(server()->ip_address); - list($username, $password) = self::retrieveCredentials(); - if (!$sftp->login($username, $password)) { - return false; - } - - $this->sftp = $sftp; - } - - return $this->sftp->get($remotePath, $localPath); - } - - public static function create( - \App\Models\Server $server, - $username, - $password, - $user_id, - $key, - $port = null - ) { - return true; - } - - public function retrieveCredentials() - { - $username = UserSettings::where([ - 'user_id' => user()->id, - 'server_id' => server()->id, - 'name' => 'clientUsername', - ])->first(); - $password = UserSettings::where([ - 'user_id' => user()->id, - 'server_id' => server()->id, - 'name' => 'clientPassword', - ])->first(); - - if (!$username || !$password) { - abort( - 504, - "Bu sunucu için SSH anahtarınız yok. Kasa üzerinden bir anahtar ekleyebilirsiniz." - ); - } - - return [lDecrypt($username["value"]), lDecrypt($password["value"])]; - } - - public function init( - $username, - $password, - $hostname, - $port = 22, - $putSession = true - ) { - $ssh = new SSH2($hostname, $port); - $key = new RSA(); - $key->loadKey($password); - if (!$ssh->login($username, $key)) { - return false; - } - $this->shell = $ssh; - - return true; - } -} diff --git a/app/Connectors/SSHConnector.php b/app/Connectors/SSHConnector.php deleted file mode 100644 index b249c0bfb..000000000 --- a/app/Connectors/SSHConnector.php +++ /dev/null @@ -1,247 +0,0 @@ -id)->exists()) { - list($username, $password) = self::retrieveCredentials(); - self::init( - $username, - $password, - $server->ip_address, - $server->key_port ? $server->key_port : 22 - ); - } - - return true; - } - - public function execute($command, $flag = true) - { - return trim( - self::request('run', [ - "token" => "cn_" . server()->id, - "command" => $command, - ]) - ); - } - - /** - * @param $script - * @param $parameters - * @param null $extra - * @return string - */ - public function runScript($script, $parameters, $runAsRoot = false) - { - $remotePath = "/tmp/" . Str::random(); - - $this->sendFile($script, $remotePath); - $output = $this->execute("[ -f '$remotePath' ] && echo 1 || echo 0"); - if ($output != "1") { - abort(504, "Betik gönderilemedi"); - } - $this->execute("chmod +x " . $remotePath); - - // Run Part Of The Script - $query = $runAsRoot ? sudo() : ''; - $query = $query . $remotePath . " " . $parameters . " 2>&1"; - $output = $this->execute($query); - - return $output; - } - - public function sendFile($localPath, $remotePath, $permissions = 0644) - { - $output = self::request('send', [ - "token" => ConnectorToken::get(server()->id)->first()->token, - "local_path" => $localPath, - "remote_path" => $remotePath, - ]); - $check = $this->execute("[ -f '$remotePath' ] && echo 1 || echo 0"); - if ($check != "1") { - abort(504, "Dosya gönderilemedi"); - } - return $output; - } - - public static function verify($ip_address, $username, $password, $port) - { - $token = self::init($username, $password, $ip_address, $port, false); - if ($token) { - return respond("Kullanıcı adı ve şifre doğrulandı.", 200); - } - return respond("Bu Kullanıcı adı ve şifre ile bağlanılamadı.", 201); - } - - public function receiveFile($localPath, $remotePath) - { - return self::request('get', [ - "token" => ConnectorToken::get(server()->id)->first()->token, - "local_path" => $localPath, - "remote_path" => $remotePath, - ]); - } - - /** - * @param \App\Models\Server $server - * @param $username - * @param $password - * @param $user_id - * @param $key - * @return bool - */ - public static function create( - \App\Models\Server $server, - $username, - $password, - $user_id, - $key, - $port = null - ) { - $token = self::init( - $username, - $password, - $server->ip_address, - $port ? $port : 22 - ); - if ($token) { - return true; - } else { - return false; - } - } - - public static function retrieveCredentials() - { - $username = UserSettings::where([ - 'user_id' => user()->id, - 'server_id' => server()->id, - 'name' => 'clientUsername', - ])->first(); - $password = UserSettings::where([ - 'user_id' => user()->id, - 'server_id' => server()->id, - 'name' => 'clientPassword', - ])->first(); - - if (!$username || !$password) { - abort( - 504, - "Bu sunucu için SSH anahtarınız yok. Kasa üzerinden bir anahtar ekleyebilirsiniz." - ); - } - - return [lDecrypt($username["value"]), lDecrypt($password["value"])]; - } - - public static function request($url, $params, $retry = 3) - { - if (!ConnectorToken::get(server()->id)->exists()) { - list($username, $password) = self::retrieveCredentials(); - self::init( - $username, - $password, - server()->ip_address, - server()->key_port ? server()->key_port : 22 - ); - } - // Create Guzzle Object. - $client = new Client(); - // Make Request. - try { - $params["token"] = ConnectorToken::get( - server()->id - )->first()->token; - $res = $client->request('POST', 'http://127.0.0.1:5000/' . $url, [ - "form_params" => $params, - ]); - } catch (BadResponseException $e) { - // In case of error, handle error. - $json = json_decode( - (string) $e - ->getResponse() - ->getBody() - ->getContents() - ); - // If it's first time, retry after recreating ticket. - if ($retry) { - list($username, $password) = self::retrieveCredentials(); - self::init( - $username, - $password, - server()->ip_address, - server()->key_port ? server()->key_port : 22 - ); - return self::request($url, $params, $retry - 1); - } else { - // If nothing works, abort. - abort(402, "Anahtarınız ile sunucuya giriş yapılamadı"); - } - } - // Simply parse and return output. - $json = json_decode((string) $res->getBody()); - return $json->output; - } - - public static function init( - $username, - $password, - $hostname, - $port, - $putSession = true - ) { - $client = new Client(); - try { - $res = $client->request('POST', 'http://127.0.0.1:5000/new', [ - 'form_params' => [ - "username" => $username, - "password" => $password, - "hostname" => $hostname, - "port" => $port, - "connection_type" => "ssh", - ], - 'timeout' => 5, - ]); - } catch (\Exception $e) { - return null; - } - $json = json_decode((string) $res->getBody()); - //Escape For . character in session. - if ($putSession) { - if (auth() && auth()->user()) { - ConnectorToken::set($json->token, server()->id); - } - } - - return $json->token; - } -} diff --git a/app/Connectors/SSHTunnelConnector.php b/app/Connectors/SSHTunnelConnector.php deleted file mode 100644 index f6dcb1861..000000000 --- a/app/Connectors/SSHTunnelConnector.php +++ /dev/null @@ -1,82 +0,0 @@ -exists()) { - $tunnel = TunnelToken::get($remote_host, $remote_port)->first(); - if (checkPort("127.0.0.1", $tunnel->local_port)) { - return $tunnel->local_port; - } - } - $req = self::request("new", [ - "connection_type" => "ssh_tunnel", - "username" => $username, - "password" => $password, - "hostname" => $remote_host, - "remote_port" => $remote_port, - ]); - $token_parse = explode(':', $req->token); - TunnelToken::set( - $token_parse[0], - $token_parse[1], - $remote_host, - $remote_port - ); - return $token_parse[1]; - } - - public static function stop($remote_host, $remote_port) - { - if (TunnelToken::get($remote_host, $remote_port)->exists()) { - $tunnel = TunnelToken::get($remote_host, $remote_port)->first(); - TunnelToken::remove($tunnel->token); - self::request("stop", [ - "token" => $tunnel->token . ":" . $tunnel->local_port, - ]); - return true; - } - return null; - } - - public static function request($url, $params, $retry = 3) - { - // Create Guzzle Object. - $client = new Client(); - // Make Request. - try { - $res = $client->request('POST', 'http://127.0.0.1:5000/' . $url, [ - "form_params" => $params, - ]); - } catch (BadResponseException $e) { - // In case of error, handle error. - $json = json_decode( - (string) $e - ->getResponse() - ->getBody() - ->getContents() - ); - // If it's first time, retry after recreating ticket. - if ($retry) { - return self::request($url, $params, $retry - 1); - } else { - // If nothing works, abort. - abort(402, "Tünel işlemleri sırasında bir hata oluştu."); - } - } - // Simply parse and return output. - $json = json_decode((string) $res->getBody()); - return $json; - } -} diff --git a/app/Connectors/WinRMConnector.php b/app/Connectors/WinRMConnector.php deleted file mode 100755 index 47ff8c474..000000000 --- a/app/Connectors/WinRMConnector.php +++ /dev/null @@ -1,202 +0,0 @@ -id)->exists()) { - list($username, $password) = self::retrieveCredentials(); - self::init($username, $password, $server->ip_address); - } - return true; - } - - public static function retrieveCredentials() - { - $username = UserSettings::where([ - 'user_id' => user()->id, - 'server_id' => server()->id, - 'name' => 'clientUsername', - ])->first(); - $password = UserSettings::where([ - 'user_id' => user()->id, - 'server_id' => server()->id, - 'name' => 'clientPassword', - ])->first(); - - if (!$username || !$password) { - abort( - 504, - "Bu sunucu için WinRM anahtarınız yok. Kasa üzerinden bir anahtar ekleyebilirsiniz." - ); - } - - $key = env('APP_KEY') . user()->id . server()->id; - return [AES256::decrypt($username["value"],$key), AES256::decrypt($password["value"],$key)]; - } - - public function execute($command) - { - // Prepare Powershell Command - $command = - "powershell.exe -encodedCommand " . - base64_encode( - mb_convert_encoding( - "\$ProgressPreference = \"SilentlyContinue\"; " . $command, - "UTF-16LE", - "UTF-8" - ) - ); - return trim( - self::request('run', [ - "token" => "cn_" . server()->id, - "command" => $command, - ]) - ); - } - - public static function request($url, $params, $retry = 3) - { - if (!ConnectorToken::get(server()->id)->exists()) { - list($username, $password) = self::retrieveCredentials(); - self::init($username, $password, server()->id); - } - // Create Guzzle Object. - $client = new Client(); - // Make Request. - - try { - $params["token"] = ConnectorToken::get( - server()->id - )->first()->token; - $res = $client->request('POST', 'http://127.0.0.1:5000/' . $url, [ - "form_params" => $params, - 'timeout' => 5, - ]); - } catch (\Exception $e) { - // In case of error, handle error. - $json = json_decode( - (string) $e - ->getResponse() - ->getBody() - ->getContents() - ); - - // If it's first time, retry after recreating ticket. - if ($retry) { - list($username, $password) = self::retrieveCredentials(); - self::init($username, $password, server()->ip_address); - return self::request($url, $params, $retry - 1); - } else { - // If nothing works, abort. - abort(402, "Anahtarınız ile sunucuya giriş yapılamadı."); - } - } - - // Simply parse and return output. - $json = json_decode((string) $res->getBody()); - return $json->output; - } - - public function sendFile($localPath, $remotePath, $permissions = 0644) - { - return self::request('send', [ - "token" => ConnectorToken::get(server()->id)->first()->token, - "local_path" => $localPath, - "remote_path" => $remotePath, - ]); - } - - public function receiveFile($localPath, $remotePath) - { - return self::request('get', [ - "token" => ConnectorToken::get(server()->id)->first()->token, - "local_path" => $localPath, - "remote_path" => $remotePath, - ]); - } - - public function runScript($script, $parameters, $runAsRoot = false) - { - // Find Remote Path - $remotePath = "\\Windows\\Temp\\" . Str::random() . ".ps1"; - - $flag = $this->sendFile($script, $remotePath); - - // Find Out Letter. DISABLED FOR NOW - // $letter = $this->execute("\$pwd.drive.name"); - - // $letter = substr($letter,0, -2); - - $query = "C:\\" . $remotePath . " " . $parameters; - - $output = $this->execute($query); - - return $output; - } - - public static function verify($ip_address, $username, $password, $port) - { - $token = self::init($username, $password, $ip_address, false); - if ($token) { - return respond("Kullanıcı adı ve şifre doğrulandı.", 200); - } - return respond("Bu Kullanıcı adı ve şifre ile bağlanılamadı.", 201); - } - - public static function init( - $username, - $password, - $hostname, - $putSession = true - ) { - $client = new Client(); - try { - $res = $client->request('POST', 'http://127.0.0.1:5000/new', [ - 'form_params' => [ - "username" => $username, - "password" => $password, - "hostname" => $hostname, - "connection_type" => "winrm", - ], - 'timeout' => 5, - ]); - } catch (\Exception $e) { - return null; - } - - $json = json_decode((string) $res->getBody()); - if ($putSession) { - if (auth() && auth()->user()) { - ConnectorToken::set($json->token, server()->id); - } - } - - return $json->token; - } - - public static function create( - Server $server, - $username, - $password, - $user_id, - $key, - $port = null - ) { - $token = self::init($username, $password, $server->ip_address); - if ($token) { - return true; - } else { - return false; - } - } -} diff --git a/app/Events/ExtensionRendered.php b/app/Events/ExtensionRendered.php deleted file mode 100644 index 9d66c6fba..000000000 --- a/app/Events/ExtensionRendered.php +++ /dev/null @@ -1,45 +0,0 @@ -data = $data; - $this->user_id = $user_id; - } - - /** - * Get the channels the event should broadcast on. - * - * @return \Illuminate\Broadcasting\Channel|array - */ - public function broadcastOn() - { - return new PrivateChannel('extension_renderer_' . $this->user_id); - } - - public function broadcastWith() - { - return ['data' => $this->data]; - } -} diff --git a/app/Http/Controllers/Extension/MainController.php b/app/Http/Controllers/Extension/MainController.php index eae813019..93a408db0 100644 --- a/app/Http/Controllers/Extension/MainController.php +++ b/app/Http/Controllers/Extension/MainController.php @@ -14,7 +14,9 @@ use Illuminate\View\View; use Illuminate\Support\Facades\Validator; use App\Jobs\ExtensionUpdaterJob; +use App\Jobs\ExtensionDependenciesJob; use Illuminate\Contracts\Bus\Dispatcher; +use App\Models\AdminNotification; /** * Class MainController @@ -221,9 +223,35 @@ public function setupNewExtension($zipFile, $verify = false) } else { $new = new Extension(); } + $new->fill($json); + $new->status = "1"; $new->save(); + if (array_key_exists("dependencies",$json) && $json["dependencies"] != ""){ + $job = (new ExtensionDependenciesJob( + $new, + $json["dependencies"] + ))->onQueue('system_updater'); + + // Dispatch job right away. + $job_id = app(Dispatcher::class)->dispatch($job); + + AdminNotification::create([ + "title" => + $new->display_name . " eklentisinin bağımlılıkları yükleniyor!", + "type" => "", + "message" => + $new->display_name . + " eklentisinin bağımlılıkları yükleniyor, bu süre içerisinde eklentiyi kullanamazsınız.", + "level" => 3, + ]); + $new->update([ + "status" == "0" + ]); + $new->save(); + } + $system = rootSystem(); $system->userAdd($new->id); @@ -355,6 +383,7 @@ public function autoUpdateExtension() request("extension_id"), $obj["versionCode"], $obj["downloadLink"], + $obj["hashSHA512"], true ))->onQueue('system_updater'); diff --git a/app/Http/Controllers/Extension/OneController.php b/app/Http/Controllers/Extension/OneController.php index 0e8d657c5..7d3dec895 100644 --- a/app/Http/Controllers/Extension/OneController.php +++ b/app/Http/Controllers/Extension/OneController.php @@ -91,10 +91,10 @@ public function serverSettings() $extension["verification"] != null && $extension["verification"] != "" ) { - $client = new Client(); + $client = new Client(['verify' => false]); $result = ""; try { - $res = $client->request('POST', 'http://127.0.0.1:5454/', [ + $res = $client->request('POST', 'https://127.0.0.1:5454/', [ 'form_params' => [ "lmntargetFunction" => $extension["verification"], "extension_id" => extension()->id, @@ -161,9 +161,13 @@ public function serverSettingsPage() "extension_id" => extension()->id, ]); $similar = []; - foreach ($extension["database"] as $item) { - if (strpos(strtolower($item["variable"]), "password")) { - continue; + $flag = server()->key(); + foreach ($extension["database"] as $key => $item) { + if ( + ($flag != null && $item["variable"] == "clientUsername") || + ($flag != null && $item["variable"] == "clientPassword") + ) { + unset($extension["database"][$key]); } $obj = DB::table("user_settings") ->where([ @@ -201,6 +205,7 @@ public function serverSettingsPage() */ public function remove() { + $ext_name = extension()->name; hook('extension_delete_attempt', extension()); try { shell_exec( @@ -219,6 +224,16 @@ public function remove() "request" => request()->all(), ]); + if(is_file(storage_path("extension_updates"))){ + $json = json_decode(file_get_contents(storage_path("extension_updates")),true); + for($i = 0; $i < count($json); $i++){ + if($json[$i]["name"] == $ext_name){ + unset($json[$i]); + } + } + file_put_contents(storage_path("extension_updates"),json_encode($json)); + } + system_log(3, "EXTENSION_REMOVE"); return respond('Eklenti Başarıyla Silindi'); } diff --git a/app/Http/Controllers/Extension/Sandbox/InternalController.php b/app/Http/Controllers/Extension/Sandbox/InternalController.php index 2641a51d1..ebe092c97 100644 --- a/app/Http/Controllers/Extension/Sandbox/InternalController.php +++ b/app/Http/Controllers/Extension/Sandbox/InternalController.php @@ -2,11 +2,9 @@ namespace App\Http\Controllers\Extension\Sandbox; -use App\Connectors\SSHTunnelConnector; use App\Models\Extension; use App\Http\Controllers\Controller; use App\Models\JobHistory; -use App\Jobs\ExtensionJob; use App\Models\Notification; use App\Models\Permission; use App\Models\Server; @@ -15,7 +13,6 @@ use Illuminate\Support\Facades\Log; use Illuminate\Http\Request; use Illuminate\Support\Str; -use App\Events\ExtensionRendered; use GuzzleHttp\Client; class InternalController extends Controller @@ -27,310 +24,6 @@ public function __construct() } } - /** - * @api {post} /lmn/private/dispatchJob Dispatch Background Job - * @apiName SandboxDispatchJob - * @apiGroup Sandbox - * - * @apiParam {String} function_name Target function name to run - * @apiParam {Array} parameters Parameters to use in function. - * @apiParam {String} server_id Target Server Id - * @apiParam {String} extension_id Target Extension Id - * @apiParam {String} token Authenticated User Token - * - * @apiSuccess {String} result Simply returns ok string. - */ - public function dispatchJob() - { - // Create a new object - $history = new JobHistory([ - "status" => "0", - "user_id" => user()->id, - "server_id" => server()->id, - "extension_id" => extension()->id, - "job" => request('function_name'), - ]); - - // Save it into database - $history->save(); - - // Create job to work on. - $job = (new ExtensionJob( - $history, - server(), - extension(), - user(), - request('function_name'), - request('parameters') - ))->onQueue('extension_queue'); - - // Dispatch job right away. - $job_id = app(Dispatcher::class)->dispatch($job); - - // Update job with it's id. - $history->job_id = $job_id; - $history->save(); - - return "ok"; - } - - /** - * @api {post} /lmn/private/getJobList Get List and Status of Background Processes - * @apiName SandboxGetJobList - * @apiGroup Sandbox - * - * @apiParam {String} function_name Target function to check - * @apiParam {String} server_id Target Server Id - * @apiParam {String} extension_id Target Extension Id - * @apiParam {String} token Authenticated User Token - * - * @apiSuccess {Array} json hold, success, fail and total counts. - */ - public function getJobList() - { - // Retrieve Objects by function_name - $all = JobHistory::where([ - "user_id" => user()->id, - "extension_id" => extension()->id, - "server_id" => server()->id, - "job" => request('function_name'), - ])->get('status'); - - // Simply sum up the counts - $holdCount = $all->where('status', 0)->count(); - $successCount = $all->where('status', 1)->count(); - $failCount = $all->where('status', 2)->count(); - - // Return everything. - return json_encode([ - "hold" => $holdCount, - "success" => $successCount, - "fail" => $failCount, - "total" => $all->count(), - ]); - } - - public function internalExtensions() - { - $extension = Extension::where([ - "name" => request("target_extension_name"), - ])->first(); - if (!$extension) { - return false; - } - - $server = Server::where(["id" => request("target_server_id")])->first(); - if (!$server) { - return false; - } - - $newRequestData = [ - "extension_id" => $extension->id, - "extension" => $extension, - "server" => $server, - "server_id" => $server->id, - ]; - - $newRequestData = array_merge( - $newRequestData, - json_decode(request('extra_params'), true) - ); - request()->merge($newRequestData); - $controller = new MainController(); - $controller->initializeClass(); - return $controller->API(); - } - - /** - * @api {post} /lmn/private/runCommandApi Run command on the server - * @apiName SandboxRunCommand - * @apiGroup Sandbox - * - * @apiParam {String} command Command to run. - * @apiParam {String} server_id Target Server Id - * @apiParam {String} extension_id Target Extension Id - * @apiParam {String} token Authenticated User Token - * - * @apiSuccess {String} output Output of the command. - */ - public function runCommand() - { - // Execute the command - request()->request->add(['server' => server()]); - $output = server()->run(request('command')); - - system_log(7, "EXTENSION_INTERNAL_RUN_COMMAND", [ - "extension_id" => extension()->id, - "server_id" => server()->id, - ]); - system_log(6, server()->id . ":" . "Komut Çalıştırma"); - - return $output; - } - - /** - * @api {post} /lmn/private/runScriptApi Run script on the server - * @apiName SandboxRunScript - * @apiGroup Sandbox - * - * @apiParam {String} scriptName Script to run (inside scripts folder) - * @apiParam {String} parameters Parameters as string -cli style- - * @apiParam {String} runAsRoot If you wish to run script as root, simply send yes - * @apiParam {String} server_id Target Server Id - * @apiParam {String} extension_id Target Extension Id - * @apiParam {String} token Authenticated User Token - * - * @apiSuccess {String} output Output of the script. - */ - public function runScript() - { - $filePath = - "/liman/extensions/" . - strtolower(extension()->name) . - "/scripts/" . - request("scriptName"); - if (!is_file($filePath)) { - system_log(7, "EXTENSION_INTERNAL_RUN_SCRIPT_FAILED_NOT_FOUND", [ - "extension_id" => extension()->id, - "server_id" => request('server_id'), - ]); - return "Betik Bulunamadi"; - } - - if ( - server()->type != "linux_ssh" && - server()->type != "linux_certificate" && - server()->type != "windows_powershell" - ) { - system_log(7, "EXTENSION_INTERNAL_RUN_COMMAND_FAILED", [ - "extension_id" => extension()->id, - "server_id" => request('server_id'), - ]); - return "Bu sunucuda komut çalıştıramazsınız."; - } - - $output = server()->runScript( - $filePath, - request("parameters"), - request("runAsRoot") == "yes" ? true : false - ); - - system_log(7, "EXTENSION_INTERNAL_RUN_COMMAND", [ - "extension_id" => extension()->id, - "server_id" => server()->id, - ]); - - return $output; - } - - /** - * @api {post} /lmn/private/putFileApi Send file to the server. - * @apiName SandboxPutFile - * @apiGroup Sandbox - * - * @apiParam {String} localPath Local full file path. - * @apiParam {String} remotePath Remote full file path you wish. - * @apiParam {String} server_id Target Server Id - * @apiParam {String} extension_id Target Extension Id - * @apiParam {String} token Authenticated User Token - * - * @apiSuccess {String} output ok or no according to status. - */ - public function putFile() - { - $output = server()->putFile( - request('localPath'), - request('remotePath') - ); - - system_log(7, "EXTENSION_INTERNAL_SEND_FILE", [ - "extension_id" => extension()->id, - "server_id" => server()->id, - "file_name" => request('remotePath'), - ]); - - return $output ? "ok" : "no"; - } - - /** - * @api {post} /lmn/private/getFileApi Receive file from the server. - * @apiName SandboxGetFile - * @apiGroup Sandbox - * - * @apiParam {String} localPath Local full file path. - * @apiParam {String} remotePath Remote full file path. - * @apiParam {String} server_id Target Server Id - * @apiParam {String} extension_id Target Extension Id - * @apiParam {String} token Authenticated User Token - * - * @apiSuccess {String} output ok or no according to status. - */ - public function getFile() - { - $output = server()->getFile( - request('remotePath'), - request('localPath') - ); - - // Update Permissions - rootSystem()->fixExtensionPermissions( - extension()->id, - extension()->name - ); - - system_log(7, "EXTENSION_INTERNAL_RECEIVE_FILE", [ - "extension_id" => extension()->id, - "server_id" => server()->id, - "file_name" => request('remotePath'), - ]); - - return $output ? "ok" : "no"; - } - - /** - * @api {post} /lmn/private/openTunnel OpenSSH Tunnel Request - * @apiName SandboxOpenSSHTunnel - * @apiGroup Sandbox - * - * @apiParam {String} remote_host server host you wish to tunnel. - * @apiParam {String} remote_port server port you wish to tunnel. - * @apiParam {String} username server username you wish to tunnel. - * @apiParam {String} password server password you wish to tunnel. - * @apiParam {String} server_id Target Server Id - * @apiParam {String} extension_id Target Extension Id - * @apiParam {String} token Authenticated User Token - * - * @apiSuccess {String} token Tunnel token to close later on. - */ - public function openTunnel() - { - return SSHTunnelConnector::new( - request('remote_host'), - request('remote_port'), - request('username'), - request('password') - ); - } - - /** - * @api {post} /lmn/private/stopTunnel Close OpenSSH Tunnel - * @apiName SandboxStopSSHTunnel - * @apiGroup Sandbox - * - * @apiParam {String} remote_host server host you wish to tunnel. - * @apiParam {String} remote_port server port you wish to tunnel. - * @apiParam {String} server_id Target Server Id - * @apiParam {String} extension_id Target Extension Id - * @apiParam {String} token Authenticated User Token - */ - public function stopTunnel() - { - return SSHTunnelConnector::stop( - request('remote_host'), - request('remote_port') - ); - } - public function sendNotification() { Notification::new( @@ -340,20 +33,6 @@ public function sendNotification() ); } - public function sendLog() - { - $client = new Client(); - $client->request('POST', 'http://127.0.0.1:5454/sendLog', [ - 'form_params' => [ - 'log_id' => request('log_id'), - 'message' => base64_encode(request('message')), - 'title' => base64_encode(request('title')), - 'token' => Token::create(user()->id), - ], - ]); - return "🤓"; - } - /** * @api {post} /lmn/private/reverseProxyRequest Add Vnc Proxy Config * @apiName SandboxAddVncProxyConfig diff --git a/app/Http/Controllers/Extension/Sandbox/MainController.php b/app/Http/Controllers/Extension/Sandbox/MainController.php index bee78da78..933f03439 100644 --- a/app/Http/Controllers/Extension/Sandbox/MainController.php +++ b/app/Http/Controllers/Extension/Sandbox/MainController.php @@ -8,6 +8,7 @@ use App\Models\Permission; use App\Models\Server; use App\Models\Token; +use App\Models\ServerKey; use Carbon\Carbon; use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; @@ -31,23 +32,29 @@ public function initializeClass() $this->checkForMissingSettings(); $this->checkPermissions(); - - $this->sandbox = sandbox(); } public function API() { if (extension()->status == "0") { return respond( - "Eklenti şu an güncelleniyor, lütfen birazdan tekrar deneyin.", + __("Eklenti şu an güncelleniyor, lütfen birazdan tekrar deneyin."), + 201 + ); + } + + if (extension()->require_key == "true" && server()->key() == null) { + return respond( + __("Bu eklentiyi kullanabilmek için bir anahtara ihtiyacınız var, lütfen kasa üzerinden bir anahtar ekleyin."), 201 ); } + $page = request('target_function') ? request('target_function') : 'index'; $view = "extension_pages.server"; - + if (env('LIMAN_RESTRICTED') == true && !user()->isAdmin()) { $view = "extension_pages.server_restricted"; } @@ -64,11 +71,20 @@ public function API() private function checkForMissingSettings() { + $key = ServerKey::where([ + "server_id" => server()->id, + "user_id" => user()->id, + ])->first(); + $extra = []; + if ($key) { + $extra = ["clientUsername", "clientPassword"]; + } foreach ($this->extension["database"] as $setting) { if (isset($setting["required"]) && $setting["required"] === false) { continue; } if ( + !in_array($setting["variable"], $extra) && !UserSettings::where([ "user_id" => user()->id, "server_id" => server()->id, @@ -143,18 +159,6 @@ private function checkPermissions() return true; } - private function executeSandbox($function) - { - if (!isset($this->sandbox)) { - $this->initializeClass(); - } - $command = $this->sandbox->command($function); - - $random = str_random(16); - rootSystem()->runCommand(user()->id,$command,true,$random); - return $random; - } - private function getNavigationServers() { $navServers = DB::select( diff --git a/app/Http/Controllers/Extension/Sandbox/_routes.php b/app/Http/Controllers/Extension/Sandbox/_routes.php index bb7da65ad..a24fdc552 100644 --- a/app/Http/Controllers/Extension/Sandbox/_routes.php +++ b/app/Http/Controllers/Extension/Sandbox/_routes.php @@ -1,60 +1,10 @@ name('SandboxDispatchJob'); - -Route::post( - '/lmn/private/getJobList', - 'Extension\Sandbox\InternalController@getJobList' -)->name('SandboxGetJobList'); - -Route::post( - '/lmn/private/extensionApi', - 'Extension\Sandbox\InternalController@internalExtensions' -); - Route::post( '/lmn/private/sendNotification', 'Extension\Sandbox\InternalController@sendNotification' )->name('SandboxSendNotification'); -Route::post( - '/lmn/private/sendLog', - 'Extension\Sandbox\InternalController@sendLog' -)->name('SandboxSendLog'); - -Route::post( - '/lmn/private/runCommandApi', - 'Extension\Sandbox\InternalController@runCommand' -)->name('SandboxRunCommand'); - -Route::post( - '/lmn/private/runScriptApi', - 'Extension\Sandbox\InternalController@runScript' -)->name('SandboxRunScript'); - -Route::post( - '/lmn/private/putFileApi', - 'Extension\Sandbox\InternalController@putFile' -)->name('SandboxPutFile'); - -Route::post( - '/lmn/private/getFileApi', - 'Extension\Sandbox\InternalController@getFile' -)->name('SandboxGetFile'); - -Route::post( - '/lmn/private/openTunnel', - 'Extension\Sandbox\InternalController@openTunnel' -)->name('SandboxOpenSSHTunnel'); - -Route::post( - '/lmn/private/stopTunnel', - 'Extension\Sandbox\InternalController@stopTunnel' -)->name('SandboxStopSSHTunnel'); - Route::post( '/lmn/private/reverseProxyRequest', 'Extension\Sandbox\InternalController@addProxyConfig' diff --git a/app/Http/Controllers/Extension/SettingsController.php b/app/Http/Controllers/Extension/SettingsController.php index 0a639593a..564046227 100755 --- a/app/Http/Controllers/Extension/SettingsController.php +++ b/app/Http/Controllers/Extension/SettingsController.php @@ -50,8 +50,8 @@ public function addLicense() ); if ($license) { return respond("Lisans Eklendi"); - } else{ - return respond("Lisans Eklenemiyor!",201); + } else { + return respond("Lisans Eklenemiyor!", 201); } } @@ -62,11 +62,6 @@ public function addLicense() */ public function settings_one() { - // Go through all files and list them as tree style in array. - $files = $this->tree( - "/liman/extensions/" . strtolower(extension()->name) - ); - system_log(7, "EXTENSION_SETTINGS_PAGE", [ "extension_id" => extension()->_id, ]); @@ -94,54 +89,10 @@ public function settings_one() } // Return view with required parameters. return magicView('extension_pages.one', [ - "files" => $files, "extension" => getExtensionJson(extension()->name), ]); } - // Search through folders and extract pages. - - /** - * @param $path - * @return array - */ - private function tree($path) - { - // If file is not path, simply return. - if (!is_dir($path)) { - return []; - } - - // List files under path - $files = scandir($path); - - // Ignore linux filesystem' '.' and '..' files. - unset($files[0]); - unset($files[1]); - - // Remake array because of corrupted index. - $files = array_values($files); - - // Loop through each files - foreach ($files as $file) { - // Create full path of file. - $newPath = $path . DIRECTORY_SEPARATOR . $file; - - // If new path is directory, go through same process recursively. - if (is_dir($newPath)) { - // Run same process. - $files[$file] = $this->tree( - $path . DIRECTORY_SEPARATOR . $file - ); - - // Delete item from array since that's array not a file. - $index = array_search($file, $files); - unset($files[$index]); - } - } - return $files; - } - public function update() { $extension = json_decode( @@ -160,7 +111,9 @@ public function update() $extension["icon"] = request("icon"); $extension["service"] = request("service"); $extension["version"] = request("version"); + $extension["require_key"] = request("require_key"); $extension["verification"] = request("verification"); + $extension["dependencies"] = request("dependencies"); $extension["sslPorts"] = request("sslPorts"); $extension["supportedLiman"] = request("supportedLiman"); } else { @@ -637,7 +590,7 @@ public function removeFunction() public function getExtensionUpdates() { return respond( - json_decode(file_get_contents(storage_path('extension_updates'))) + array_values(json_decode(file_get_contents(storage_path('extension_updates')),true)) ); } } diff --git a/app/Http/Controllers/Extension/_routes.php b/app/Http/Controllers/Extension/_routes.php index 9dd580985..da00db7a8 100644 --- a/app/Http/Controllers/Extension/_routes.php +++ b/app/Http/Controllers/Extension/_routes.php @@ -8,12 +8,6 @@ ->name('extension_server') ->middleware(['server', 'extension']); -// Extension' Server' Home Route -// Route::get('/l/{extension_id}/{city}/{server_id}/{page?}', 'Extension\Sandbox\MainController@getAPI')->name('extension_server')->middleware(['server','extension']); - -// Extension Function Api -// Route::post('/eklenti2/{extension_id}/{function_name?}', 'Extension\Sandbox\MainController@postAPI')->name('extension_function_api')->middleware('server_api'); - // Extension Management Route Route::post('/extension/run/{unique_code}', 'Extension\OneController@route') ->name('extension_api') @@ -60,9 +54,9 @@ ->name('get_extension_updates') ->middleware('admin'); - Route::post( - '/ayarlar/eklentiGuncelle', - 'Extension\MainController@autoUpdateExtension' +Route::post( + '/ayarlar/eklentiGuncelle', + 'Extension\MainController@autoUpdateExtension' ) ->name('update_extension_auto') ->middleware('admin'); @@ -82,8 +76,8 @@ // Extension Upload Page Route::post('/ayarlar/eklentilisans', 'Extension\SettingsController@addLicense') -->name('add_extension_license') -->middleware('admin'); + ->name('add_extension_license') + ->middleware('admin'); Route::post( '/ayarlar/eklenti', diff --git a/app/Http/Controllers/HomeController.php b/app/Http/Controllers/HomeController.php index b05c15945..166bd8640 100644 --- a/app/Http/Controllers/HomeController.php +++ b/app/Http/Controllers/HomeController.php @@ -70,19 +70,19 @@ public function index() public function getLimanStats() { $cpuUsage = shell_exec( - "grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print \"%\" usage}'" + "ps -eo %cpu --no-headers | grep -v 0.0 | awk '{s+=$1} END {print s/NR*10}'" ); - $cpuUsage = substr($cpuUsage, 0, 5); + $cpuUsage = round($cpuUsage, 0, 2); $ramUsage = shell_exec("free -t | awk 'NR == 2 {printf($3/$2*100)}'"); - $ramUsage = substr($ramUsage, 0, 5); - $disk = shell_exec('df -h / | grep /'); - preg_match("/(\d+)%/", $disk, $diskUsage); + $ramUsage = round($ramUsage, 0, 2); + $diskUsage = shell_exec("df --output=pcent / | tr -dc '0-9'"); + $diskUsage = round($diskUsage, 0, 2); - $firstDown = self::calculateNetworkBytes(); - $firstUp = self::calculateNetworkBytes(false); + $firstDown = $this->calculateNetworkBytes(); + $firstUp = $this->calculateNetworkBytes(false); sleep(1); - $secondDown = self::calculateNetworkBytes(); - $secondUp = self::calculateNetworkBytes(false); + $secondDown = $this->calculateNetworkBytes(); + $secondUp = $this->calculateNetworkBytes(false); $network = strval(intval(($secondDown - $firstDown) / 1024 / 1024) / 2) . @@ -90,9 +90,9 @@ public function getLimanStats() strval(intval(($secondUp - $firstUp) / 1024 / 1024) / 2) . " mb/sn ↑"; return response([ - "cpu" => $cpuUsage, + "cpu" => "%" . $cpuUsage, "ram" => "%" . $ramUsage, - "disk" => "%" . $diskUsage[1], + "disk" => "%" . $diskUsage, "network" => $network, ]); } diff --git a/app/Http/Controllers/MarketController.php b/app/Http/Controllers/MarketController.php index 509ebae4c..3063c09ad 100644 --- a/app/Http/Controllers/MarketController.php +++ b/app/Http/Controllers/MarketController.php @@ -109,12 +109,12 @@ public function checkMarketUpdates($returnRaw = false) ->where('packageName', $params[$i]["packageName"]) ->first(); if (!$obj) { - $params[$i]["status"] = "Güncel"; + $params[$i]["status"] = __("Güncel"); $params[$i]["updateAvailable"] = 0; } else { $obj = json_decode(json_encode($obj), true); $params[$i]["status"] = - $obj["version"]["versionName"] . " sürümü mevcut"; + $obj["version"]["versionName"] . __(" sürümü mevcut"); $params[$i]["updateAvailable"] = 1; if ( $params[$i]["extension_id"] != null && @@ -123,7 +123,8 @@ public function checkMarketUpdates($returnRaw = false) $job = (new ExtensionUpdaterJob( $params[$i]["extension_id"], $obj["version"]["versionCode"], - $obj["platforms"][0]["downloadLink"] + $obj["platforms"][0]["downloadLink"], + $obj["platforms"][0]["hashSHA512"] ))->onQueue('system_updater'); // Dispatch job right away. @@ -134,6 +135,7 @@ public function checkMarketUpdates($returnRaw = false) "currentVersion" => $params[$i]["currentVersion"], "newVersion" => $obj["version"]["versionName"], "downloadLink" => $obj["platforms"][0]["downloadLink"], + "hashSHA512" => $obj["platforms"][0]["hashSHA512"], "versionCode" => $obj["version"]["versionCode"], "changeLog" => $obj["version"]["versionDescription"], "extension_id" => $params[$i]["extension_id"], diff --git a/app/Http/Controllers/Notification/ExternalNotificationController.php b/app/Http/Controllers/Notification/ExternalNotificationController.php index c43e0c28a..f54dbf909 100644 --- a/app/Http/Controllers/Notification/ExternalNotificationController.php +++ b/app/Http/Controllers/Notification/ExternalNotificationController.php @@ -4,9 +4,11 @@ use Illuminate\Http\Request; use App\Models\ExternalNotification; +use App\Models\AdminNotification; use Illuminate\Support\Str; use App\Http\Controllers\Controller; - +use Validator; +use Carbon\Carbon; class ExternalNotificationController extends Controller { /** @@ -105,7 +107,57 @@ public function edit() } } - public function accept() + public function accept(Request $request) { + $channel = ExternalNotification::where('token', request("token"))->first(); + if(!$channel){ + return response()->json([ + "Not authorized, token missing" + ],403); + } + if (self::ip_in_range($request->ip(),$channel->ip) == false) { + return response()->json([ + "Not authorized, unacceptable ip block" + ],403); + } + + $validator = Validator::make($request->all(), [ + 'title' => 'required|max:120', + 'message' => 'required', + ]); + + if ($validator->fails()) { + return response()->json([ + "Not Acceptable, inputs invalid" + ],406); + } + + AdminNotification::create([ + "title" => "Dış Bildirim -> " . $request->get('title'), + "type" => "external_notification", + "message" => $request->get('message'), + "level" => 3, + ]); + + $channel->update([ + "last_used" => Carbon::now() + ]); + + return response()->json([ + "OK" + ]); + } + + private function ip_in_range( $ip, $range ) { + if ( strpos( $range, '/' ) == false ) { + $range .= '/32'; + } + // $range is in IP/CIDR format eg 127.0.0.1/24 + list( $range, $netmask ) = explode( '/', $range, 2 ); + $range_decimal = ip2long( $range ); + $ip_decimal = ip2long( $ip ); + $wildcard_decimal = pow( 2, ( 32 - $netmask ) ) - 1; + $netmask_decimal = ~ $wildcard_decimal; + return ( ( $ip_decimal & $netmask_decimal ) == ( $range_decimal & $netmask_decimal ) ); } } diff --git a/app/Http/Controllers/Server/AddController.php b/app/Http/Controllers/Server/AddController.php index 81b90092c..5dd7fd200 100644 --- a/app/Http/Controllers/Server/AddController.php +++ b/app/Http/Controllers/Server/AddController.php @@ -4,10 +4,7 @@ use App\Models\AdminNotification; use App\Models\Certificate; -use App\Connectors\SSHConnector; -use App\Connectors\SNMPConnector; -use App\Connectors\SSHCertificateConnector; -use App\Connectors\WinRMConnector; +use App\Models\ServerKey; use App\Http\Controllers\Controller; use App\Models\Permission; use App\Models\Server; @@ -44,13 +41,16 @@ public function main() } if (strlen(request('name')) > 24) { - return respond("Lütfen daha kısa bir sunucu adı girin.",201); + return respond("Lütfen daha kısa bir sunucu adı girin.", 201); } // Create object with parameters. $this->server = new Server(); $this->server->fill(request()->all()); $this->server->user_id = auth()->id(); + if (request('type') == null ){ + $this->server->type = "none"; + } request('key_port') ? ($this->server->key_port = request('key_port')) : null; @@ -71,157 +71,24 @@ public function main() // Add Server to request object to use it later. request()->request->add(["server" => $this->server]); - if ( - server()->type == "windows_powershell" || - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { + if (request('type')) { $encKey = env('APP_KEY') . user()->id . server()->id; - UserSettings::create([ - "server_id" => $this->server->id, - "user_id" => user()->id, - "name" => "clientUsername", - "value" => AES256::encrypt(request('username'),$encKey), - ]); - UserSettings::create([ - "server_id" => $this->server->id, - "user_id" => user()->id, - "name" => "clientPassword", - "value" => AES256::encrypt(request('password'),$encKey), - ]); - } elseif (server()->type == "snmp") { - $targetValues = [ - "username", - "SNMPsecurityLevel", - "SNMPauthProtocol", - "SNMPauthPassword", - "SNMPprivacyProtocol", - "SNMPprivacyPassword", + $data = [ + "clientUsername" => AES256::encrypt( + request('username'), + $encKey + ), + "clientPassword" => AES256::encrypt( + request('password'), + $encKey + ), ]; - $encKey = env('APP_KEY') . user()->id . server()->id; - foreach ($targetValues as $target) { - UserSettings::create([ - "server_id" => $this->server->id, - "user_id" => user()->id, - "name" => $target, - "value" => AES256::encrypt(request($target),$encKey), - ]); - } - } - - // Run required function for specific type. - $next = null; - switch ($this->server->type) { - case "linux": - $next = $this->linux(); - break; - - case "linux_ssh": - $next = $this->linux_ssh(); - break; - - case "windows": - $next = $this->windows(); - break; - - case "windows_powershell": - $next = $this->windows_powershell(); - break; - - case "linux_certificate": - $next = $this->linux_certificate(); - break; - case "snmp": - $next = $this->snmp(); - break; - default: - $next = respond("Sunucu türü bulunamadı.", 404); - break; - } - return $next; - } - - private function linux_ssh() - { - $flag = SSHConnector::create( - $this->server, - request('username'), - request('password'), - auth()->id(), - null, - $this->server->key_port - ); - - if (!$flag) { - $this->server->delete(); - return respond("SSH Hatası", 400); - } - - return $this->grantPermissions(); - } - - private function snmp() - { - $flag = SNMPConnector::createSnmp( - $this->server, - request('username'), - request('SNMPsecurityLevel'), - request('SNMPauthProtocol'), - request('SNMPauthPassword'), - request('SNMPprivacyProtocol'), - request('SNMPprivacyPassword'), - user()->id - ); - - if (!$flag) { - $this->server->delete(); - return respond("SNMP Hatası", 400); - } - - return $this->grantPermissions(); - } - - private function linux_certificate() - { - $flag = SSHCertificateConnector::create( - $this->server, - request('username'), - request('certificateText'), - auth()->id(), - null - ); - - if (!$flag) { - $this->server->delete(); - return respond("SSH Hatası", 400); - } - - return $this->grantPermissions(); - } - - private function linux() - { - return $this->grantPermissions(); - } - - private function windows() - { - return $this->grantPermissions(); - } - - private function windows_powershell() - { - $flag = WinRMConnector::create( - $this->server, - request('username'), - request('password'), - auth()->id(), - null - ); + $data["key_port"] = request('key_port'); - if (!$flag) { - $this->server->delete(); - return respond("WinRM Hatası", 400); + ServerKey::updateOrCreate( + ["server_id" => server()->id, "user_id" => user()->id], + ["type" => request('type'), "data" => json_encode($data)] + ); } return $this->grantPermissions(); diff --git a/app/Http/Controllers/Server/MainController.php b/app/Http/Controllers/Server/MainController.php index 08697ae13..3a30fd461 100644 --- a/app/Http/Controllers/Server/MainController.php +++ b/app/Http/Controllers/Server/MainController.php @@ -2,10 +2,8 @@ namespace App\Http\Controllers\Server; -use App\Connectors\SSHConnector; +use App\Connectors\GenericConnector; use App\Connectors\SNMPConnector; -use App\Connectors\SSHCertificateConnector; -use App\Connectors\WinRMConnector; use App\Models\Server; use App\Http\Controllers\Controller; @@ -33,7 +31,7 @@ public function checkAccess() public function verifyName() { if (strlen(request('server_name')) > 24) { - return respond("Lütfen daha kısa bir sunucu adı girin.",201); + return respond("Lütfen daha kısa bir sunucu adı girin.", 201); } if (!Server::where('name', request('server_name'))->exists()) { return respond("İsim Onaylandı.", 200); @@ -54,38 +52,27 @@ public function verifyKey() ], ]); - if (request('key_type') == "linux_ssh") { - return SSHConnector::verify( + if (request('key_type') == "snmp") { + $output = SNMPConnector::verifySnmp( request('ip_address'), request('username'), - request('password'), - request('port') - ); - } elseif (request('key_type') == "windows_powershell") { - return WinRMConnector::verify( - request('ip_address'), - request('username'), - request('password'), - request('port') + request('password') ); - } elseif (request('key_type') == "linux_certificate") { - return SSHCertificateConnector::verify( + } else { + $connector = new GenericConnector(); + $output = $connector->verify( request('ip_address'), request('username'), request('password'), - request('port') - ); - } elseif (request('key_type') == "snmp") { - return SNMPConnector::verifySnmp( - request('ip_address'), - request('username'), - request('SNMPsecurityLevel'), - request('SNMPauthProtocol'), - request('SNMPauthPassword'), - request('SNMPprivacyProtocol'), - request('SNMPprivacyPassword') + request('port'), + request('key_type') ); } - return respond("Bu anahtara göre bir yapı bulunamadı.", 201); + + if ($output == "ok") { + return respond("Anahtarınız doğrulandı!"); + } else { + return respond("Anahtarınız doğrulanamadı!", 201); + } } } diff --git a/app/Http/Controllers/Server/OneController.php b/app/Http/Controllers/Server/OneController.php index f764d8e91..cdf303a22 100644 --- a/app/Http/Controllers/Server/OneController.php +++ b/app/Http/Controllers/Server/OneController.php @@ -2,8 +2,6 @@ namespace App\Http\Controllers\Server; -use App\Connectors\SSHConnector; -use App\Connectors\WinRMConnector; use App\Models\ConnectorToken; use App\Models\Extension; use App\Http\Controllers\Controller; @@ -175,9 +173,9 @@ public function enableExtension() public function update() { if (strlen(request('name')) > 24) { - return respond("Lütfen daha kısa bir sunucu adı girin.",201); + return respond("Lütfen daha kısa bir sunucu adı girin.", 201); } - + if (server()->name !== request('name')) { Notification::new( __("Server Adı Güncellemesi"), @@ -309,28 +307,34 @@ public function favorite() public function stats() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { - $disk = server()->run('df -h / | grep /', false); - preg_match("/(\d+)%/", $disk, $test); - $disk = $test[1]; - $ram = server()->run( - "free -t | awk 'NR == 2 {printf($3/$2*100)}'", - false + if (server()->isLinux()) { + $cpuPercent = server()->run( + "ps -eo %cpu --no-headers | grep -v 0.0 | awk '{s+=$1} END {print s/NR*10}'" ); - $cpu = substr( - server()->run( - "grep 'cpu ' /proc/stat | awk '{usage=($2+$4)*100/($2+$4+$5)} END {print usage}'", - false - ), - 0, - 7 + $ramPercent = server()->run( + "free | grep Mem | awk '{print $3/$2 * 100.0}'" ); - // $cpu = server()->run("vmstat 1 1|tail -1|awk '{print $15}'", false); - // $cpu = 100 - intval($cpu); - } elseif (server()->type == "windows_powershell") { + $diskPercent = server()->run("df --output=pcent / | tr -dc '0-9'"); + $ioPercent = server()->run( + "iostat -d | tail -n +4 | head -n -1 | awk '{s+=$2} END {print s}'" + ); + $firstDown = $this->calculateNetworkBytes(); + $firstUp = $this->calculateNetworkBytes(false); + sleep(1); + $secondDown = $this->calculateNetworkBytes(); + $secondUp = $this->calculateNetworkBytes(false); + return [ + 'cpuPercent' => round($cpuPercent, 2), + 'ramPercent' => round($ramPercent, 2), + 'diskPercent' => round($diskPercent, 2), + 'ioPercent' => round($ioPercent, 2), + 'network' => [ + 'down' => round(($secondDown - $firstDown) / 1024 / 2, 2), + 'up' => round(($secondUp - $firstUp) / 1024 / 2, 2), + ], + 'time' => \Carbon\Carbon::now()->format('H:i:s'), + ]; + } elseif (server()->isWindows()) { $cpu = substr( server()->run( "Get-WmiObject win32_processor | Measure-Object -property LoadPercentage -Average | Select Average" @@ -372,25 +376,107 @@ public function stats() ]; } + private function parsePsOutput($output) + { + $data = []; + foreach (explode("\n", $output) as $row) { + $row = explode('*-*', $row); + $row[3] = str_replace('\\', '/', $row[3]); + $fetch = explode('/', $row[3]); + $data[] = [ + 'pid' => $row[0], + 'percent' => $row[1], + 'user' => $row[2], + 'cmd' => end($fetch), + ]; + } + return $data; + } + + private function parseDfOutput($output) + { + $data = []; + foreach (explode("\n", $output) as $row) { + $row = explode('*-*', $row); + $row[1] = str_replace('\\', '/', $row[1]); + $fetch = explode('/', $row[1]); + $data[] = [ + 'percent' => $row[0], + 'source' => end($fetch), + 'size' => $row[2], + 'used' => $row[3], + ]; + } + return $data; + } + + public function topMemoryProcesses() + { + $output = trim( + server()->run( + "ps -eo pid,%mem,user,cmd --sort=-%mem --no-headers | head -n 5 | awk '{print $1\"*-*\"$2\"*-*\"$3\"*-*\"$4}'" + ) + ); + return view('table', [ + 'value' => $this->parsePsOutput($output), + 'title' => [__('Kullanıcı'), __('İşlem'), '%'], + 'display' => ['user', 'cmd', 'percent'], + ]); + } + + public function topCpuProcesses() + { + $output = trim( + server()->run( + "ps -eo pid,%cpu,user,cmd --sort=-%cpu --no-headers | head -n 5 | awk '{print $1\"*-*\"$2\"*-*\"$3\"*-*\"$4}'" + ) + ); + return view('table', [ + 'value' => $this->parsePsOutput($output), + 'title' => [__('Kullanıcı'), __('İşlem'), '%'], + 'display' => ['user', 'cmd', 'percent'], + ]); + } + + public function topDiskUsage() + { + $output = trim( + server()->run( + "df --output=pcent,source,size,used -hl -x squashfs -x tmpfs -x devtmpfs | sed -n '1!p' | head -n 5 | sort -hr | awk '{print $1\"*-*\"$2\"*-*\"$3\"*-*\"$4}'" + ) + ); + return view('table', [ + 'value' => $this->parseDfOutput($output), + 'title' => [__('Disk'), __('Boyut'), __('Dolu'), '%'], + 'display' => ['source', 'size', 'used', 'percent'], + ]); + } + + private function calculateNetworkBytes($download = true) + { + $text = $download ? 'rx_bytes' : 'tx_bytes'; + $count = 0; + $raw = server()->run("cat /sys/class/net/*/statistics/$text"); + foreach (explode("\n", trim($raw)) as $data) { + $count += intval($data); + } + return $count; + } + public function getLocalUsers() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { - $output = server()->run( - "cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1" - ); - $output = trim($output); - if (empty($output)) { - $users = []; - } else { - $output = explode("\n", $output); - foreach ($output as $user) { - $users[] = [ - "user" => $user, - ]; - } + $output = server()->run( + "cut -d: -f1,3 /etc/passwd | egrep ':[0-9]{4}$' | cut -d: -f1" + ); + $output = trim($output); + if (empty($output)) { + $users = []; + } else { + $output = explode("\n", $output); + foreach ($output as $user) { + $users[] = [ + "user" => $user, + ]; } } return magicView('table', [ @@ -402,48 +488,38 @@ public function getLocalUsers() public function addLocalUser() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { - $user_name = request("user_name"); - $user_password = request("user_password"); - $user_password_confirmation = request("user_password_confirmation"); - if ($user_password !== $user_password_confirmation) { - return respond("Şifreler uyuşmuyor!", 201); - } - $output = trim( - server()->run( - sudo() . - "bash -c 'useradd --no-user-group -p $(openssl passwd -1 $user_password) $user_name -s \"/bin/bash\"' &> /dev/null && echo 1 || echo 0" - ) - ); - if ($output == "0") { - return respond("Kullanıcı eklenemedi!", 201); - } - return respond("Kullanıcı başarıyla eklendi!", 200); + $user_name = request("user_name"); + $user_password = request("user_password"); + $user_password_confirmation = request("user_password_confirmation"); + if ($user_password !== $user_password_confirmation) { + return respond("Şifreler uyuşmuyor!", 201); } + $output = trim( + server()->run( + sudo() . + "bash -c 'useradd --no-user-group -p $(openssl passwd -1 $user_password) $user_name -s \"/bin/bash\"' &> /dev/null && echo 1 || echo 0" + ) + ); + if ($output == "0") { + return respond("Kullanıcı eklenemedi!", 201); + } + return respond("Kullanıcı başarıyla eklendi!", 200); } public function getLocalGroups() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { - $output = server()->run("getent group | cut -d ':' -f1"); - $output = trim($output); - if (empty($output)) { - $groups = []; - } else { - $output = explode("\n", $output); - foreach ($output as $group) { - $groups[] = [ - "group" => $group, - ]; - } - $groups = array_reverse($groups); + $output = server()->run("getent group | cut -d ':' -f1"); + $output = trim($output); + if (empty($output)) { + $groups = []; + } else { + $output = explode("\n", $output); + foreach ($output as $group) { + $groups[] = [ + "group" => $group, + ]; } + $groups = array_reverse($groups); } return magicView('table', [ "value" => $groups, @@ -455,21 +531,16 @@ public function getLocalGroups() public function getLocalGroupDetails() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { - $group = request("group"); - $output = trim( - server()->run(sudo() . "getent group $group | cut -d ':' -f4") - ); + $group = request("group"); + $output = trim( + server()->run(sudo() . "getent group $group | cut -d ':' -f4") + ); - $users = []; - if (!empty($output)) { - $users = array_map(function ($value) { - return ["name" => $value]; - }, explode(",", $output)); - } + $users = []; + if (!empty($output)) { + $users = array_map(function ($value) { + return ["name" => $value]; + }, explode(",", $output)); } return magicView('table', [ "value" => $users, @@ -480,65 +551,49 @@ public function getLocalGroupDetails() public function addLocalGroup() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { - $group_name = request("group_name"); - $output = trim( - server()->run( - sudo() . - "groupadd $group_name &> /dev/null && echo 1 || echo 0" - ) - ); - if ($output == "0") { - return respond("Grup eklenemedi!", 201); - } - return respond("Grup başarıyla eklendi!", 200); + $group_name = request("group_name"); + $output = trim( + server()->run( + sudo() . "groupadd $group_name &> /dev/null && echo 1 || echo 0" + ) + ); + if ($output == "0") { + return respond("Grup eklenemedi!", 201); } + return respond("Grup başarıyla eklendi!", 200); } public function addLocalGroupUser() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { - $group = request("group"); - $user = request("user"); - $output = trim( - server()->run( - sudo() . - "usermod -a -G $group $user &> /dev/null && echo 1 || echo 0" - ) - ); - if ($output != "1") { - return respond("Kullanıcı gruba eklenemedi!", 201); - } - return respond("Kullanıcı gruba başarıyla eklendi!"); + $group = request("group"); + $user = request("user"); + $output = trim( + server()->run( + sudo() . + "usermod -a -G $group $user &> /dev/null && echo 1 || echo 0" + ) + ); + if ($output != "1") { + return respond("Kullanıcı gruba eklenemedi!", 201); } + return respond("Kullanıcı gruba başarıyla eklendi!"); } public function getSudoers() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { - $output = trim( - server()->run( - sudo() . - "cat /etc/sudoers /etc/sudoers.d/* | grep -v '^#\|^Defaults' | sed '/^$/d' | awk '{ print $1 \"*-*\" $2 \" \" $3 }'" - ) - ); + $output = trim( + server()->run( + sudo() . + "cat /etc/sudoers /etc/sudoers.d/* | grep -v '^#\|^Defaults' | sed '/^$/d' | awk '{ print $1 \"*-*\" $2 \" \" $3 }'" + ) + ); - $sudoers = []; - if (!empty($output)) { - $sudoers = array_map(function ($value) { - $fetch = explode("*-*", $value); - return ["name" => $fetch[0], "access" => $fetch[1]]; - }, explode("\n", $output)); - } + $sudoers = []; + if (!empty($output)) { + $sudoers = array_map(function ($value) { + $fetch = explode("*-*", $value); + return ["name" => $fetch[0], "access" => $fetch[1]]; + }, explode("\n", $output)); } return magicView('table', [ "value" => $sudoers, @@ -555,51 +610,40 @@ public function getSudoers() public function addSudoers() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { - $name = request("name"); - $name = str_replace(" ", "\\x20", $name); - $checkFile = server()->run( - "[ -f '/etc/sudoers.d/$name' ] && echo 1 || echo 0" - ); - if ($checkFile == "1") { - return respond("Bu isimde bir kullanıcı zaten ekli!", 201); - } - $output = trim( - server()->run( - sudo() . - "bash -c 'echo \"$name ALL=(ALL:ALL) ALL\" | tee /etc/sudoers.d/$name' &> /dev/null && echo 1 || echo 0" - ) - ); - if ($output == "0") { - return respond("Tam yetkili kullanıcı eklenemedi!", 201); - } - return respond("Tam yetkili kullanıcı başarıyla eklendi!", 200); + $name = request("name"); + $name = str_replace(" ", "\\x20", $name); + $checkFile = server()->run( + "[ -f '/etc/sudoers.d/$name' ] && echo 1 || echo 0" + ); + if ($checkFile == "1") { + return respond("Bu isimde bir kullanıcı zaten ekli!", 201); + } + $output = trim( + server()->run( + sudo() . + "bash -c 'echo \"$name ALL=(ALL:ALL) ALL\" | tee /etc/sudoers.d/$name' &> /dev/null && echo 1 || echo 0" + ) + ); + if ($output == "0") { + return respond("Tam yetkili kullanıcı eklenemedi!", 201); } + return respond("Tam yetkili kullanıcı başarıyla eklendi!", 200); } public function deleteSudoers() { - //TODO: check here for bugs - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { - $name = request("name"); - $name = str_replace(" ", "\\x20", $name); - $output = trim( - server()->run( - sudo() . - "bash -c 'if [ -f \"/etc/sudoers.d/$name\" ]; then rm /etc/sudoers.d/$name && echo 1 || echo 0; else echo 0; fi'" - ) - ); - if ($output == "0") { - return respond("Tam yetkili kullanıcı silinemedi!", 201); - } - return respond("Tam yetkili kullanıcı başarıyla silindi!", 200); + $name = request("name"); + $name = str_replace(" ", "\\x20", $name); + $output = trim( + server()->run( + sudo() . + "bash -c 'if [ -f \"/etc/sudoers.d/$name\" ]; then rm /etc/sudoers.d/$name && echo 1 || echo 0; else echo 0; fi'" + ) + ); + if ($output == "0") { + return respond("Tam yetkili kullanıcı silinemedi!", 201); } + return respond("Tam yetkili kullanıcı başarıyla silindi!", 200); } public function serviceList() @@ -608,10 +652,7 @@ public function serviceList() return respond("Bu işlemi yapmak için yetkiniz yok!", 201); } $services = []; - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { + if (server()->isLinux()) { $raw = server()->run( "systemctl list-units | grep service | awk '{print $1 \":\"$2\" \"$3\" \"$4\":\"$5\" \"$6\" \"$7\" \"$8\" \"$9\" \"$10}'", false @@ -630,7 +671,7 @@ public function serviceList() } catch (Exception $exception) { } } - } elseif (server()->type == "windows_powershell") { + } else { $rawServices = server()->run( "(Get-WmiObject win32_service | select Name, DisplayName, State, StartMode) -replace '\s\s+',':'" ); @@ -649,13 +690,12 @@ public function serviceList() } catch (Exception $exception) { } } - } else { - return respond("Bu sunucudaki servisleri goremezsiniz.", 403); } + return magicView('table', [ "id" => "servicesTable", "value" => $services, - "title" => ["Servis Adı", "Aciklamasi", "Durumu"], + "title" => ["Servis Adı", "Açıklama", "Durumu"], "display" => ["name", "description", "status"], "menu" => [ "Detaylar" => [ @@ -798,10 +838,7 @@ public function getLogDetails() public function installPackage() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { + if (server()->isLinux()) { $package = request("package_name"); $raw = server()->run( sudo() . @@ -812,7 +849,7 @@ public function installPackage() system_log(7, "Paket Güncelleme", [ 'package_name' => request("package_name"), ]); - } elseif (server()->type == "windows_powershell") { + } else { $raw = ""; } return $raw; @@ -820,98 +857,86 @@ public function installPackage() public function checkPackage() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { - $mode = request("mode") ? request("mode") : 'update'; - $output = trim( - server()->run( - "ps aux | grep \"apt \|dpkg \" | grep -v grep 2>/dev/null 1>/dev/null && echo '1' || echo '0'" - ) - ); - $command_output = server()->run( - sudo() . - 'cat "/tmp/' . - basename(request("package_name")) . - '.txt" 2> /dev/null | base64' - ); - $command_output = base64_decode($command_output); + $mode = request("mode") ? request("mode") : 'update'; + $output = trim( server()->run( - sudo() . - 'truncate -s 0 /tmp/' . - basename(request("package_name")) . - '.txt' - ); - if ($output === "0") { - $list_method = - $mode == "install" ? "--installed" : "--upgradable"; - $package = request("package_name"); - if (endsWith($package, ".deb")) { - $package = server()->run( - sudo() . - 'dpkg -I ' . - $package . - ' | grep Package: | cut -d\':\' -f2 | tr -d \'[:space:]\'' - ); - } - $output = server()->run( + "ps aux | grep \"apt \|dpkg \" | grep -v grep 2>/dev/null 1>/dev/null && echo '1' || echo '0'" + ) + ); + $command_output = server()->run( + sudo() . + 'cat "/tmp/' . + basename(request("package_name")) . + '.txt" 2> /dev/null | base64' + ); + $command_output = base64_decode($command_output); + server()->run( + sudo() . + 'truncate -s 0 /tmp/' . + basename(request("package_name")) . + '.txt' + ); + if ($output === "0") { + $list_method = $mode == "install" ? "--installed" : "--upgradable"; + $package = request("package_name"); + if (endsWith($package, ".deb")) { + $package = server()->run( sudo() . - 'apt list ' . - $list_method . - ' 2>/dev/null | grep ' . + 'dpkg -I ' . $package . - ' && echo 1 || echo 0' + ' | grep Package: | cut -d\':\' -f2 | tr -d \'[:space:]\'' ); - if ( - ($mode == "update" && $output == "0") || - ($mode == "install" && $output != "0") - ) { - system_log(7, "Paket Güncelleme Başarılı", [ - 'package_name' => request("package_name"), - ]); - return respond([ - "status" => __( - ":package_name paketi başarıyla kuruldu.", - ['package_name' => request("package_name")] - ), - "output" => trim($command_output), - ]); - } else { - system_log(7, "Paket Güncelleme Başarısız", [ + } + $output = server()->run( + sudo() . + 'apt list ' . + $list_method . + ' 2>/dev/null | grep ' . + $package . + ' && echo 1 || echo 0' + ); + if ( + ($mode == "update" && $output == "0") || + ($mode == "install" && $output != "0") + ) { + system_log(7, "Paket Güncelleme Başarılı", [ + 'package_name' => request("package_name"), + ]); + return respond([ + "status" => __(":package_name paketi başarıyla kuruldu.", [ 'package_name' => request("package_name"), - ]); - return respond([ - "status" => __(":package_name paketi kurulamadı.", [ - 'package_name' => request("package_name"), - ]), - "output" => trim($command_output), - ]); - } + ]), + "output" => trim($command_output), + ]); } else { - return respond( - [ - "status" => __( - ":package_name paketinin kurulum işlemi henüz bitmedi.", - ['package_name' => request("package_name")] - ), - "output" => trim($command_output), - ], - 400 - ); + system_log(7, "Paket Güncelleme Başarısız", [ + 'package_name' => request("package_name"), + ]); + return respond([ + "status" => __(":package_name paketi kurulamadı.", [ + 'package_name' => request("package_name"), + ]), + "output" => trim($command_output), + ]); } - } elseif (server()->type == "windows_powershell") { - $output = ""; + } else { + return respond( + [ + "status" => __( + ":package_name paketinin kurulum işlemi henüz bitmedi.", + ['package_name' => request("package_name")] + ), + "output" => trim($command_output), + ], + 400 + ); } return $output; } public function uploadDebFile() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { + if (server()->isLinux()) { $filePath = request('filePath'); if (!$filePath) { return respond("Dosya yolu zorunludur.", 403); @@ -926,35 +951,27 @@ public function uploadDebFile() public function updateList() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { - $updates = []; - $raw = server()->run( + $updates = []; + $raw = server()->run( + sudo() . + "apt-get -qq update 2> /dev/null > /dev/null; " . sudo() . - "apt-get -qq update 2> /dev/null > /dev/null; " . - sudo() . - "apt list --upgradable 2>/dev/null | sed '1,1d'" - ); - foreach (explode("\n", $raw) as $package) { - if ($package == "" || strpos($package, 'List') !== false) { - continue; - } - $row = explode(" ", $package, 4); - try { - array_push($updates, [ - "name" => $row[0], - "version" => $row[1], - "type" => $row[2], - "status" => $row[3], - ]); - } catch (\Exception $exception) { - } + "apt list --upgradable 2>/dev/null | sed '1,1d'" + ); + foreach (explode("\n", $raw) as $package) { + if ($package == "" || strpos($package, 'List') !== false) { + continue; + } + $row = explode(" ", $package, 4); + try { + array_push($updates, [ + "name" => $row[0], + "version" => $row[1], + "type" => $row[2], + "status" => $row[3], + ]); + } catch (\Exception $exception) { } - } elseif (server()->type == "windows_powershell") { - } else { - return respond("Bu sunucudaki güncellemeleri goremezsiniz.", 403); } return [ "count" => count($updates), @@ -976,32 +993,25 @@ public function updateList() public function packageList() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { - $raw = server()->run( - sudo() . "apt list --installed 2>/dev/null | sed '1,1d'", - false - ); - $packages = []; - foreach (explode("\n", $raw) as $package) { - if ($package == "") { - continue; - } - $row = explode(" ", $package); - try { - array_push($packages, [ - "name" => $row[0], - "version" => $row[1], - "type" => $row[2], - "status" => $row[3], - ]); - } catch (Exception $exception) { - } + $raw = server()->run( + sudo() . "apt list --installed 2>/dev/null | sed '1,1d'", + false + ); + $packages = []; + foreach (explode("\n", $raw) as $package) { + if ($package == "") { + continue; + } + $row = explode(" ", $package); + try { + array_push($packages, [ + "name" => $row[0], + "version" => $row[1], + "type" => $row[2], + "status" => $row[3], + ]); + } catch (Exception $exception) { } - } else { - return respond("Bu sunucudaki paketleri goremezsiniz.", 403); } return magicView('l.table', [ "value" => $packages, @@ -1010,87 +1020,6 @@ public function packageList() ]); } - public function upgradeServer() - { - if ( - server()->type == "linux_ssh" || - server()->type == "windows_powershell" || - server()->type == "linux_certificate" || - server()->type == "snmp" - ) { - return respond("Bu sunucuda yükseltme yapılamaz.", 201); - } - - // Init key with parameters. - if (server()->type == "linux") { - try { - $flag = SSHConnector::create( - server(), - request('username'), - request('password'), - auth()->id(), - null - ); - } catch (\Exception $exception) { - $flag = "Sunucuya bağlanılamadı."; - } - } - - if (server()->type == "windows") { - try { - $flag = WinRMConnector::create( - server(), - request('username'), - request('password'), - auth()->id(), - null - ); - } catch (\Exception $exception) { - $flag = "Sunucuya bağlanılamadı."; - } - } - - if (!$flag) { - return respond($flag, 201); - } - - if (server()->type == "linux") { - server()->update([ - "type" => "linux_ssh", - ]); - } else { - server()->update([ - "type" => "windows_powershell", - ]); - } - - // Add credentials - $encKey = env('APP_KEY') . user()->id . server()->id; - UserSettings::updateOrCreate( - [ - "user_id" => user()->id, - "server_id" => server()->id, - "name" => "clientUsername", - ], - [ - "value" => AES256::encrypt(request('username'),$encKey), - ] - ); - - UserSettings::updateOrCreate( - [ - "user_id" => user()->id, - "server_id" => server()->id, - "name" => "clientPassword", - ], - [ - "value" => AES256::encrypt(request('password'),$encKey), - ] - ); - - return respond("Sunucu Başarıyla Yükseltildi."); - } - public function removeExtension() { hook('server_extension_remove', [ @@ -1123,10 +1052,7 @@ public function removeExtension() public function startService() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { + if (server()->isLinux()) { $command = sudo() . "systemctl start " . request('name'); } else { $command = "Start-Service " . request("name"); @@ -1137,10 +1063,7 @@ public function startService() public function stopService() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { + if (server()->isLinux()) { $command = sudo() . "systemctl stop " . request('name'); } else { $command = "Stop-Service " . request("name"); @@ -1151,10 +1074,7 @@ public function stopService() public function restartService() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { + if (server()->isLinux()) { $command = sudo() . "systemctl restart " . request('name'); } else { $command = "Restart-Service " . request("name"); @@ -1165,10 +1085,7 @@ public function restartService() public function statusService() { - if ( - server()->type == "linux_ssh" || - server()->type == "linux_certificate" - ) { + if (server()->isLinux()) { $command = sudo() . "systemctl status " . request('name'); } else { return respond( @@ -1182,10 +1099,7 @@ public function statusService() public function getOpenPorts() { - if ( - server()->type != "linux_ssh" && - server()->type != "linux_certificate" - ) { + if (server()->os != "linux") { return respond("Bu sunucuda portları kontrol edemezsiniz!", 201); } diff --git a/app/Http/Controllers/Server/_routes.php b/app/Http/Controllers/Server/_routes.php index b14eaa7aa..ef16ba7bb 100644 --- a/app/Http/Controllers/Server/_routes.php +++ b/app/Http/Controllers/Server/_routes.php @@ -8,7 +8,7 @@ Route::post('/sunucu/ekle', 'Server\AddController@main') ->name('server_add') - ->middleware('parameters:name,ip_address,control_port,type,city'); + ->middleware('parameters:name,ip_address,control_port,city'); // Server Update Route @@ -24,8 +24,9 @@ ->name('server_verify_name') ->middleware('parameters:server_name'); -Route::post('/sunucu/anahtarKontrol', 'Server\MainController@verifyKey') - ->name('server_verify_key'); +Route::post('/sunucu/anahtarKontrol', 'Server\MainController@verifyKey')->name( + 'server_verify_key' +); // Remove Server Route @@ -94,6 +95,21 @@ 'server_stats' ); + Route::post( + '/sunucu/bellek_durum', + 'Server\OneController@topMemoryProcesses' + )->name('top_memory_processes'); + + Route::post( + '/sunucu/islemci_durum', + 'Server\OneController@topCpuProcesses' + )->name('top_cpu_processes'); + + Route::post( + '/sunucu/disk_durum', + 'Server\OneController@topDiskUsage' + )->name('top_disk_usage'); + Route::post('/sunucu/servis/', 'Server\OneController@serviceList')->name( 'server_service_list' ); @@ -177,10 +193,6 @@ 'server_package_list' ); - Route::post('/sunucu/yukselt', 'Server\OneController@upgradeServer')->name( - 'server_upgrade' - ); - Route::post( '/sunucu/eklentiSil', 'Server\OneController@removeExtension' diff --git a/app/Http/Controllers/Settings/MainController.php b/app/Http/Controllers/Settings/MainController.php index 42c9c4acd..57316de60 100755 --- a/app/Http/Controllers/Settings/MainController.php +++ b/app/Http/Controllers/Settings/MainController.php @@ -241,7 +241,7 @@ public function getExtensionFunctions() return view('l.table', [ "value" => $cleanFunctions, - "title" => ["*hidden*", "Aciklama"], + "title" => ["*hidden*", "Açıklama"], "display" => ["name:name", "description"], ]); } diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php index 05ef626a3..161a22eaa 100644 --- a/app/Http/Controllers/UserController.php +++ b/app/Http/Controllers/UserController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Models\Permission; +use App\Models\ServerKey; use App\Models\RoleUser; use App\User; use App\Models\UserSettings; @@ -46,7 +47,10 @@ public function add() try { $flag->validate(); } catch (\Exception $exception) { - return respond("Lütfen geçerli veri giriniz. " . $exception->getMessage(), 201); + return respond( + "Lütfen geçerli veri giriniz. " . $exception->getMessage(), + 201 + ); } // Check If user already exists. @@ -298,10 +302,11 @@ public function adminUpdate() */ public function removeSetting() { - $first = UserSettings::where([ - 'user_id' => user()->id, - 'id' => request('setting_id'), - ])->first(); + if (request('type') == "key") { + $first = ServerKey::find(request('id')); + } else { + $first = UserSettings::find(request('id')); + } if (!$first) { return respond("Ayar bulunamadi", 201); @@ -320,10 +325,7 @@ public function removeSetting() } } - $flag = UserSettings::where([ - 'user_id' => auth()->user()->id, - 'id' => request('setting_id'), - ])->delete(); + $flag = $first->delete(); if ($flag) { return respond("Başarıyla silindi", 200); @@ -364,7 +366,7 @@ public function updateSetting() } $key = env('APP_KEY') . $setting->user_id . $setting->server_id; - $encrypted = AES256::encrypt(request('new_value'),$key); + $encrypted = AES256::encrypt(request('new_value'), $key); $flag = $setting->update([ "value" => $encrypted, @@ -446,20 +448,30 @@ public function userKeyList() foreach ($settings as $setting) { $server = $servers->find($setting->server_id); - if ($setting->name == "clientUsername") { - $setting->name = __("Anahtar - Kullanıcı Adı"); - } - if ($setting->name == "clientPassword") { - $setting->name = __("Anahtar - Şifre"); - } $setting->server_name = $server ? $server->name : __("Sunucu Silinmiş."); + $setting->type = "setting"; + } + + $keys = user()->keys; + + foreach ($keys as $key) { + $server = $servers->find($key->server_id); + $key->server_name = $server + ? $server->name + : __("Sunucu Silinmiş."); + $key->name = "Sunucu Anahtarı"; + $key->type = "key"; } return magicView('keys.index', [ - "servers" => objectToArray($servers, "name", "id"), - "settings" => json_decode(json_encode($settings), true), + "settings" => json_decode( + json_encode( + array_merge($settings->toArray(), $keys->toArray()) + ), + true + ), ]); } @@ -475,31 +487,29 @@ public function userKeyList() */ public function addKey() { + $encKey = env('APP_KEY') . user()->id . server()->id; UserSettings::where([ "server_id" => server()->id, "user_id" => user()->id, "name" => "clientUsername", ])->delete(); - UserSettings::where([ "server_id" => server()->id, "user_id" => user()->id, "name" => "clientPassword", ])->delete(); - $encKey = env('APP_KEY') . user()->id . server()->id; - UserSettings::create([ - "server_id" => server()->id, - "user_id" => user()->id, - "name" => "clientUsername", - "value" => AES256::encrypt(request('username'),$encKey), - ]); - UserSettings::create([ - "server_id" => server()->id, - "user_id" => user()->id, - "name" => "clientPassword", - "value" => AES256::encrypt(request('password'),$encKey), - ]); + $data = [ + "clientUsername" => AES256::encrypt(request('username'), $encKey), + "clientPassword" => AES256::encrypt(request('password'), $encKey), + "key_port" => request('key_port'), + ]; + + ServerKey::updateOrCreate( + ["server_id" => server()->id, "user_id" => user()->id], + ["type" => request('type'), "data" => json_encode($data)] + ); + ConnectorToken::clear(); return respond("Başarıyla eklendi."); } diff --git a/app/Http/Controllers/Widgets/OneController.php b/app/Http/Controllers/Widgets/OneController.php index bd8e08334..300ff1b9c 100644 --- a/app/Http/Controllers/Widgets/OneController.php +++ b/app/Http/Controllers/Widgets/OneController.php @@ -16,70 +16,6 @@ class OneController extends Controller { - public function one() - { - $widget = Widget::find(\request('widget_id')); - if (!$widget) { - return respond(__("Bileşen Bulunamadı"), 201); - } - $extension = Extension::one($widget->extension_id); - $extensionData = json_decode( - file_get_contents( - "/liman/extensions/" . - strtolower(extension($widget->extension_id)->name) . - DIRECTORY_SEPARATOR . - "db.json" - ), - true - ); - foreach ($extensionData["database"] as $item) { - if ( - !UserSettings::where([ - "user_id" => auth()->user()->id, - "server_id" => $widget->server_id, - "name" => $item["variable"], - ])->exists() - ) { - return respond( - __("Eklenti ayarları eksik.") . - " id . - '/' . - $widget->server_id - ) . - "'>" . - __("Ayarlara Git.") . - "", - 400 - ); - } - } - - $server = Server::find($widget->server_id); - request()->request->add([ - 'server' => $server, - 'widget' => $widget, - 'extension_id' => $extension->id, - 'extension' => $extension, - 'target_function' => $widget->function, - ]); - - $sandboxController = new MainController(); - $sandboxController->initializeClass(); - $output = $sandboxController->API()->content(); - - if (!$output) { - return respond(__("Bileşen Hiçbir Veri Döndürmedi"), 400); - } - $output_json = json_decode($output, true); - if (!isset($output_json)) { - return respond(__("Bilinmeyen bir hata oluştu."), 400); - } - return respond($output_json['message'], $output_json['status']); - } - public function remove() { $widget = Widget::find(\request('widget_id')); diff --git a/app/Http/Controllers/Widgets/_routes.php b/app/Http/Controllers/Widgets/_routes.php index 874042538..1c20d33c0 100644 --- a/app/Http/Controllers/Widgets/_routes.php +++ b/app/Http/Controllers/Widgets/_routes.php @@ -6,10 +6,6 @@ Route::view('/bilesen/ekle', 'widgets.add')->name('widget_add_page'); -Route::post('/widget', 'Widgets\OneController@one') - ->name('widget_one') - ->middleware('server_api'); - Route::post('/widget/sil', 'Widgets\OneController@remove')->name( 'widget_remove' ); diff --git a/app/Http/Helpers.php b/app/Http/Helpers.php index 38d9a9c0b..700c7bcb4 100755 --- a/app/Http/Helpers.php +++ b/app/Http/Helpers.php @@ -372,7 +372,10 @@ function adminNotifications() */ function addCertificate($hostname, $port, $path) { - rootSystem()->addCertificate('/tmp/' . $path, "liman-" . $hostname . "_" . $port); + rootSystem()->addCertificate( + '/tmp/' . $path, + "liman-" . $hostname . "_" . $port + ); // Create Certificate Object. return Certificate::create([ @@ -388,7 +391,9 @@ function addCertificate($hostname, $port, $path) */ function getLimanId() { - return md5("l1m@ns3cur1ty".trim(shell_exec("ls /dev/disk/by-uuid -1"))).PHP_EOL; + return md5( + "l1m@ns3cur1ty" . trim(shell_exec("ls /dev/disk/by-uuid -1")) + ) . PHP_EOL; } } @@ -400,7 +405,7 @@ function getLimanId() */ function system_log($level, $message, $array = []) { - $array["user_id"] = user()->id; + $array["user_id"] = user() ? user()->id : ""; $array["ip_address"] = request()->ip(); switch ($level) { @@ -592,9 +597,18 @@ function extensionDb($key = "*") "name" => $key, ]) ->first(); + if ($key == "clientPassword" || $key == "clientUsername"){ + $serverKey = server()->key(); + if ($serverKey == null){ + return null; + } + $data = json_decode($serverKey->data,true); + $encKey = env('APP_KEY') . auth()->user()->id . server()->id; + return AES256::decrypt($data[$key], $encKey); + } if ($target) { $key = env('APP_KEY') . auth()->user()->id . server()->id; - return AES256::decrypt($target->value,$key); + return AES256::decrypt($target->value, $key); } return null; } @@ -603,7 +617,7 @@ function extensionDb($key = "*") if (!function_exists('sudo')) { function sudo() { - if (server()->type == "linux_certificate") { + if (server()->key()->type == "ssh_certificate") { return "sudo "; } $pass64 = base64_encode(extensionDb("clientPassword") . "\n"); @@ -813,7 +827,7 @@ function checkHealth() if (empty($messages)) { array_push($messages, [ "type" => "success", - "message" => "Herşey Yolunda, sıkıntı yok!", + "message" => __("Herşey Yolunda, sıkıntı yok!"), ]); } @@ -825,7 +839,7 @@ function checkHealth() function lDecrypt($data) { $key = env('APP_KEY') . user()->id . server()->id; - return AES256::decrypt($data,$key); + return AES256::decrypt($data, $key); } } diff --git a/app/Http/Middleware/VerifyCsrfToken.php b/app/Http/Middleware/VerifyCsrfToken.php index eb00d7741..46bdadbfe 100644 --- a/app/Http/Middleware/VerifyCsrfToken.php +++ b/app/Http/Middleware/VerifyCsrfToken.php @@ -19,19 +19,7 @@ class VerifyCsrfToken extends Middleware * @var array */ protected $except = [ - "/lmn/private/extensionApi", - "/lmn/private/runCommandApi", - "/lmn/private/putFileApi", - "/lmn/private/getFileApi", - "/lmn/private/runScriptApi", - "/lmn/private/putSession", "/lmn/private/reverseProxyRequest", - "/lmn/private/dispatchJob", - "/lmn/private/getJobList", - "/lmn/private/openTunnel", - "/lmn/private/stopTunnel", "/lmn/private/sendNotification", - "/lmn/private/sendLog", - "/lmn/private/extensionRenderedHandler" ]; } diff --git a/app/Jobs/ExtensionDependenciesJob.php b/app/Jobs/ExtensionDependenciesJob.php new file mode 100644 index 000000000..748b0c1ce --- /dev/null +++ b/app/Jobs/ExtensionDependenciesJob.php @@ -0,0 +1,76 @@ +extension = $extension; + $this->dependencies = $dependencies; + $this->extension->update([ + "status" => "0" + ]); + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + $package = $this->dependencies; + $tmp = "/tmp/" . str_random(16); + $installCommand = "if [ -z '\$(find /var/cache/apt/pkgcache.bin -mmin -60)' ]; then sudo apt-get update; fi;DEBIAN_FRONTEND=noninteractive sudo apt-get install -o Dpkg::Use-Pty=0 -o Dpkg::Options::='--force-confdef' -o Dpkg::Options::='--force-confold' $package -qqy --force-yes >" . $tmp . " 2>&1"; + rootSystem()->runCommand($installCommand); + $checkCommand = "dpkg --get-selections | grep -v deinstall | awk '{print $1}' | grep -xE '" . str_replace(" ","|", $package) ."'"; + $installed = rootSystem()->runCommand($checkCommand); + $dep = explode(" ",$this->dependencies); + sort($dep); + $installed = explode("\n",trim($installed)); + sort($installed); + + if ($dep == $installed){ + $this->extension->update([ + "status" => "1" + ]); + $this->extension->save(); + + AdminNotification::create([ + "title" => + $this->extension->display_name . " eklentisi hazır!", + "type" => "", + "message" => + $this->extension->display_name . + " eklentisinin bağımlılıkları başarıyla yüklendi, hemen kullanmaya başlayabilirsiniz.", + "level" => 3, + ]); + }else{ + AdminNotification::create([ + "title" => + $this->extension->display_name . " eklentisi kurulamadı!", + "type" => "error", + "message" => + $this->extension->display_name . + " eklentisinin bağımlılıkları yüklenemedi, detayları " . $tmp . " dosyasından inceleyebilirsiniz.", + "level" => 3, + ]); + } + } +} diff --git a/app/Jobs/ExtensionJob.php b/app/Jobs/ExtensionJob.php deleted file mode 100644 index cc35c5f02..000000000 --- a/app/Jobs/ExtensionJob.php +++ /dev/null @@ -1,219 +0,0 @@ -history = $history; - $this->extension = $extension; - $this->server = $server; - $this->user = $user; - $this->function = $function; - $this->parameters = $parameters; - $this->session = session()->all(); - foreach ($parameters as $key => $param) { - request()->request->add([$key => $param]); - } - $this->sandbox = sandbox(); - } - - /** - * Execute the job. - * - * @return void - */ - public function handle() - { - $command = $this->sandbox->command($this->function); - - $output = rootSystem()->runCommand("",$command,false); - - // system_log(7, "EXTENSION_BACKGROUND_RUN", [ - // "extension_id" => $this->extension->id, - // "server_id" => $this->server->id, - // "target_name" => $this->function, - // ]); - - $code = 200; - try { - $json = json_decode($output, true); - if (array_key_exists("status", $json)) { - $code = intval($json["status"]); - } - } catch (\Exception $exception) { - } - if (strval($code) == "200" && $json["message"] != "") { - $this->history->status = 1; - $this->history->save(); - return true; - } else { - $this->history->status = 2; - $this->history->save(); - return false; - } - } - - private function sandbox( - $serverObj, - $extensionObj, - $extension_id, - $user_id, - $outputs, - $viewName, - $functionName, - $extensionDb = null - ) { - $functions = - "/liman/extensions/" . - strtolower($extensionObj["name"]) . - "/views/functions.php"; - - $combinerFile = "/liman/sandbox/php/index.php"; - - $server = json_encode($serverObj->toArray()); - - $extension = json_encode($extensionObj); - - if ($extensionDb == null) { - $settings = DB::table("user_settings")->where([ - "user_id" => $user_id, - "server_id" => $serverObj->id, - ]); - $extensionDb = []; - foreach ($settings->get() as $setting) { - $key = - env('APP_KEY') . $user_id . $serverObj->id; - $extensionDb[$setting->name] = AES256::decrypt($setting->value,$key); - } - } - - $extensionDb = json_encode($extensionDb); - - $outputsJson = json_encode($outputs); - - $request = $this->request; - unset($request["permissions"]); - unset($request["extension"]); - unset($request["server"]); - unset($request["script"]); - unset($request["server_id"]); - $request = json_encode($request); - - $apiRoute = route('extension_server', [ - "extension_id" => $extension_id, - ]); - - $navigationRoute = route('extension_server_route', [ - "server_id" => $serverObj->id, - "extension_id" => $extension_id, - "city" => $serverObj->city, - ]); - - $token = Token::create($user_id); - - if (!$this->user->isAdmin()) { - $extensionJson = json_decode( - file_get_contents( - "/liman/extensions/" . - strtolower($extensionObj->name) . - DIRECTORY_SEPARATOR . - "db.json" - ), - true - ); - $permissions = []; - if (array_key_exists("functions", $extensionJson)) { - foreach ($extensionJson["functions"] as $item) { - if ( - Permission::can( - $user_id, - "function", - "name", - strtolower($extensionObj->name), - $item["name"] - ) || - $item["isActive"] != "true" - ) { - array_push($permissions, $item["name"]); - } - } - } - $permissions = json_encode($permissions); - } else { - $permissions = "admin"; - } - $sessionData = json_encode($this->session); - $array = [ - $functions, - strtolower($extensionObj->name), - $viewName, - $server, - $extension, - $extensionDb, - $outputsJson, - $request, - $functionName, - $apiRoute, - $navigationRoute, - $token, - $extension_id, - $permissions, - 'tr', - $this->cookie, - $sessionData, - ]; - $encrypted = openssl_encrypt( - Str::random() . base64_encode(json_encode($array)), - 'aes-256-cfb8', - shell_exec( - 'cat ' . '/liman/keys' . DIRECTORY_SEPARATOR . $extension_id - ), - 0, - Str::random() - ); - $keyPath = '/liman/keys' . DIRECTORY_SEPARATOR . $extension_id; - - $command = - "sudo runuser " . - cleanDash($extension_id) . - " -c 'timeout 30 /usr/bin/php -d display_errors=on $combinerFile $keyPath $encrypted'"; - return $command; - } -} diff --git a/app/Jobs/ExtensionUpdaterJob.php b/app/Jobs/ExtensionUpdaterJob.php index 1e02ffe9c..785eb6b79 100644 --- a/app/Jobs/ExtensionUpdaterJob.php +++ b/app/Jobs/ExtensionUpdaterJob.php @@ -20,7 +20,9 @@ class ExtensionUpdaterJob implements ShouldQueue private $download; private $version_code; private $forceUpdate; - + private $hash; + private $retry = 3; + private $signed = false; /** * Create a new job instance. * @@ -30,12 +32,14 @@ public function __construct( $extension_id, $version_code, $download, + $hash, $forceUpdate = false ) { $this->extension = Extension::find($extension_id); $this->version_code = $version_code; $this->download = $download; $this->forceUpdate = $forceUpdate; + $this->hash = $hash; } /** @@ -51,12 +55,12 @@ public function handle() shell_exec("[ -e '$downloadPath' ] && echo 1 || echo 0") ); $flag = true; - - if ($exists != "1") { + $fileHash = trim(shell_exec("sha512sum $downloadPath 2>/dev/null | cut -d ' ' -f 1")); + if ($exists != "1" || $fileHash != $this->hash) { $flag = self::downloadFile($downloadPath); } - if ($this->forceUpdate) { + if ($flag && $this->forceUpdate) { $controller = new MainController(); list($flag, $extension) = $controller->setupNewExtension( $downloadPath @@ -88,20 +92,43 @@ private function downloadFile($downloadPath) "verify" => false, ]); $resource = fopen($downloadPath, 'w'); - $client->request('GET', $this->download, ['sink' => $resource]); - if (is_file($downloadPath)) { + $response = $client->request('GET', $this->download, ['sink' => $resource]); + try{ + $str = $response->getHeaders()["Content-Disposition"][0]; + $arr = explode(";",$str); + if (substr($arr[1],-7) == 'signed"') { + $this->signed = true; + } + }catch(\Exception $e){ + return false; + } + + $fileHash = trim(shell_exec("sha512sum $downloadPath | cut -d ' ' -f 1")); + if (is_file($downloadPath) && $fileHash == $this->hash) { + if ($this->signed) { + $tmp2 = "/tmp/" . str_random(); + shell_exec( + "gpg --status-fd 1 -d -o '" . $tmp2 . "' " . $downloadPath . " >/dev/null 2>/dev/null" + ); + shell_exec("mv " . $tmp2 . " " . $downloadPath); + } return true; } else { - return false; + $this->retry = $this->retry -1; + if($this->retry < 0 ){ + return false; + } else{ + return self::downloadFile($downloadPath); + } } } private function updateUpdatesFile() { - $json = json_decode( + $json = array_values(json_decode( file_get_contents(storage_path('extension_updates')), true - ); + )); for ($i = 0; $i < count($json); $i++) { if ($json[$i]["extension_id"] = $this->extension->id) { unset($json[$i]); diff --git a/app/Jobs/LimanUpdaterJob.php b/app/Jobs/LimanUpdaterJob.php index ec598b925..706fa7d45 100644 --- a/app/Jobs/LimanUpdaterJob.php +++ b/app/Jobs/LimanUpdaterJob.php @@ -9,6 +9,7 @@ use Illuminate\Queue\SerializesModels; use GuzzleHttp\Client; use GuzzleHttp\Exception\BadResponseException; +use App\Models\AdminNotification; class LimanUpdaterJob implements ShouldQueue { @@ -50,7 +51,30 @@ private function downloadFile() "verify" => false, ]); $resource = fopen($this->downloadTo, 'w'); - $client->request('GET', $this->downloadUrl, ['sink' => $resource]); + try{ + $client->request('GET', $this->downloadUrl, ['sink' => $resource]); + }catch(\Exception $e){ + AdminNotification::create([ + "title" => + $this->extension->display_name . " eklentisinin güncellemesi indirilemedi!", + "type" => "error", + "message" => + "Oluşan hata : " . $e->getMessage(), + "level" => 3, + ]); + return false; + } + + AdminNotification::create([ + "title" => + $this->extension->display_name . " eklentisinin güncellemesi indirildi!", + "type" => "", + "message" => + $this->extension->display_name . + " eklentisinin güncellemesi başarıyla indirildi, eklentiler sekmesi üzerinden değişim kaydını görebilir, eklentiyi güncelleyebilirsiniz.", + "level" => 3, + ]); + if (is_file($this->downloadTo)) { return true; } else { diff --git a/app/Mail/BasicNotification.php b/app/Mail/BasicNotification.php index ca394b9d2..7278f3ed9 100644 --- a/app/Mail/BasicNotification.php +++ b/app/Mail/BasicNotification.php @@ -2,7 +2,7 @@ namespace App\Mail; -use App\Models\Notification; +use App\Models\AdminNotification; use Illuminate\Bus\Queueable; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; @@ -17,10 +17,9 @@ class BasicNotification extends Mailable * * @return void */ - public function __construct(Notification $notification) + public function __construct(AdminNotification $notification) { $this->notification = $notification; - $this->user = \Auth::user(); } /** @@ -33,6 +32,6 @@ public function build() return $this->from([ "address" => env('APP_NOTIFICATION_EMAIL'), "name" => __("Liman Bildiri Sistemi"), - ])->view('emails.basic'); + ])->view('email.external_notification'); } } diff --git a/app/Models/Extension.php b/app/Models/Extension.php index 6e3b5e764..39328e76a 100644 --- a/app/Models/Extension.php +++ b/app/Models/Extension.php @@ -22,6 +22,8 @@ class Extension extends Model "language", "support", "displays", + "require_key", + "status" ]; protected $casts = [ diff --git a/app/Models/ExternalNotification.php b/app/Models/ExternalNotification.php index db93fe9e8..eed9fff62 100644 --- a/app/Models/ExternalNotification.php +++ b/app/Models/ExternalNotification.php @@ -8,7 +8,7 @@ class ExternalNotification extends Model { use UsesUuid; - protected $fillable = ["name", "last_used", "ip"]; + protected $fillable = ["name", "last_used", "ip", "token"]; protected $hidden = ["token"]; } diff --git a/app/Models/Server.php b/app/Models/Server.php index 2d4efbd8a..ec65d46c5 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -2,11 +2,8 @@ namespace App\Models; -use App\Connectors\Connector; -use App\Connectors\SSHConnector; +use App\Connectors\GenericConnector; use App\Connectors\SNMPConnector; -use App\Connectors\SSHCertificateConnector; -use App\Connectors\WinRMConnector; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Query\Builder; @@ -25,6 +22,7 @@ class Server extends Model 'city', 'type', 'control_port', + 'os', ]; /** * @var @@ -36,20 +34,16 @@ class Server extends Model */ private function connector() { - if ($this->type == "linux_ssh") { - return new SSHConnector($this, user()->id); - } elseif ($this->type == "windows_powershell") { - return new WinRMConnector($this, user()->id); - } elseif ($this->type == "linux_certificate") { - return new SSHCertificateConnector($this, user()->id); - } elseif ($this->type == "snmp") { - return new SNMPConnector($this, user()->id); - } else { + if ($this->key() == null) { abort( 504, "Bu sunucuda komut çalıştırmak için bir bağlantınız yok." ); } + if ($this->key()->type == "snmp") { + return new SNMPConnector($this, user()->id); + } + return new GenericConnector($this, user()); } /** @@ -108,7 +102,7 @@ public function runScript($script, $parameters, $runAsRoot = false) */ public function isRunning($service_name) { - if ($this->type == "windows" || $this->type == "linux") { + if (!$this->canRunCommand()) { if ($this->control_port == -1) { return true; } @@ -196,27 +190,22 @@ public function isFavorite() public function canRunCommand() { - return $this->type == "linux_ssh" || - $this->type == "linux_certificate" || - $this->type == "windows_powershell" || - $this->type == "snmp"; + return $this->key() != null ? true : false; } public function isLinux() { - return $this->type == "linux_ssh" || - $this->type == "linux_certificate" || - $this->type == "linux"; + return $this->os == "linux"; } public function isWindows() { - return $this->type == "windows" || $this->type == "windows_powershell"; + return $this->os == "windows"; } public function getVersion() { - if (!$this->canRunCommand() || $this->type == "snmp") { + if (!$this->canRunCommand()) { return ""; } @@ -231,10 +220,19 @@ public function getVersion() public function getHostname() { - if (!$this->canRunCommand() || $this->type == "snmp") { + if (!$this->canRunCommand()) { return ""; } return $this->run("hostname"); } + + public function key() + { + return $this->hasOne( + '\App\Models\ServerKey', + 'server_id', + 'id' + )->first(); + } } diff --git a/app/Models/ServerKey.php b/app/Models/ServerKey.php new file mode 100644 index 000000000..fa4b24cde --- /dev/null +++ b/app/Models/ServerKey.php @@ -0,0 +1,12 @@ +get(); foreach ($adminUsers as $user) { $user->notify(new NotificationSent($adminNotification)); + if (env('MAIL_ENABLED') == true && $adminNotification->type == "external_notification"){ + Mail::to($user)->send(new BasicNotification($adminNotification)); + } } } /** diff --git a/app/System/Helper.php b/app/System/Helper.php index ac0b380a0..794ea0b64 100644 --- a/app/System/Helper.php +++ b/app/System/Helper.php @@ -110,16 +110,13 @@ public function fixExtensionPermissions($extension_id, $extension_name) return true; } - public function runCommand($user_id, $command,$background = true, $handler = null) + public function runCommand($command) { try{ $response = $this->client->get('/extensionRun',[ 'query' => [ 'liman_token' => $this->authKey, - 'command' => $command, - 'background' => $background ? "true" : "false", - 'user_id' => $user_id, - 'handler' => $handler + 'command' => $command ] ]); }catch(\Exception $e){ diff --git a/app/User.php b/app/User.php index aa5b76a99..15bdb807f 100644 --- a/app/User.php +++ b/app/User.php @@ -87,6 +87,11 @@ public function settings() return $this->hasMany('\App\Models\UserSettings'); } + public function keys() + { + return $this->hasMany('\App\Models\ServerKey'); + } + public function notifications() { return $this->hasMany('\App\Models\Notification'); diff --git a/composer.lock b/composer.lock index d6050f48e..0d0c2b9be 100644 --- a/composer.lock +++ b/composer.lock @@ -68,16 +68,16 @@ }, { "name": "beyondcode/laravel-websockets", - "version": "1.7.0", + "version": "1.8.1", "source": { "type": "git", "url": "https://github.com/beyondcode/laravel-websockets.git", - "reference": "00dd9b0b2521a9aa7cfba30d75b4e38838c80509" + "reference": "c85ec38452f8dfdad4310dc22af19108f89fa9fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/beyondcode/laravel-websockets/zipball/00dd9b0b2521a9aa7cfba30d75b4e38838c80509", - "reference": "00dd9b0b2521a9aa7cfba30d75b4e38838c80509", + "url": "https://api.github.com/repos/beyondcode/laravel-websockets/zipball/c85ec38452f8dfdad4310dc22af19108f89fa9fe", + "reference": "c85ec38452f8dfdad4310dc22af19108f89fa9fe", "shasum": "" }, "require": { @@ -142,7 +142,7 @@ "beyondcode", "laravel-websockets" ], - "time": "2020-09-10T13:44:10+00:00" + "time": "2020-09-19T08:50:04+00:00" }, { "name": "cboden/ratchet", @@ -430,30 +430,30 @@ }, { "name": "doctrine/dbal", - "version": "2.10.4", + "version": "2.11.1", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "47433196b6390d14409a33885ee42b6208160643" + "reference": "6e6903cd5e3a5be60a79439e3ee8fe126f78fe86" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/47433196b6390d14409a33885ee42b6208160643", - "reference": "47433196b6390d14409a33885ee42b6208160643", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/6e6903cd5e3a5be60a79439e3ee8fe126f78fe86", + "reference": "6e6903cd5e3a5be60a79439e3ee8fe126f78fe86", "shasum": "" }, "require": { "doctrine/cache": "^1.0", "doctrine/event-manager": "^1.0", "ext-pdo": "*", - "php": "^7.2" + "php": "^7.3" }, "require-dev": { "doctrine/coding-standard": "^8.1", "jetbrains/phpstorm-stubs": "^2019.1", "nikic/php-parser": "^4.4", "phpstan/phpstan": "^0.12.40", - "phpunit/phpunit": "^8.5.5", + "phpunit/phpunit": "^9.3", "psalm/plugin-phpunit": "^0.10.0", "symfony/console": "^2.0.5|^3.0|^4.0|^5.0", "vimeo/psalm": "^3.14.2" @@ -467,8 +467,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.10.x-dev", - "dev-develop": "3.0.x-dev" + "dev-master": "4.0.x-dev" } }, "autoload": { @@ -535,7 +534,7 @@ "type": "tidelift" } ], - "time": "2020-09-12T21:20:41+00:00" + "time": "2020-09-27T04:09:41+00:00" }, { "name": "doctrine/event-manager", @@ -850,16 +849,16 @@ }, { "name": "egulias/email-validator", - "version": "2.1.20", + "version": "2.1.22", "source": { "type": "git", "url": "https://github.com/egulias/EmailValidator.git", - "reference": "f46887bc48db66c7f38f668eb7d6ae54583617ff" + "reference": "68e418ec08fbfc6f58f6fd2eea70ca8efc8cc7d5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/f46887bc48db66c7f38f668eb7d6ae54583617ff", - "reference": "f46887bc48db66c7f38f668eb7d6ae54583617ff", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/68e418ec08fbfc6f58f6fd2eea70ca8efc8cc7d5", + "reference": "68e418ec08fbfc6f58f6fd2eea70ca8efc8cc7d5", "shasum": "" }, "require": { @@ -904,7 +903,7 @@ "validation", "validator" ], - "time": "2020-09-06T13:44:32+00:00" + "time": "2020-09-26T15:48:38+00:00" }, { "name": "evenement/evenement", @@ -1270,20 +1269,20 @@ }, { "name": "jenssegers/blade", - "version": "v1.3.0", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/jenssegers/blade.git", - "reference": "d221b717b4302ad71476ebd05abf0c2b98cbd7d8" + "reference": "22a3700e9fc469c19dd1c5e5bd1b9138195e421f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jenssegers/blade/zipball/d221b717b4302ad71476ebd05abf0c2b98cbd7d8", - "reference": "d221b717b4302ad71476ebd05abf0c2b98cbd7d8", + "url": "https://api.github.com/repos/jenssegers/blade/zipball/22a3700e9fc469c19dd1c5e5bd1b9138195e421f", + "reference": "22a3700e9fc469c19dd1c5e5bd1b9138195e421f", "shasum": "" }, "require": { - "illuminate/view": "^5.5|^6.0|^7.0", + "illuminate/view": "^5.5|^6.0|^7.0|^8.0", "php": ">=7.0" }, "require-dev": { @@ -1314,7 +1313,17 @@ "template", "view" ], - "time": "2020-03-17T15:00:55+00:00" + "funding": [ + { + "url": "https://github.com/jenssegers", + "type": "github" + }, + { + "url": "https://opencollective.com/jenssegers-blade", + "type": "open_collective" + } + ], + "time": "2020-09-17T08:25:26+00:00" }, { "name": "laravel/framework", @@ -1706,16 +1715,16 @@ }, { "name": "league/mime-type-detection", - "version": "1.4.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "fda190b62b962d96a069fcc414d781db66d65b69" + "reference": "ea2fbfc988bade315acd5967e6d02274086d0f28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/fda190b62b962d96a069fcc414d781db66d65b69", - "reference": "fda190b62b962d96a069fcc414d781db66d65b69", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ea2fbfc988bade315acd5967e6d02274086d0f28", + "reference": "ea2fbfc988bade315acd5967e6d02274086d0f28", "shasum": "" }, "require": { @@ -1753,7 +1762,7 @@ "type": "tidelift" } ], - "time": "2020-08-09T10:34:01+00:00" + "time": "2020-09-21T18:10:53+00:00" }, { "name": "mervick/aes-everywhere", @@ -1885,16 +1894,16 @@ }, { "name": "nesbot/carbon", - "version": "2.39.2", + "version": "2.40.1", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "326efde1bc09077a26cb77f6e2e32e13f06c27f2" + "reference": "d9a76d8b7eb0f97cf3a82529393245212f40ba3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/326efde1bc09077a26cb77f6e2e32e13f06c27f2", - "reference": "326efde1bc09077a26cb77f6e2e32e13f06c27f2", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/d9a76d8b7eb0f97cf3a82529393245212f40ba3b", + "reference": "d9a76d8b7eb0f97cf3a82529393245212f40ba3b", "shasum": "" }, "require": { @@ -1970,7 +1979,7 @@ "type": "tidelift" } ], - "time": "2020-09-10T12:16:42+00:00" + "time": "2020-09-23T08:17:37+00:00" }, { "name": "opis/closure", @@ -2834,24 +2843,24 @@ }, { "name": "react/cache", - "version": "v1.0.0", + "version": "v1.1.0", "source": { "type": "git", "url": "https://github.com/reactphp/cache.git", - "reference": "aa10d63a1b40a36a486bdf527f28bac607ee6466" + "reference": "44a568925556b0bd8cacc7b49fb0f1cf0d706a0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/cache/zipball/aa10d63a1b40a36a486bdf527f28bac607ee6466", - "reference": "aa10d63a1b40a36a486bdf527f28bac607ee6466", + "url": "https://api.github.com/repos/reactphp/cache/zipball/44a568925556b0bd8cacc7b49fb0f1cf0d706a0c", + "reference": "44a568925556b0bd8cacc7b49fb0f1cf0d706a0c", "shasum": "" }, "require": { "php": ">=5.3.0", - "react/promise": "~2.0|~1.1" + "react/promise": "^3.0 || ^2.0 || ^1.1" }, "require-dev": { - "phpunit/phpunit": "^6.4 || ^5.7 || ^4.8.35" + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35" }, "type": "library", "autoload": { @@ -2863,6 +2872,28 @@ "license": [ "MIT" ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], "description": "Async, Promise-based cache interface for ReactPHP", "keywords": [ "cache", @@ -2870,20 +2901,30 @@ "promise", "reactphp" ], - "time": "2019-07-11T13:45:28+00:00" + "funding": [ + { + "url": "https://github.com/WyriHaximus", + "type": "github" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2020-09-18T12:12:35+00:00" }, { "name": "react/dns", - "version": "v1.3.0", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/reactphp/dns.git", - "reference": "89d83794e959ef3e0f1ab792f070b0157de1abf2" + "reference": "665260757171e2ab17485b44e7ffffa7acb6ca1f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/dns/zipball/89d83794e959ef3e0f1ab792f070b0157de1abf2", - "reference": "89d83794e959ef3e0f1ab792f070b0157de1abf2", + "url": "https://api.github.com/repos/reactphp/dns/zipball/665260757171e2ab17485b44e7ffffa7acb6ca1f", + "reference": "665260757171e2ab17485b44e7ffffa7acb6ca1f", "shasum": "" }, "require": { @@ -2895,7 +2936,7 @@ }, "require-dev": { "clue/block-react": "^1.2", - "phpunit/phpunit": "^9.0 || ^4.8.35" + "phpunit/phpunit": "^9.3 || ^4.8.35" }, "type": "library", "autoload": { @@ -2907,6 +2948,28 @@ "license": [ "MIT" ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], "description": "Async DNS resolver for ReactPHP", "keywords": [ "async", @@ -2914,7 +2977,17 @@ "dns-resolver", "reactphp" ], - "time": "2020-07-10T12:12:50+00:00" + "funding": [ + { + "url": "https://github.com/WyriHaximus", + "type": "github" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2020-09-18T12:12:55+00:00" }, { "name": "react/event-loop", @@ -3000,6 +3073,7 @@ "keywords": [ "http" ], + "abandoned": "react/http", "time": "2020-01-14T08:36:16+00:00" }, { @@ -3405,16 +3479,16 @@ }, { "name": "symfony/console", - "version": "v4.4.13", + "version": "v4.4.14", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "b39fd99b9297b67fb7633b7d8083957a97e1e727" + "reference": "90933b39c7b312fc3ceaa1ddeac7eb48cb953124" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/b39fd99b9297b67fb7633b7d8083957a97e1e727", - "reference": "b39fd99b9297b67fb7633b7d8083957a97e1e727", + "url": "https://api.github.com/repos/symfony/console/zipball/90933b39c7b312fc3ceaa1ddeac7eb48cb953124", + "reference": "90933b39c7b312fc3ceaa1ddeac7eb48cb953124", "shasum": "" }, "require": { @@ -3492,11 +3566,11 @@ "type": "tidelift" } ], - "time": "2020-09-02T07:07:21+00:00" + "time": "2020-09-15T07:58:55+00:00" }, { "name": "symfony/css-selector", - "version": "v5.1.5", + "version": "v5.1.6", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", @@ -3563,16 +3637,16 @@ }, { "name": "symfony/debug", - "version": "v4.4.13", + "version": "v4.4.14", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "aeb73aca16a8f1fe958230fe44e6cf4c84cbb85e" + "reference": "726b85e69342e767d60e3853b98559a68ff74183" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/aeb73aca16a8f1fe958230fe44e6cf4c84cbb85e", - "reference": "aeb73aca16a8f1fe958230fe44e6cf4c84cbb85e", + "url": "https://api.github.com/repos/symfony/debug/zipball/726b85e69342e767d60e3853b98559a68ff74183", + "reference": "726b85e69342e767d60e3853b98559a68ff74183", "shasum": "" }, "require": { @@ -3630,20 +3704,20 @@ "type": "tidelift" } ], - "time": "2020-08-10T07:47:39+00:00" + "time": "2020-09-09T05:20:36+00:00" }, { "name": "symfony/error-handler", - "version": "v4.4.13", + "version": "v4.4.14", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "2434fb32851f252e4f27691eee0b77c16198db62" + "reference": "5a6feca7a384015a09e14265c35ee0bd6f54b2ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/2434fb32851f252e4f27691eee0b77c16198db62", - "reference": "2434fb32851f252e4f27691eee0b77c16198db62", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/5a6feca7a384015a09e14265c35ee0bd6f54b2ed", + "reference": "5a6feca7a384015a09e14265c35ee0bd6f54b2ed", "shasum": "" }, "require": { @@ -3701,20 +3775,20 @@ "type": "tidelift" } ], - "time": "2020-08-17T09:56:45+00:00" + "time": "2020-09-25T08:51:35+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.4.13", + "version": "v4.4.14", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "3e8ea5ccddd00556b86d69d42f99f1061a704030" + "reference": "e17bb5e0663dc725f7cdcafc932132735b4725cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3e8ea5ccddd00556b86d69d42f99f1061a704030", - "reference": "3e8ea5ccddd00556b86d69d42f99f1061a704030", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/e17bb5e0663dc725f7cdcafc932132735b4725cd", + "reference": "e17bb5e0663dc725f7cdcafc932132735b4725cd", "shasum": "" }, "require": { @@ -3732,6 +3806,7 @@ "psr/log": "~1.0", "symfony/config": "^3.4|^4.0|^5.0", "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/error-handler": "~3.4|~4.4", "symfony/expression-language": "^3.4|^4.0|^5.0", "symfony/http-foundation": "^3.4|^4.0|^5.0", "symfony/service-contracts": "^1.1|^2", @@ -3785,7 +3860,7 @@ "type": "tidelift" } ], - "time": "2020-08-13T14:18:44+00:00" + "time": "2020-09-18T14:07:46+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -3865,16 +3940,16 @@ }, { "name": "symfony/finder", - "version": "v4.4.13", + "version": "v4.4.14", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "2a78590b2c7e3de5c429628457c47541c58db9c7" + "reference": "5ef0f6c609c1a36f723880dfe78301199bc96868" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/2a78590b2c7e3de5c429628457c47541c58db9c7", - "reference": "2a78590b2c7e3de5c429628457c47541c58db9c7", + "url": "https://api.github.com/repos/symfony/finder/zipball/5ef0f6c609c1a36f723880dfe78301199bc96868", + "reference": "5ef0f6c609c1a36f723880dfe78301199bc96868", "shasum": "" }, "require": { @@ -3924,20 +3999,95 @@ "type": "tidelift" } ], - "time": "2020-08-17T09:56:45+00:00" + "time": "2020-09-02T16:08:58+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v2.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "3a5d0fe7908daaa23e3dbf4cee3ba4bfbb19fdd3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/3a5d0fe7908daaa23e3dbf4cee3ba4bfbb19fdd3", + "reference": "3a5d0fe7908daaa23e3dbf4cee3ba4bfbb19fdd3", + "shasum": "" + }, + "require": { + "php": ">=7.2.5" + }, + "suggest": { + "symfony/http-client-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-09-07T11:33:47+00:00" }, { "name": "symfony/http-foundation", - "version": "v4.4.13", + "version": "v4.4.14", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "e3e5a62a6631a461954d471e7206e3750dbe8ee1" + "reference": "ff509ca7a73641bdbd7b56169a9004e64a58451d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e3e5a62a6631a461954d471e7206e3750dbe8ee1", - "reference": "e3e5a62a6631a461954d471e7206e3750dbe8ee1", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ff509ca7a73641bdbd7b56169a9004e64a58451d", + "reference": "ff509ca7a73641bdbd7b56169a9004e64a58451d", "shasum": "" }, "require": { @@ -3993,20 +4143,20 @@ "type": "tidelift" } ], - "time": "2020-08-17T07:39:58+00:00" + "time": "2020-09-13T05:00:26+00:00" }, { "name": "symfony/http-kernel", - "version": "v4.4.13", + "version": "v4.4.14", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "2bb7b90ecdc79813c0bf237b7ff20e79062b5188" + "reference": "e3eac6daeb0c65965a6201bd2de9564a802fe0a9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/2bb7b90ecdc79813c0bf237b7ff20e79062b5188", - "reference": "2bb7b90ecdc79813c0bf237b7ff20e79062b5188", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/e3eac6daeb0c65965a6201bd2de9564a802fe0a9", + "reference": "e3eac6daeb0c65965a6201bd2de9564a802fe0a9", "shasum": "" }, "require": { @@ -4014,6 +4164,7 @@ "psr/log": "~1.0", "symfony/error-handler": "^4.4", "symfony/event-dispatcher": "^4.4", + "symfony/http-client-contracts": "^1.1|^2", "symfony/http-foundation": "^4.4|^5.0", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-php73": "^1.9", @@ -4098,20 +4249,20 @@ "type": "tidelift" } ], - "time": "2020-09-02T08:09:29+00:00" + "time": "2020-09-27T04:25:44+00:00" }, { "name": "symfony/mime", - "version": "v5.1.5", + "version": "v5.1.6", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "89a2c9b4cb7b5aa516cf55f5194c384f444c81dc" + "reference": "4404d6545125863561721514ad9388db2661eec5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/89a2c9b4cb7b5aa516cf55f5194c384f444c81dc", - "reference": "89a2c9b4cb7b5aa516cf55f5194c384f444c81dc", + "url": "https://api.github.com/repos/symfony/mime/zipball/4404d6545125863561721514ad9388db2661eec5", + "reference": "4404d6545125863561721514ad9388db2661eec5", "shasum": "" }, "require": { @@ -4175,7 +4326,7 @@ "type": "tidelift" } ], - "time": "2020-08-17T10:01:29+00:00" + "time": "2020-09-02T16:23:27+00:00" }, { "name": "symfony/polyfill-ctype", @@ -4881,16 +5032,16 @@ }, { "name": "symfony/process", - "version": "v4.4.13", + "version": "v4.4.14", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "65e70bab62f3da7089a8d4591fb23fbacacb3479" + "reference": "9b887acc522935f77555ae8813495958c7771ba7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/65e70bab62f3da7089a8d4591fb23fbacacb3479", - "reference": "65e70bab62f3da7089a8d4591fb23fbacacb3479", + "url": "https://api.github.com/repos/symfony/process/zipball/9b887acc522935f77555ae8813495958c7771ba7", + "reference": "9b887acc522935f77555ae8813495958c7771ba7", "shasum": "" }, "require": { @@ -4940,7 +5091,7 @@ "type": "tidelift" } ], - "time": "2020-07-23T08:31:43+00:00" + "time": "2020-09-02T16:08:58+00:00" }, { "name": "symfony/psr-http-message-bridge", @@ -5022,16 +5173,16 @@ }, { "name": "symfony/routing", - "version": "v4.4.13", + "version": "v4.4.14", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "e3387963565da9bae51d1d3ab8041646cc93bd04" + "reference": "8db77d97152f55f0df5158cc0a877ad8e16099ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/e3387963565da9bae51d1d3ab8041646cc93bd04", - "reference": "e3387963565da9bae51d1d3ab8041646cc93bd04", + "url": "https://api.github.com/repos/symfony/routing/zipball/8db77d97152f55f0df5158cc0a877ad8e16099ac", + "reference": "8db77d97152f55f0df5158cc0a877ad8e16099ac", "shasum": "" }, "require": { @@ -5108,7 +5259,7 @@ "type": "tidelift" } ], - "time": "2020-08-10T07:27:51+00:00" + "time": "2020-09-02T16:08:58+00:00" }, { "name": "symfony/service-contracts", @@ -5188,16 +5339,16 @@ }, { "name": "symfony/translation", - "version": "v4.4.13", + "version": "v4.4.14", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "700e6e50174b0cdcf0fa232773bec5c314680575" + "reference": "0b8c4bb49b05b11d2b9dd1732f26049b08d96884" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/700e6e50174b0cdcf0fa232773bec5c314680575", - "reference": "700e6e50174b0cdcf0fa232773bec5c314680575", + "url": "https://api.github.com/repos/symfony/translation/zipball/0b8c4bb49b05b11d2b9dd1732f26049b08d96884", + "reference": "0b8c4bb49b05b11d2b9dd1732f26049b08d96884", "shasum": "" }, "require": { @@ -5274,7 +5425,7 @@ "type": "tidelift" } ], - "time": "2020-08-17T09:56:45+00:00" + "time": "2020-09-24T09:40:01+00:00" }, { "name": "symfony/translation-contracts", @@ -5353,16 +5504,16 @@ }, { "name": "symfony/var-dumper", - "version": "v4.4.13", + "version": "v4.4.14", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "1bef32329f3166486ab7cb88599cae4875632b99" + "reference": "0dc22bdf9d1197467bb04d505355180b6f20bcca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/1bef32329f3166486ab7cb88599cae4875632b99", - "reference": "1bef32329f3166486ab7cb88599cae4875632b99", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/0dc22bdf9d1197467bb04d505355180b6f20bcca", + "reference": "0dc22bdf9d1197467bb04d505355180b6f20bcca", "shasum": "" }, "require": { @@ -5440,7 +5591,7 @@ "type": "tidelift" } ], - "time": "2020-08-17T07:31:35+00:00" + "time": "2020-09-18T08:35:10+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -6097,16 +6248,16 @@ }, { "name": "facade/flare-client-php", - "version": "1.3.5", + "version": "1.3.6", "source": { "type": "git", "url": "https://github.com/facade/flare-client-php.git", - "reference": "25907a113bfc212a38d458ae365bfb902b4e7fb8" + "reference": "451fadf38e9f635e7f8e1f5b3cf5c9eb82f11799" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/facade/flare-client-php/zipball/25907a113bfc212a38d458ae365bfb902b4e7fb8", - "reference": "25907a113bfc212a38d458ae365bfb902b4e7fb8", + "url": "https://api.github.com/repos/facade/flare-client-php/zipball/451fadf38e9f635e7f8e1f5b3cf5c9eb82f11799", + "reference": "451fadf38e9f635e7f8e1f5b3cf5c9eb82f11799", "shasum": "" }, "require": { @@ -6119,7 +6270,6 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.14", - "larapack/dd": "^1.1", "phpunit/phpunit": "^7.5.16", "spatie/phpunit-snapshot-assertions": "^2.0" }, @@ -6155,7 +6305,7 @@ "type": "github" } ], - "time": "2020-08-26T18:06:23+00:00" + "time": "2020-09-18T06:35:11+00:00" }, { "name": "facade/ignition", @@ -6729,16 +6879,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.9.1", + "version": "v4.10.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "88e519766fc58bd46b8265561fb79b54e2e00b28" + "reference": "658f1be311a230e0907f5dfe0213742aff0596de" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/88e519766fc58bd46b8265561fb79b54e2e00b28", - "reference": "88e519766fc58bd46b8265561fb79b54e2e00b28", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/658f1be311a230e0907f5dfe0213742aff0596de", + "reference": "658f1be311a230e0907f5dfe0213742aff0596de", "shasum": "" }, "require": { @@ -6777,7 +6927,7 @@ "parser", "php" ], - "time": "2020-08-30T16:15:20+00:00" + "time": "2020-09-26T10:30:38+00:00" }, { "name": "nunomaduro/collision", @@ -6996,16 +7146,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.2.1", + "version": "5.2.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d870572532cd70bc3fab58f2e23ad423c8404c44" + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d870572532cd70bc3fab58f2e23ad423c8404c44", - "reference": "d870572532cd70bc3fab58f2e23ad423c8404c44", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", "shasum": "" }, "require": { @@ -7044,20 +7194,20 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2020-08-15T11:14:08+00:00" + "time": "2020-09-03T19:13:55+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.3.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "e878a14a65245fbe78f8080eba03b47c3b705651" + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e878a14a65245fbe78f8080eba03b47c3b705651", - "reference": "e878a14a65245fbe78f8080eba03b47c3b705651", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", "shasum": "" }, "require": { @@ -7089,7 +7239,7 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2020-06-27T10:12:23+00:00" + "time": "2020-09-17T18:55:26+00:00" }, { "name": "phpspec/prophecy", @@ -8369,16 +8519,16 @@ }, { "name": "spatie/laravel-web-tinker", - "version": "1.7.5", + "version": "1.7.6", "source": { "type": "git", "url": "https://github.com/spatie/laravel-web-tinker.git", - "reference": "bcdc383240ff3518dcd75510a66c87bd1d47c45c" + "reference": "b10982a48819ae871c776cc072de28181e3c0ea4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-web-tinker/zipball/bcdc383240ff3518dcd75510a66c87bd1d47c45c", - "reference": "bcdc383240ff3518dcd75510a66c87bd1d47c45c", + "url": "https://api.github.com/repos/spatie/laravel-web-tinker/zipball/b10982a48819ae871c776cc072de28181e3c0ea4", + "reference": "b10982a48819ae871c776cc072de28181e3c0ea4", "shasum": "" }, "require": { @@ -8433,20 +8583,20 @@ "type": "custom" } ], - "time": "2020-09-09T09:48:48+00:00" + "time": "2020-09-22T15:23:39+00:00" }, { "name": "symfony/filesystem", - "version": "v5.1.5", + "version": "v5.1.6", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "f7b9ed6142a34252d219801d9767dedbd711da1a" + "reference": "f3194303d3077829dbbc1d18f50288b2a01146f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/f7b9ed6142a34252d219801d9767dedbd711da1a", - "reference": "f7b9ed6142a34252d219801d9767dedbd711da1a", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/f3194303d3077829dbbc1d18f50288b2a01146f2", + "reference": "f3194303d3077829dbbc1d18f50288b2a01146f2", "shasum": "" }, "require": { @@ -8497,7 +8647,7 @@ "type": "tidelift" } ], - "time": "2020-08-21T17:19:47+00:00" + "time": "2020-09-02T16:23:27+00:00" }, { "name": "theseer/tokenizer", diff --git a/database/migrations/2020_09_15_080512_create_server_keys_table.php b/database/migrations/2020_09_15_080512_create_server_keys_table.php new file mode 100644 index 000000000..276649fff --- /dev/null +++ b/database/migrations/2020_09_15_080512_create_server_keys_table.php @@ -0,0 +1,45 @@ +uuid('id')->primary(); + $table->string('type'); + $table->string('data')->nullable(); + $table->uuid("server_id"); + $table + ->foreign("server_id") + ->references("id") + ->on("servers") + ->onDelete("cascade"); + $table->uuid("user_id"); + $table + ->foreign("user_id") + ->references("id") + ->on("users") + ->onDelete("cascade"); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('server_keys'); + } +} diff --git a/database/migrations/2020_09_15_133821_update_os_in_servers.php b/database/migrations/2020_09_15_133821_update_os_in_servers.php new file mode 100644 index 000000000..935c6b510 --- /dev/null +++ b/database/migrations/2020_09_15_133821_update_os_in_servers.php @@ -0,0 +1,83 @@ + $server->id]) + ->where(["name" => "clientUsername"]) + ->orWhere(["name" => "clientPassword"]) + ->get(); + foreach ($settings as $setting) { + $user_ids[$setting->user_id][$setting->name] = $setting->value; + $setting->delete(); + } + switch ($server->type) { + case "linux_ssh": + $type = "ssh"; + $os = "linux"; + break; + case "linux": + $os = "linux"; + break; + case "linux_certificate": + $type = "ssh_certificate"; + $os = "linux"; + break; + case "windows_powershell": + $type = "winrm"; + $os = "windows"; + break; + case "windows": + $os = "windows"; + break; + } + if ($type != "") { + foreach ($user_ids as $user_id => $data) { + if ( + !array_key_exists("clientUsername", $data) || + !array_key_exists("clientPassword", $data) + ) { + continue; + } + ServerKey::updateOrCreate( + ["server_id" => $server->id, "user_id" => $user_id], + ["type" => $type, "data" => json_encode($data)] + ); + } + } + if ($os == "") { + continue; + } + $flag = $server->update([ + "os" => $os, + ]); + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + } +} diff --git a/database/migrations/2020_09_23_165704_add_requirekey_to_extensions.php b/database/migrations/2020_09_23_165704_add_requirekey_to_extensions.php new file mode 100644 index 000000000..418166718 --- /dev/null +++ b/database/migrations/2020_09_23_165704_add_requirekey_to_extensions.php @@ -0,0 +1,32 @@ +string('require_key')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('extensions', function (Blueprint $table) { + // + }); + } +} diff --git a/database/migrations/2020_09_30_171001_add_missing_key_port_server_keys.php b/database/migrations/2020_09_30_171001_add_missing_key_port_server_keys.php new file mode 100644 index 000000000..4f89cccd8 --- /dev/null +++ b/database/migrations/2020_09_30_171001_add_missing_key_port_server_keys.php @@ -0,0 +1,63 @@ +data; + $arr = json_decode($temp,true); + + if(!array_key_exists("key_port",$arr)){ + $type = $key->type; + $port = null; + switch($type){ + case "ssh": + case "ssh_certificate": + $port = "22"; + break; + case "winrm": + case "winrm_certificate": + $port = "5986"; + break; + case "snmp": + $port = "161"; + break; + } + + if($port == null){ + continue; + } + + $arr["key_port"] = $port; + $foo = json_encode($arr); + $key->update([ + "data" => $foo + ]); + $key->save(); + } + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/package-lock.json b/package-lock.json index d6943c870..fcc34e9b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5854,9 +5854,9 @@ } }, "lint-staged": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.3.0.tgz", - "integrity": "sha512-an3VgjHqmJk0TORB/sdQl0CTkRg4E5ybYCXTTCSJ5h9jFwZbcgKIx5oVma5e7wp/uKt17s1QYFmYqT9MGVosGw==", + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-10.4.0.tgz", + "integrity": "sha512-uaiX4U5yERUSiIEQc329vhCTDDwUcSvKdRLsNomkYLRzijk3v8V9GWm2Nz0RMVB87VcuzLvtgy6OsjoH++QHIg==", "dev": true, "requires": { "chalk": "^4.1.0", @@ -8407,9 +8407,9 @@ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" }, "prettier": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.1.tgz", - "integrity": "sha512-9bY+5ZWCfqj3ghYBLxApy2zf6m+NJo5GzmLTpr9FsApsfjriNnS2dahWReHMi7qNPhhHl9SYHJs2cHZLgexNIw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz", + "integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==", "dev": true }, "private": { diff --git a/package.json b/package.json index 2371d7938..0e098b07a 100644 --- a/package.json +++ b/package.json @@ -24,9 +24,9 @@ "devDependencies": { "@prettier/plugin-php": "^0.14.3", "laravel-mix": "^4.1.4", - "lint-staged": "^10.3.0", + "lint-staged": "^10.4.0", "pre-commit": "^1.2.2", - "prettier": "^2.1.1", + "prettier": "^2.1.2", "webpack-cli": "^3.3.12" }, "dependencies": { diff --git a/public/english.json b/public/english.json new file mode 100644 index 000000000..10e0f5edf --- /dev/null +++ b/public/english.json @@ -0,0 +1,23 @@ +{ + "sEmptyTable": "No data available in table", + "sInfo": "Showing _START_ to _END_ of _TOTAL_ entries", + "sInfoEmpty": "Showing 0 to 0 of 0 entries", + "sInfoFiltered": "(filtered from _MAX_ total entries)", + "sInfoPostFix": "", + "sInfoThousands": ",", + "sLengthMenu": "Show _MENU_ entries", + "sLoadingRecords": "Loading...", + "sProcessing": "Processing...", + "sSearch": "Search:", + "sZeroRecords": "No matching records found", + "oPaginate": { + "sFirst": "First", + "sLast": "Last", + "sNext": "Next", + "sPrevious": "Previous" + }, + "oAria": { + "sSortAscending": ": activate to sort column ascending", + "sSortDescending": ": activate to sort column descending" + } +} \ No newline at end of file diff --git a/resources/lang/en.json b/resources/lang/en.json index 5ac64cc63..8c7a1aa21 100644 --- a/resources/lang/en.json +++ b/resources/lang/en.json @@ -1,41 +1,125 @@ { + "Email Adresi": "Email Address", + "Beni Hatırla": "Remember Me", + "Giriş Yap ": "Login ", "Ana Sayfa": "Homepage", + "Yetki Talepleri": "Authorization Requests", + "Kaydediliyor.": "Saving.", + "Yetki Taleplerim": "My Requests", + "Talepleriniz": "Your Requests", + "Bakım": "Maintenance", + "Bakım Zamanı": "Maintenance Time", + "Liman Merkezi Yönetim Sistemi şu an bakımda. Lütfen daha sonra tekrar deneyin.": "Liman Central Management System is in maintenance. Please try again later.", + "Bir şeyler ters gitti.": "Something went wrong.", + "Geri Dön": "Go Back", + "Limandaki Sunucu Sayısı": "Server Count in Liman", + "Limandaki Eklenti Sayısı": "Extension Count in Liman", + "Eklenti Sayısı" : "Extension Count", + "Limandaki Kullanıcı Sayısı": "User Count in Liman", + "Limandaki Ayar Sayısı": "Setting Count in Liman", + "Cpu Kullanımı": "Cpu Usage", + "Yükleniyor": "Loading", + "Ram Kullanımı": "Ram Usage", + "Disk Kullanımı": "Disk Usage", + "Düzenlenme Tarihi" : "Last Update Date", + "Ağ Kullanımı": "Network Usage", + "Sunucusu": "Server", + "Yükleniyor..": "Loading..", + "Okundu Olarak İşaretle": "Mark as Read", + "Sil": "Delete", + "Servis Adı" : "Service Name", + "Durumu" : "Status", + "Paket Adı" : "Package Name", + "Tümünü Okundu Olarak İşaretle": "Mark all as Read", + "Okunanları Sil": "Delete read ones.", + "Profilim": "My profile", + "Kullanıcı Adı": "Username", + "Eski Parola": "Old password", + "Parola": "Password", + "Yeni parolanız en az 10 karakter uzunluğunda olmalı ve en az 1 sayı,özel karakter ve büyük harf içermelidir.": "Your new password must be at least 10 characters long and contain at least 1 number, special character, and uppercase letter.", + "Parola Onayı": "Password confirmation", + "Kaydet": "Save", + "Kaydediliyor...": "Saving...", + "Kişisel Erişim Anahtarları": "Personal Access Token", + "Size ait Kişisel Erişim Anahtarları'nın listesini görüntüleyebilirsiniz. Mevcut anahtar üzerinde işlem yapmak için sağ tıklayabilirsiniz.": "You can view the list of your Personal Access Keys. You can right click to update the current key.", + "Çıkış Yap": "Logout", + "Lütfen devam etmeden önce parolanızı değiştirin.": "Please change your password before continuing.", + "Mevcut Parola": "Current Password", + "Yeni Parola": "New Password", + "Yeni Parola Tekrar": "New Password Confirmation", + "Şifreyi Güncelle ": "Update Password ", + "Bileşenler": "Widgets", + "Bileşen Ekle": "Add Widget", + "Sunucu": "Server", + "Eklenti": "Extension", + "Bileşen": "Widget", "Sunucular": "Servers", + "Sistem Durumu": "System Status", + "Eklentiler": "Extensions", + "Servisler": "Services", + "Paketler": "Packages", + "Güncellemeler": "Updates", + "Kullanıcı İşlemleri": "User Operations", + "Yerel Kullanıcılar": "Local Users", + "Yerel Gruplar": "Local Groups", + "Yetkili Kullanıcılar": "Authorized Users", + "Açık Portlar": "Open Ports", + "Erişim Kayıtları": "Access Logs", + "Sunucu Ayarları": "Server Settings", + "Kaynak Kullanımı": "Resource Usage", + "Yükleniyor...": "Loading...", + "Tümünü Güncelle": "Update All", + "Seçilenleri Güncelle": "Update Selected", + "Paket Kur": "Install Package", + "Arama Terimi": "Search Term", + "Sunucu Adı": "Server Name", + "Kontrol Portu": "Control Port", + "Ip Adresi": "Ip Address", + "Şehir": "City", + "Bilgileri Güncelle": "Update Information", + "Okunuyor...": "Reading...", + "Lütfen önce seçim yapınız.": "Please select first.", + "Ayarlarınız doğrulanamadı!": "Your settings could not be verified!", + "Download": "Download", + "Upload": "Upload", + "Onay": "Confirmation", + "Yetkili kullanıcıyı silmek istediğinizden emin misiniz?": "Are you sure you want to delete the authorized user?", + "İptal": "Cancel", + "Lütfen önce bir deb paketi yükleyin.": "Please install a deb package first.", + "Siliniyor...": "Deleting...", + "Deb Paketi" : "Deb Package", + "Depodan Yükle": "Load From Repository", + "Paket Yükle (.deb)": "Upload Package (.deb)", + "Seçilebilir herhangi bir eklenti bulunmamaktadır!": "No extensions can be selected!", + "Sunucu Bilgileri": "Server Information", + "Hostname": "Hostname", + "İşletim Sistemi": "Operating System", + "IP Adresi": "IP Address", + "Kur" : "Install", + "Şifre Onayı" : "Password Confirmation", + "Eklenti Durumları": "Extension Statuses", + "Yüklü eklenti yok.": "No extension installed.", + "Bu sayfadan mevcut sunucularını görebilirsiniz. Ayrıca yeni sunucu eklemek için Sunucu Ekle butonunu kullanabilirsiniz.": "You can see their current servers from this page. You can also use the Add Server button to add a new server.", "Sunucu Ekle": "Add Server", "Bağlantı Bilgileri": "Connection Information", "Genel Ayarlar": "General Settings", "Anahtar": "Key", - "Özet": "Özet", + "Özet": "Summary", "Sunucunuzun Adresi": "Server' Network Address", "Sunucunuzun Hostname yada IP Adresini girin.": "Enter your server' hostname or ip address", "Sunucunuzun Portu": "Server' Control Port", "Sunucunuzun açık olup olmadığını algılamak için kontrol edilebilecek bir port girin.": "Enter a port to determine if your server is open or closed.", "SSH : 22\\nWinRM : 5986\\nActive Directory, Samba : 636": "SSH : 22\\nWinRM : 5986\\nActive Directory, Samba : 636", - "Kontrol Portu Girin (Yalnızca Sayı).": "Kontrol Portu Girin (Yalnızca Sayı).", + "Kontrol Portu Girin (Yalnızca Sayı).": "Enter Control Port (Number Only).", + "Eğer hedefiniz UDP protokolü üzerinden dinliyorsa bu kontrolü atlamak için -1 girebilirsiniz.": "If your target is listening over UDP protocol, you can enter -1 to skip this check.", "Bağlantıyı Kontrol Et": "Check Access", "Sunucunuzun Adı": "Name of the server", - "Şehir": "City", "Sunucunuza bir şehir atayarak, eklentileri kullanırken Türkiye haritası üzerinde erişiminizi kolaylaştırabilirsiniz.": "By the assign a city to your server, you can access it easily from the Turkey map, while using it.", "Şehir Seçiniz": "Choose a city", "Sunucunuzun İşletim Sistemi": "Operating System of the server", "Microsoft Windows": "Microsoft Windows", "GNU\/Linux": "GNU\/Linux", - "Ayarları Onayla": "Ayarları Onayla", - "Liman üzerindeki sunucuların eklentileri servisler üzerinden kullanabileceğiniz gibi, bazı eklentileri sunucuya bağlantı kurmadan kullanamazsınız.": "You can not use some extensions without the key.", - "Bu sebeple, bir anahtar eklemek istiyorsanız öncelikle konuşma protokolünü seçin.": "That's way, if you want to add a key, please select the communication protocol.", - "Bir Anahtar Kullanmak İstiyorum": "I want to use a key", - "Anahtar Türü": "Key Type", - "SSH": "SSH", - "SSH Anahtarı": "SSH Anahtarı", - "WinRM": "WinRM", - "Kullanıcı Adı": "Username", - "Şifre": "Password", - "SSH Private Key": "SSH Private Key", - "Anahtarınızın çalışabilmesi için şifreli olmaması ve sudo komutlarını çalıştırması için sudoers dosyasında NOPASSWD olarak eklenmiş olması gerekmektedir.": "Anahtarınızın çalışabilmesi için şifreli olmaması ve sudo komutlarını çalıştırması için sudoers dosyasında NOPASSWD olarak eklenmiş olması gerekmektedir.", - "Port": "Port", - "Eğer bilmiyorsanız varsayılan olarak bırakabilirsiniz.": "If you don't know you can keep it blank.", - "Sunucu Adı": "Server Name", - "İşletim Sistemi": "Operating System", + "Ayarları Onayla": "Confirm Settings", "Sunucu Adresi": "Server Address", "Sunucu Portu": "Server Port", "Sunucuyu Ekle": "Add Server", @@ -43,105 +127,45 @@ "Anahtarsız": "Anahtarsız", "Lütfen Tüm Ayarları Tamamlayın": "Lütfen Tüm Ayarları Tamamlayın", "Sunucu Ekleniyor...": "Sunucu Ekleniyor...", - "Sunucu Bilgileri": "Sunucu Bilgileri", - "Hostname": "Hostname", - "IP Adresi": "IP Adresi", - "Eklenti Durumları": "Eklenti Durumları", - "Yüklü eklenti yok.": "Yüklü eklenti yok.", - "Sistem Durumu": "Sistem Durumu", - "Eklentiler": "Extensions", - "Servisler": "Servisler", - "Paketler": "Paketler", - "Güncellemeler": "Güncellemeler", - "Kullanıcı İşlemleri": "Kullanıcı İşlemleri", - "Yerel Kullanıcılar": "Yerel Kullanıcılar", - "Yerel Gruplar": "Yerel Gruplar", - "Yetkili Kullanıcılar": "Yetkili Kullanıcılar", - "Açık Portlar": "Açık Portlar", - "Günlük Kayıtları": "Günlük Kayıtları", - "Sunucu Ayarları": "Server Settings", - "Ek Özellikler": "Ek Özellikler", - "Kaynak Kullanımı": "Kaynak Kullanımı", - "Cpu Kullanımı": "Cpu Kullanımı", - "Yükleniyor...": "Loading...", - "Disk Kullanımı": "Disk Kullanımı", - "Ram Kullanımı": "Ram Kullanımı", - "Tümünü Güncelle": "Tümünü Güncelle", - "Seçilenleri Güncelle": "Seçilenleri Güncelle", - "Paket Kur": "Paket Kur", - "Kontrol Portu": "Kontrol Portu", - "Ip Adresi": "Ip Adresi", - "Bilgileri Güncelle": "Bilgileri Güncelle", - "Linux Sunucunuza SSH anahtarı ekleyerek Liman üzerindeki ekstra özelliklere erişebilirsiniz.": "Linux Sunucunuza SSH anahtarı ekleyerek Liman üzerindeki ekstra özelliklere erişebilirsiniz.", - "Windows Sunucunuza WinRM anahtarı ekleyerek Liman üzerindeki ekstra özelliklere erişebilirsiniz.": "Windows Sunucunuza WinRM anahtarı ekleyerek Liman üzerindeki ekstra özelliklere erişebilirsiniz.", - "Parola": "Password", - "Yükselt": "Yükselt", - "Depodan Yükle": "Depodan Yükle", - "Paket Yükle (.deb)": "Paket Yükle (.deb)", - "Seçilebilir herhangi bir eklenti bulunmamaktadır!": "Seçilebilir herhangi bir eklenti bulunmamaktadır!", - "Okunuyor...": "Okunuyor...", - "Lütfen önce seçim yapınız.": "Lütfen önce seçim yapınız.", - "Ayarlarınız doğrulanamadı!": "Ayarlarınız doğrulanamadı!", - "Onay": "Onay", - "Yetkili kullanıcıyı silmek istediğinizden emin misiniz?": "Yetkili kullanıcıyı silmek istediğinizden emin misiniz?", - "İptal": "Cancel", - "Sil": "Sil", - "Lütfen önce bir deb paketi yükleyin.": "Lütfen önce bir deb paketi yükleyin.", - "Siliniyor...": "Deleting...", - "Tümünü Okundu Olarak İşaretle": "Tümünü Okundu Olarak İşaretle", - "Okunanları Sil": "Okunanları Sil", - "Okundu Olarak İşaretle": "Okundu Olarak İşaretle", + "Tam yetkili ana yönetici hesabı ile giriş yaptınız, sisteme zarar verebilirsiniz.": "You are logged in with a fully authorized administrator account, you can damage the system.", + "Favori Sunucular": "Favorite Servers", + "Sunucu Detayları": "Server Details", + "...daha fazla": "...more", + "Yönetim Paneli": "Dashboard", + "Modüller": "Modules", + "Sistem Ayarları": "System Settings", + "Yetki Talebi": "Permission Request", + "Taleplerim": "My Requests", + "Hesap": "Account", + "Profil": "Profile", + "Erişim Anahtarları": "Access Tokens", + "Kasa": "Vault", + "Liman Merkezi Yönetim Sistemi": "Liman Merkezi Yönetim Sistemi", + "\/turkce.json": "\/english.json", + "İşlem" : "Process", + "Boyut" : "Size", + "Dolu" : "Full", + "Tümünü Seç": "Select all", + "Tümünü Kaldır": "Remove All", + "daha az...": "less...", "Ayarlar": "Settings", - "Kullanıcı Ayarları": "User Settings", - "Rol Grupları": "Rol Grupları", - "Sunucu Grupları": "Sunucu Grupları", - "Sertifikalar": "Sertifikalar", - "Sağlık Durumu": "Health Check", - "Güncelleme": "Güncelleme", - "Son Değişiklikler": "Son Değişiklikler", - "Log Yönetimi": "Log Yönetimi", - "Dış Bildirimler": "Dış Bildirimler", - "Sertifika Ekle": "Sertifika Ekle", - "Aktif": "Aktif", - "Pasif": "Pasif", - "Aktifleştir": "Aktifleştir", - "Pasifleştir": "Pasifleştir", - "Liman Üzerindeki İşlem Loglarını hedef bir log sunucusuna rsyslog servisi ile göndermek için hedef log sunucusunun adresi ve portunu yazınız.": "Liman Üzerindeki İşlem Loglarını hedef bir log sunucusuna rsyslog servisi ile göndermek için hedef log sunucusunun adresi ve portunu yazınız.", - "Log Gönderme Aralığı (Dakika)": "Log Gönderme Aralığı (Dakika)", - "Ayarları Kaydet": "Ayarları Kaydet", - "Sunucuları bir gruba ekleyerek eklentiler arası geçişi daha akıcı yapabilirsiniz.": "Sunucuları bir gruba ekleyerek eklentiler arası geçişi daha akıcı yapabilirsiniz.", - "Sunucu Grubu Adı": "Sunucu Grubu Adı", - "Görsel olarak hiçbir yerde gösterilmeyecektir, yalnızca düzenleme kısmındak kolay erişim için eklenmiştir.": "Görsel olarak hiçbir yerde gösterilmeyecektir, yalnızca düzenleme kısmındak kolay erişim için eklenmiştir.", - "Bu gruba eklemek istediğiniz sunucuları seçin.": "Bu gruba eklemek istediğiniz sunucuları seçin.", - "Kaydediliyor...": "Kaydediliyor...", - "Ekleniyor...": "Ekleniyor...", - "Düzenleniyor...": "Düzenleniyor...", - "Sağlık Kontrolü": "Sağlık Kontrolü", - "Sisteme SSL Sertifikası Ekleme": "Sisteme SSL Sertifikası Ekleme", - "sunucusu talebi.": "sunucusu talebi.", - "Al": "Al", - "Sertifika Bilgileri": "Sertifika Bilgileri", - "İmzalayan": "İmzalayan", - "İstemci": "İstemci", - "Otorite": "Otorite", - "Parmak İzleri": "Parmak İzleri", - "Geçerlilik Tarihi": "Geçerlilik Tarihi", - "Başlangıç Tarihi": "Başlangıç Tarihi", - "Bitiş Tarihi": "Bitiş Tarihi", - "Sertifikayı Onayla": "Sertifikayı Onayla", - "Not : Eklediğiniz sertifika işletim sistemi tarafından güvenilecektir.": "Not : Eklediğiniz sertifika işletim sistemi tarafından güvenilecektir.", - "Sertifika Alınıyor...": "Sertifika Alınıyor...", - "Sertifika Ekleniyor...": "Sertifika Ekleniyor...", - " kullanıcısı ayarları": " kullanıcısı ayarları", - ":user_name kullanıcısı ayarları": ":user_name kullanıcısı ayarları", + "Destek Al": "Get Support", + "Son Giriş Tarihi : ": "Last Login Date : ", + "Giriş Yapılan Son Ip : ": "The last IP address logged in : ", + "Bağlı Liman : ": "Connected Liman : ", + "Liman ID: ": "Liman ID: ", + "Sağlık Kontrolü": "Health check", + " kullanıcısı ayarları": " user' settings", + ":user_name kullanıcısı ayarları": ":user_name user' settings", + "Rol Grupları": "Role Groups", "Eklenti Yetkileri": "Extension Authorization", "Sunucu Yetkileri": "Server Authorization", "Fonksiyon Yetkileri": "Function Authorization", + "Liman Yetkileri": "Liman Permissions", "Hesap Türü": "Account Type", "Kullanıcı": "User", "Yönetici": "Admin", "Adı": "Name", - "Email Adresi": "Email Address", "Kullanıcıyı Sil": "Delete User", "Parola Sıfırla": "Reset Password", "Değişiklikleri Kaydet": "Save Changes", @@ -149,166 +173,205 @@ "...": "...", "Seçili Fonksiyonlara Yetki Ver": "Authorize To The Selected", "Güncelleniyor...": "Updating...", - " rol grubunun ayarları": " rol grubunun ayarları", + "Ekleniyor...": "Adding...", + "Kullanıcı Ayarları": "User Settings", + "Sunucu Grupları": "Server Groups", + "Sertifikalar": "Certificates", + "Sağlık Durumu": "Health Check", + "Güncelleme": "Update", + "Son Değişiklikler": "Recent Changes", + "Log Yönetimi": "Log Management", + "Dış Bildirimler": "External Notifications", + "Kısıtlı Mod": "Restricted Mod", + "Liman Market": "Liman Market", + "DNS Ayarları": "DNS Settings", + "Sertifika Ekle": "Add Certificate", + "Liman kurulumunuzu Liman Market'e bağlayarak sistemdeki tüm güncellemeleri takip edebilir, güncellemeleri indirebilirsiniz.": "By connecting your Liman setup to the Liman Market, you can follow and download all updates in the system.", + "Liman Market'i Bağla": "Connect Liman Market", + "Liman'ın sunucu adreslerini çözebilmesi için gerekli DNS sunucularını aşağıdan düzenleyebilirsiniz.": "You can edit the DNS servers required for the Liman to resolve server addresses.", + "Öncelikli DNS Sunucusu": "Priority DNS Server", + "Alternatif DNS Sunucusu": "Alternative DNS Server", + "Aktif": "Active", + "Pasif": "Passive", + "Aktifleştir": "Activate", + "Pasifleştir": "Disable", + "Liman Sürümünüz : \" . getVersion() . \" güncel.": "Liman Version : \" . getVersion() . \" is up to date.", + "Liman'ı kısıtlamak ve kullanıcıların yalnızca bir eklentiyi kullanması için bu modu kullanabilirsiniz. Bu modu kullandığınız taktirde, kullanıcılar varsayılan olarak eklenti ve sunucu yetkisine sahip olacak, ancak fonksiyon yetkilerine sahip olmayacaklardır. Yöneticiler mevcut liman arayüzünü görmeye devam edecek, kullanıcılar ise yalnızca eklenti çerçevesini görüntüleyebilecektir.": "You can use this mode to restrict the Liman and for users to use only one extension. If you use this mode, users will have extension and server permissions by default, but they will not have function permissions. Administrators will still see the current Liman interface, while users will only be able to view the extension framework.", + "Kısıtlı Modu Aktifleştir.": "Enable Restricted Mode.", + "Gösterilecek Sunucu": "Server to Show", + "Lütfen bir sunucu seçin.": "Please choose a server.", + "Gösterilecek Eklenti": "Extension to Show", + "Lütfen bir eklenti seçin.": "Please choose a extension.", + "Ayarları Kaydet": "Save Settings", + "Liman Üzerindeki İşlem Loglarını hedef bir log sunucusuna rsyslog servisi ile göndermek için hedef log sunucusunun adresi ve portunu yazınız.": "Type the address and port of the target log server to send the Transaction Logs on the Liman to a target log server via rsyslog service..", + "Log Gönderme Aralığı (Dakika)": "Log Posting Interval (Minutes)", + "Sunucuları bir gruba ekleyerek eklentiler arası geçişi daha akıcı yapabilirsiniz.": "By adding servers to a group, you can switch between extensions more smoothly.", + "Sunucu Grubu Adı": "Server Group Name", + "Görsel olarak hiçbir yerde gösterilmeyecektir, yalnızca düzenleme kısmındak kolay erişim için eklenmiştir.": "It will not be displayed visually anywhere, only added for easy access in the editing section.", + "Bu gruba eklemek istediğiniz sunucuları seçin.": "Select the servers you want to add to this group.", + "Düzenleniyor...": "Editing...", + "Okunuyor": "Reading", + "Sisteme SSL Sertifikası Ekleme": "Adding an SSL Certificate to the System", + "sunucusu talebi.": "server' request.", + "Port": "Port", + "Al": "Get", + "İmzalayan": "Signatory", + "İstemci": "Client", + "Otorite": "Authority", + "Parmak İzleri": "Finger Prints", + "Geçerlilik Tarihi": "Validity Date", + "Başlangıç Tarihi": "Starting Date", + "Bitiş Tarihi": "End Date", + "Sertifikayı Onayla": "Confirm Certificate", + "Not : Eklediğiniz sertifika işletim sistemi tarafından güvenilecektir.": "Note: The certificate you add will be trusted by the operating system.", + "Sertifika Alınıyor...": "Getting a Certificate...", + "Sertifika Ekleniyor...": "Adding a Certificate...", + " rol grubunun ayarları": " role group settings", "Kullanıcılar": "Users", - "Tam yetkili ana yönetici hesabı ile giriş yaptınız, sisteme zarar verebilirsiniz.": "You are logged in with a fully authorized administrator account, you can damage the system.", - "Liman Sistem Yönetimi": "Liman System Manager", - "Tümünü Seç": "Tümünü Seç", - "Tümünü Kaldır": "Tümünü Kaldır", - "...daha fazla": "...more", - "daha az...": "less...", - "Favori Sunucular": "Favorite Servers", - "Sunucu Detayları": "Server Details", - "Yönetim Paneli": "Dashboard", - "Modüller": "Modüller", - "Yetki Talepleri": "Authorization Requests", - "Yetki Talebi": "Yetki Talebi", - "Taleplerim": "Taleplerim", - "Kasa": "Vault", - "Bileşenler": "Widgets", - "Son Giriş Tarihi : ": "Son Giriş Tarihi : ", - "Giriş Yapılan Son Ip : ": "The last IP address logged in : ", - "Profil": "Profile", - "Çıkış Yap": "Logout", - "Devre Dışı": "Devre Dışı", - "Tetikleyiciler Liman MYS içerisindeki belli başlı olayların modüllere iletilmesi ile görevlidir.Örneğin bir modül eğer bir anahtar yöntemi oluşturmak ile görevli ise, bunun için anahtar doğrulama tetiğine ihtiyaç duyar.": "Tetikleyiciler Liman MYS içerisindeki belli başlı olayların modüllere iletilmesi ile görevlidir.Örneğin bir modül eğer bir anahtar yöntemi oluşturmak ile görevli ise, bunun için anahtar doğrulama tetiğine ihtiyaç duyar.", - "Tetikleyicileri aşağıdan kısıtlayabilirsiniz, fakat bu durumda modül çalışmayabilir.": "Tetikleyicileri aşağıdan kısıtlayabilirsiniz, fakat bu durumda modül çalışmayabilir.", - "Seçili Tetikleyicilere : ": "Seçili Tetikleyicilere : ", - "İzin Ver": "İzin Ver", - "İznini Sil": "İznini Sil", - "Kaydet": "Save", - "Sunucu Bakımda": "Sunucu Bakımda", - "Bakım Zamanı": "Bakım Zamanı", - "Liman Merkezi Yönetim Sistemi şu an bakımda. Lütfen daha sonra tekrar deneyin.": "Liman Merkezi Yönetim Sistemi şu an bakımda. Lütfen daha sonra tekrar deneyin.", - "Limandaki Sunucu Sayısı": "Limandaki Sunucu Sayısı", - "Limandaki Eklenti Sayısı": "Limandaki Eklenti Sayısı", - "Limandaki Kullanıcı Sayısı": "Limandaki Kullanıcı Sayısı", - "Limandaki Ayar Sayısı": "Limandaki Ayar Sayısı", - "Yükleniyor": "Loading", - "Ağ Kullanımı": "Ağ Kullanımı", - "Sunucusu": "Server", - "Yükleniyor..": "Yükleniyor..", - "Bileşen Ekle": "Add Widget", - "Sunucu": "Server", - "Eklenti": "Extension", - "Bileşen": "Bileşen", - "Lütfen devam etmeden önce parolanızı değiştirin.": "Lütfen devam etmeden önce parolanızı değiştirin.", - "Mevcut Parola": "Mevcut Parola", - "Yeni Parola": "Yeni Parola", - "Yeni Parola Tekrar": "Yeni Parola Tekrar", - "Şifreyi Güncelle ": "Şifreyi Güncelle ", - "Profilim": "Profilim", - "Eski Parola": "Eski Parola", - "Yeni parolanız en az 10 karakter uzunluğunda olmalı ve en az 1 sayı,özel karakter ve büyük harf içermelidir.": "Yeni parolanız en az 10 karakter uzunluğunda olmalı ve en az 1 sayı,özel karakter ve büyük harf içermelidir.", - "Parola Onayı": "Parola Onayı", - "Tümünü gör": "Tümünü gör", - "Gözat": "Gözat", - "Yükle": "Upload", - "Yükleme tamamlandı": "Yükleme tamamlandı", - "Düzenle": "Edit", - "Önceki": "Önceki", - "Sonraki": "Sonraki", + "Önceki": "Previous", + "Sonraki": "Next", "Eklenti Yönetimi": "Extension Management", - "Geri Dön": "Go Back", - "Başarıyla kaydedildi": "Başarıyla kaydedildi", - "Hata!": "Hata!", + "Başarıyla kaydedildi": "Successfully saved", + "Gözat": "Browse", + "Yükle": "Upload", + "Yükleme tamamlandı": "Upload Complete", "Tipi": "Type", - "Tablo Oluşturulamadı.": "Tablo Oluşturulamadı.", - "Anahtar Ekle": "Add Key", - "Önbelleği Temizle": "Önbelleği Temizle", - "Bilgilendirme!": "Bilgilendirme!", - "Güvenliğiniz için varolan verileriniz gösterilmemektedir.": "Güvenliğiniz için varolan verileriniz gösterilmemektedir.", - "Önbellek temizlendi!": "Önbellek temizlendi!", - "Email Adresi ve Ldap Kullanıcı Adı": "Email Adresi ve Ldap Kullanıcı Adı", - "Beni Hatırla": "Remember Me", - "Giriş Yap ": "Giriş Yap ", - "Kaydediliyor.": "Kaydediliyor.", - "Yetki Taleplerim": "Yetki Taleplerim", - "Talepleriniz": "Talepleriniz", - "Eklenti Ayarları": "Extension Settings", - "Önceki ayarlarınızdan sizin için birkaç veri eklendi.": "Önceki ayarlarınızdan sizin için birkaç veri eklendi.", - "Tekrar": "Tekrar", - "Bu eklentinin hiçbir ayarı yok.": "Bu eklentinin hiçbir ayarı yok.", - "Sunucuları": "Servers", - "İstek": "İstek", - "saniyede tamamlandı.": "saniyede tamamlandı.", - "Güvenli olmayan üretici!": "Güvenli olmayan üretici!", - "Maksimum eklenti boyutunu (100MB) aştınız!": "Maksimum eklenti boyutunu (100MB) aştınız!", - "Tamam": "Tamam", - "Eklenti Veritabanı": "Eklenti Veritabanı", - "Widgetlar": "Widgetlar", - "Fonksiyonlar": "Fonksiyonlar", + "Tablo Oluşturulamadı.": "Failed To Create Table.", + "Yönlendiriliyor...": "Redirecting...", + "Düzenle": "Edit", + "Hata!": "Error!", + "Tümünü gör": "See all", + "Güncellemeleri Yükle": "Install Updates", + "Şimdi Güncelle": "Update Now", + "Maksimum eklenti boyutunu (100MB) aştınız!": "You have exceeded the maximum extension size (100MB)!", + "Tamam": "OK", + "Eklenti Veritabanı": "Extension Database", + "Fonksiyonlar": "Functions", "Eklenti Adı": "Extension Name", - "Yayınlayan": "Yayınlayan", - "Yazılım Dili": "Yazılım Dili", - "Destek Email'i": "Destek Email'i", - "Logo (Font Awesome Ikon)": "Logo (Font Awesome Ikon)", + "Yayınlayan": "Publisher", + "Yazılım Dili": "Software Language", + "Anahtar'ı Zorunlu Kıl": "Require Key", + "Destek Email'i": "Support Email", + "Logo (Font Awesome Ikon)": "Logo (Font Awesome Icon)", + "Gerekli Minimum Liman Sürüm Kodu": "Required Minimum Liman Version Code", + "Mevcut Liman Sürüm Kodunu Al": "Get Current Liman Version Code", "Versiyon": "Version", - "Ayar Doğrulama Fonksiyonu\/Betiği": "Ayar Doğrulama Fonksiyonu\/Betiği", - "Servis Adı yada Kontrol Etmek için Port": "Servis Adı yada Kontrol Etmek için Port", - "SSL Sertifikası Eklenecek Portlar": "SSL Sertifikası Eklenecek Portlar", - "Birden fazla port yazmak için aralarında virgül bırakabilirsiniz.": "Birden fazla port yazmak için aralarında virgül bırakabilirsiniz.", - "Parametreyi silmek istediğinizden emin misiniz?": "Parametreyi silmek istediğinizden emin misiniz?", - ":server_name isimli sunucuya erişim sağlanamadı!": ":server_name isimli sunucuya erişim sağlanamadı!", - ":server_name isimli sunucu için gerekli SSL sertifikası henüz eklenmemiş!": ":server_name isimli sunucu için gerekli SSL sertifikası henüz eklenmemiş!", - "Başarılı": "Success", - "Kaydedildi!": "Kaydedildi!", - "Parola alanları uyuşmuyor!": "Parola alanları uyuşmuyor!", - "Talep Alındı": "Talep Alındı", - "İşleniyor": "İşleniyor", - "Tamamlandı.": "Tamamlandı.", - "Reddedildi.": "Reddedildi.", - "Bilinmeyen.": "Bilinmeyen.", - "Anahtar - Kullanıcı Adı": "Anahtar - Kullanıcı Adı", - "Anahtar - Şifre": "Anahtar - Şifre", - "Sunucu Silinmiş.": "Sunucu Silinmiş.", - "Diğer": "Diğer", - "Normal": "Normal", - "ACİL": "ACİL", - "İşleniyor.": "İşleniyor.", - "Tamamlandı": "Tamamlandı", - "Reddedildi": "Reddedildi", - "Talebiniz güncellendi": "Talebiniz güncellendi", - "Talebiniz \\\":status\\\" olarak güncellendi.": "Talebiniz \\\":status\\\" olarak güncellendi.", - "Bileşen Bulunamadı": "Bileşen Bulunamadı", - "Eklenti ayarları eksik.": "Eklenti ayarları eksik.", - "Ayarlara Git.": "Ayarlara Git.", - "Bileşen Hiçbir Veri Döndürmedi": "Bileşen Hiçbir Veri Döndürmedi", - "Bilinmeyen bir hata oluştu.": "Unknown error.", - "Başarıyla silindi": "Başarıyla silindi", - "Başarıyla güncellendi.": "Başarıyla güncellendi.", - "Yeni sunucu eklendi.": "Yeni sunucu eklendi.", - ":server (:ip) isimli yeni bir sunucu eklendi.": ":server (:ip) isimli yeni bir sunucu eklendi.", - "Bir sunucu silindi.": "Bir sunucu silindi.", - ":server (:ip) isimli sunucu silindi.": ":server (:ip) isimli sunucu silindi.", - "Server Adı Güncellemesi": "Server Adı Güncellemesi", - ":old isimli sunucunun adı :new olarak değiştirildi.": ":old isimli sunucunun adı :new olarak değiştirildi.", - "Paket Güncelleme: :package_name": "Paket Güncelleme: :package_name", - ":package_name paketi için güncelleme isteği gönderildi.": ":package_name paketi için güncelleme isteği gönderildi.", - ":package_name paketi başarıyla kuruldu.": ":package_name paketi başarıyla kuruldu.", - ":package_name paketi kurulamadı.": ":package_name paketi kurulamadı.", - "Grup üyeleri başarıyla eklendi.": "Grup üyeleri başarıyla eklendi.", - "Rol grupları kullanıcıya başarıyla eklendi.": "Rol grupları kullanıcıya başarıyla eklendi.", - "Rol grupları başarıyla silindi.": "Rol grupları başarıyla silindi.", - "Grup üyeleri başarıyla silindi.": "Grup üyeleri başarıyla silindi.", - "Sunucuya Bağlanılamadı.": "Sunucuya Bağlanılamadı.", - "Liman Bildiri Sistemi": "Liman Bildiri Sistemi", - "Not Found": "Not Found", + "Paketin Adı" : "Name of the Package", + "Paketin depodaki adını giriniz. Örneğin: chromium" : "Enter the package name in the repository. Ex: chromium", + "Ayar Doğrulama Fonksiyonu\/Betiği": "Setting Verification Function \/ Script", + "Paket bağımlılıkları": "Package dependencies", + "Birden fazla paket yazmak için aralarında boşluk bırakabilirsiniz.": "To write multiple packages, you can leave a space between them..", + "Servis Adı yada Kontrol Etmek için Port": "Service Name or Port to Check", + "SSL Sertifikası Eklenecek Portlar": "Ports to Add SSL Certificate", + "Birden fazla port yazmak için aralarında virgül bırakabilirsiniz.": "To write more than one port, you can leave commas between them..", + "Parametreyi silmek istediğinizden emin misiniz?": "Are you sure you want to delete the parameter?", + "Sunucuları": "Servers", + "Aşağıdaki komut ile Liman MYS'ye dışarıdan istek gönderebilirsiniz.Eğer SSL sertifikanız yoksa, komutun sonuna --insecure ekleyebilirsiniz.": "You can send an external request to Liman MYS with the following command.If you don't have an SSL certificate, you can add --insecure to the end of the command.", + "Bu sorgu içerisinde ve(ya) sonucunda kurumsal veriler bulunabilir, sorumluluk size aittir.": "Institutional data can be found in this query and (or as a result), you are responsible.", + "Kullanılacak Kişisel Erişim Anahtarı": "Personal Access Key to be used", + "Eklenti Ayarları": "Extension Settings", + "Önceki ayarlarınızdan sizin için birkaç veri eklendi.": "Several data has been added for you from your previous settings.", + "Tekrar": "Again", + "Bu eklentinin hiçbir ayarı yok.": "This extension has no settings.", + "Anahtar Ekle": "Add Key", + "Önbelleği Temizle": "Clear Cache", + "Bilgilendirme!": "Information!", + "Güvenliğiniz için varolan verileriniz gösterilmemektedir.": "For your security, your existing data is not shown.", + "Önbellek temizlendi!": "Cache cleared!", + "Liman üzerindeki sunucuların eklentileri servisler üzerinden kullanabileceğiniz gibi, bazı eklentileri sunucuya bağlantı kurmadan kullanamazsınız.": "You can not use some extensions without the key.", + "Bu sebeple, bir anahtar eklemek istiyorsanız öncelikle konuşma protokolünü seçin.": "That's way, if you want to add a key, please select the communication protocol.", + "Bir Anahtar Kullanmak İstiyorum": "I want to use a key", + "Anahtar Türü": "Key Type", + "SSH": "SSH", + "SSH Anahtarı": "SSH Key", + "WinRM": "WinRM", + "WinRM (Sertifikalı)": "WinRM (Certificate)", + "SNMP": "SNMP", + "Şifre": "Password", + "SSH Private Key": "SSH Private Key", + "Anahtarınızın çalışabilmesi için şifreli olmaması ve sudo komutlarını çalıştırması için sudoers dosyasında NOPASSWD olarak eklenmiş olması gerekmektedir.": "In order for your key to work, it must not be encrypted and must be added as NOPASSWD in the sudoers file to run sudo commands.", + "Eğer bilmiyorsanız varsayılan olarak bırakabilirsiniz.": "If you don't know you can keep it blank.", + "Server Error": "Server Error", + "Unauthorized": "Unauthorized", "Oh no": "Oh no", "Go Home": "Go Home", - "Unauthorized": "Unauthorized", - "Server Error": "Server Error", - "Page Expired": "Page Expired", - "Forbidden": "Forbidden", + "Not Found": "Not Found", + "Anahtarı Ekle" : "Add the Key", + "Veriyi Sil" : "Delete Data", "Service Unavailable": "Service Unavailable", + "Page Expired": "Page Expired", "Too Many Requests": "Too Many Requests", + "Forbidden": "Forbidden", + "Bir sunucu silindi.": "A server was deleted.", + ":server (:ip) isimli sunucu silindi.": ":server (:ip) named server was deleted.", + "Server Adı Güncellemesi": "Server Name Update", + ":old isimli sunucunun adı :new olarak değiştirildi.": "Name of the server named: old changed to: new.", + ":package_name paketi başarıyla kuruldu.": ":package_name has been installed successfully.", + ":package_name paketi kurulamadı.": ":package_name could not be installed.", + "Yeni sunucu eklendi.": "New server added.", + ":server (:ip) isimli yeni bir sunucu eklendi.": "A new server named :server (:ip) has been added.", + "Diğer": "Other", + "Bilinmeyen.": "Unknown.", + "Talep Alındı": "Request Received", + "İşleniyor": "Processing", + "Tamamlandı.": "Completed.", + "Reddedildi.": "Denied.", + "Normal": "Normal", + "ACİL": "URGENT", + "İşleniyor.": "Processing.", + "Tamamlandı": "Completed", + "Reddedildi": "Denied", + "Talebiniz güncellendi": "Your request has been updated", + "Talebiniz \\\":status\\\" olarak güncellendi.": "Your request \\\":status\\\" been updated.", + "Başarıyla silindi": "Successfully deleted", + "Başarıyla güncellendi.": "Successfully updated.", + "Güvenli olmayan üretici!": "Unsafe producer!", + "Başarılı": "Success", + "Yetki(ler) silinemedi": "The authorization (s) could not be deleted", + "Kaydedildi!": "Saved!", + "Sunucu Silinmiş.": "Server Deleted.", + "Parola alanları uyuşmuyor!": "Password fields do not match!", + "Grup üyeleri başarıyla eklendi.": "Group members successfully added.", + "Rol grupları kullanıcıya başarıyla eklendi.": "Role groups have been successfully added to the user.", + "Rol grupları başarıyla silindi.": "Role groups successfully deleted.", + "Grup üyeleri başarıyla silindi.": "Group members were deleted successfully.", + ":server_name isimli sunucuya erişim sağlanamadı!": "Could not access server named :server_name !", + "Liman Sistem Servisine Erişilemiyor!": "Cannot Access Liman System Service!", + "Liman Bildiri Sistemi": "Liman Notification System", + "Sunucuya Bağlanılamadı.": "Could Not Connect to Server.", + "Liman Merkezi Sistem Yönetimi": "Liman Central System Management", + "Günlük Kayıtları": "Journal Records", + "Ek Özellikler": "Additional Features", + "Yükselt": "Upgrade", + "Sertifika Bilgileri": "Certificate information", + "Liman Sistem Yönetimi": "Liman System Manager", + "Devre Dışı": "Out of Order", + "Tetikleyiciler Liman MYS içerisindeki belli başlı olayların modüllere iletilmesi ile görevlidir.Örneğin bir modül eğer bir anahtar yöntemi oluşturmak ile görevli ise, bunun için anahtar doğrulama tetiğine ihtiyaç duyar.": "Triggers are responsible for transmitting certain events in the Liman MYS to modules.For example, if a module is tasked with generating a key method, it needs a key validation trigger..", + "Tetikleyicileri aşağıdan kısıtlayabilirsiniz, fakat bu durumda modül çalışmayabilir.": "You can restrict the triggers below, but in this case the module may not work..", + "Seçili Tetikleyicilere : ": "Selected Triggers : ", + "İzin Ver": "Allow", + "İznini Sil": "Delete Permission", + "Sunucu Bakımda": "Server Maintenance", + "Email Adresi ve Ldap Kullanıcı Adı": "Email Address and Ldap Username", + "İstek": "Request", + "saniyede tamamlandı.": "seconds took.", + "Widgetlar": "Widgets", + ":server_name isimli sunucu için gerekli SSL sertifikası henüz eklenmemiş!": ":server_name named server missing required SSL certificate!", + "Anahtar - Kullanıcı Adı": "Key - Username", + "Anahtar - Şifre": "Key - Password", + "Bileşen Bulunamadı": "Widget Not Found", + "Eklenti ayarları eksik.": "Extension settings missing.", + "Ayarlara Git.": "Go to Settings.", + "Bileşen Hiçbir Veri Döndürmedi": "Widget returned nothing", + "Bilinmeyen bir hata oluştu.": "Unknown error.", + "Paket Güncelleme: :package_name": "Package update: :package_name", + ":package_name paketi için güncelleme isteği gönderildi.": ":package_name requested to update.", "Giriş Yap": "Login", "E-Mail Adresi": "E-Mail Adress", "SSH Anahtarları": "SSH Keys", "Liman Kullanıcıları": "Liman Users", "Gruplar": "Groups", "Bilgisayarlar": "Computers", - "Sistem Ayarları": "System Settings", "Anahtar Adı": "Key Name", "Şifreyi Göster": "Show Password", "Ekle": "Add", @@ -321,7 +384,7 @@ "3 Saniye içinde geri yönlendirileceksiniz...": "You will be redirected within 3 seconds...", "Sunucu bulunamadı.": "Cannot find the server.", "Sunucuya erişmek için izniniz yok.": "You are not allowed to access this server.", - "No Server Information Supplied": "Server bilgisi verilmedi.", + "No Server Information Supplied": "Server information was not provided.", "Komut Çalıştır": "Execute Command", "Servisleri Düzenle": "Edit Services", "Özel komut çalıştırma sorumluluğunu kabul ediyorum. ": "I accept the responsibility to run a custom command.", @@ -369,7 +432,7 @@ "Politika Sayısı": "Policy Count", "Sunucuya bağlanılamadı": "Couldn't connect to the server", "Hatalar": "Errors", - "Başarılı Girişler": "Succes Logins", + "Başarılı Girişler": "Successful Logins", "İndir": "Download", "Yeni": "New", "Tip": "Type", @@ -389,22 +452,98 @@ "Liman Sistem Yönetimi'ne Hoşgeldiniz!": "Welcome to the Liman MYS!", "Onayla": "Verify", "İsim Onaylandı.": "Name Verified", + "İsim" : "Name", + "Grup Ekle" : "Add Group", + "Grup Adı" : "Group Name", + "Yetki" : "Permission", + "Tam Yetkili Kullanıcı Ekle" : "Add Fully Authorized User", + "Grup veya kullanıcı ekleyebilirsiniz. Örneğin: kullanıcı adı veya %grupadı" : "You can add groups or users. For example: username or %groupname", + "Program Adı" : "Program Name", + "İp Türü" : "IP Type", + "Paket Türü" : "Package Type", + "Fonksiyon" : "Function", + "İşlem Tarihi" : "Transaction Date", + "Sorgu Oluştur" : "Create Query", + "Eklenti Güncellemeleri" : "Extension Updates", + "Taşı" : "Move", + "Lisans Ekle" : "Add License", + "Lisans" : "License", + "Varsa mevcut lisansınızın üzerine yazılacaktır." : "Your current license will be overwritten if any.", + "Sunucuyu silmek istediğinize emin misiniz? Bu işlem geri alınamayacaktır." : "Are you sure you want to delete the server? This process cannot be undone.", + "Kullanıcıyı silmek istediğinize emin misiniz? Bu işlem geri alınamayacaktır." : "Are you sure you want to delete the user? This process cannot be undone.", + "Eklentiyi silmek istediğinize emin misiniz? Bu işlem geri alınamayacaktır." : "Are you sure you want to delete the extension? This process cannot be undone.", + "Rol grubunu silmek istediğinize emin misiniz? Bu işlem geri alınamayacaktır." : "Are you sure you want to delete the role group? This process cannot be undone.", + "Sunucuyu Düzenle" : "Edit Server", + "Eklentiyi Sil" : "Delete Extension", + "Sol menüde kaç eklenti gözüksün?" : "How many extensions appear in the left menu?", "Bu isimde zaten bir sunucu var.": "There's already a server with this name", + "Eklenti şu an güncelleniyor, lütfen birazdan tekrar deneyin." : "The extension is currently being updated, please try again later.", + "Bu eklentiyi kullanabilmek için bir anahtara ihtiyacınız var, lütfen kasa üzerinden bir anahtar ekleyin." : "You need a key to use this extension, please add a key through the vault.", "Sunucuya erişim sağlanamadı.": "Couldn't connect to the server", "Son Güncelleme Tarihi": "Last Update", "Parolayı Sıfırla": "Reset Password", "Parolayı sıfırlamak istediğinize emin misiniz? Bu işlem geri alınamayacaktır.": "Password wil be reset, are you sure? It can not be undone.", "Eklenti Listesi": "Extensions", + "Kullanıcı Listesi": "User List", + "Seçili Kullanıcıları Gruba Ekle": "Add selected user to Role", "Seçili Eklentilere Yetki Ver": "Authorize To The Selected", "Başarılı!": "Success!", "Seçili Betiklere Yetki Ver": "Authorize To The Selected", "Sunucu Listesi": "Servers", + "Türü" : "Type", + "Kaldır" : "Remove", + "Fonksiyon Adı" : "Function Name", + "Özellik Listesi" : "Feature List", + "Seçili Özelliklere Yetki Ver" : "Authorize Selected Features", + "Variable Adı" : "Variable Name", + "Veri Düzenle" : "Edit Data", + "Ayarları Düzenle" : "Edit Settings", + "Zorunlu Alan" : "Required Field", + "Veri'yi Sil" : "Delete Data", + "Rol Grubu Ekle" : "Add Role Group", + "Rol Grubu Adı" : "Role Group Name", + "Rol Grubunu Sil" : "Delete Role Group", + "Sunucuları Gruplama" : "Server Groupping", + "Sunucu Grubu Ekle" : "Add Server Group", + "Herşey Yolunda, sıkıntı yok!" : "Everything is fine!", + "Yeni Bildirim İstemcisi Ekle" : "Add External Notification Client", + "İp Adresi / Hostname" : "Ip Address / Hostname", + "İp Adresi bölümüne izin vermek istediğiniz bir subnet adresini ya da ip adresini yazarak erişimi kısıtlayabilirsiniz. Örneğin : 192.168.1.0/24" : "You can restrict access by typing a subnet address or ip address that you want to allow in the Ip Address section. For example: 192.168.1.0/24", + "Servis" : "Service", + "Yeni İstemci Ekle" : "Add New Client", + "Güncellemeler kontrol ediliyor..." : "Checking for updates ...", + "Güncellemeler başarıyla kontrol edildi" : "Updates checked successfully", + "Veri'yi silmek istediğinize emin misiniz? Bu işlem geri alınamayacaktır." : "Are you sure you want to delete data? This process cannot be undone.", + "Sunucu grubunu silmek istediğinize emin misiniz? Bu işlem geri alınamayacaktır." : "Are you sure you want to delete server group? This process cannot be undone.", + "Verinizin türü form elemanını belirler. Örneğin text, password vs." : "The type of your data determines the form element. For example text, password etc.", + "Eklenti içinden veriye bu isim ile erişirsiniz." : "You access the data with this name from within the extension.", + "Veri Ekle" : "Add Data", + "Veri adı oluşturulan formlarda gösterilmek için kullanılır." : "The data name is used to display in the created forms.", "Seçili Sunuculara Yetki Ver": "Authorize To The Selected", "Sunucu Seçin": "Choose Server", + "Bu sayfadan mevcut bileşenleri görebilirsiniz. Ayrıca yeni bileşen eklemek için Bileşen Ekle butonunu kullanabilirsiniz." : "You can view the available widgets from this page. You can also use the Add Widget button to add new widgets.", + "Market bağlantısı kontrol ediliyor..." : "Checking the market connection ...", + "Market Bağlantısı Başarıyla Sağlandı." : "Market Connection Successfully Established.", + "Mevcut Versiyon" : "Current Version", "Ayar Adı": "Name", + "Başlık" : "Title", + "Güncel" : "Up to date", + " sürümü mevcut" : " version available", + "Sunucu Grubu Düzenleme" : "Edit Server Group", + "Sunucu Grubunu Sil" : "Delete Server Group", "Yeni Eklenti Oluştur": "Create a new extension", "Oluştur": "Create", + "Son Giriş Yapılan IP" : "Last Logged in IP", "Eklenti İndir": "Download Extension", + "Son Giriş Tarihi" : "Last Login Time", + "Bilgiler" : "Informations", + "Anahtar Oluştur" : "Add Key", + "Son Kullanılan Tarih" : "Last Used Date", + "Son Kullanan Ip Adresi" : "Last Used IP Address", + "Anahtarı Sil" : "Delete Key", + "Veri Adı" : "Data Name", + "Güncelle" : "Update", + "Sunucu anahtarını güncellemek için yeniden anahtar eklemelisiniz." : "To update the server key, you must add key again.", "Eklenti Seçin": "Choose Extension", "Eklenti Yükle": "Upload Extension", "Lütfen Eklenti Dosyasını(.lmne) Seçiniz": "Please select the extension file(.lmne)", diff --git a/resources/views/email/external_notification.blade.php b/resources/views/email/external_notification.blade.php new file mode 100644 index 000000000..23e247614 --- /dev/null +++ b/resources/views/email/external_notification.blade.php @@ -0,0 +1,3 @@ +
{{$notification->message}}\ No newline at end of file diff --git a/resources/views/extension_pages/manager.blade.php b/resources/views/extension_pages/manager.blade.php index 62822d0d0..2a05b014a 100644 --- a/resources/views/extension_pages/manager.blade.php +++ b/resources/views/extension_pages/manager.blade.php @@ -19,7 +19,7 @@ @endif