Merge branch 'release/v0.7.11'

This commit is contained in:
Dane Everitt 2018-11-10 15:42:13 -08:00
commit 75a222fe06
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
64 changed files with 1115 additions and 442 deletions

76
.dev/docker/README.md Normal file
View file

@ -0,0 +1,76 @@
# Pterodactyl Panel - Docker Image
This is a ready to use docker image for the panel.
## Requirements
This docker image requires some additional software to function. The software can either be provided in other containers (see the [docker-compose.yml](docker-compose.yml) as an example) or as existing instances.
A mysql database is required. We recommend the stock [MariaDB Image](https://hub.docker.com/_/mariadb/) image if you prefer to run it in a docker container. As a non-containerized option we recommend mariadb.
A caching software is required as well. We recommend the stock [Redis Image](https://hub.docker.com/_/redis/) image. You can choose any of the [supported options](#cache-drivers).
You can provide additional settings using a custom `.env` file or by setting the appropriate environment variables in the docker-compose file.
## Setup
Start the docker container and the required dependencies (either provide existing ones or start containers as well, see the [docker-compose.yml](docker-compose.yml) file as an example).
After the startup is complete you'll need to create a user.
If you are running the docker container without docker-compose, use:
```
docker exec -it <container id> php artisan p:user:make
```
If you are using docker compose use
```
docker-compose exec panel php artisan p:user:make
```
## Environment Variables
There are multiple environment variables to configure the panel when not providing your own `.env` file, see the following table for details on each available option.
Note: If your `APP_URL` starts with `https://` you need to provide an `LETSENCRYPT_EMAIL` as well so Certificates can be generated.
| Variable | Description | Required |
| ------------------- | ------------------------------------------------------------------------------ | -------- |
| `APP_URL` | The URL the panel will be reachable with (including protocol) | yes |
| `APP_TIMEZONE` | The timezone to use for the panel | yes |
| `LETSENCRYPT_EMAIL` | The email used for letsencrypt certificate generation | yes |
| `DB_HOST` | The host of the mysql instance | yes |
| `DB_PORT` | The port of the mysql instance | yes |
| `DB_DATABASE` | The name of the mysql database | yes |
| `DB_USERNAME` | The mysql user | yes |
| `DB_PASSWORD` | The mysql password for the specified user | yes |
| `CACHE_DRIVER` | The cache driver (see [Cache drivers](#cache-drivers) for detais) | yes |
| `SESSION_DRIVER` | | yes |
| `QUEUE_DRIVER` | | yes |
| `REDIS_HOST` | The hostname or IP address of the redis database | yes |
| `REDIS_PASSWORD` | The password used to secure the redis database | maybe |
| `REDIS_PORT` | The port the redis database is using on the host | maybe |
| `MAIL_DRIVER` | The email driver (see [Mail drivers](#mail-drivers) for details) | yes |
| `MAIL_FROM` | The email that should be used as the sender email | yes |
| `MAIL_HOST` | The host of your mail driver instance | maybe |
| `MAIL_PORT` | The port of your mail driver instance | maybe |
| `MAIL_USERNAME` | The username for your mail driver | maybe |
| `MAIL_PASSWORD` | The password for your mail driver | maybe |
### Cache drivers
You can choose between different cache drivers depending on what you prefer.
We recommend redis when using docker as it can be started in a container easily.
| Driver | Description | Required variables |
| -------- | ------------------------------------ | ------------------------------------------------------ |
| redis | host where redis is running | `REDIS_HOST` |
| redis | port redis is running on | `REDIS_PORT` |
| redis | redis database password | `REDIS_PASSWORD` |
### Mail drivers
You can choose between different mail drivers according to your needs.
Every driver requires `MAIL_FROM` to be set.
| Driver | Description | Required variables |
| -------- | ------------------------------------ | ------------------------------------------------------------- |
| mail | uses the installed php mail | |
| mandrill | [Mandrill](http://www.mandrill.com/) | `MAIL_USERNAME` |
| postmark | [Postmark](https://postmarkapp.com/) | `MAIL_USERNAME` |
| mailgun | [Mailgun](https://www.mailgun.com/) | `MAIL_USERNAME`, `MAIL_HOST` |
| smtp | Any SMTP server can be configured | `MAIL_USERNAME`, `MAIL_HOST`, `MAIL_PASSWORD`, `MAIL_PORT` |

51
.dev/docker/default.conf Normal file
View file

@ -0,0 +1,51 @@
# If using Ubuntu this file should be placed in:
# /etc/nginx/sites-available/
#
# If using CentOS this file should be placed in:
# /etc/nginx/conf.d/
#
server {
listen 80;
server_name _;
root /app/public;
index index.html index.htm index.php;
charset utf-8;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
access_log off;
error_log /var/log/nginx/pterodactyl.app-error.log error;
# allow larger file uploads and longer script runtimes
client_max_body_size 100m;
client_body_timeout 120s;
sendfile off;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# the fastcgi_pass path needs to be changed accordingly when using CentOS
fastcgi_pass unix:/var/run/php/php-fpm7.2.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M";
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTP_PROXY "";
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
}
location ~ /\.ht {
deny all;
}
}

View file

@ -0,0 +1,70 @@
# If using Ubuntu this file should be placed in:
# /etc/nginx/sites-available/
#
server {
listen 80;
server_name <domain>;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name <domain>;
root /var/www/pterodactyl/public;
index index.php;
access_log /var/log/nginx/pterodactyl.app-access.log;
error_log /var/log/nginx/pterodactyl.app-error.log error;
# allow larger file uploads and longer script runtimes
client_max_body_size 100m;
client_body_timeout 120s;
sendfile off;
# strengthen ssl security
ssl_certificate /etc/letsencrypt/live/<domain>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<domain>/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
# See the link below for more SSL information:
# https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
#
# ssl_dhparam /etc/ssl/certs/dhparam.pem;
# Add headers to serve security related headers
add_header Strict-Transport-Security "max-age=15768000; preload;";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header X-Robots-Tag none;
add_header Content-Security-Policy "frame-ancestors 'self'";
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/pterodactyl.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M";
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param HTTP_PROXY "";
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
include /etc/nginx/fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}

46
.dev/docker/entrypoint.sh Normal file
View file

@ -0,0 +1,46 @@
#!/bin/ash
## Ensure we are in /app
cd /app
## check for .env file and generate app keys if missing
if [ -f /app/var/.env ]; then
echo "external vars exist"
rm /app/.env
ln -s /app/var/.env /app/
else
echo "external vars don't exist"
rm /app/.env
touch /app/var/.env
## manually generate a key because key generate --force fails
echo -e "Generating key"
APP_KEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
echo -e "Generated app key: $APP_KEY"
echo -e "APP_KEY=$APP_KEY" > /app/var/.env
ln -s /app/var/.env /app/
fi
## check for DB up before starting the panel
echo "Checking database status."
until nc -z -v -w30 $DB_HOST 3306
do
echo "Waiting for database connection..."
# wait for 5 seconds before check again
sleep 5
done
## make sure the db is set up
echo -e "Migrating and Seeding DB"
php artisan migrate --force
php artisan db:seed --force
## start cronjobs for the queue
echo -e "Starting cron jobs"
crond
echo -e "Starting supervisord"
exec "$@"

View file

@ -0,0 +1,39 @@
[unix_http_server]
file=/tmp/supervisor.sock ; path to your socket file
[supervisord]
logfile=/var/log/supervisord/supervisord.log ; supervisord log file
logfile_maxbytes=50MB ; maximum size of logfile before rotation
logfile_backups=2 ; number of backed up logfiles
loglevel=error ; info, debug, warn, trace
pidfile=/var/run/supervisord.pid ; pidfile location
nodaemon=false ; run supervisord as a daemon
minfds=1024 ; number of startup file descriptors
minprocs=200 ; number of process descriptors
user=root ; default user
childlogdir=/var/log/supervisord/ ; where child log files will live
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
[program:php-fpm]
command=/usr/sbin/php-fpm7 -F
autostart=true
autorestart=true
[program:queue-worker]
command=/usr/bin/php /app/artisan queue:work --queue=high,standard,low --sleep=3 --tries=3
user=nginx
autostart=true
autorestart=true
[program:nginx]
command=/usr/sbin/nginx -g 'daemon off;'
autostart=true
autorestart=true
priority=10
stdout_events_enabled=true
stderr_events_enabled=true

16
.dev/docker/www.conf Normal file
View file

@ -0,0 +1,16 @@
[pterodactyl]
user = nginx
group = nginx
listen = /var/run/php/php-fpm7.2.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0750
pm = ondemand
pm.max_children = 9
pm.process_idle_timeout = 10s
pm.max_requests = 200
clear_env = no

3
.gitignore vendored
View file

@ -20,8 +20,9 @@ sami.phar
# For local development with docker
# Remove if we ever put the Dockerfile in the repo
.dockerignore
Dockerfile
#Dockerfile
docker-compose.yml
# for image related files
misc
.phpstorm.meta.php

View file

@ -1,29 +0,0 @@
phraseapp:
project_id: 94f8b39450cd749ae9c3cc0ab8cdb61d
file_format: laravel
push:
sources:
- file: ./resources/lang/<locale_code>/<tag>.php
pull:
targets:
- file: ./resources/lang/<locale_code>/auth.php
params:
tag: "auth"
- file: ./resources/lang/<locale_code>/base.php
params:
tag: "base"
- file: ./resources/lang/<locale_code>/pagination.php
params:
tag: "pagination"
- file: ./resources/lang/<locale_code>/passwords.php
params:
tag: "passwords"
- file: ./resources/lang/<locale_code>/server.php
params:
tag: "server"
- file: ./resources/lang/<locale_code>/strings.php
params:
tag: "strings"
- file: ./resources/lang/<locale_code>/validation.php
params:
tag: "validation"

View file

@ -3,6 +3,22 @@ This file is a running track of new features and fixes to each version of the pa
This project follows [Semantic Versioning](http://semver.org) guidelines.
## v0.7.11 (Derelict Dermodactylus)
### Fixed
* Fixes an issue with certain systems not handling an API folder that was named `API` but referenced as `Api` in the namespace.
* TS3 egg updated to use CLI arguments correctly and have a more minimalistic installation script.
* Terminal was not properly displaying longer lines leading to some visual inconsistency.
* Assorted translation updates.
* Pagination for server listing now properly respects configuration setting.
* Client API now properly respects permissions that are set and allows subusers to access their assigned servers.
### Changed
* Removed PhraseApp integration from Panel code as it is no longer used.
* SFTP login endpoint now returns the permissions for that user rather than requiring additional queries to get that data.
### Added
* You can now test your mail settings from the Admin CP without waiting to see if things are working correctly.
## v0.7.10 (Derelict Dermodactylus)
### Fixed
* Scheduled tasks triggered manually no longer improperly change the `next_run_at` time and do not run twice in a row anymore.

26
Dockerfile Normal file
View file

@ -0,0 +1,26 @@
FROM alpine:3.8
WORKDIR /app
RUN apk add --no-cache --update ca-certificates certbot nginx dcron curl tini php7 php7-bcmath php7-common php7-dom php7-fpm php7-gd php7-mbstring php7-openssl php7-zip php7-pdo php7-phar php7-json php7-pdo_mysql php7-session php7-ctype php7-tokenizer php7-zlib php7-simplexml php7-fileinfo supervisor \
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
COPY . ./
RUN cp .env.example .env \
&& composer install --no-dev --optimize-autoloader \
&& rm .env \
&& chown -R nginx:nginx . && chmod -R 777 storage/* bootstrap/cache
RUN cp .dev/docker/default.conf /etc/nginx/conf.d/default.conf \
&& cp .dev/docker/www.conf /etc/php7/php-fpm.d/www.conf \
&& cat .dev/docker/supervisord.conf > /etc/supervisord.conf \
&& echo "* * * * * /usr/bin/php /app/pterodactyl/artisan schedule:run >> /dev/null 2>&1" >> /var/spool/cron/crontabs/root \
&& mkdir -p /var/run/php /var/run/nginx \
&& mkdir -p /var/log/supervisord/
EXPOSE 80 443
ENTRYPOINT ["/bin/ash", ".dev/docker/entrypoint.sh"]
CMD [ "supervisord", "-n", "-c", "/etc/supervisord.conf" ]

View file

@ -41,8 +41,7 @@ In addition to our standard nest of supported games, our community is constantly
* Discord ATLBot
## Credits
A huge thank you to [PhraseApp](https://phraseapp.com) who provide us the software to help translate this project. This software would not be possible
without the work of other open-source authors who provide tools such as:
This software would not be possible without the work of other open-source authors who provide tools such as:
[Ace Editor](https://ace.c9.io), [AdminLTE](https://almsaeedstudio.com), [Animate.css](http://daneden.github.io/animate.css/), [AnsiUp](https://github.com/drudru/ansi_up), [Async.js](https://github.com/caolan/async),
[Bootstrap](http://getbootstrap.com), [Bootstrap Notify](http://bootstrap-notify.remabledesigns.com), [Chart.js](http://www.chartjs.org), [FontAwesome](http://fontawesome.io),

View file

@ -103,10 +103,10 @@ interface ServerRepositoryInterface extends RepositoryInterface, SearchableInter
*
* @param \Pterodactyl\Models\User $user
* @param int $level
* @param bool $paginate
* @param bool|int $paginate
* @return \Illuminate\Pagination\LengthAwarePaginator|\Illuminate\Database\Eloquent\Collection
*/
public function filterUserAccessServers(User $user, int $level, bool $paginate = true);
public function filterUserAccessServers(User $user, int $level, $paginate = 25);
/**
* Return a server by UUID.

View file

@ -1,31 +0,0 @@
<?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Extensions;
use Illuminate\Translation\Translator as LaravelTranslator;
class PhraseAppTranslator extends LaravelTranslator
{
/**
* Get the translation for the given key.
*
* @param string $key
* @param array $replace
* @param string|null $locale
* @param bool $fallback
* @return string
*/
public function get($key, array $replace = [], $locale = null, $fallback = true)
{
$key = substr($key, strpos($key, '.') + 1);
return "{{__phrase_${key}__}}";
}
}

View file

@ -285,6 +285,27 @@ class NodesController extends Controller
return response('', 204);
}
/**
* Removes multiple individual allocations from a node.
*
* @param \Illuminate\Http\Request $request
* @param int $node
* @return \Illuminate\Http\Response
*
* @throws \Pterodactyl\Exceptions\Service\Allocation\ServerUsingAllocationException
*/
public function allocationRemoveMultiple(Request $request, int $node): Response
{
$allocations = $request->input('allocations');
foreach ($allocations as $rawAllocation) {
$allocation = new Allocation();
$allocation->id = $rawAllocation['id'];
$this->allocationRemoveSingle($node, $allocation);
}
return response('', 204);
}
/**
* Remove all allocations for a specific IP at once on a node.
*

View file

@ -2,10 +2,14 @@
namespace Pterodactyl\Http\Controllers\Admin\Settings;
use Exception;
use Illuminate\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Prologue\Alerts\AlertsMessageBag;
use Illuminate\Contracts\Console\Kernel;
use Pterodactyl\Notifications\MailTested;
use Illuminate\Support\Facades\Notification;
use Pterodactyl\Exceptions\DisplayException;
use Pterodactyl\Http\Controllers\Controller;
use Illuminate\Contracts\Encryption\Encrypter;
@ -81,13 +85,13 @@ class MailController extends Controller
* Handle request to update SMTP mail settings.
*
* @param \Pterodactyl\Http\Requests\Admin\Settings\MailSettingsFormRequest $request
* @return \Illuminate\Http\RedirectResponse
* @return \Illuminate\Http\Response
*
* @throws DisplayException
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
*/
public function update(MailSettingsFormRequest $request): RedirectResponse
public function update(MailSettingsFormRequest $request): Response
{
if ($this->config->get('mail.driver') !== 'smtp') {
throw new DisplayException('This feature is only available if SMTP is the selected email driver for the Panel.');
@ -107,8 +111,25 @@ class MailController extends Controller
}
$this->kernel->call('queue:restart');
$this->alert->success('Mail settings have been updated successfully and the queue worker was restarted to apply these changes.')->flash();
return redirect()->route('admin.settings.mail');
return response('', 204);
}
/**
* Submit a request to send a test mail message.
*
* @param Request $request
* @return \Illuminate\Http\Response
*/
public function test(Request $request): Response
{
try {
Notification::route('mail', $request->user()->email)
->notify(new MailTested($request->user()));
} catch (Exception $exception) {
return response($exception->getMessage(), 500);
}
return response('', 204);
}
}

View file

@ -35,7 +35,7 @@ class ClientController extends ClientApiController
*/
public function index(GetServersRequest $request): array
{
$servers = $this->repository->filterUserAccessServers($request->user(), User::FILTER_LEVEL_SUBUSER);
$servers = $this->repository->filterUserAccessServers($request->user(), User::FILTER_LEVEL_SUBUSER, config('pterodactyl.paginate.frontend.servers'));
return $this->fractal->collection($servers)
->transformWith($this->getTransformer(ServerTransformer::class))

View file

@ -7,7 +7,6 @@ use Pterodactyl\Models\Server;
use Psr\Http\Message\ResponseInterface;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\RequestException;
use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService;
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
use Pterodactyl\Http\Requests\Api\Client\Servers\SendCommandRequest;
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
@ -16,11 +15,6 @@ use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException;
class CommandController extends ClientApiController
{
/**
* @var \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService
*/
private $keyProviderService;
/**
* @var \Pterodactyl\Contracts\Repository\Daemon\CommandRepositoryInterface
*/
@ -30,13 +24,11 @@ class CommandController extends ClientApiController
* CommandController constructor.
*
* @param \Pterodactyl\Contracts\Repository\Daemon\CommandRepositoryInterface $repository
* @param \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService $keyProviderService
*/
public function __construct(CommandRepositoryInterface $repository, DaemonKeyProviderService $keyProviderService)
public function __construct(CommandRepositoryInterface $repository)
{
parent::__construct();
$this->keyProviderService = $keyProviderService;
$this->repository = $repository;
}
@ -46,14 +38,12 @@ class CommandController extends ClientApiController
* @param \Pterodactyl\Http\Requests\Api\Client\Servers\SendCommandRequest $request
* @return \Illuminate\Http\Response
*
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
*/
public function index(SendCommandRequest $request): Response
{
$server = $request->getModel(Server::class);
$token = $this->keyProviderService->handle($server, $request->user());
$token = $request->attributes->get('server_token');
try {
$this->repository->setServer($server)

View file

@ -4,18 +4,12 @@ namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
use Illuminate\Http\Response;
use Pterodactyl\Models\Server;
use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService;
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
use Pterodactyl\Http\Requests\Api\Client\Servers\SendPowerRequest;
use Pterodactyl\Contracts\Repository\Daemon\PowerRepositoryInterface;
class PowerController extends ClientApiController
{
/**
* @var \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService
*/
private $keyProviderService;
/**
* @var \Pterodactyl\Contracts\Repository\Daemon\PowerRepositoryInterface
*/
@ -24,14 +18,12 @@ class PowerController extends ClientApiController
/**
* PowerController constructor.
*
* @param \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService $keyProviderService
* @param \Pterodactyl\Contracts\Repository\Daemon\PowerRepositoryInterface $repository
*/
public function __construct(DaemonKeyProviderService $keyProviderService, PowerRepositoryInterface $repository)
public function __construct(PowerRepositoryInterface $repository)
{
parent::__construct();
$this->keyProviderService = $keyProviderService;
$this->repository = $repository;
}
@ -41,14 +33,12 @@ class PowerController extends ClientApiController
* @param \Pterodactyl\Http\Requests\Api\Client\Servers\SendPowerRequest $request
* @return \Illuminate\Http\Response
*
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
* @throws \Pterodactyl\Exceptions\Repository\Daemon\InvalidPowerSignalException
*/
public function index(SendPowerRequest $request): Response
{
$server = $request->getModel(Server::class);
$token = $this->keyProviderService->handle($server, $request->user());
$token = $request->attributes->get('server_token');
$this->repository->setServer($server)->setToken($token)->sendSignal($request->input('signal'));

View file

@ -56,7 +56,7 @@ class IndexController extends Controller
public function getIndex(Request $request)
{
$servers = $this->repository->setSearchTerm($request->input('query'))->filterUserAccessServers(
$request->user(), User::FILTER_LEVEL_ALL
$request->user(), User::FILTER_LEVEL_ALL, config('pterodactyl.paginate.frontend.servers')
);
return view('base.index', ['servers' => $servers]);

View file

@ -4,24 +4,57 @@ namespace Pterodactyl\Http\Middleware\Api\Client;
use Closure;
use Illuminate\Http\Request;
use Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService;
use Pterodactyl\Exceptions\Repository\RecordNotFoundException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
class AuthenticateClientAccess
{
/**
* @var \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService
*/
private $keyProviderService;
/**
* AuthenticateClientAccess constructor.
*
* @param \Pterodactyl\Services\DaemonKeys\DaemonKeyProviderService $keyProviderService
*/
public function __construct(DaemonKeyProviderService $keyProviderService)
{
$this->keyProviderService = $keyProviderService;
}
/**
* Authenticate that the currently authenticated user has permission
* to access the specified server.
* to access the specified server. This only checks that the user is an
* admin, owner, or a subuser. You'll need to do more specific checks in
* the API calls to determine if they can perform different actions.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
*/
public function handle(Request $request, Closure $next)
{
if (is_null($request->user())) {
throw new AccessDeniedHttpException('This account does not have permission to access this resource.');
throw new AccessDeniedHttpException('A request must be made using an authenticated client.');
}
/** @var \Pterodactyl\Models\Server $server */
$server = $request->route()->parameter('server');
try {
$token = $this->keyProviderService->handle($server, $request->user());
} catch (RecordNotFoundException $exception) {
throw new NotFoundHttpException('The requested server could not be located.');
}
$request->attributes->set('server_token', $token);
return $next($request);
}
}

View file

@ -2,7 +2,6 @@
namespace Pterodactyl\Http\Requests\Api\Client\Servers;
use Pterodactyl\Models\Server;
use Pterodactyl\Http\Requests\Api\Client\ClientApiRequest;
class GetServerRequest extends ClientApiRequest
@ -18,14 +17,4 @@ class GetServerRequest extends ClientApiRequest
{
return true;
}
/**
* Determine if the user should even know that this server exists.
*
* @return bool
*/
public function resourceExists(): bool
{
return $this->user()->can('view-server', $this->getModel(Server::class));
}
}

View file

@ -0,0 +1,33 @@
<?php
namespace Pterodactyl\Notifications;
use Pterodactyl\Models\User;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\MailMessage;
class MailTested extends Notification
{
/**
* @var \Pterodactyl\Models\User
*/
private $user;
public function __construct(User $user)
{
$this->user = $user;
}
public function via()
{
return ['mail'];
}
public function toMail()
{
return (new MailMessage)
->subject('Pterodactyl Test Message')
->greeting('Hello ' . $this->user->name . '!')
->line('This is a test of the Pterodactyl mail system. You\'re good to go!');
}
}

View file

@ -1,44 +0,0 @@
<?php
/**
* Pterodactyl - Panel
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
*
* This software is licensed under the terms of the MIT license.
* https://opensource.org/licenses/MIT
*/
namespace Pterodactyl\Providers;
use Pterodactyl\Extensions\PhraseAppTranslator;
use Illuminate\Translation\TranslationServiceProvider;
use Illuminate\Translation\Translator as IlluminateTranslator;
class PhraseAppTranslationProvider extends TranslationServiceProvider
{
/**
* Register the service provider.
*/
public function register()
{
$this->registerLoader();
$this->app->singleton('translator', function ($app) {
$loader = $app['translation.loader'];
// When registering the translator component, we'll need to set the default
// locale as well as the fallback locale. So, we'll grab the application
// configuration so we can easily get both of these values from there.
$locale = $app['config']['app.locale'];
if ($app['config']['pterodactyl.lang.in_context']) {
$trans = new PhraseAppTranslator($loader, $locale);
} else {
$trans = new IlluminateTranslator($loader, $locale);
}
$trans->setFallback($app['config']['app.fallback_locale']);
return $trans;
});
}
}

View file

@ -78,7 +78,7 @@ class SettingsServiceProvider extends ServiceProvider
return [$setting->key => $setting->value];
})->toArray();
} catch (QueryException $exception) {
$log->notice('A query exception was encountered while trying to load settings from the database.');
$log->notice('A query exception was encountered while trying to load settings from the database: ' . $exception->getMessage());
return;
}

View file

@ -211,10 +211,10 @@ class ServerRepository extends EloquentRepository implements ServerRepositoryInt
*
* @param \Pterodactyl\Models\User $user
* @param int $level
* @param bool $paginate
* @param bool|int $paginate
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator|\Illuminate\Database\Eloquent\Collection
*/
public function filterUserAccessServers(User $user, int $level, bool $paginate = true)
public function filterUserAccessServers(User $user, int $level, $paginate = 25)
{
$instance = $this->getBuilder()->select($this->getColumns())->with(['user', 'node', 'allocation']);
@ -240,7 +240,7 @@ class ServerRepository extends EloquentRepository implements ServerRepositoryInt
$instance->search($this->getSearchTerm());
return $paginate ? $instance->paginate(25) : $instance->get();
return $paginate ? $instance->paginate($paginate) : $instance->get();
}
/**

View file

@ -102,6 +102,7 @@ class AuthenticateUsingPasswordService
return [
'server' => $server->uuid,
'token' => $this->keyProviderService->handle($server, $user),
'permissions' => $permissions ?? ['*'],
];
}
}

View file

@ -9,7 +9,7 @@ return [
| change this value if you are not maintaining your own internal versions.
*/
'version' => '0.7.10',
'version' => '0.7.11',
/*
|--------------------------------------------------------------------------
@ -166,6 +166,7 @@ return [
Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
@ -179,7 +180,6 @@ return [
Pterodactyl\Providers\HashidsServiceProvider::class,
Pterodactyl\Providers\RouteServiceProvider::class,
Pterodactyl\Providers\MacroServiceProvider::class,
Pterodactyl\Providers\PhraseAppTranslationProvider::class,
Pterodactyl\Providers\RepositoryServiceProvider::class,
Pterodactyl\Providers\ViewComposerServiceProvider::class,

View file

@ -153,23 +153,10 @@ return [
/*
|--------------------------------------------------------------------------
| Language Editor
| Client Features
|--------------------------------------------------------------------------
|
| Set `PHRASE_IN_CONTEXT` to true to enable the PhaseApp in-context editor
| on this site which allows you to translate the panel, from the panel.
*/
'lang' => [
'in_context' => env('PHRASE_IN_CONTEXT', false),
],
/*
|--------------------------------------------------------------------------
| Language Editor
|--------------------------------------------------------------------------
|
| Set `PHRASE_IN_CONTEXT` to true to enable the PhaseApp in-context editor
| on this site which allows you to translate the panel, from the panel.
| Allow clients to create their own databases.
*/
'client_features' => [
'databases' => [

View file

@ -3,21 +3,21 @@
"meta": {
"version": "PTDL_v1"
},
"exported_at": "2018-01-21T17:01:45-06:00",
"exported_at": "2018-10-28T20:50:23+01:00",
"name": "Teamspeak3 Server",
"author": "support@pterodactyl.io",
"description": "VoIP software designed with security in mind, featuring crystal clear voice quality, endless customization options, and scalabilty up to thousands of simultaneous users.",
"image": "quay.io\/pterodactyl\/core:glibc",
"startup": ".\/ts3server_minimal_runscript.sh default_voice_port={{SERVER_PORT}} query_port={{SERVER_PORT}}",
"startup": ".\/ts3server_minimal_runscript.sh default_voice_port={{SERVER_PORT}} query_port={{SERVER_PORT}} license_accepted=1",
"config": {
"files": "{\"ts3server.ini\":{\"parser\": \"ini\", \"find\":{\"default_voice_port\": \"{{server.build.default.port}}\", \"voice_ip\": \"0.0.0.0\", \"query_port\": \"{{server.build.default.port}}\", \"query_ip\": \"0.0.0.0\"}}}",
"files": "{}",
"startup": "{\"done\": \"listening on 0.0.0.0:\", \"userInteraction\": []}",
"logs": "{\"custom\": true, \"location\": \"logs\/ts3.log\"}",
"stop": "^C"
},
"scripts": {
"installation": {
"script": "#!\/bin\/ash\n# TS3 Installation Script\n#\n# Server Files: \/mnt\/server\napk update\napk add tar curl\n\ncd \/tmp\n\ncurl -sSLO http:\/\/dl.4players.de\/ts\/releases\/${TS_VERSION}\/teamspeak3-server_linux_amd64-${TS_VERSION}.tar.bz2\n\ntar -xjvf teamspeak3-server_linux_amd64-${TS_VERSION}.tar.bz2\ncp -r teamspeak3-server_linux_amd64\/* \/mnt\/server\n\necho \"machine_id=\ndefault_voice_port=${SERVER_PORT}\nvoice_ip=0.0.0.0\nlicensepath=\nfiletransfer_port=30033\nfiletransfer_ip=\nquery_port=${SERVER_PORT}\nquery_ip=0.0.0.0\nquery_ip_whitelist=query_ip_whitelist.txt\nquery_ip_blacklist=query_ip_blacklist.txt\ndbplugin=ts3db_sqlite3\ndbpluginparameter=\ndbsqlpath=sql\/\ndbsqlcreatepath=create_sqlite\/\ndbconnections=10\nlogpath=logs\nlogquerycommands=0\ndbclientkeepdays=30\nlogappend=0\nquery_skipbruteforcecheck=0\" > \/mnt\/server\/ts3server.ini\n\ntouch \/mnt\/server\/.ts3server_license_accepted",
"script": "#!\/bin\/ash\n# TS3 Installation Script\n#\n# Server Files: \/mnt\/server\napk update\napk add tar curl\n\ncd \/mnt\/server\n\ncurl http:\/\/dl.4players.de\/ts\/releases\/${TS_VERSION}\/teamspeak3-server_linux_amd64-${TS_VERSION}.tar.bz2 | tar xj --strip-components=1",
"container": "alpine:3.4",
"entrypoint": "ash"
}
@ -27,7 +27,7 @@
"name": "Server Version",
"description": "The version of Teamspeak 3 to use when running the server.",
"env_variable": "TS_VERSION",
"default_value": "3.1.1",
"default_value": "3.4.0",
"user_viewable": 1,
"user_editable": 1,
"rules": "required|regex:\/^([0-9_\\.-]{5,10})$\/"

View file

@ -0,0 +1,72 @@
version: '2'
services:
database:
image: mariadb
volumes:
- "/srv/pterodactyl/database:/var/lib/mysql"
environment:
## Database settings
## change if you want it to be more secure.
- "MYSQL_ROOT_PASSWORD=apassword"
- "MYSQL_DATABASE=pterodb"
- "MYSQL_USER=ptero"
- "MYSQL_PASSWORD=pterodbpass"
cache:
image: redis:alpine
panel:
image: quay.io/pterodactyl/panel:latest
ports:
- "80:80"
- "443:443"
links:
- database
- cache
volumes:
- "/srv/pterodactyl/var/:/app/var/"
environment:
## These are defaults and should be left alone
- "APP_ENV=production"
- "APP_DEBUG=false"
- "APP_THEME=pterodactyl"
- "APP_CLEAR_TASKLOG=720"
- "APP_DELETE_MINUTES=10"
- "APP_ENVIRONMENT_ONLY=false"
- "QUEUE_HIGH=high"
- "QUEUE_STANDARD=standard"
- "QUEUE_LOW=low"
## Cache settings
- "CACHE_DRIVER=redis"
- "SESSION_DRIVER=redis"
- "QUEUE_DRIVER=redis"
- "REDIS_HOST=cache"
- "REDIS_PASSWORD=null"
- "REDIS_PORT=6379"
## Domain settings
- "APP_URL=https://your.domain.here"
## Timezone settings
- "APP_TIMEZONE=America/New_York"
## Service egg settings
- "APP_SERVICE_AUTHOR=noreply@your.domain.here"
## Database settings
## change if you want it to be more secure.
- "DB_HOST=database"
- "DB_PORT=3306"
- "DB_DATABASE=pterodb"
- "DB_USERNAME=ptero"
- "DB_PASSWORD=pterodbpass"
## Email settings
- "MAIL_FROM=noreply@your.domain.here"
- "MAIL_DRIVER=smtp"
- "MAIL_HOST=mail"
- "MAIL_PORT=1025"
- "MAIL_USERNAME=''"
- "MAIL_PASSWORD=''"
- "MAIL_ENCRYPTION=true"
networks:
default:
ipam:
config:
- subnet: 172.20.0.0/16

File diff suppressed because one or more lines are too long

View file

@ -26,7 +26,7 @@
#terminal > .cmd {
padding: 1px 0;
white-space: pre;
word-wrap: break-word;
}
#terminal_input {

View file

@ -113,7 +113,7 @@ class FileManager {
addFolderButton() {
$('[data-action="add-folder"]').unbind().on('click', () => {
new ActionsClass().folder($('#file_listing').data('current-dir') || '/');
})
});
}
selectRow() {

View file

@ -30,7 +30,7 @@ var Server = (function () {
}
if (typeof io !== 'function') {
console.error('Socket.io is reqired to use this panel.');
console.error('Socket.io is required to use this panel.');
return;
}

View file

@ -55,7 +55,7 @@ $(document).ready(function () {
console.error(jqXHR);
swal({
title: 'Whoops!',
text: 'An error occured while attempting to set the EULA as accepted: ' . jqXHR.responseJSON.error,
text: 'An error occurred while attempting to set the EULA as accepted: ' + jqXHR.responseJSON.error,
type: 'error'
})
});

View file

@ -1,8 +0,0 @@
window.PHRASEAPP_CONFIG = {
projectId: '94f8b39450cd749ae9c3cc0ab8cdb61d'
};
(function() {
var phraseapp = document.createElement('script'); phraseapp.type = 'text/javascript'; phraseapp.async = true;
phraseapp.src = ['https://', 'phraseapp.com/assets/in-context-editor/2.0/app.js?', new Date().getTime()].join('');
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(phraseapp, s);
})();

View file

@ -2,26 +2,26 @@
return [
'2fa_failed' => 'Der 2FA-Token war ungültig.',
'2fa_must_be_enabled' => 'Der Administrator hat festgelegt, dass dein Konto 2-Faktor-Authentifizierung benutzen muss, um das Panel verwenden zu können.',
'2fa_must_be_enabled' => 'Der Administrator hat festgelegt, dass dein Konto die 2-Faktor-Authentifizierung benutzen muss, um das Panel verwenden zu können.',
'2fa_required' => 'Zwei-Faktor Authentifizierung',
'authentication_required' => 'Sie müssen angemeldet sein, um fortzufahren.',
'auth_error' => 'Währen dem Einloggen ist ein Fehler aufgetreten.',
'authentication_required' => 'Du musst angemeldet sein, um fortzufahren.',
'auth_error' => 'Während dem anmelden ist ein Fehler aufgetreten.',
'confirmpassword' => 'Passwort bestätigen',
'emailsent' => 'Ihre E-Mail zum Zurücksetzen des Passworts ist nun unterwegs.',
'email_sent' => 'Du erhälst eine E-Mail mit weiteren Anweisungen zum Zurücksetzen deines Passworts.',
'emailsent' => 'Deine E-Mail zum zurücksetzen des Passworts ist unterwegs.',
'email_sent' => 'Du erhälst eine E-Mail mit weiteren Anweisungen zum zurücksetzen deines Passworts.',
'failed' => 'Die Anmeldeinformationen stimmen nicht überein.',
'forgot_password' => 'Passwort vergessen',
'not_authorized' => 'Du bist nicht autorisiert diese Aktion auszuführen0.',
'not_authorized' => 'Du bist nicht autorisiert diese Aktion auszuführen.',
'password_requirements' => 'Passwörter müssen Zahlen, Klein-, Großbuchstaben enthalten und mindestens 8 Zeichen lang sein.',
'remeberme' => 'Angemeldet bleiben',
'remember_me' => 'Eingeloggt bleiben',
'remember_me' => 'Angemeldet bleiben',
'request_reset' => 'Konto suchen',
'request_reset_text' => 'Du hast dein Passwort vergessen? Das ist keinWeltuntergang! Gib einfach deine Email hier an.',
'request_reset_text' => 'Du hast dein Passwort vergessen? Das ist kein Weltuntergang! Gib einfach deine E-Mail hier an.',
'resetpassword' => 'Passwort zurücksetzen',
'reset_password' => 'Passwort zurücksetzen',
'reset_password_text' => 'Passwort zurücksetzen.',
'sendlink' => 'Passwortrücksetzungslink senden.',
'sign_in' => 'Einloggen',
'throttle' => 'Du hast zu oft versucht dich anzumalen bitte warte noch :seconds Sekunden.',
'sign_in' => 'Anmelden',
'throttle' => 'Du hast zu oft versucht dich anzumelden, bitte warte noch :seconds Sekunden.',
'totp_failed' => 'Der TOTP Code war ungültig.',
];

View file

@ -6,7 +6,7 @@ return [
'delete_user' => 'Benutzer löschen',
'details_updated' => 'Dein Account wurde erfolgreich bearbeitet.',
'email_password' => 'Email Passwort',
'exception' => 'Währen dem Aktualisieren deines Account ist ein Fehler aufgetreten.',
'exception' => 'Während dem aktualisieren deines Kontos ist ein Fehler aufgetreten.',
'first_name' => 'Vorname',
'header' => 'BENUTZERVERWALTUNG',
'header_sub' => 'Verwalte deine Kontodetails.',
@ -18,11 +18,11 @@ return [
'new_password_again' => 'Neues Passwort wiederholen',
'totp_disable' => 'Deaktiviere die Zwei-Faktor-Authentifizierung',
'totp_enable' => 'Zwei-Faktor-Authentifizierung aktivieren',
'totp_enable_help' => 'Es sieht so aus als hättest du Zwei-Faktor-Authentifizierung deaktiviert. Diese Authentifizierungsmethode schützt dein Konto zusätzlich vor unerlaubtem Zugriff. Wenn du es aktivierst musst du zukünftig neben deinem Passwort auch einen Code, der von deinem Smartphone oder einem anderen TOTP fähigen Gerät generiert wird, eingeben um dich anzumelden.',
'totp_enable_help' => 'Es sieht so aus als hättest du die Zwei-Faktor-Authentifizierung deaktiviert. Diese Authentifizierungsmethode schützt dein Konto zusätzlich vor unerlaubtem Zugriff. Wenn du sie aktivierst musst du zukünftig neben deinem Passwort auch einen Code, der von deinem Smartphone oder einem anderen TOTP fähigen Gerät generiert wird, eingeben um dich anzumelden.',
'totp_header' => 'Zwei-Faktor Authentifizierung',
'update_email' => 'E-Mail Adresse aktualisieren',
'update_identitity' => 'Kotodetails aktualisieren',
'update_identity' => 'Account bearbeiten',
'update_identity' => 'Konto bearbeiten',
'update_pass' => 'Passwort ändern',
'update_user' => 'Benutzer aktualisieren',
'username_help' => 'Dein Benutzername muss für dein Konto einzigartig sein und darf nur die folgenden Zeichen enthalten: :requirements.',
@ -32,7 +32,7 @@ return [
'create_new' => 'Neuen API Schlüssel erstellen',
'header' => 'API Zugriff',
'header_sub' => 'Verwalte deine API Zugangsschlüssel.',
'keypair_created' => 'An API Key-Pair has been generated. Your API secret token is <code>:token</code>. Please take note of this key as it will not be displayed again.',
'keypair_created' => 'Ein API-Schlüsselpaar wurde generiert. Dein API Secret Token ist <code>: token </ code>. Bitte notiere diesen Schlüssel, da er nicht mehr angezeigt wird. ',
'list' => 'API Schlüssel',
],
'new' => [
@ -141,7 +141,7 @@ return [
],
'title' => 'Benutzerverwaltung',
'update' => [
'description' => 'Erlaubt Benutzerdetails zu ändern (E-Mail, Passwort, TOPT einstellungen).',
'description' => 'Erlaubt Benutzerdetails zu ändern (E-Mail, Passwort, TOPT Einstellungen).',
'title' => 'Benutzer aktualisieren',
],
'view' => [
@ -154,7 +154,7 @@ return [
'admin' => [
'location' => [
'list' => [
'desc' => 'Der User darf alle Standorte sehen.',
'desc' => 'Der Benutzer darf alle Standorte sehen.',
'title' => 'Liste Standorte',
],
],
@ -169,11 +169,11 @@ return [
'title' => 'Node löschen',
],
'list' => [
'desc' => 'Der User darf alle Nodes sehen.',
'desc' => 'Der Benutzer darf alle Nodes sehen.',
'title' => 'Nodes auflisten',
],
'view-config' => [
'desc' => 'Achtung. Der User kann die Konfiguration dieser Node sehen.',
'desc' => 'Der Benutzer kann die Konfiguration dieser Node sehen.',
'title' => 'Node Konfiguration anzeigen',
],
'view' => [
@ -202,70 +202,70 @@ return [
'pack_header' => 'Pack Control',
'server' => [
'create' => [
'desc' => 'Der User darf Server erstellen.',
'title' => 'Create Server',
'desc' => 'Der Benutzer darf Server erstellen.',
'title' => 'Server erstellen',
],
'delete' => [
'desc' => 'Der User darf Server löschen.',
'title' => 'Delete Server',
'desc' => 'Der Benutzer darf Server löschen.',
'title' => 'Server löschen',
],
'edit-build' => [
'desc' => 'Der User darf Server einstellungen bearbeiten.',
'title' => 'Edit Server Build',
'desc' => 'Der Benutzer darf Servereinstellungen bearbeiten.',
'title' => 'Servereinstellungen ändern',
],
'edit-container' => [
'desc' => 'Der User darf die Container Einstellungen des Servers verändern.',
'title' => 'Edit Server Container',
'desc' => 'Der Benutzer darf die Container Einstellungen des Servers verändern.',
'title' => 'Server Container Einstellungen ändern',
],
'edit-details' => [
'desc' => 'Der User darf die Server EInstellungen bearbeiten.',
'title' => 'Edit Server Details',
'desc' => 'Der Benutzer darf die Servereinstellungen bearbeiten.',
'title' => 'Server Details ändern',
],
'edit-startup' => [
'desc' => 'Der User darf die Startparameter ändern.',
'title' => 'Edit Server Startup',
'title' => 'Server Startparameter ändern',
],
'install' => [
'desc' => 'Der User darf den Installationstatus bearbeiten',
'title' => 'Toggle Install Status',
'desc' => 'Der Benutzer darf den Installationstatus bearbeiten',
'title' => 'Installlations Status ändern',
],
'list' => [
'desc' => 'Der User darf alle Server dieser Instanz sehen.',
'title' => 'List Servers',
'desc' => 'Der Benutzer darf alle Server dieser Instanz sehen.',
'title' => 'Servers Liste anzeigen',
],
'rebuild' => [
'desc' => 'Der User darf den Server ner erstellen',
'desc' => 'Der Benutzer darf den Server ner erstellen',
'title' => 'Rebuild Server',
],
'suspend' => [
'desc' => 'Der User darf Server sperren.',
'title' => 'Suspend Server',
'title' => 'Server sperren',
],
'view' => [
'desc' => 'Der user darf detaillierte Informationen zu allen Servern dieser Instanz sehen.',
'title' => 'View Server',
'desc' => 'Der Benutzer darf detaillierte Informationen zu allen Servern dieser Instanz sehen.',
'title' => 'Server Informationen anzeigen',
],
],
'server_header' => 'Server Control',
'service' => [
'list' => [
'desc' => 'Der User kann alle Services sehen.',
'title' => 'List Service',
'desc' => 'Der Benutzer kann alle Services sehen.',
'title' => 'Services anzeigen',
],
'view' => [
'desc' => 'Der user kann detaillierte Informationen über einen Service sehen.',
'title' => 'View Service',
'desc' => 'Der Benutzer kann detaillierte Informationen über einen Service sehen.',
'title' => 'Service anzeigen',
],
],
'service_header' => 'Service Control',
'user' => [
'create' => [
'desc' => 'Der User kann einen User erstellen.',
'title' => 'Create User',
'desc' => 'Der Benutzer kann einen User erstellen.',
'title' => 'Benutzer erstellen',
],
'delete' => [
'desc' => 'Der User kann einen Server löschen.',
'title' => 'Delete User',
'title' => 'Benutzer löschen',
],
'edit' => [
'desc' => 'Der User kann einen User bearbeiten.',
@ -273,11 +273,11 @@ return [
],
'list' => [
'desc' => 'Ermöglicht die Auflistung aller derzeit im System befindlichen Benutzer.',
'title' => 'List Users',
'title' => 'Benutzerliste anzeigen',
],
'view' => [
'desc' => 'Der User kann detaillierte Informationen der User sehen.',
'title' => 'View User',
'title' => 'Benutzerinformationen anzeigen',
],
],
'user_header' => 'Benutzer Control',
@ -285,20 +285,20 @@ return [
'user' => [
'server' => [
'command' => [
'desc' => 'Der User hat Zugriff auf die Server Console.',
'title' => 'Send Command',
'desc' => 'Der Benutzer hat Zugriff auf die Server Konsole.',
'title' => 'Befehl senden',
],
'list' => [
'desc' => 'Der user darf seine Serverliste ansehen.',
'title' => 'List Servers',
'desc' => 'Der Benutzer darf seine Serverliste ansehen.',
'title' => 'Serverliste',
],
'power' => [
'desc' => 'Der User darf den Server starten/stoppen/restartet.',
'title' => 'Toggle Power',
'desc' => 'Der Benutzer darf den Server starten/stoppen/restartet.',
'title' => 'Server start/stop/restart',
],
'view' => [
'desc' => 'Der User darf detaillierte Informationen über seine Server sehen.',
'title' => 'View Server',
'desc' => 'Der Benutzer darf detaillierte Informationen über seine Server sehen.',
'title' => 'Serverinformationen anzeigen',
],
],
'server_header' => 'Benutzer Rechte',
@ -312,13 +312,13 @@ return [
'header' => 'Forbidden',
],
'404' => [
'desc' => 'Die Angefragte Ressource konnte nicht gefunden werden.',
'desc' => 'Die angefragte Ressource konnte nicht gefunden werden.',
'header' => 'File Not Found',
],
'home' => 'Gehe zur Startseite',
'installing' => [
'desc' => 'Der angeforderte Server wird derzeit noch installiert. Bitte versuche es in ein paar Minuten erneut, du solltest eine E-Mail erhalten, sobald dieser Prozess abgeschlossen ist.',
'header' => 'Server Installing',
'desc' => 'Dieser Server wird derzeit noch installiert. Bitte versuche es in ein paar Minuten erneut, du solltest eine E-Mail erhalten, sobald dieser Prozess abgeschlossen ist.',
'header' => 'Server Installation',
],
'return' => 'Zur vorherigen Seite zurückkehren',
'suspended' => [
@ -335,13 +335,13 @@ return [
'no_servers' => 'Deinem Benutzerkonto sind aktuell keine Server zugeordnet.',
'password_req' => 'Passwörter müssen den folgenden Anforderungen genügen: mindestens ein Großbuchstabe, ein Kleinbuchstabe, eine Ziffer und eine Länge von mindestens 8 Zeichen.',
'security' => [
'2fa_checkpoint_help' => 'Verwende die 2FA-Anwendung auf deinem Telefon, um den QR-Codes auf der linken Seite zu scannen, oder gebe den Code darunter manuell ein. Sobald du dies getan haben, generiere einen Token und gebe ihn unten ein.',
'2fa_disabled' => '2-Faktor-Authentifizierung ist deaktiviert! Du solltest 2-Faktor-Authentifizierung aktivieren um dein Konto zusätzlich zu schützen.',
'2fa_checkpoint_help' => 'Verwende die 2FA-Anwendung auf deinem Telefon, um den QR-Codes auf der linken Seite zu scannen, oder gebe den Code darunter manuell ein. Sobald du dies getan hast, generiere einen Token und gebe ihn unten ein.',
'2fa_disabled' => '2-Faktor-Authentifizierung ist deaktiviert! Du solltest die 2-Faktor-Authentifizierung aktivieren um dein Konto zusätzlich zu schützen.',
'2fa_disable_error' => 'Der bereitgestellte 2FA-Token war nicht gültig. Der Schutz wurde für dieses Konto nicht deaktiviert.',
'2fa_header' => '2-Faktor-Authentifizierung',
'2fa_qr' => '2FA konfigurieren',
'2fa_token_help' => 'Bitte gebe den 2FA Code von deiner 2FA APP ein (Google Authenticatior, Authy, etc.).',
'disable_2fa' => '2-Factor-Authentification deaktivieren',
'2fa_token_help' => 'Bitte gebe den 2FA Code von deiner 2FA APP ein (Google Authenticator, Authy, etc.).',
'disable_2fa' => '2-Factor-Authentifizierung deaktivieren',
'enable_2fa' => '2-Faktor-Authentifizierung aktivieren',
'header' => 'Kontosicherheit',
'header_sub' => 'Verwalte aktive Sitzungen und die 2-Faktor-Authentifizierung.',
@ -349,6 +349,6 @@ return [
'session_mgmt_disabled' => 'Der Administrator hat die Möglichkeit, aktive Sitzungen über dieses Panel zu verwalten, nicht aktiviert.',
],
'server_name' => 'Name des Servers',
'validation_error' => 'Es gab ein Problem mit einer oder mehreren deriner Eingaben.',
'validation_error' => 'Es gab ein Problem mit einer oder mehreren deiner Eingaben.',
'view_as_admin' => 'Du siehst die Serverliste als Administrator. Deshalb siehst du alle im System vorhandenen Server. Die Server bei denen du als Besitzer eingetragen bist sind mit einem blauen Punkt markiert.',
];

View file

@ -3,18 +3,18 @@
return [
'location' => [
'no_location_found' => 'Shortcode wurde nicht gefunden.',
'ask_short' => 'Location Short Code',
'ask_long' => 'Location Beschreibung',
'created' => 'Neue Location (:name) mit der ID :id erstellt.',
'deleted' => 'Location gelöscht.',
'ask_short' => 'Standort Short Code',
'ask_long' => 'Standortbeschreibung',
'created' => 'Neuer Standort (:name) mit der ID :id erstellt.',
'deleted' => 'Standort gelöscht.',
],
'user' => [
'search_users' => 'Gib einen Benutzernamen, eine UUID oder eine Email an',
'search_users' => 'Gib einen Benutzernamen, eine UUID oder eine E-Mail an',
'select_search_user' => 'ID des Benutzers (Gib \'0\' ein, um erneut zu suchen)',
'deleted' => 'Benutzer erfolgreich gelöscht.',
'confirm_delete' => 'Bist du dir wirklich sicher?',
'no_users_found' => 'Es wurden keine Benutzer gefunden.',
'multiple_found' => 'Es wurden mehrere Accounts gefunden.',
'multiple_found' => 'Es wurden mehrere Benutzer gefunden.',
'ask_admin' => 'Ist dieser Benutzer ein Administrator?',
'ask_email' => 'Email Adresse',
'ask_username' => 'Benutzername',
@ -24,8 +24,8 @@ return [
'ask_password_tip' => 'Wenn du das wirklich tun willst drücke Strg+c und benutze das `--no-password` flag.',
'ask_password_help' => 'Das Passwort muss Zahlen, Groß- und Kleinbuchstaben enthalten und mindestens 8 Zeichen lang sein.',
'2fa_help_text' => [
'Dieser Befehl deaktiviert 2-Faktor-Authentifizierung für ein Benutzerkonto, falls es aktiviert ist. Dieser Befehl sollte nur zur Accountrettung verwendet werden, wenn sich ein Nutzer aus seinem Account ausgeschlossen hat.',
'Falls das nicht ist, was du erreichen wolltest, drücke Strg+C, um diesen Prozess zu beenden.',
'Dieser Befehl deaktiviert die 2-Faktor-Authentifizierung für ein Benutzerkonto, falls es aktiviert ist. Dieser Befehl sollte nur zur Accountrettung verwendet werden, wenn sich ein Nutzer aus seinem Account ausgeschlossen hat.',
'Falls es nicht das ist, was du erreichen wolltest, drücke Strg+C, um diesen Prozess zu beenden.',
],
'2fa_disabled' => '2-Faktor-Authentifizierung wurde für :email deaktiviert.',
],
@ -43,7 +43,7 @@ return [
'ask_smtp_host' => 'SMTP Host (e.g. smtp.gmail.com)',
'ask_smtp_port' => 'SMTP Port',
'ask_smtp_username' => 'SMTP Benutzername',
'ask_smtp_password' => 'SMTP Password',
'ask_smtp_password' => 'SMTP Passwort',
'ask_mailgun_domain' => 'Mailgun Domain',
'ask_mailgun_secret' => 'Mailgun Secret',
'ask_mandrill_secret' => 'Mandrill Secret',
@ -54,17 +54,17 @@ return [
'ask_encryption' => 'Encryption method to use',
],
'database' => [
'host_warning' => 'It is highly recommended to not use "localhost" as your database host as we have seen frequent socket connection issues. If you want to use a local connection you should be using "127.0.0.1".',
'host' => 'Database Host',
'port' => 'Database Port',
'database' => 'Database Name',
'username_warning' => 'Using the "root" account for MySQL connections is not only highly frowned upon, it is also not allowed by this application. You\'ll need to have created a MySQL user for this software.',
'username' => 'Database Benutzername',
'password_defined' => 'It appears you already have a MySQL connection password defined, would you like to change it?',
'password' => 'Database Password',
'connection_error' => 'Unable to connect to the MySQL server using the provided credentials. The error returned was ":error".',
'creds_not_saved' => 'Your connection credentials have NOT been saved. You will need to provide valid connection information before proceeding.',
'try_again' => 'Go back and try again?',
'host_warning' => 'Es wird dringend empfohlen, "localhost" nicht als Datenbank-Host zu verwenden, da es zu häufigen Socket-Verbindungsproblemen gekommen ist. Wenn du eine lokale Verbindung verwenden möchten, solltest du "127.0.0.1" verwenden.',
'host' => 'Datenbank Host',
'port' => 'Datenbank Port',
'database' => 'Datenbank Name',
'username_warning' => 'Die Verwendung des "root" -Kontos für MySQL-Verbindungen ist nicht erlaubt, Du musst einen extra MySQL-Benutzer erstellt haben.',
'username' => 'Datenbank Benutzername',
'password_defined' => 'Es scheint so, als ob du schon ein MySQL-kennwort definiert haast. Möchtest du es ändern?',
'password' => 'Datenbank Passwort',
'connection_error' => 'Es konnte keine Verbindung zum MySQL-Server mit den angegebenen Anmeldeinformationen hergestellt werden. Zurückgegebene Fehler ":error".',
'creds_not_saved' => 'Die Verbindungsdaten wurden NICHT gespeichert. Du musst gültige Verbindungsinformationen angeben, bevor du fortfahren kannst.',
'try_again' => 'Zurück und erneuert versuchen?',
],
'app' => [
'app_url_help' => 'The application URL MUST begin with https:// or http:// depending on if you are using SSL or not. If you do not include the scheme your emails and other content will link to the wrong location.',

View file

@ -40,7 +40,7 @@ return [
],
'subusers' => [
'editing_self' => 'Du darfst deinen eigenen Subuser nicht bearbeiten.',
'user_is_owner' => 'Du kannst den Owner nicht als Subuser hinzufügen.',
'user_is_owner' => 'Du kannst den Serverbesitzer nicht als Subuser hinzufügen.',
'subuser_exists' => 'Diese Email ist bereits registriert.',
],
'databases' => [

View file

@ -23,7 +23,7 @@ return [
'port_allocations' => 'Port-Einstellungen',
'sftp_settings' => 'SFTP Einstellungen',
'startup_parameters' => 'Startup Parameter',
'databases' => 'Datenbaken',
'databases' => 'Datenbanken',
'edit_file' => 'Datei bearbeiten',
'admin_header' => 'ADMINISTRATIV',
'admin' => 'Server Konfiguration',

View file

@ -1,16 +1,16 @@
<?php
<?php
return [
'next' => 'Nächste &raquo;',
'previous' => '&laquo; Vorherige',
'sidebar' => [
'account_controls' => 'Kontoeinstellungen',
'account_security' => 'Account Sicherheit',
'account_settings' => 'Account Einstellungen',
'account_controls' => 'Kontosteuerung',
'account_security' => 'Kontosicherheit',
'account_settings' => 'Kontoeinstellungen',
'files' => 'Dateimanager',
'manage' => 'Server verwalten',
'overview' => 'Server Übersicht',
'servers' => 'Deine Server',
'subusers' => 'Unterbenutzer verwalten',
'subusers' => 'Subuser verwalten',
],
];

View file

@ -3,7 +3,7 @@
return [
'password' => 'Passwort',
'reset' => 'Dein Passwort wurde zurückgesetzt!',
'sent' => 'Wir haben Ihren Link zum Zurücksetzen des Passworts per E-Mail gesendet!',
'sent' => 'Ein Link zum zurücksetzen des Passworts wurde per E-Mail gesendet!',
'token' => 'Der Token war ungültig',
'user' => 'Es gibt keinen User mit dieser Email.',
'user' => 'Es gibt keinen Benutzer mit dieser E-Mail.',
];

View file

@ -3,11 +3,11 @@
return [
'config' => [
'allocation' => [
'available' => 'Available Allocations',
'available' => 'Verfügbare Allocations',
'header' => 'Server Allocations',
'header_sub' => 'Control the IPs and ports available on this server.',
'header_sub' => 'Verfügbare IPs und Ports für diesen Server verwalten.',
'help' => 'Allocation Help',
'help_text' => 'The list to the left includes all available IPs and ports that are open for your server to use for incoming connections.',
'help_text' => 'Die Liste auf der linken Seite zeigt alle verfügbaren IPs und Ports, die für eingehende Verbindungen auf diesem Server geöffnet sind.',
],
'database' => [
'add_db' => 'Datenbank hinzufügen.',
@ -23,16 +23,16 @@ return [
'conn_addr' => 'Verbindungsadresse',
'details' => 'SFTP Details',
'header' => 'SFTP Information',
'header_sub' => 'Details für eine SFTP verbindung.',
'header_sub' => 'Details für eine SFTP Verbindung.',
'warning' => 'Bitte benutze SFTP und nicht FTP!.',
],
'startup' => [
'command' => 'Startup Command',
'command' => 'Startbefehl',
'edited' => 'Die Einstellungen wurden gespeichert und werden beim nächsten Serverstart verwendet.',
'edit_params' => 'Parameter bearbeiten',
'header' => 'Start Konfiguration',
'header_sub' => 'Bearbeite die Startparameter des Serves.',
'startup_regex' => 'Input Rules',
'startup_regex' => 'Input Regeln',
'startup_var' => 'Startbefehl Variablen',
'update' => 'Absenden',
],
@ -47,7 +47,7 @@ return [
'add_folder' => 'Neuen Ordner erstellen',
'add_new' => 'Neue Datei erstellen',
'back' => 'Zurück zum Datei-Manager',
'delete' => 'löschen',
'delete' => 'Löschen',
'edit' => [
'header' => 'Datei bearbeiten',
'header_sub' => 'Bearbeite Dateien direkt vom Browser aus.',
@ -87,21 +87,21 @@ return [
],
'schedule' => [
'actions' => [
'command' => 'Command ausführen',
'command' => 'Befehl ausführen',
'power' => 'Power Aktion',
],
'current' => 'Derzeitige Aktionen',
'day_of_month' => 'Day of Month',
'day_of_week' => 'Day of Week',
'header' => 'Schedule Manager',
'day_of_month' => 'Tag eines Monats',
'day_of_week' => 'Tag einer Woche',
'header' => 'Zeitplan Manager',
'header_sub' => 'Erstelle geplante Aktionen.',
'hour' => 'Hour of Day',
'hour' => 'Stunde des Tages',
'manage' => [
'delete' => 'Aktion löschen',
'header' => 'Aktion verwalten',
'submit' => 'Aktion bearbeiten',
],
'minute' => 'Minute of Hour',
'minute' => 'Minute der Stunde',
'new' => [
'header' => 'Neue Aktion erstellen',
'header_sub' => 'Erstelle eine neue Gruppe an Aktionen.',
@ -110,26 +110,26 @@ return [
'run_now' => 'Zeitplan jetzt ausführen',
'schedule_created' => 'Neuen Zeitplan für diesen Server erfolgreich erstellt.',
'schedule_updated' => 'Der Zeitplan wurde aktualisiert.',
'setup' => 'Schedule Setup',
'setup' => 'Zeitplan Erstellung',
'task' => [
'action' => 'Aktion ausführen',
'add_more' => 'Weitere Aktion',
'payload' => 'With Payload',
'payload' => 'Mit Payload',
'time' => 'Nach',
],
'task_help' => 'Times for tasks are relative to the previously defined task. Each schedule may have no more than 5 tasks assigned to it and tasks may not be scheduled more than 15 minutes apart.',
'task_help' => 'Zeiten für Aufgaben sind relativ zu der zuvor definierten Aufgabe. Jedem Zeitplan dürfen nicht mehr als 5 Aufgaben zugewiesen sein und Aufgaben dürfen nicht mehr als 15 Minuten voneinander entfernt liegen.',
'time_help' => 'Dieses System unterstützt dern Cronjob Syntax.',
'toggle' => 'Status wechseln',
'unnamed' => 'Unnamed Schedule',
'unnamed' => 'Unbenannter Zeitplan',
],
'tasks' => [
'actions' => [
'command' => 'Command ausführen',
'command' => 'Befehl ausführen',
'power' => 'Power Aktion senden',
],
'current' => 'Aktuelle Aktionen',
'edit' => [
'header' => 'Aktion beareiten',
'header' => 'Aktion bearbeiten',
'submit' => 'Abschicken',
],
'header' => 'Geplante Aufgaben',
@ -146,16 +146,16 @@ return [
'header_sub' => 'Neuen Aktion erstellen.',
'hour' => 'Stunde',
'minute' => 'Minute',
'mon' => 'Montad',
'mon' => 'Montag',
'payload' => 'Task Payload',
'payload_help' => 'Wenn du die send command Methode ausgewählt hast wird ein Command zur angegebenen Zeit ausgeführt.',
'payload_help' => 'Wenn du die Befehl ausführen Methode ausgewählt hast, wird ein Befehl zur angegebenen Zeit ausgeführt.',
'sat' => 'Samstag',
'submit' => 'Absenden',
'sun' => 'Sontag',
'sun' => 'Sonntag',
'task_name' => 'Name',
'thurs' => 'Donnerstag',
'tues' => 'Dienstag',
'type' => 'TTyp',
'type' => 'Typ',
'wed' => 'Mittwoch',
],
'new_task' => 'Neue Aufgabe hinzufügen',
@ -164,26 +164,26 @@ return [
'toggle' => 'Status ändern',
],
'users' => [
'add' => 'Neuen User erstellen',
'add' => 'Neuen Benutzer erstellen',
'configure' => 'Rechte einstellen',
'edit' => [
'header' => 'User bearbeiten',
'header_sub' => 'Bearbeite den Zugriff eines Users auf deine Server.',
'header' => 'Benutzer bearbeiten',
'header_sub' => 'Verwalte den Zugriff eines Benutzers auf diesen Server.',
],
'header' => 'User verwalten',
'header' => 'Benutzer verwalten',
'header_sub' => 'Bestimme wer den Server verwalten kann.',
'list' => 'Account Liste',
'new' => [
'access_sftp' => [
'description' => 'Ermöglicht dem Benutzer, eine Verbindung mit dem vom Daemon bereitgestellten SFTP-Server herzustellen.',
'title' => 'SFTP erlaubt',
'title' => 'SFTP-Verbindung erlauben',
],
'command' => [
'title' => 'Konsolenbefehl senden',
],
'compress_files' => [
'description' => 'Der User darf die Server-Dateien komprimieren(zip).',
'title' => 'Compress Files',
'title' => 'Dateien komprimieren',
],
'copy_files' => [
'description' => 'Der User darf die Server-Dateien kopieren.',
@ -195,97 +195,97 @@ return [
],
'create_files' => [
'description' => 'Der User darf Server-Dateien erstellen.',
'title' => 'Create Files',
'title' => 'Dateien erstellen',
],
'create_schedule' => [
'description' => 'Der User darf geplante Aktionen für den Server erstellen.',
'title' => 'Create Schedule',
'title' => 'Aktionen erstellen',
],
'create_subuser' => [
'description' => 'Der User darf Subuser erstellen.',
'title' => 'Create Subuser',
'title' => 'Subuser erstellen',
],
'create_task' => [
'description' => 'Ermöglicht es einem Benutzer, neue Aufgaben zu erstellen.',
'title' => 'Aufgabe erstellen',
],
'database_header' => 'Database Verwaltung',
'database_header' => 'Datenbank Verwaltung',
'db_header' => 'Datenbankverwaltung',
'decompress_files' => [
'description' => 'Der User darf zip Archive entpacken.',
'title' => 'Decompress Files',
'description' => 'Der Benutzer darf ZIP Archive entpacken.',
'title' => 'Dateien entpacken',
],
'delete_database' => [
'description' => 'Ermöglicht es dem Benutzer, Datenbanken für diesen Server über das Panel zu löschen.',
'title' => 'Datenbank löschen',
],
'delete_files' => [
'description' => 'Der User darf Server-Dateien löschen.',
'title' => 'Delete Files',
'description' => 'Der Benutzer darf Server-Dateien löschen.',
'title' => 'Dateien löschen',
],
'delete_schedule' => [
'description' => 'Der User darf geplante Aktionen für den Server löschen.',
'title' => 'Delete Schedule',
'description' => 'Der Benutzer darf geplante Aktionen für den Server löschen.',
'title' => 'Aktionen löschen',
],
'delete_subuser' => [
'description' => 'Der User darf Subuser löschen.',
'title' => 'Delete Subuser',
'description' => 'Der Benutzer darf Subuser löschen.',
'title' => 'Subuser löschen',
],
'delete_task' => [
'description' => 'Ermöglicht es dem Benutzer, eine Aufgabe zu löschen.',
'title' => 'Aufgabe löschen',
],
'download_files' => [
'description' => 'Der User darf Server-Dateien herunterladen.',
'description' => 'Der Benutzer darf Server-Dateien herunterladen.',
'title' => 'Dateien herunterladen',
],
'edit_allocation' => [
'description' => 'Allows user to change the default connection allocation to use for a server.',
'title' => 'Edit Default Connection',
'description' => 'Ermöglicht es dem Benutzer, die IP:Port Adresse für einen Server zu ändern.',
'title' => 'Standardverbindung bearbeiten',
],
'edit_files' => [
'description' => 'Der User darf die Server-Dateien sehen.',
'title' => 'Edit Files',
'description' => 'Der Benutzer darf die Server-Dateien bearbeiten.',
'title' => 'Dateien bearbeiten',
],
'edit_schedule' => [
'description' => 'Der User darf geplante Aktionen für den Server bearbeiten.',
'title' => 'Edit Schedule',
'description' => 'Der Benutzer darf geplante Aktionen für den Server bearbeiten.',
'title' => 'Aktionen bearbeiten',
],
'edit_startup' => [
'description' => 'Allows a user to modify startup variables for a server.',
'title' => 'Edit Startup Command',
'description' => 'Ermöglicht einem Benutzer, Startvariablen für einen Server zu ändern.',
'title' => 'Startbefehl bearbeiten',
],
'edit_subuser' => [
'description' => 'Der User darf Subuser bearbeiten.',
'title' => 'Edit Subuser',
'description' => 'Der Benutzer darf Subuser bearbeiten.',
'title' => 'Subuser bearbeiten',
],
'email' => 'E-Mail Adresse',
'email_help' => 'Email Adresse für Einladungs mail.',
'file_header' => 'Datein Verwaltung',
'email_help' => 'Email Adresse für Einladungs Mail.',
'file_header' => 'Dateien Verwaltung',
'header' => 'Neuen Benutzer erstellen',
'header_sub' => 'Erstelle einen neuen Benutzer und gebe ihm Zugriff auf diesen Server.',
'kill' => [
'description' => 'Ermöglicht es dem Benutzer, den Serverprozess abzubrechen.',
'description' => 'Ermöglicht es dem Benutzer, den Serverprozess zu töten.',
'title' => 'Server sofort beenden',
],
'list_files' => [
'description' => 'Der User darf die Server-Dateien sehen.',
'title' => 'List Files',
'description' => 'Der Benutzer darf die Server-Dateien sehen.',
'title' => 'Dateien anzeigen',
],
'list_schedules' => [
'description' => 'Der User darf geplante Aktionen für den Server sehen.',
'title' => 'List Schedules',
'description' => 'Der Benutzer darf geplante Aktionen für den Server sehen.',
'title' => 'Geplante Aktionen anzeigen',
],
'list_subusers' => [
'description' => 'Der User darf Subuser sehen.',
'title' => 'List Subusers',
'description' => 'Der Benutzer darf Subuser sehen.',
'title' => 'Subusers anzeigen',
],
'list_tasks' => [
'title' => 'Aufgaben auflisten',
],
'move_files' => [
'description' => 'Der User darf die Server-Dateien ubenennen und verschieben.',
'title' => 'Rename & Move Files',
'description' => 'Der Benutzer darf die Server-Dateien umbenennen und verschieben.',
'title' => 'Dateien umbenennen & verschieben',
],
'power_header' => 'Power Verwaltung',
'power_kill' => [
@ -293,43 +293,43 @@ return [
'title' => 'Kill Server',
],
'power_restart' => [
'description' => 'Der User darf den Server neu starten.',
'description' => 'Der Benutzer darf den Server neu starten.',
'title' => 'Server neu starten',
],
'power_start' => [
'description' => 'Der Benutzer darf den Server starten.',
'title' => 'Start Server',
'title' => 'Server starten',
],
'power_stop' => [
'description' => 'Der User darf den Server stoppen.',
'title' => 'Stop Server',
'description' => 'Der Benutzer darf den Server stoppen.',
'title' => 'Server stoppen',
],
'queue_schedule' => [
'description' => "Allows a user to queue a schedule to run it's tasks on the next process cycle.",
'description' => 'Ermöglicht einem Benutzer, einen Zeitplan in die Warteschlange zu stellen.',
'title' => 'Queue Schedule',
],
'queue_task' => [
'title' => 'Aufgabe einreihen',
],
'reset_db_password' => [
'description' => 'Der User darf das Datenbankpasswort zurücksetzen.',
'title' => 'Reset Database Password',
'description' => 'Der Benutzer darf das Datenbankpasswort zurücksetzen.',
'title' => 'Datenbank Passwort zurücksetzen ',
],
'reset_sftp' => [
'description' => 'Der User darf dass SFTP Passwort zurücksetzen.',
'title' => 'Reset SFTP Password',
'description' => 'Der Benutzer darf dass SFTP Passwort zurücksetzen.',
'title' => 'SFTP Passwort zurücksetzen',
],
'restart' => [
'description' => 'Der Benutzer darf den Server neu starten.',
'title' => 'Server neu starten',
],
'save_files' => [
'description' => 'Der User darf die Server-Dateien bearbeiten.',
'title' => 'Save Files',
'description' => 'Der Benutzer darf bearbeitete Server-Dateien speichern.',
'title' => 'Dateien speichern',
],
'send_command' => [
'description' => 'Der User darf die Konsole benutzen.',
'title' => 'Send Console Command',
'description' => 'Der Benutzer darf die Konsole benutzen.',
'title' => 'Konsolenbefehle senden',
],
'server_header' => 'Server Verwaltung',
'set_connection' => [
@ -341,57 +341,57 @@ return [
'title' => 'Server starten',
],
'stop' => [
'description' => 'Der User darf den Server stoppen.',
'description' => 'Der Benutzer darf den Server stoppen.',
'title' => 'Server stoppen',
],
'subuser_header' => 'Subuser Verwaltung',
'task_header' => 'Schedule Verwaltung',
'task_header' => 'Aktion Verwaltung',
'toggle_schedule' => [
'description' => 'Der User darf geplante Aktionen für den Server de-/aktivieren.',
'title' => 'Toggle Schedule',
'description' => 'Der Benutzer darf geplante Aktionen für den Server de-/aktivieren.',
'title' => 'De-/Aktivieren von Aktionen',
],
'toggle_task' => [
'description' => 'Der User darf geplante Aktionen für den Server de-/aktivieren.',
'description' => 'Der Benutzer darf geplante Aufgaben für den Server de-/aktivieren.',
],
'upload_files' => [
'description' => 'Der User darf Server-Dateien hochladen.',
'title' => 'Upload Files',
'description' => 'Der Benutzr darf Server-Dateien hochladen.',
'title' => 'Dateien hochladen',
],
'view_allocations' => [
'description' => 'Allows user to view all of the IPs and ports assigned to a server.',
'title' => 'View Allocations',
'description' => 'Ermöglicht dem Benutzer, alle einem Server zugewiesenen IPs und Ports anzuzeigen.',
'title' => 'Zugewiesen IPs und Ports anzeigen',
],
'view_databases' => [
'description' => 'Der User darf die Datenbankinformationen sehen.',
'title' => 'View Database Details',
'description' => 'Der Benutzer darf die Datenbankinformationen sehen.',
'title' => 'Datenbankinformationen anzeigen',
],
'view_schedule' => [
'description' => 'Der User darf eine Aktion ansehen.',
'title' => 'View Schedule',
'description' => 'Der Benutzer darf Aktionen ansehen.',
'title' => 'Aktionen anzeigen',
],
'view_sftp' => [
'description' => 'Der User darf die SFTP Informationen sehen (nicht das Passwort).',
'title' => 'View SFTP Details',
'title' => 'SFTP Informationen anzeigen',
],
'view_sftp_password' => [
'description' => 'Der User darf dass SFTP Passwort sehen.',
'title' => 'View SFTP Password',
'description' => 'Der Benutzer darf dass SFTP Passwort sehen.',
'title' => 'SFTP Password anzeigen',
],
'view_startup' => [
'description' => 'Allows user to view the startup command and associated variables for a server.',
'title' => 'View Startup Command',
'description' => 'Ermöglicht dem Benutzer, den Startbefehl und zugehörige Variablen für einen Server anzuzeigen.',
'title' => 'Startbefehl anzeigen',
],
'view_subuser' => [
'description' => 'Der User darf Subuser genauer sehen.',
'description' => 'Der Benutzer darf Subuser genauer sehen.',
'title' => 'View Subuser',
],
'view_task' => [
'description' => 'Der User darf eine Aktion ansehen.',
'description' => 'Der Benutzer darf Aufgaben ansehen.',
'title' => 'Aufgaben ansehen',
],
],
'update' => 'User bearbeiten',
'user_assigned' => 'User an einen Server gebunden.',
'user_updated' => 'User Rechte erfolgreich aktualisiert.',
'update' => 'Benutzer bearbeiten',
'user_assigned' => 'Benutzer zum Server hinzugefügt.',
'user_updated' => 'Benutzer Rechte erfolgreich aktualisiert.',
],
];

View file

@ -10,7 +10,7 @@ return [
'admin_cp' => 'Administration',
'again' => 'Nochmals',
'alias' => 'Alias',
'api_access' => 'Api Access',
'api_access' => 'API Access',
'cancel' => 'Abbrechen',
'captcha_invalid' => 'Der Captcha war ungültig.',
'close' => 'Schließen',

View file

@ -258,6 +258,10 @@ return [
],
],
],
'allocations' => [
'mass_actions' => 'Mass Actions',
'delete' => 'Delete Allocations',
],
'files' => [
'exceptions' => [
'invalid_mime' => 'This type of file cannot be edited via the Panel\'s built-in editor.',

View file

@ -362,7 +362,7 @@ return [
'2fa_enabled' => '2-Factor de Autenticación está habilitada en esta cuenta y será necesario iniciar la sesión en el panel de. Si usted desea deshabilitar el 2FA, simplemente ingrese un token válido a continuación y envíe el formulario.',
'2fa_header' => '2-Factor De Autenticación',
'2fa_qr' => 'Confgure 2FA en Su Dispositivo',
'2fa_token_help' => 'Introduzca el 2FA Token generado por la aplicación (Google Authenticatior, Authy, etc.).',
'2fa_token_help' => 'Introduzca el 2FA Token generado por la aplicación (Google Authenticator, Authy, etc.).',
'disable_2fa' => 'Deshabilitar 2-Factor De Autenticación',
'enable_2fa' => 'Habilitar 2-Factor De Autenticación',
'header' => 'Seguridad De La Cuenta',

View file

@ -2,17 +2,17 @@
return [
'2fa_failed' => 'De gegeven 2FA token is niet geldig.',
'2fa_must_be_enabled' => 'De administrator heeft ingesteld dat je 2-factor authenticatie moet gebruiken voor je acount voordat je het panel kan gebruiken',
'2fa_must_be_enabled' => 'De administrator heeft ingesteld dat je 2-factor authenticatie moet gebruiken voor je acount voordat je het paneel kan gebruiken',
'2fa_required' => '2-factor authenticatie',
'confirmpassword' => 'Bevestig wachtwoord',
'emailsent' => 'Je wachtwoord reset email is onderweg.',
'emailsent' => 'Je wachtwoord herstel e-mail is onderweg.',
'forgot_password' => 'Ik ben mijn wachtwoord vergeten!',
'not_authorized' => 'U hebt geen toestemming om deze actie uit te voeren.',
'password_requirements' => 'Paswoorden moeten minstens één kleine letter, één hoofdletter en één numeriek karakter bevatten, het paswoord moet ook minstens 8 karakters lang zijn.',
'not_authorized' => 'U heeft geen toestemming om deze actie uit te voeren.',
'password_requirements' => 'Wachtwoorden moeten minstens één kleine letter, één hoofdletter en één numeriek karakter bevatten, het wachtwoord moet ook minstens 8 karakters lang zijn.',
'remember_me' => 'Onthoud mij',
'resetpassword' => 'Reset wachtwoord',
'reset_password' => 'Reset account wachtwoord',
'reset_password_text' => 'Reset uw account wachtwoord.',
'sendlink' => 'Stuur wachtwoord reset link',
'throttle' => 'Teveel inlog pogingen. Probeer opnieuw in :seconds seconden.',
'resetpassword' => 'Herstel wachtwoord',
'reset_password' => 'Herstel account wachtwoord',
'reset_password_text' => 'Herstel uw account wachtwoord.',
'sendlink' => 'Stuur wachtwoord herstel link',
'throttle' => 'Teveel inlog pogingen. Probeer het opnieuw in :seconds seconden.',
];

View file

@ -2,58 +2,57 @@
return [
'account' => [
'current_password' => 'Huidig Paswoord',
'delete_user' => 'Verwijder Gebruiker',
'current_password' => 'Huidig Wachtwoord',
'delete_user' => 'Gebruiker Verwijderen',
'details_updated' => 'Je account details zijn succesvol veranderd',
'email_password' => 'Email paswoord',
'email_password' => 'E-mail wachtwoord',
'exception' => 'Er is een fout opgetreden tijdens het veranderen van je account.',
'first_name' => 'Voornaam',
'header' => 'Account Beheer',
'header_sub' => 'Beheer uw account details',
'invalid_pass' => 'Het opgegeven wachtwoord is niet geldig voor dit account.',
'invalid_password' => 'Het gegeven wachtwoord voor je account is niet geldig.',
'invalid_pass' => 'Het opgegeven wachtwoord is ongeldig voor dit account.',
'invalid_password' => 'Het opgegeven wachtwoord voor je account is ongeldig.',
'last_name' => 'Naam',
'new_email' => 'Nieuw email adres',
'new_password' => 'Nieuw Paswoord',
'new_email' => 'Nieuw e-mail adres',
'new_password' => 'Nieuw Wachtwoord',
'new_password_again' => 'Herhaal nieuw wachtwoord',
'totp_apps' => 'U moet een TOTP ondersteunde applicatie hebben (vb Google Authenticator, DUO Mobile, Auth, Enpass) om van deze optie gebruik te kunnen maken.',
'totp_checkpoint_help' => 'Bevestig aub uw TOTP instellingen door de QR code rechts te scannen met de authenticator applicatie op uw smartphone. Vul vervolgens de 6-delige code, die de applicatie genereerde, in onderstaand veld in. Druk op enter wanneer u klaar bent.',
'totp_apps' => 'U moet een TOTP ondersteunde applicatie hebben (bijv. Google Authenticator, DUO Mobile, Auth, Enpass) om van deze optie gebruik te kunnen maken.',
'totp_checkpoint_help' => 'Bevestig a.u.b. uw TOTP instellingen door de QR code rechts te scannen met de authenticator applicatie op uw smartphone. Vul vervolgens de 6-delige code, die de applicatie genereerde, in het onderstaand veld in. Druk op enter wanneer u klaar bent.',
'totp_disable' => 'Schakel 2-delige authenticatie uit.',
'totp_disable_help' => 'Om TOTP uit te schakelen op dit account moet je een geldige TOTP token geven. TOTP bescherming zal uitgeschakeld worden als de token geldig is.',
'totp_enable' => 'Schakel Two-Factor Authentication in',
'totp_enabled' => 'TOTP is nu ingeschakeld op dit account. Klik op de sluit knop om te beëindigen.',
'totp_enabled_error' => 'De opgegeven TOTP token kon niet gevalideerd worden. Probeer het aub nogmaals.',
'totp_header' => 'Twee-Factor Authenticatie',
'totp_header' => 'Two-Factor Authenticatie',
'totp_qr' => 'TOTP QR Code',
'totp_token' => 'TOTP Token
',
'update_email' => 'Update Email Adres',
'update_identitity' => 'Update identiteit',
'update_pass' => 'Werk wachtwoord bij',
'update_user' => 'Update Gebruiker',
'username_help' => 'Uw gebruikersnaam moet uniek zijn en mas enkel volgende characters bevatten: :requirements.',
'totp_token' => 'TOTP Token',
'update_email' => 'E-mail Adres Bijwerken',
'update_identitity' => 'Identiteit Bijwerken',
'update_pass' => 'Wachtwoord Bijwerken',
'update_user' => 'Gebruiker Bijwerken',
'username_help' => 'Uw gebruikersnaam moet uniek zijn en mag enkel de volgende characters bevatten: :requirements.',
],
'api' => [
'index' => [
'create_new' => 'Creëer nieuwe API sleutel',
'header' => 'API toegang',
'header_sub' => 'Beheer jouw API keys.',
'keypair_created' => 'Een API Key-Pair is gegenereerd. Jouw API secret token is <code>:token</code>. Noteer deze code, hij wordt later niet nog een keer weergegeven.',
'header_sub' => 'Beheer jouw API sleutels.',
'keypair_created' => 'Een API Key-Pair is gegenereerd. Jouw API geheime token is <code>:token</code>. Noteer deze code, hij wordt later niet nog een keer weergegeven.',
'list' => 'API sleutels',
],
'new' => [
'allowed_ips' => [
'title' => 'Toegestane IPs',
'title' => 'Toegestane IP\'s',
],
'base' => [
'title' => 'Basis Informatie',
],
'descriptive_memo' => [
'description' => 'Voeg een korte beschrijving over waarvoor deze API key gebruikt zal worden toe.',
'description' => 'Voeg een korte beschrijving over waarvoor deze API sleutel gebruikt zal worden toe.',
'title' => 'Beschrijvende notitie',
],
'form_title' => 'Details',
'header' => 'Nieuwe API Key',
'header' => 'Nieuwe API Sleutel',
'header_sub' => 'Maak een nieuwe API toegangs sleutel',
'node_management' => [
'delete' => [
@ -91,7 +90,7 @@ return [
],
'user_management' => [
'create' => [
'title' => 'Maak gebruiker',
'title' => 'Gebruiker Aanmaken',
],
'delete' => [
'description' => 'Geeft toegang tot het verwijderen van een gebruiker',
@ -101,7 +100,7 @@ return [
],
'title' => 'Gebruikersbeheer',
'update' => [
'title' => 'Werk gebruiker bij',
'title' => 'Gebruiker bijwerken',
],
'view' => [
'title' => 'Toon gebruiker',
@ -122,9 +121,9 @@ return [
'security' => [
'2fa_header' => '2-factor authenticatie',
'2fa_qr' => 'Configureer 2FA op uw toestel',
'enable_2fa' => 'Zet 2-Factor Authentication aan',
'enable_2fa' => 'Zet 2-Factor authenticatie aan',
],
'server_name' => 'Server naam',
'validation_error' => 'Er is een fout opgetreden tijdens het valideren van de data die u opgegeven hebt.',
'validation_error' => 'Er is een fout opgetreden tijdens het valideren van de data die u heeft opgegeven.',
'view_as_admin' => 'U bekijkt de server lijst als een administrator. Hierdoor zijn alle servers die geïnstalleerd zijn op het systeem zichtbaar. Alle servers waarvan u de eigenaar bent zijn gemarkeerd met een blauwe bol links van hun naam.',
];

View file

@ -1,7 +1,7 @@
<?php
return [
'password' => 'Paswoord',
'password' => 'Wachtwoord',
'sent' => 'We hebben u een wachtwoord herstel link gestuurd!',
'user' => 'We kunnen geen gebruiker vinden met dat e-mail adres.',
];

View file

@ -84,7 +84,7 @@ return [
'description' => 'Staat gebruikers toe om een nieuw bestand aan te maken binnen het paneel.',
],
'create_task' => [
'title' => 'Maak een taak',
'title' => 'Taak aanmaken',
],
'db_header' => 'Database beheer',
'delete_files' => [
@ -118,10 +118,10 @@ return [
'title' => 'Plan taak',
],
'reset_db_password' => [
'title' => 'Reset database wachtwoord',
'title' => 'Herstel database wachtwoord',
],
'reset_sftp' => [
'title' => 'Reset SFTP wachtwoord',
'title' => 'Herstel SFTP wachtwoord',
],
'restart' => [
'title' => 'Herstart server',
@ -141,8 +141,7 @@ return [
'description' => 'Staat gebruikers toe om bestanden te uploaden via het bestandsbeheer.',
],
'view_databases' => [
'title' => 'Geef database details weer
',
'title' => 'Geef database details weer',
],
'view_schedule' => [
'title' => 'Bekijk Schema',
@ -170,6 +169,6 @@ return [
],
'update' => 'Werk sub gebruiker bij',
'user_assigned' => 'De subuser is succesvol toegevoegd aan deze server.',
'user_updated' => 'Permissies zijn geupdate.',
'user_updated' => 'Rechten zijn bijgewerkt.',
],
];

View file

@ -17,7 +17,7 @@ return [
'created_at' => 'Gecreëerd op',
'data' => 'Bestanden',
'database' => 'Database',
'email' => 'Email',
'email' => 'E-mail',
'enabled' => 'Ingeschakeld',
'expires' => 'Verloopt',
'home' => 'Home',
@ -29,7 +29,7 @@ return [
'next_run' => 'Volgende ronde',
'node' => 'Node',
'none' => 'Geen',
'password' => 'Paswoord',
'password' => 'Wachtwoord',
'players' => 'Spelers',
'primary' => 'Primair',
'queued' => 'Wachtrij',

View file

@ -8,7 +8,7 @@ return [
'alpha' => 'Het :attribute mag enkel letters bevatten.',
'alpha_dash' => 'De :attribute mag alleen letters, nummers en streepjes bevatten.',
'alpha_num' => 'De :attribute mag alleen letters en nummers bevatten.',
'email' => 'Email',
'email' => 'E-mail',
'in' => 'Het geselecteerde :attribute is ongeldig.',
'timezone' => 'Het :attribute moet een geldige tijdszone zijn.',
'totp' => 'De totp token is ongeldig. Is het verlopen?',

View file

@ -39,23 +39,42 @@
<div class="box-header with-border">
<h3 class="box-title">Existing Allocations</h3>
</div>
<div class="box-body table-responsive no-padding">
<div class="box-body table-responsive no-padding" style="overflow-x: visible">
<table class="table table-hover" style="margin-bottom:0;">
<tr>
<th>
<input type="checkbox" class="select-all-files hidden-xs" data-action="selectAll">
</th>
<th>IP Address <i class="fa fa-fw fa-minus-square" style="font-weight:normal;color:#d9534f;cursor:pointer;" data-toggle="modal" data-target="#allocationModal"></i></th>
<th>IP Alias</th>
<th>Port</th>
<th>Assigned To</th>
<th></th>
<th>
<div class="btn-group hidden-xs">
<button type="button" id="mass_actions" class="btn btn-sm btn-default dropdown-toggle disabled"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">@lang('server.allocations.mass_actions') <span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-massactions">
<li><a href="#" id="selective-deletion" data-action="selective-deletion">@lang('server.allocations.delete') <i class="fa fa-fw fa-trash-o"></i></a></li>
</ul>
</div>
</th>
</tr>
@foreach($node->allocations as $allocation)
<tr>
<td class="col-sm-3 middle">{{ $allocation->ip }}</td>
<td class="middle min-size" data-identifier="type">
@if(is_null($allocation->server_id))
<input type="checkbox" class="select-file hidden-xs" data-action="addSelection">
@else
<input disabled="disabled" type="checkbox" class="select-file hidden-xs" data-action="addSelection">
@endif
</td>
<td class="col-sm-3 middle" data-identifier="ip">{{ $allocation->ip }}</td>
<td class="col-sm-3 middle">
<input class="form-control input-sm" type="text" value="{{ $allocation->ip_alias }}" data-action="set-alias" data-id="{{ $allocation->id }}" placeholder="none" />
<span class="input-loader"><i class="fa fa-refresh fa-spin fa-fw"></i></span>
</td>
<td class="col-sm-2 middle">{{ $allocation->port }}</td>
<td class="col-sm-2 middle" data-identifier="port">{{ $allocation->port }}</td>
<td class="col-sm-3 middle">
@if(! is_null($allocation->server))
<a href="{{ route('admin.servers.view', $allocation->server_id) }}">{{ $allocation->server->name }}</a>
@ -153,17 +172,35 @@
@section('footer-scripts')
@parent
<script>
$('[data-action="addSelection"]').on('click', function () {
updateMassActions();
});
$('[data-action="selectAll"]').on('click', function () {
$('input.select-file').not(':disabled').prop('checked', function (i, val) {
return !val;
});
updateMassActions();
});
$('[data-action="selective-deletion"]').on('mousedown', function () {
deleteSelected();
});
$('#pAllocationIP').select2({
tags: true,
maximumSelectionLength: 1,
selectOnClose: true,
tokenSeparators: [',', ' '],
});
$('#pAllocationPorts').select2({
tags: true,
selectOnClose: true,
tokenSeparators: [',', ' '],
});
$('button[data-action="deallocate"]').click(function (event) {
event.preventDefault();
var element = $(this);
@ -216,7 +253,7 @@
alias: element.val(),
allocation_id: element.data('id'),
}
}).done(function (data) {
}).done(function () {
element.parent().addClass('has-success');
}).fail(function (jqXHR) {
console.error(jqXHR);
@ -230,5 +267,99 @@
function clearHighlight(element) {
element.parent().removeClass('has-error has-success');
}
function updateMassActions() {
if ($('input.select-file:checked').length > 0) {
$('#mass_actions').removeClass('disabled');
} else {
$('#mass_actions').addClass('disabled');
}
}
function deleteSelected() {
var selectedIds = [];
var selectedItems = [];
var selectedItemsElements = [];
$('input.select-file:checked').each(function () {
var $parent = $($(this).closest('tr'));
var id = $parent.find('[data-action="deallocate"]').data('id');
var $ip = $parent.find('td[data-identifier="ip"]');
var $port = $parent.find('td[data-identifier="port"]');
var block = `${$ip.text()}:${$port.text()}`;
selectedIds.push({
id: id
});
selectedItems.push(block);
selectedItemsElements.push($parent);
});
if (selectedItems.length !== 0) {
var formattedItems = "";
var i = 0;
$.each(selectedItems, function (key, value) {
formattedItems += ("<code>" + value + "</code>, ");
i++;
return i < 5;
});
formattedItems = formattedItems.slice(0, -2);
if (selectedItems.length > 5) {
formattedItems += ', and ' + (selectedItems.length - 5) + ' other(s)';
}
swal({
type: 'warning',
title: '',
text: 'Are you sure you want to delete the following allocations: ' + formattedItems + '?',
html: true,
showCancelButton: true,
showConfirmButton: true,
closeOnConfirm: false,
showLoaderOnConfirm: true
}, function () {
$.ajax({
method: 'DELETE',
url: Router.route('admin.nodes.view.allocation.removeMultiple', {
node: Pterodactyl.node.id
}),
headers: {'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')},
data: JSON.stringify({
allocations: selectedIds
}),
contentType: 'application/json',
processData: false
}).done(function () {
$('#file_listing input:checked').each(function () {
$(this).prop('checked', false);
});
$.each(selectedItemsElements, function () {
$(this).addClass('warning').delay(200).fadeOut();
});
swal({
type: 'success',
title: 'Allocations Deleted'
});
}).fail(function (jqXHR) {
console.error(jqXHR);
swal({
type: 'error',
title: 'Whoops!',
html: true,
text: 'An error occurred while attempting to delete these allocations. Please try again.',
});
});
});
} else {
swal({
type: 'warning',
title: '',
text: 'Please select allocation(s) to delete.',
});
}
}
</script>
@endsection

View file

@ -32,7 +32,7 @@
</div>
</div>
@else
<form action="{{ route('admin.settings.mail') }}" method="POST">
<form>
<div class="box-body">
<div class="row">
<div class="form-group col-md-6">
@ -98,7 +98,10 @@
</div>
<div class="box-footer">
{{ csrf_field() }}
<button type="submit" name="_method" value="PATCH" class="btn btn-sm btn-primary pull-right">Save</button>
<div class="pull-right">
<button type="button" id="testButton" class="btn btn-sm btn-success">Test</button>
<button type="button" id="saveButton" class="btn btn-sm btn-primary">Save</button>
</div>
</div>
</form>
@endif
@ -106,3 +109,96 @@
</div>
</div>
@endsection
@section('footer-scripts')
{!! Theme::js('js/laroute.js?t={cache-version}') !!}
{!! Theme::js('vendor/jquery/jquery.min.js?t={cache-version}') !!}
{!! Theme::js('vendor/sweetalert/sweetalert.min.js?t={cache-version}') !!}
<script>
function saveSettings() {
return $.ajax({
method: 'PATCH',
url: Router.route('admin.settings.mail'),
contentType: 'application/json',
data: JSON.stringify({
'mail:host': $('input[name="mail:host"]').val(),
'mail:port': $('input[name="mail:port"]').val(),
'mail:encryption': $('select[name="mail:encryption"]').val(),
'mail:username': $('input[name="mail:username"]').val(),
'mail:password': $('input[name="mail:password"]').val(),
'mail:from:address': $('input[name="mail:from:address"]').val(),
'mail:from:name': $('input[name="mail:from:name"]').val()
}),
headers: { 'X-CSRF-Token': $('input[name="_token"]').val() }
}).fail(function (jqXHR) {
showErrorDialog(jqXHR, 'save');
});
}
function testSettings() {
swal({
type: 'info',
title: 'Test Mail Settings',
text: 'Click "Test" to begin the test.',
showCancelButton: true,
confirmButtonText: 'Test',
closeOnConfirm: false,
showLoaderOnConfirm: true
}, function () {
$.ajax({
method: 'GET',
url: Router.route('admin.settings.mail.test'),
headers: { 'X-CSRF-Token': $('input[name="_token"]').val() }
}).fail(function (jqXHR) {
showErrorDialog(jqXHR, 'test');
}).done(function () {
swal({
title: 'Success',
text: 'The test message was sent successfully.',
type: 'success'
});
});
});
}
function saveAndTestSettings() {
saveSettings().done(testSettings);
}
function showErrorDialog(jqXHR, verb) {
console.error(jqXHR);
var errorText = '';
if (!jqXHR.responseJSON) {
errorText = jqXHR.responseText;
} else if (jqXHR.responseJSON.error) {
errorText = jqXHR.responseJSON.error;
} else if (jqXHR.responseJSON.errors) {
$.each(jqXHR.responseJSON.errors, function (i, v) {
if (v.detail) {
errorText += v.detail + ' ';
}
});
}
swal({
title: 'Whoops!',
text: 'An error occurred while attempting to ' + verb + ' mail settings: ' + errorText,
type: 'error'
});
}
$(document).ready(function () {
$('#testButton').on('click', saveAndTestSettings);
$('#saveButton').on('click', function () {
saveSettings().done(function () {
swal({
title: 'Success',
text: 'Mail settings have been updated successfully and the queue worker was restarted to apply these changes.',
type: 'success'
});
});
});
});
</script>
@endsection

View file

@ -60,7 +60,5 @@
particlesJS.load('particles-js', '{!! Theme::url('vendor/particlesjs/particles.json?t={cache-version}') !!}', function() {});
})
</script>
@if(config('pterodactyl.lang.in_context')) {!! Theme::js('vendor/phraseapp/phraseapp.js?t={cache-version}') !!} @endif
</body>
</html>

View file

@ -286,9 +286,6 @@
{!! Theme::js('vendor/socketio/socket.io.v203.min.js?t={cache-version}') !!}
{!! Theme::js('vendor/bootstrap-notify/bootstrap-notify.min.js?t={cache-version}') !!}
{!! Theme::js('js/autocomplete.js?t={cache-version}') !!}
@if(config('pterodactyl.lang.in_context'))
{!! Theme::js('vendor/phraseapp/phraseapp.js?t={cache-version}') !!}
@endif
@if(Auth::user()->root_admin)
<script>

View file

@ -64,6 +64,7 @@ Route::group(['prefix' => 'databases'], function () {
Route::group(['prefix' => 'settings'], function () {
Route::get('/', 'Settings\IndexController@index')->name('admin.settings');
Route::get('/mail', 'Settings\MailController@index')->name('admin.settings.mail');
Route::get('/mail/test', 'Settings\MailController@test')->name('admin.settings.mail.test');
Route::get('/advanced', 'Settings\AdvancedController@index')->name('admin.settings.advanced');
Route::patch('/', 'Settings\IndexController@update');
@ -153,6 +154,7 @@ Route::group(['prefix' => 'nodes'], function () {
Route::delete('/view/{node}/delete', 'NodesController@delete')->name('admin.nodes.view.delete');
Route::delete('/view/{node}/allocation/remove/{allocation}', 'NodesController@allocationRemoveSingle')->name('admin.nodes.view.allocation.removeSingle');
Route::delete('/view/{node}/allocations', 'NodesController@allocationRemoveMultiple')->name('admin.nodes.view.allocation.removeMultiple');
});
/*

View file

@ -0,0 +1,82 @@
<?php
namespace Tests\Unit\Http\Controllers;
use Mockery as m;
use Prologue\Alerts\AlertsMessageBag;
use Illuminate\Contracts\Console\Kernel;
use Illuminate\Contracts\Encryption\Encrypter;
use Illuminate\Contracts\Config\Repository as ConfigRepository;
use Pterodactyl\Http\Controllers\Admin\Settings\MailController;
use Pterodactyl\Contracts\Repository\SettingsRepositoryInterface;
class MailControllerTest extends ControllerTestCase
{
/**
* @var \Prologue\Alerts\AlertsMessageBag
*/
private $alert;
/**
* @var \Illuminate\Contracts\Config\Repository
*/
private $configRepository;
/**
* @var \Illuminate\Contracts\Encryption\Encrypter
*/
private $encrypter;
/**
* @var \Illuminate\Contracts\Console\Kernel
*/
private $kernel;
/**
* @var \Pterodactyl\Contracts\Repository\SettingsRepositoryInterface
*/
private $settingsRepositoryInterface;
/**
* Setup tests.
*/
public function setUp()
{
parent::setUp();
$this->alert = m::mock(AlertsMessageBag::class);
$this->configRepository = m::mock(ConfigRepository::class);
$this->encrypter = m::mock(Encrypter::class);
$this->kernel = m::mock(Kernel::class);
$this->settingsRepositoryInterface = m::mock(SettingsRepositoryInterface::class);
}
/**
* Test the mail controller for viewing mail settings page.
*/
public function testIndex()
{
$this->configRepository->shouldReceive('get');
$response = $this->getController()->index();
$this->assertIsViewResponse($response);
$this->assertViewNameEquals('admin.settings.mail', $response);
}
/**
* Prepare a MailController using our mocks.
*
* @return MailController
*/
public function getController()
{
return new MailController(
$this->alert,
$this->configRepository,
$this->encrypter,
$this->kernel,
$this->settingsRepositoryInterface
);
}
}

View file

@ -73,7 +73,7 @@ class IndexControllerTest extends ControllerTestCase
$this->request->shouldReceive('input')->with('query')->once()->andReturn('searchTerm');
$this->repository->shouldReceive('setSearchTerm')->with('searchTerm')->once()->andReturnSelf()
->shouldReceive('filterUserAccessServers')->with($model, User::FILTER_LEVEL_ALL)
->shouldReceive('filterUserAccessServers')->with($model, User::FILTER_LEVEL_ALL, config('pterodactyl.paginate.frontend.servers'))
->once()->andReturn($paginator);
$response = $this->controller->getIndex($this->request);