Compare commits
No commits in common. "main" and "0.0.1" have entirely different histories.
1353 changed files with 1489 additions and 172916 deletions
28
.github/workflows/compile-ngix-package.yml
vendored
28
.github/workflows/compile-ngix-package.yml
vendored
|
@ -1,10 +1,8 @@
|
|||
name: Compile Phyre NGINX Package
|
||||
|
||||
on:
|
||||
push:
|
||||
# Pattern matched against refs/tags
|
||||
tags:
|
||||
- '**'
|
||||
release:
|
||||
branches: [ "main" ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
@ -27,15 +25,15 @@ jobs:
|
|||
./nginx-compile.sh
|
||||
ls
|
||||
|
||||
- name: Pushes to Phyre Panel Dist Repo
|
||||
uses: cpina/github-action-push-to-another-repository@main
|
||||
env:
|
||||
SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}
|
||||
API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
|
||||
- uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
source-directory: './compilators/debian/nginx/dist'
|
||||
target-directory: './debian/nginx/dist'
|
||||
destination-github-username: 'CloudVisionApps'
|
||||
destination-repository-name: 'PhyrePanelNginxDist'
|
||||
user-email: bobicloudvision@gmail.com
|
||||
target-branch: main
|
||||
commit_user_name: Cloud Vision Bot
|
||||
commit_user_email: bobicloudvision@gmail.com
|
||||
commit_author: Cloud Vision Bot <bobicloudvision@gmail.com>
|
||||
commit_message: Upload compiled packages [BOT]
|
||||
repository: ./compilators/debian/nginx/dist
|
||||
#skip_checkout: true
|
||||
#push_options: '--force'
|
||||
#skip_fetch: true
|
||||
#create_branch: true
|
||||
# status_options: '--untracked-files=no'
|
||||
|
|
41
.github/workflows/compile-php-package.yml
vendored
41
.github/workflows/compile-php-package.yml
vendored
|
@ -1,41 +0,0 @@
|
|||
name: Compile Phyre PHP Package
|
||||
|
||||
on:
|
||||
push:
|
||||
# Pattern matched against refs/tags
|
||||
tags:
|
||||
- '**'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Compile PHP
|
||||
run: |
|
||||
cd compilators/debian/php
|
||||
chmod 775 ./php-compile.sh
|
||||
./php-compile.sh
|
||||
ls
|
||||
|
||||
- name: Pushes to Phyre Panel Dist Repo
|
||||
uses: cpina/github-action-push-to-another-repository@main
|
||||
env:
|
||||
SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}
|
||||
API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
|
||||
with:
|
||||
source-directory: './compilators/debian/php/dist'
|
||||
target-directory: './debian/php/dist'
|
||||
destination-github-username: 'CloudVisionApps'
|
||||
destination-repository-name: 'PhyrePanelPHPDist'
|
||||
user-email: bobicloudvision@gmail.com
|
||||
target-branch: main
|
39
.github/workflows/compile-php-package.yml.old
vendored
Normal file
39
.github/workflows/compile-php-package.yml.old
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
name: Compile Phyre PHP Package
|
||||
|
||||
on:
|
||||
release:
|
||||
branches: [ "main" ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Compile PHP
|
||||
run: |
|
||||
cd compilators/debian/php
|
||||
chmod 775 ./php-compile.sh
|
||||
./php-compile.sh
|
||||
ls
|
||||
|
||||
- uses: stefanzweifel/git-auto-commit-action@v5
|
||||
with:
|
||||
commit_user_name: Cloud Vision Bot
|
||||
commit_user_email: bobicloudvision@gmail.com
|
||||
commit_author: Cloud Vision Bot <bobicloudvision@gmail.com>
|
||||
commit_message: Upload compiled packages [BOT]
|
||||
repository: ./compilators/debian/php/dist
|
||||
#skip_checkout: true
|
||||
#push_options: '--force'
|
||||
#skip_fetch: true
|
||||
#create_branch: true
|
||||
# status_options: '--untracked-files=no'
|
67
.github/workflows/compile-web-panel.yml
vendored
67
.github/workflows/compile-web-panel.yml
vendored
|
@ -1,67 +0,0 @@
|
|||
name: Compile Phyre Web Panel
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
compile-phyre-web-panel:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
repository: ${{ github.repository }}
|
||||
- name: Npm install
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.2
|
||||
|
||||
- name: Install Composer Dependencies
|
||||
working-directory: ./web
|
||||
run: |
|
||||
rm -rf composer.lock
|
||||
composer install
|
||||
composer dump-autoload
|
||||
|
||||
- name: Install NODE Dependencies
|
||||
working-directory: ./web
|
||||
run: |
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
- name: Inject slug/short variables
|
||||
uses: rlespinasse/github-slug-action@v3.x
|
||||
|
||||
- name: Zip the files
|
||||
working-directory: ./web
|
||||
run: |
|
||||
rm -rf .git
|
||||
rm -rf .github
|
||||
rm -rf .nmp
|
||||
rm -rf node_modules
|
||||
rm -rf .phpunit.cache
|
||||
rm -rf vendor/composer/tmp-*.zip
|
||||
find . \( -name ".git" -o -name ".gitignore" -o -name ".gitmodules" -o -name ".gitattributes" \) -exec rm -rf -- {} +
|
||||
zip -r phyre-web-panel-build.zip `ls -A`
|
||||
mkdir -p ../dist
|
||||
mv ./phyre-web-panel-build.zip ../dist/phyre-web-panel.zip
|
||||
|
||||
- name: Pushes to Phyre Panel Dist Repo
|
||||
uses: cpina/github-action-push-to-another-repository@main
|
||||
env:
|
||||
SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}
|
||||
API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
|
||||
with:
|
||||
source-directory: './dist'
|
||||
destination-github-username: 'CloudVisionApps'
|
||||
destination-repository-name: 'PhyrePanelWebDist'
|
||||
user-email: bobicloudvision@gmail.com
|
||||
target-branch: main
|
5
.github/workflows/php.yml_
vendored
5
.github/workflows/php.yml_
vendored
|
@ -22,8 +22,3 @@ jobs:
|
|||
wget https://raw.githubusercontent.com/CloudVisionApps/PhyrePanel/main/installers/install.sh
|
||||
chmod +x install.sh
|
||||
sudo ./install.sh
|
||||
|
||||
- name: Run PhyrePanel Tests
|
||||
working-directory: ./
|
||||
run: |
|
||||
/usr/local/phyre/php/bin/php artisan test
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,2 +0,0 @@
|
|||
|
||||
web/storage/installed
|
|
@ -1,7 +1,5 @@
|
|||
# PhyrePanel
|
||||
|
||||

|
||||
|
||||
## Introduction
|
||||
PhyrePanel is a web-based panel for linux. It is written in PHP and uses the Laravel framework.
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
ls
|
|
@ -1,19 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
username=$1
|
||||
schedule=$2
|
||||
command=$3
|
||||
|
||||
# Create a temporary file to hold the existing user's crontab
|
||||
crontab -u $username -l > /tmp/temp_crontab
|
||||
|
||||
# Add a new cron job to the temporary file
|
||||
echo "$schedule $command" >> /tmp/temp_crontab
|
||||
|
||||
# Install the modified crontab from the temporary file
|
||||
crontab -u $username /tmp/temp_crontab
|
||||
|
||||
# Remove the temporary file
|
||||
rm /tmp/temp_crontab
|
||||
|
||||
echo "done!"
|
|
@ -1,10 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
username=$1
|
||||
schedule=$2
|
||||
command=$3
|
||||
|
||||
# Get the user's crontab, filter out the specific command and schedule, and install the updated crontab
|
||||
crontab -u $username -l | grep -v -F "$schedule $command" | crontab -u $username -
|
||||
|
||||
echo "done!"
|
|
@ -1,7 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Replace 'username' with the actual username you want to retrieve cron jobs for
|
||||
username=$1
|
||||
|
||||
# Get the user's crontab entries and convert them to JSON
|
||||
crontab -u $username -l | grep -v -e '^#' -e '^\s*$' | awk '{print "{\"schedule\":\"" $1 " " $2 " " $3 " " $4 " " $5 "\", \"command\":\"" substr($0, index($0,$6)) "\"}"}' | jq -s .
|
|
@ -1,22 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo "Creating MySQL user and database"
|
||||
|
||||
PASS=$3
|
||||
if [ -z "$3" ]; then
|
||||
PASS=`openssl rand -base64 8`
|
||||
fi
|
||||
|
||||
mysql -u root <<MYSQL_SCRIPT
|
||||
CREATE DATABASE $1;
|
||||
CREATE USER '$2'@'localhost' IDENTIFIED BY '$PASS';
|
||||
GRANT ALL PRIVILEGES ON $1.* TO '$2'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
MYSQL_SCRIPT
|
||||
|
||||
echo "MySQL user and database created."
|
||||
echo "Database: $1"
|
||||
echo "Username: $2"
|
||||
echo "Password: $PASS"
|
||||
echo "Success!"
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
DOMAIN=$1
|
||||
USER=$2
|
||||
|
||||
# Path to NGINX sites-available directory
|
||||
SITES_AVAILABLE_DIR="/etc/nginx/sites-available"
|
||||
SITES_ENABLED_DIR="/etc/nginx/sites-enabled"
|
||||
|
||||
# Create the site
|
||||
SERVER_ROOT="/var/www/$DOMAIN/public_html"
|
||||
|
||||
cp -f /usr/local/phyre/samples/ubuntu/nginx.conf.sample $SITES_AVAILABLE_DIR/$DOMAIN.conf
|
||||
ln -s $SITES_AVAILABLE_DIR/$DOMAIN.conf $SITES_ENABLED_DIR/$DOMAIN.conf
|
||||
|
||||
mkdir -p $SERVER_ROOT
|
||||
chown -R www-data:www-data $SERVER_ROOT
|
||||
|
||||
# Replace the domain name in the NGINX config
|
||||
sed -i "s/%SERVER_NAME%/${DOMAIN}/g" $SITES_AVAILABLE_DIR/$DOMAIN.conf
|
||||
sed -i "s/%USER%/${USER}/g" $SITES_AVAILABLE_DIR/$DOMAIN.conf
|
||||
|
||||
SERVER_ROOT_ESCAPED=$(printf '%s\n' "$SERVER_ROOT" | sed -e 's/[\/&]/\\&/g')
|
||||
sed -i "s#%SERVER_ROOT%#${SERVER_ROOT_ESCAPED}#g" $SITES_AVAILABLE_DIR/$DOMAIN.conf
|
||||
|
||||
cp -f /usr/local/phyre/samples/sample-website-index.html $SERVER_ROOT/index.html
|
||||
sed -i "s/%DOMAIN%/${DOMAIN}/g" $SERVER_ROOT/index.html
|
||||
|
||||
|
||||
# Reload NGINX
|
||||
service nginx reload
|
||||
|
||||
echo "Created site $DOMAIN"
|
||||
echo "done!"
|
|
@ -1,16 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Path to NGINX sites-available directory
|
||||
SITES_AVAILABLE_DIR="/etc/nginx/sites-available"
|
||||
SITES_ENABLED_DIR="/etc/nginx/sites-enabled"
|
||||
|
||||
# Delete the site
|
||||
rm -rf $SITES_AVAILABLE_DIR/$1.conf
|
||||
rm -rf $SITES_ENABLED_DIR/$1.conf
|
||||
rm -rf /var/www/$1
|
||||
|
||||
# Reload NGINX
|
||||
service nginx reload
|
||||
|
||||
echo "Deleted site $1"
|
||||
echo "done!"
|
|
@ -1,24 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Path to NGINX sites-available directory
|
||||
sites_available_dir="/etc/nginx/sites-available"
|
||||
|
||||
# Array to hold site configurations
|
||||
declare -a sites_array=()
|
||||
|
||||
# Loop through NGINX site configuration files and collect data
|
||||
for file in "$sites_available_dir"/*; do
|
||||
if [ -f "$file" ] && [ "$(basename "$file")" != "default" ]; then
|
||||
server_name=$(awk '$1 == "server_name" {gsub(/;/, "", $2); print $2; exit}' "$file")
|
||||
root=$(awk '$1 == "root" {gsub(/;/, "", $2); print $2; exit}' "$file")
|
||||
|
||||
# Append site data to the array
|
||||
sites_array+=("{\"file\": \"$file\", \"server_name\": \"$server_name\", \"root\": \"$root\"}")
|
||||
fi
|
||||
done
|
||||
|
||||
# Convert array to JSON
|
||||
json_output=$(printf '%s\n' "${sites_array[@]}" | jq -s '.')
|
||||
|
||||
# Output JSON
|
||||
echo "$json_output"
|
11
cer.txt
Normal file
11
cer.txt
Normal file
|
@ -0,0 +1,11 @@
|
|||
sudo ufw allow 22
|
||||
|
||||
|
||||
sudo apt install certbot python3-certbot-nginx -y
|
||||
sudo ufw allow 3036
|
||||
sudo ufw allow 'Nginx Full'
|
||||
sudo ufw delete allow 'Nginx HTTP'
|
||||
sudo ufw status
|
||||
|
||||
sudo certbot --nginx -d webesembly.com -d www.webesembly.com
|
||||
sudo systemctl status certbot.timer
|
BIN
compilators/debian/nginx/dist/phyre-nginx-1.24.0.deb
vendored
BIN
compilators/debian/nginx/dist/phyre-nginx-1.24.0.deb
vendored
Binary file not shown.
|
@ -1,6 +1,5 @@
|
|||
# Server globals
|
||||
#user phyreweb;
|
||||
user root;
|
||||
user phyreweb;
|
||||
worker_processes 1;
|
||||
worker_rlimit_nofile 65535;
|
||||
#error_log /var/log/phyre/nginx-error.log;
|
||||
|
@ -88,27 +87,23 @@ http {
|
|||
"~Firefox/((58|59)|([6-9]\d)|([1-9]\d{2,}))\.\d+" 1;
|
||||
}
|
||||
|
||||
# Admin Panel
|
||||
# Vhost
|
||||
server {
|
||||
listen 8443;
|
||||
listen [::]:8443;
|
||||
listen 4990;
|
||||
listen [::]:4990;
|
||||
server_name _;
|
||||
root /usr/local/phyre/web/public;
|
||||
root /usr/local/phyre/web;
|
||||
# Fix error "The plain HTTP request was sent to HTTPS port"
|
||||
error_page 497 https://$host:$server_port$request_uri;
|
||||
error_page 403 /error/404.html;
|
||||
error_page 404 /error/404.html;
|
||||
error_page 410 /error/410.html;
|
||||
error_page 500 501 502 503 504 505 /error/50x.html;
|
||||
|
||||
add_header X-Frame-Options "SAMEORIGIN";
|
||||
add_header X-Content-Type-Options "nosniff";
|
||||
|
||||
index index.php;
|
||||
charset utf-8;
|
||||
|
||||
error_page 404 /index.php;
|
||||
|
||||
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; }
|
||||
location / {
|
||||
expires off;
|
||||
index index.php;
|
||||
}
|
||||
|
||||
location /error/ {
|
||||
expires off;
|
||||
|
@ -123,44 +118,12 @@ http {
|
|||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
|
||||
location ~ \.php$ {
|
||||
fastcgi_pass unix:/run/phyre-php.sock;
|
||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
}
|
||||
|
||||
location ~ /\.(?!well-known).* {
|
||||
deny all;
|
||||
}
|
||||
location ~ \.php$ {
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME /usr/local/phyre/web/$fastcgi_script_name;
|
||||
fastcgi_pass unix:/run/phyre-php.sock;
|
||||
fastcgi_intercept_errors on;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
# File manager
|
||||
server {
|
||||
listen 8446;
|
||||
listen [::]:8446;
|
||||
server_name file_manager;
|
||||
root /usr/local/phyre/web/thirdparty/filegator/dist;
|
||||
|
||||
add_header X-Frame-Options "SAMEORIGIN";
|
||||
add_header X-Content-Type-Options "nosniff";
|
||||
|
||||
index index.php;
|
||||
charset utf-8;
|
||||
|
||||
error_page 404 /index.php;
|
||||
|
||||
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; }
|
||||
|
||||
location ~ \.php$ {
|
||||
fastcgi_pass unix:/run/phyre-php.sock;
|
||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ NGINX_DESC=phyre-nginx
|
|||
NGINX_PID=/run/phyre-nginx.pid
|
||||
NGINX_CONF=/usr/local/phyre/nginx/conf/nginx.conf
|
||||
|
||||
PHP_DAEMON=/usr/local/phyre/php/sbin/phyre-php-fpm
|
||||
PHP_DAEMON=/usr/local/phyre/php/sbin/phyre-php
|
||||
PHP_NAME=phyre-php
|
||||
PHP_DESC=phyre-php
|
||||
PHP_PID=/run/phyre-php.pid
|
||||
|
@ -38,7 +38,7 @@ stop_nginx() {
|
|||
|
||||
start_php() {
|
||||
start-stop-daemon --start --quiet --pidfile $PHP_PID \
|
||||
--retry 5 --startas /bin/bash -- -c "exec $PHP_DAEMON --allow-to-run-as-root" --oknodo
|
||||
--retry 5 --exec $PHP_DAEMON --oknodo
|
||||
}
|
||||
|
||||
stop_php() {
|
||||
|
|
|
@ -6,4 +6,6 @@ Section: web
|
|||
Maintainer: CloudVision Ltd.
|
||||
Homepage: https://www.phyrepanel.com
|
||||
Architecture: amd64
|
||||
Depends: libzip4, unzip, libonig5 | libonig4 | libonig2
|
||||
Conflct: libzip5
|
||||
Description: Phyre Panel PHP SDK
|
||||
|
|
BIN
compilators/debian/php/dist/phyre-php-8.2.0.deb
vendored
BIN
compilators/debian/php/dist/phyre-php-8.2.0.deb
vendored
Binary file not shown.
|
@ -2,79 +2,9 @@
|
|||
|
||||
MAIN_DIR=$(pwd)
|
||||
|
||||
sudo apt-get update -y && sudo apt-get upgrade -y
|
||||
|
||||
# Build Essentials
|
||||
sudo apt-get install -y build-essential
|
||||
sudo apt-get install -y libsodium-dev
|
||||
sudo apt-get install -y libonig-dev
|
||||
|
||||
# Install Dependencies
|
||||
DEPENDENCIES_LIST=(
|
||||
"re2c"
|
||||
"ccache"
|
||||
"mysql-server"
|
||||
"libbz2-dev"
|
||||
"libcurl4-gnutls-dev"
|
||||
"libenchant-dev"
|
||||
"libfreetype6-dev"
|
||||
"libgmp-dev"
|
||||
"libicu-dev"
|
||||
"libjpeg-dev"
|
||||
"libkrb5-dev"
|
||||
"libonig-dev"
|
||||
"libpng-dev"
|
||||
"libpq-dev"
|
||||
"libsasl2-dev"
|
||||
"libsqlite3-dev"
|
||||
"libsodium-dev"
|
||||
"libtidy-dev"
|
||||
"libwebp-dev"
|
||||
"libxml2-dev"
|
||||
"libxpm-dev"
|
||||
"libxslt1-dev"
|
||||
"libzip-dev"
|
||||
"autoconf"
|
||||
"re2c"
|
||||
"bison"
|
||||
"sqlite3"
|
||||
"libsqlite3-dev"
|
||||
"libpq-dev"
|
||||
"libfcgi-dev"
|
||||
"libfcgi0ldbl"
|
||||
"libjpeg-dev"
|
||||
"libpng-dev"
|
||||
"libssl-dev"
|
||||
"libcurl4-openssl-dev"
|
||||
"libxpm-dev"
|
||||
"libgd-dev"
|
||||
"libmysqlclient-dev"
|
||||
"libfreetype6-dev"
|
||||
"libxslt1-dev"
|
||||
"libpspell-dev"
|
||||
"libzip-dev"
|
||||
"libicu-dev"
|
||||
"libldap2-dev"
|
||||
"libxslt-dev"
|
||||
"libssl-dev"
|
||||
"libldb-dev"
|
||||
"libgccjit-10-dev"
|
||||
"libargon2-dev"
|
||||
"zlib1g-dev"
|
||||
"binutils"
|
||||
"libtool"
|
||||
"bison"
|
||||
"re2c"
|
||||
"pkg-config"
|
||||
"make"
|
||||
"autoconf"
|
||||
"automake"
|
||||
)
|
||||
# Check if the dependencies are installed
|
||||
for DEPENDENCY in "${DEPENDENCIES_LIST[@]}"; do
|
||||
echo "Installing $DEPENDENCY..."
|
||||
sudo apt install -y $DEPENDENCY
|
||||
done
|
||||
# Install dependencies
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y libzip-dev libonig-dev openssl zip unzip git ibgmp-dev gmp-dev libcurl4-openssl-dev libsqlite3-dev libxml2-dev pkg-config build-essential dpkg-dev debhelper autotools-dev libgeoip-dev libssl-dev libpcre3-dev zlib1g-dev
|
||||
|
||||
# Download PHP source
|
||||
wget http://de2.php.net/distributions/php-8.2.0.tar.gz
|
||||
|
@ -82,82 +12,21 @@ tar -zxvf php-8.2.0.tar.gz
|
|||
cd php-8.2.0
|
||||
|
||||
# Configure PHP
|
||||
sudo make LIBDIR=/usr/lib/$(arch)-linux-gnu install
|
||||
|
||||
./buildconf --force
|
||||
./configure --prefix=/usr/local/phyre/php \
|
||||
--with-libdir=lib/$(arch)-linux-gnu \
|
||||
--enable-fpm --with-fpm-user=phyreweb --with-fpm-group=phyreweb \
|
||||
--with-openssl \
|
||||
--with-mysqli \
|
||||
--with-pdo-mysql=mysqlnd \
|
||||
--with-mysqli=mysqlnd \
|
||||
--with-pdo-sqlite \
|
||||
--with-gettext \
|
||||
--with-curl \
|
||||
--enable-intl \
|
||||
--with-zip \
|
||||
--with-zlib \
|
||||
--with-gmp \
|
||||
--with-sodium \
|
||||
--enable-sockets \
|
||||
--enable-mbstring
|
||||
|
||||
#sudo ./configure --prefix=/usr/local/phyre/php \
|
||||
# --enable-fpm \
|
||||
# --with-fpm-user=admin \
|
||||
# --with-fpm-group=admin \
|
||||
# --enable-phpdbg \
|
||||
# --enable-fpm \
|
||||
# --with-pdo-mysql=mysqlnd \
|
||||
# --with-mysqli=mysqlnd \
|
||||
# --with-pgsql \
|
||||
# --with-pdo-pgsql \
|
||||
# --with-pdo-sqlite \
|
||||
# --enable-intl \
|
||||
# --without-pear \
|
||||
# --enable-gd \
|
||||
# --with-jpeg \
|
||||
# --with-webp \
|
||||
# --with-freetype \
|
||||
# --with-xpm \
|
||||
# --enable-exif \
|
||||
# --with-zip \
|
||||
# --with-zlib \
|
||||
# --enable-soap \
|
||||
# --enable-xmlreader \
|
||||
# --with-xsl \
|
||||
# --with-tidy \
|
||||
# --enable-sysvsem \
|
||||
# --enable-sysvshm \
|
||||
# --enable-shmop \
|
||||
# --enable-pcntl \
|
||||
# --with-readline \
|
||||
# --enable-mbstring \
|
||||
# --with-curl \
|
||||
# --with-gettext \
|
||||
# --enable-sockets \
|
||||
# --with-bz2 \
|
||||
# --with-openssl \
|
||||
# --with-gmp \
|
||||
# --enable-bcmath \
|
||||
# --enable-calendar \
|
||||
# --enable-ftp \
|
||||
# --enable-sysvmsg \
|
||||
# --with-sodium \
|
||||
# --enable-zend-test=shared \
|
||||
# --enable-dl-test=shared \
|
||||
# --enable-werror \
|
||||
# --with-pear \
|
||||
# --with-libdir=lib/$(arch)-linux-gnu
|
||||
sudo ./configure --prefix=/usr/local/phyre/php \
|
||||
--enable-fpm --with-fpm-user=admin --with-fpm-group=admin \
|
||||
# --with-libdir=lib/$(arch)-linux-gnu \
|
||||
# --with-openssl \
|
||||
# --with-mysqli \
|
||||
# --with-gettext \
|
||||
#--with-curl \
|
||||
#--with-zip \
|
||||
#--enable-mbstring
|
||||
|
||||
# Compile PHP
|
||||
sudo make -j 4
|
||||
#sudo make test
|
||||
sudo make
|
||||
sudo make install
|
||||
|
||||
/usr/local/phyre/php/bin/php -v
|
||||
|
||||
PACKAGE_MAIN_DIR=$MAIN_DIR/phyre-php-8.2.0
|
||||
sudo mkdir $PACKAGE_MAIN_DIR
|
||||
|
||||
|
@ -168,7 +37,6 @@ sudo mkdir -p $PACKAGE_MAIN_DIR/usr/local/phyre
|
|||
# Copy php compiled files
|
||||
sudo mv /usr/local/phyre/php $PACKAGE_MAIN_DIR/usr/local/phyre
|
||||
sudo cp $MAIN_DIR/php-fpm.conf $PACKAGE_MAIN_DIR/usr/local/phyre/php/etc
|
||||
sudo mv $PACKAGE_MAIN_DIR/usr/local/phyre/php/sbin/php-fpm $PACKAGE_MAIN_DIR/usr/local/phyre/php/sbin/phyre-php-fpm
|
||||
|
||||
# Copy debian package META file
|
||||
sudo cp $MAIN_DIR/control $PACKAGE_MAIN_DIR/DEBIAN
|
||||
|
|
|
@ -10,13 +10,11 @@ events.mechanism = epoll
|
|||
[www]
|
||||
listen = /run/phyre-php.sock
|
||||
|
||||
user = phyreweb
|
||||
group = phyreweb
|
||||
|
||||
user = root
|
||||
group = root
|
||||
|
||||
listen.owner = root
|
||||
listen.group = root
|
||||
|
||||
listen.owner = phyreweb
|
||||
listen.group = phyreweb
|
||||
listen.mode = 0660
|
||||
|
||||
pm = ondemand
|
||||
|
@ -24,13 +22,6 @@ pm.max_children = 4
|
|||
pm.max_requests = 1000
|
||||
pm.process_idle_timeout = 10s;
|
||||
|
||||
|
||||
env[PATH] = /usr/local/bin:/usr/bin:/bin
|
||||
env[TMP] = /tmp
|
||||
env[TMPDIR] = /tmp
|
||||
env[TEMP] = /tmp
|
||||
env[LANG] = en_US.UTF-8
|
||||
|
||||
php_flag[display_errors] = off
|
||||
php_admin_flag[log_errors] = on
|
||||
php_admin_flag[session.cookie_httponly] = on
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
/usr/local/phyre/php/sbin/phyre-php-fpm --allow-to-run-as-root
|
34
configurations/ubuntu/nginx/panel.conf
Normal file
34
configurations/ubuntu/nginx/panel.conf
Normal file
|
@ -0,0 +1,34 @@
|
|||
user phyreweb;
|
||||
|
||||
server {
|
||||
listen 3036;
|
||||
listen [::]:3036;
|
||||
server_name _;
|
||||
root /usr/local/phyre/web/public;
|
||||
|
||||
add_header X-Frame-Options "SAMEORIGIN";
|
||||
add_header X-Content-Type-Options "nosniff";
|
||||
|
||||
index 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; }
|
||||
|
||||
error_page 404 /index.php;
|
||||
|
||||
location ~ \.php$ {
|
||||
fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
|
||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||
include fastcgi_params;
|
||||
}
|
||||
|
||||
location ~ /\.(?!well-known).* {
|
||||
deny all;
|
||||
}
|
||||
}
|
|
@ -5,37 +5,13 @@ apt-get update && apt-get install ca-certificates
|
|||
|
||||
apt install -y git
|
||||
cd /
|
||||
mkdir -p $MAIN_DIR
|
||||
git clone https://github.com/CloudVisionApps/PhyrePanel.git $MAIN_DIR
|
||||
mkdir -p /phyre/raw-repo
|
||||
git clone https://github.com/CloudVisionApps/PhyrePanel.git /phyre/raw-repo
|
||||
|
||||
HELPERS_DIR=$MAIN_DIR"/shell/helpers/ubuntu"
|
||||
. $HELPERS_DIR"/common.sh"
|
||||
. $HELPERS_DIR"/create-mysql-db-and-user.sh"
|
||||
|
||||
|
||||
# Create the new phyreweb user
|
||||
|
||||
random_password="$(openssl rand -base64 32)"
|
||||
email="admin@phyrepanel.com"
|
||||
|
||||
# Create the new phyreweb user
|
||||
/usr/sbin/useradd "phyreweb" -c "$email" --no-create-home
|
||||
|
||||
# Add the phyreweb user to the www-data group
|
||||
sudo usermod -a -G www-data phyreweb
|
||||
|
||||
# Add the root user to the www-data group
|
||||
#sudo usermod -a -G www-data root
|
||||
|
||||
|
||||
# do not allow login into phyreweb user
|
||||
echo phyreweb:$random_password | sudo chpasswd -e
|
||||
|
||||
mkdir -p /etc/sudoers.d
|
||||
cp -f $MAIN_DIR/installers/Ubuntu/22.04/sudo/phyreweb /etc/sudoers.d/
|
||||
chmod 440 /etc/sudoers.d/phyreweb
|
||||
|
||||
|
||||
# Update the system
|
||||
apt update -y
|
||||
|
||||
|
@ -49,14 +25,10 @@ for REPOSITORY in "${REPOSITORIES_LIST[@]}"; do
|
|||
done
|
||||
|
||||
DEPENDENCIES_LIST=(
|
||||
"jq"
|
||||
"curl"
|
||||
"wget"
|
||||
"git"
|
||||
"apache2"
|
||||
"libapache2-mod-php8.2"
|
||||
"libapache2-mod-ruid2"
|
||||
"apache2-suexec-custom"
|
||||
"nginx"
|
||||
"nodejs"
|
||||
"npm"
|
||||
"unzip"
|
||||
|
@ -71,12 +43,19 @@ DEPENDENCIES_LIST=(
|
|||
"apt-transport-https"
|
||||
"software-properties-common"
|
||||
"supervisor"
|
||||
"libonig-dev"
|
||||
"libzip-dev"
|
||||
"libcurl4-openssl-dev"
|
||||
"libssl-dev"
|
||||
"zlib1g-dev"
|
||||
"php8.2-{bcmath,xml,bz2,intl,curl,dom,fileinfo,gd,intl,mbstring,mysql,opcache,sqlite3,xmlrpc,zip}"
|
||||
"php8.2"
|
||||
"php8.2-fpm"
|
||||
"php8.2-cli"
|
||||
"php8.2-json"
|
||||
"php8.2-mysql"
|
||||
"php8.2-zip"
|
||||
"php8.2-gd"
|
||||
"php8.2-mbstring"
|
||||
"php8.2-curl"
|
||||
"php8.2-xml"
|
||||
"php8.2-intl"
|
||||
"php8.2-pear"
|
||||
"php8.2-bcmath"
|
||||
)
|
||||
# Check if the dependencies are installed
|
||||
for DEPENDENCY in "${DEPENDENCIES_LIST[@]}"; do
|
||||
|
@ -89,21 +68,6 @@ for DEPENDENCY in "${DEPENDENCIES_LIST[@]}"; do
|
|||
fi
|
||||
done
|
||||
|
||||
sudo a2enmod php8.2
|
||||
sudo a2enmod rewrite
|
||||
sudo a2enmod env
|
||||
sudo a2enmod ssl
|
||||
sudo a2enmod headers
|
||||
sudo a2enmod suexec
|
||||
sudo a2enmod ruid2
|
||||
sudo a2enconf ssl-params
|
||||
sudo ufw allow in "Apache Full"
|
||||
|
||||
#sudo a2ensite default-ssl
|
||||
#sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/apache-selfsigned.key -out /etc/ssl/certs/apache-selfsigned.crt
|
||||
|
||||
systemctl restart apache2
|
||||
|
||||
#DEPENDENCIES_FOR_REMOVE_LIST=(
|
||||
# "apache2"
|
||||
#)
|
||||
|
@ -117,52 +81,42 @@ systemctl restart apache2
|
|||
# fi
|
||||
#done
|
||||
|
||||
# Install PHYRE NGINX
|
||||
wget https://github.com/CloudVisionApps/PhyrePanelNginxDist/raw/main/debian/nginx/dist/phyre-nginx-1.24.0.deb
|
||||
sudo dpkg -i phyre-nginx-1.24.0.deb
|
||||
|
||||
# Install PHYRE PHP
|
||||
wget https://github.com/CloudVisionApps/PhyrePanelPHPDist/raw/main/debian/php/dist/phyre-php-8.2.0.deb
|
||||
sudo dpkg -i phyre-php-8.2.0.deb
|
||||
|
||||
# sudo ufw allow proto tcp from any to any port 80,443
|
||||
|
||||
# Run Nginx
|
||||
#systemctl start nginx
|
||||
#systemctl enable nginx
|
||||
|
||||
service phyre start
|
||||
systemctl start nginx
|
||||
systemctl enable nginx
|
||||
|
||||
# Change NGINX index.html
|
||||
rm -rf /var/www/html/*
|
||||
cp $MAIN_DIR/samples/sample-index.html /var/www/html/index.html
|
||||
|
||||
# Restart NGINX
|
||||
#systemctl restart nginx
|
||||
# Add NGINX config
|
||||
cp $MAIN_DIR/configurations/ubuntu/nginx/panel.conf /etc/nginx/sites-available/PhyrePanel.conf
|
||||
|
||||
PHYRE_PHP=/usr/local/phyre/php/bin/php
|
||||
# Create a symbolic link
|
||||
if [ -f /etc/nginx/sites-enabled/PhyrePanel.conf ]; then
|
||||
rm -rf /etc/nginx/sites-enabled/PhyrePanel.conf
|
||||
fi
|
||||
ln -s /etc/nginx/sites-available/PhyrePanel.conf /etc/nginx/sites-enabled/PhyrePanel.conf
|
||||
|
||||
# Restart NGINX
|
||||
systemctl restart nginx
|
||||
|
||||
mkdir -p /usr/local/phyre/web
|
||||
cp -r $MAIN_DIR/web/* /usr/local/phyre/web
|
||||
cp $MAIN_DIR/web/.env.example /usr/local/phyre/web/.env.example
|
||||
|
||||
mkdir -p /usr/local/phyre/bin
|
||||
cp -r $MAIN_DIR/bin/* /usr/local/phyre/bin
|
||||
cp -r $MAIN_DIR/samples/* /usr/local/phyre/samples
|
||||
|
||||
mkdir -p /usr/local/phyre/update
|
||||
cp -r $MAIN_DIR/update/* /usr/local/phyre/update
|
||||
chmod +x /usr/local/phyre/update/*
|
||||
|
||||
# Install Composer
|
||||
cd /usr/local/phyre/web
|
||||
|
||||
$PHYRE_PHP -v
|
||||
$PHYRE_PHP -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
||||
$PHYRE_PHP ./composer-setup.php
|
||||
$PHYRE_PHP -r "unlink('composer-setup.php');"
|
||||
php8.2 -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
||||
php8.2 -r "if (hash_file('sha384', 'composer-setup.php') === 'e21205b207c3ff031906575712edab6f13eb0b361f2085f1f1237b7126d785e826a450292b6cfd1d64d92e6563bbde02') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
|
||||
php8.2 composer-setup.php
|
||||
php8.2 -r "unlink('composer-setup.php');"
|
||||
|
||||
COMPOSER_ALLOW_SUPERUSER=1 $PHYRE_PHP ./composer.phar install --no-interaction
|
||||
COMPOSER_ALLOW_SUPERUSER=1 php8.2 composer.phar install --no-dev --optimize-autoloader --no-interaction
|
||||
|
||||
# Create database
|
||||
PANEL_DB_NAME="phyredb"
|
||||
|
@ -179,9 +133,11 @@ sed -i "s/^DB_USERNAME=.*/DB_USERNAME=$PANEL_DB_USER/" .env
|
|||
sed -i "s/^DB_PASSWORD=.*/DB_PASSWORD=$PANEL_DB_PASSWORD/" .env
|
||||
sed -i "s/^DB_CONNECTION=.*/DB_CONNECTION=mysql/" .env
|
||||
|
||||
$PHYRE_PHP artisan key:generate
|
||||
$PHYRE_PHP artisan migrate
|
||||
$PHYRE_PHP artisan db:seed
|
||||
php8.2 artisan key:generate
|
||||
php8.2 artisan migrate
|
||||
php8.2 artisan db:seed
|
||||
|
||||
sudo chmod -R o+w /usr/local/phyre/web/storage/
|
||||
sudo chmod -R o+w /usr/local/phyre/web/bootstrap/cache/
|
||||
|
||||
#systemctl status php8.2-fpm.service
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
Defaults:root !requiretty
|
||||
|
||||
# sudo is limited to PhyrePanel scripts
|
||||
# phyreweb ALL=NOPASSWD:/usr/local/phyre/bin/*
|
||||
|
||||
phyreweb ALL=(ALL) NOPASSWD: ALL
|
|
@ -7,152 +7,15 @@
|
|||
</head>
|
||||
<body>
|
||||
<div class="flex flex-col bg-gray-50 justify-center h-screen text-center">
|
||||
|
||||
<div>
|
||||
<div class="mb-4">
|
||||
<svg class="w-[26rem] m-auto" id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 808.52 192.65">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: url(#linear-gradient-12);
|
||||
}
|
||||
|
||||
.cls-1, .cls-2, .cls-3, .cls-4, .cls-5, .cls-6, .cls-7, .cls-8, .cls-9, .cls-10, .cls-11, .cls-12, .cls-13 {
|
||||
stroke-width: 0px;
|
||||
}
|
||||
|
||||
.cls-2 {
|
||||
fill: url(#linear-gradient);
|
||||
}
|
||||
|
||||
.cls-3 {
|
||||
fill: url(#linear-gradient-6);
|
||||
}
|
||||
|
||||
.cls-4 {
|
||||
fill: url(#linear-gradient-11);
|
||||
}
|
||||
|
||||
.cls-5 {
|
||||
fill: url(#linear-gradient-5);
|
||||
}
|
||||
|
||||
.cls-6 {
|
||||
fill: #f9be22;
|
||||
}
|
||||
|
||||
.cls-7 {
|
||||
fill: url(#linear-gradient-2);
|
||||
}
|
||||
|
||||
.cls-8 {
|
||||
fill: url(#linear-gradient-7);
|
||||
}
|
||||
|
||||
.cls-9 {
|
||||
fill: url(#linear-gradient-3);
|
||||
}
|
||||
|
||||
.cls-10 {
|
||||
fill: url(#linear-gradient-9);
|
||||
}
|
||||
|
||||
.cls-11 {
|
||||
fill: url(#linear-gradient-8);
|
||||
}
|
||||
|
||||
.cls-12 {
|
||||
fill: url(#linear-gradient-10);
|
||||
}
|
||||
|
||||
.cls-13 {
|
||||
fill: url(#linear-gradient-4);
|
||||
}
|
||||
</style>
|
||||
<linearGradient id="linear-gradient" x1="5.89" y1="67.83" x2="786.82" y2="71" gradientUnits="userSpaceOnUse">
|
||||
<stop offset=".25" stop-color="#f8bd20"/>
|
||||
<stop offset=".41" stop-color="#f9c628"/>
|
||||
<stop offset=".69" stop-color="#fbd131"/>
|
||||
<stop offset="1" stop-color="#fcd535"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-2" x1="694.68" y1="13.95" x2="808.52" y2="13.95" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#f8bd20"/>
|
||||
<stop offset=".63" stop-color="#fcd535"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-3" x1="642.49" y1="69.62" x2="785.47" y2="69.62" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#f8bd20" stop-opacity=".9"/>
|
||||
<stop offset=".15" stop-color="rgba(249, 197, 39, .94)" stop-opacity=".94"/>
|
||||
<stop offset=".37" stop-color="rgba(250, 206, 47, .97)" stop-opacity=".97"/>
|
||||
<stop offset=".63" stop-color="rgba(251, 211, 51, .99)" stop-opacity=".99"/>
|
||||
<stop offset="1" stop-color="#fcd535"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-4" x1="647.99" y1="69.56" x2="785.96" y2="69.56" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#f8bd20"/>
|
||||
<stop offset=".63" stop-color="#fcd535"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-5" x1="161.7" y1="69.56" x2="212.2" y2="69.56" gradientUnits="userSpaceOnUse">
|
||||
<stop offset=".45" stop-color="#f8bd20"/>
|
||||
<stop offset=".54" stop-color="#f9c326"/>
|
||||
<stop offset=".78" stop-color="#fbd031"/>
|
||||
<stop offset="1" stop-color="#fcd535"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-6" x1="-14.8" y1="68.54" x2="812.93" y2="71.9" gradientUnits="userSpaceOnUse">
|
||||
<stop offset=".23" stop-color="#f8bd20"/>
|
||||
<stop offset=".23" stop-color="#f8bd20"/>
|
||||
<stop offset=".4" stop-color="#faca2c"/>
|
||||
<stop offset=".6" stop-color="#fbd232"/>
|
||||
<stop offset="1" stop-color="#fcd535"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-7" x1="19.43" y1="68.42" x2="756.99" y2="71.42" xlink:href="#linear-gradient-6"/>
|
||||
<linearGradient id="linear-gradient-8" x1="-12.06" y1="69.99" x2="808.02" y2="73.32" xlink:href="#linear-gradient-6"/>
|
||||
<linearGradient id="linear-gradient-9" x1="0" y1="69.56" x2="54.12" y2="69.56" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#f8bd20"/>
|
||||
<stop offset=".21" stop-color="#f9c628"/>
|
||||
<stop offset=".58" stop-color="#fbd131"/>
|
||||
<stop offset="1" stop-color="#fcd535"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-10" x1="-24.07" y1="41.56" x2="837.97" y2="45.06" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#f8bd20"/>
|
||||
<stop offset=".07" stop-color="#f9c628"/>
|
||||
<stop offset=".2" stop-color="#fbd131"/>
|
||||
<stop offset=".34" stop-color="#fcd535"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-11" x1="485.03" y1="69.56" x2="538.44" y2="69.56" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#f8bd20"/>
|
||||
<stop offset=".21" stop-color="#f9c628"/>
|
||||
<stop offset=".58" stop-color="#fbd131"/>
|
||||
<stop offset="1" stop-color="#fcd535"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linear-gradient-12" x1="521.21" y1="69.56" x2="642.79" y2="69.56" xlink:href="#linear-gradient-11"/>
|
||||
</defs>
|
||||
<g>
|
||||
<path class="cls-6" d="M383.66,189.79l.87-4.15c.31-1.47-.81-2.86-2.32-2.86h-10.04c-1.12,0-2.08.78-2.32,1.87l-1.31,6.12c-.23,1.09-1.2,1.87-2.32,1.87h0c-1.51,0-2.63-1.39-2.32-2.86l4.22-19.87c.23-1.09,1.2-1.88,2.32-1.88h0c1.51,0,2.63,1.39,2.32,2.86l-.88,4.17c-.31,1.47.81,2.86,2.32,2.86h10.04c1.12,0,2.08-.78,2.32-1.87l1.32-6.14c.23-1.09,1.2-1.87,2.32-1.87h0c1.51,0,2.63,1.39,2.32,2.86l-4.22,19.87c-.23,1.09-1.2,1.88-2.32,1.88h0c-1.51,0-2.63-1.39-2.32-2.86Z"/>
|
||||
<path class="cls-6" d="M416.74,192.65h-11c-1.72,0-3.35-.79-4.41-2.14h0c-1.03-1.31-1.42-3-1.08-4.62l2.37-11.23c.33-1.56,1.18-2.96,2.41-3.97l.86-.7c1.53-1.25,3.45-1.94,5.43-1.94h10.39c1.72,0,3.35.79,4.41,2.14h0c1.03,1.31,1.42,3,1.08,4.62l-2.37,11.19c-.34,1.59-1.2,3.01-2.45,4.04l-1.27,1.04c-1.23,1.01-2.78,1.57-4.38,1.57ZM419.35,172.9h-8.48c-1.77,0-3.3,1.24-3.66,2.97l-1.7,7.97c-.43,2.03,1.12,3.95,3.2,3.95h7.89c1.76,0,3.28-1.23,3.64-2.95l1.83-8.58c.37-1.73-.95-3.35-2.72-3.35Z"/>
|
||||
<path class="cls-6" d="M450.21,192.65h-13.09c-1.44,0-2.52-1.33-2.22-2.74l.07-.32c.22-1.05,1.15-1.8,2.22-1.8h14.24c1.27,0,2.51-.44,3.49-1.25h0c.35-.29.59-.68.69-1.12h0c.14-.6,0-1.22-.38-1.71l-.04-.05c-.43-.55-1.09-.88-1.79-.88h-10.13c-1.67,0-2.95-.63-3.99-1.94h0c-1.07-1.36-1.12-3.12-1.09-4.97l.07-1.88c0-.68.15-1.66.56-2.43.48-.92.95-1.56,2.87-2.8h0c1.32-.83,3.78-.72,6.91-.72h12.75c1.44,0,2.52,1.33,2.22,2.74l-.07.32c-.22,1.05-1.15,1.8-2.22,1.8h-14.3c-1.25,0-2.46.43-3.43,1.22h0c-.36.3-.61.7-.7,1.16h0c-.12.59.02,1.2.39,1.67h0c.48.61,1.21.97,1.99.97h10.37c1.41,0,2.74.64,3.61,1.75h0c1.23,1.56,1.71,3.59,1.29,5.53l-.25,1.19c-.28,1.33-1.01,2.52-2.05,3.38h0c-2.26,1.86-5.09,2.87-8.01,2.87Z"/>
|
||||
<path class="cls-6" d="M488.37,174.78l-3.4,16c-.23,1.09-1.2,1.88-2.32,1.88h0c-1.51,0-2.63-1.39-2.32-2.86l2.98-14.03c.31-1.47-.81-2.86-2.32-2.86h-4.04c-1.51,0-2.63-1.39-2.32-2.86l.03-.12c.23-1.1,1.2-1.88,2.32-1.88h19.77c1.51,0,2.63,1.39,2.32,2.86l-.03.12c-.23,1.1-1.2,1.88-2.32,1.88h-6.04c-1.12,0-2.08.78-2.32,1.88Z"/>
|
||||
<path class="cls-6" d="M505.5,189.68l4.2-19.69c.24-1.14,1.25-1.95,2.41-1.95h0c1.57,0,2.73,1.44,2.41,2.97l-4.2,19.69c-.24,1.14-1.25,1.95-2.41,1.95h0c-1.57,0-2.73-1.44-2.41-2.97Z"/>
|
||||
<path class="cls-6" d="M539.69,191.61l-9.6-14.15c-.48-.7-1.56-.49-1.74.34l-2.76,12.97c-.23,1.09-1.2,1.88-2.32,1.88h0c-1.51,0-2.63-1.39-2.32-2.86l4.13-19.43c.29-1.35,1.48-2.31,2.86-2.31h.53c1.06,0,2.06.53,2.65,1.41l9.51,14.05c.41.6,1.34.42,1.49-.29l2.83-13.29c.23-1.09,1.2-1.88,2.32-1.88h0c1.51,0,2.63,1.39,2.32,2.86l-4.22,19.87c-.23,1.09-1.2,1.88-2.32,1.88h-1.4c-.79,0-1.52-.39-1.96-1.04Z"/>
|
||||
<path class="cls-6" d="M573.43,192.64l-10.43.02c-1.83,0-3.56-.83-4.7-2.27l-.04-.05c-.95-1.2-1.31-2.74-.99-4.22l2.41-11.39c.34-1.6,1.21-3.04,2.48-4.08l1.22-1c1.26-1.04,2.85-1.6,4.48-1.6h10.94c1.72,0,3.34.79,4.4,2.14h0c1.02,1.3,1.42,2.99,1.08,4.62-.05.26-.11.51-.16.74-.16.75-.82,1.29-1.6,1.29h-1.49c-1.03,0-1.8-.96-1.59-1.97h0c.21-1.01-.55-1.96-1.59-1.96-3.11,0-9,0-11.62,0-.77,0-1.43.54-1.59,1.29l-2.46,11.65c-.21,1.01.56,1.97,1.6,1.97h11.59c.77,0,1.44-.54,1.6-1.29l.37-1.76c.21-1.01-.56-1.97-1.6-1.97h-5.86c-1.04,0-1.81-.96-1.59-1.97l.34-1.6c.16-.75.83-1.29,1.59-1.29h6.15c1.9,0,3.7.87,4.88,2.36l.15.19c.84,1.05,1.16,2.43.88,3.74l-.55,2.61c-.22,1.05-.8,1.99-1.63,2.67l-1.62,1.33c-1.42,1.17-3.21,1.81-5.05,1.81Z"/>
|
||||
<path class="cls-6" d="M629.48,182.79h-10.75c-1.12,0-2.08.78-2.32,1.87l-1.31,6.12c-.23,1.09-1.2,1.87-2.32,1.87h0c-1.51,0-2.63-1.39-2.32-2.86l4.22-19.87c.23-1.09,1.2-1.88,2.32-1.88h15.74c1.73,0,3.37.8,4.44,2.16h0c1.02,1.3,1.41,2.98,1.07,4.59l-.43,2.02c-.24,1.13-.85,2.15-1.75,2.89l-1.51,1.25c-1.43,1.19-3.23,1.83-5.09,1.83ZM631.75,172.9h-11.58c-.73,0-1.35.51-1.51,1.22l-.4,1.88c-.21.99.55,1.92,1.56,1.92h11.52c.82,0,1.54-.58,1.71-1.38l.34-1.6c.23-1.05-.57-2.04-1.65-2.04Z"/>
|
||||
<path class="cls-6" d="M665.75,189.79l.89-4.18c.31-1.47-.81-2.86-2.32-2.86h-10.07c-1.12,0-2.08.78-2.32,1.87l-1.32,6.15c-.23,1.1-1.21,1.88-2.33,1.87h-.02c-1.5,0-2.62-1.39-2.31-2.86l3.11-14.63c.4-1.88,1.43-3.57,2.92-4.79l.53-.43c1.5-1.22,3.37-1.89,5.3-1.89h10.74c1.55,0,3.01.71,3.97,1.93h0c1.13,1.45,1.57,3.32,1.19,5.11l-3.33,15.69c-.23,1.09-1.2,1.88-2.32,1.88h0c-1.51,0-2.63-1.39-2.32-2.86ZM667.11,172.9h-11.14c-.9,0-1.67.63-1.86,1.5l-.32,1.52c-.22,1.03.57,2,1.62,2h11.64c.71,0,1.33-.5,1.48-1.19l.35-1.64c.24-1.13-.61-2.19-1.77-2.19Z"/>
|
||||
<path class="cls-6" d="M700.08,191.39l-9.28-13.69c-.54-.79-1.76-.55-1.96.38l-2.7,12.69c-.23,1.09-1.2,1.88-2.32,1.88h0c-1.51,0-2.63-1.39-2.32-2.86l4.16-19.56c.27-1.28,1.4-2.19,2.71-2.19h.51c1.15,0,2.23.57,2.88,1.53l9.3,13.74c.45.67,1.49.47,1.66-.32l2.78-13.07c.23-1.09,1.2-1.88,2.32-1.88h0c1.51,0,2.63,1.39,2.32,2.86l-4.12,19.37c-.29,1.39-1.52,2.38-2.94,2.38h-.62c-.95,0-1.84-.47-2.37-1.26Z"/>
|
||||
<path class="cls-6" d="M717.03,189.71l4.2-19.75c.24-1.12,1.23-1.92,2.38-1.92h19.64c1.54,0,2.7,1.42,2.38,2.93h0c-.24,1.12-1.23,1.93-2.38,1.93h-15.81c-1.15,0-2.14.8-2.38,1.92l-.03.16c-.32,1.51.83,2.94,2.38,2.94h9.8c1.54,0,2.7,1.42,2.38,2.93h0c-.24,1.12-1.23,1.93-2.38,1.93h-11.87c-1.14,0-2.13.8-2.37,1.92l-.03.14c-.33,1.51.83,2.95,2.37,2.95h13.75c1.54,0,2.7,1.42,2.38,2.93h0c-.24,1.12-1.23,1.93-2.38,1.93h-19.64c-1.55,0-2.7-1.42-2.38-2.94Z"/>
|
||||
<path class="cls-6" d="M752.53,189.67l4.22-19.85c.23-1.1,1.2-1.88,2.33-1.88h0c1.51,0,2.64,1.39,2.33,2.87l-2.99,14c-.32,1.48.81,2.87,2.33,2.87h13.78c1.57,0,2.74,1.44,2.41,2.97h0c-.09.41-.14.86-.42,1.18-.76.87-1.78.71-3.38.71h-12.75c-2.1,0-2.93.07-5.76.01-1.58-.03-2.19-.74-2.09-2.89Z"/>
|
||||
</g>
|
||||
<path class="cls-2" d="M428.17,83.3h-2.67c-6.07,0-11.32,4.24-12.59,10.18l-7.54,35.19c-1.27,5.94-6.52,10.18-12.59,10.18h-.87c-8.18,0-14.28-7.52-12.6-15.52l4.96-23.63c1.77-8.45-4.67-16.4-13.31-16.4h0c-9.55,0-18.57-4.38-24.47-11.89l-.06-.08c-5.89-7.49-8.16-17.22-6.17-26.54l7.29-34.33c1.26-5.95,6.52-10.2,12.6-10.2h.87c8.18,0,14.28,7.52,12.6,15.52l-5.17,24.62c-.77,3.69.11,7.53,2.41,10.51h0c2.44,3.16,6.21,5.01,10.2,5.01h50.24c5.4,0,10.62-1.9,14.76-5.38h0c3.4-2.85,5.74-6.76,6.66-11.1l6.16-28.99c1.26-5.95,6.52-10.2,12.6-10.2h.95c8.19,0,14.3,7.54,12.6,15.55l-5.43,25.56c-2.5,11.74-8.89,22.3-18.14,29.95h0c-9.36,7.74-21.12,11.98-33.26,11.98Z"/>
|
||||
<path class="cls-7" d="M808.22,16.77h0c1.79-8.51-4.7-16.51-13.39-16.51h-94.61s-5.53,27.37-5.53,27.37h100.15c6.47,0,12.06-4.53,13.39-10.86Z"/>
|
||||
<path class="cls-9" d="M774.88,72.44h0c1.79-8.51-4.7-16.51-13.39-16.51h-72.87l-5.77,27.37h78.64c6.47,0,12.06-4.53,13.39-10.86Z"/>
|
||||
<path class="cls-13" d="M677.87,111.48l6.11-28.18h0l6.01-28.49h.05s5.78-27.18,5.78-27.18l5.79-27.03c.04-.18-.1-.34-.27-.34h-5.32c-12.69,0-23.65,8.88-26.29,21.29l-21.42,100.78c-1.81,8.51,4.68,16.53,13.39,16.53h110.59c6.47,0,12.06-4.53,13.39-10.86h0c1.79-8.51-4.7-16.51-13.39-16.51h-94.4Z"/>
|
||||
<path class="cls-5" d="M203.58,55.93l8.32-39.57c1.75-8.3-4.59-16.1-13.06-16.1h0c-6.3,0-11.75,4.41-13.06,10.58l-23.78,111.89c-1.77,8.31,4.57,16.13,13.06,16.13h0c6.29,0,11.73-4.4,13.05-10.55l9.66-45.01h0l5.82-27.37h0Z"/>
|
||||
<polygon class="cls-3" points="203.58 55.87 197.77 83.24 282.37 83.3 288.17 55.93 203.58 55.87"/>
|
||||
<path class="cls-8" d="M311.44.26c-6.29,0-11.73,4.4-13.05,10.55l-9.59,44.73h0l-6.55,30.92h-.03s-7.64,36.29-7.64,36.29c-1.75,8.3,4.58,16.1,13.06,16.1h.01c6.3,0,11.75-4.41,13.06-10.57l23.78-111.9c1.77-8.3-4.57-16.12-13.06-16.12h0Z"/>
|
||||
<polygon class="cls-11" points="288.73 55.94 288.7 55.93 288.7 55.93 288.17 55.93 282.37 83.3 282.88 83.3 282.22 86.46 282.25 86.47 288.73 55.94"/>
|
||||
<path class="cls-10" d="M21.82,21.46L.3,122.73c-1.77,8.31,4.57,16.13,13.06,16.13h0c6.29,0,11.73-4.4,13.05-10.55l9.66-45.01-.02.12,5.84-27.49,6.01-28.3h0L54.12.26h-6.12c-12.64,0-23.55,8.84-26.18,21.2Z"/>
|
||||
<path class="cls-12" d="M111.53,0l-57.79.26-5.95,27.37h66.44c9.04,0,15.77,8.34,13.87,17.18h0c-1.4,6.5-7.12,11.16-13.77,11.2l-72.69.53-5.73,27.37,69.83-.49c11.47-.08,24.22-2.55,33.06-9.86h0c6.97-5.77,14.29-13.29,16.46-31.62h0c-.56-20.89-7.73-28.5-7.73-28.5h0S140.06,1,111.53,0Z"/>
|
||||
<path class="cls-4" d="M506.81,21.58l-21.48,101.08c-1.77,8.34,4.59,16.2,13.12,16.2h0c6.32,0,11.78-4.41,13.11-10.59l9.65-44.96h.02l5.71-27.37h0l5.96-28.17,5.55-27.42s-.02-.08-.07-.08h-5.23c-12.71,0-23.69,8.89-26.33,21.32Z"/>
|
||||
<path class="cls-1" d="M636.82,13.71l-2.27-2.89c-5.24-6.67-13.25-10.57-21.73-10.57h-74.36l-5.55,27.37h78.11c3.05,0,5.35,2.78,4.77,5.78h0c-.21,1.11-.81,2.11-1.68,2.82l-16.44,13.56c-4.81,3.96-10.84,6.13-17.07,6.13h-53.68l-5.72,27.37h51.65c7.31,0,14.23,3.35,18.76,9.09l1.28,1.62c4.97,6.29,6.86,14.46,5.18,22.29l-1.48,6.87c-1.74,8.07,4.41,15.68,12.66,15.68h0c6.55,0,12.2-4.58,13.56-10.99l5.11-24.08c1.74-8.21-.24-16.77-5.42-23.38l-5.33-6.81c-1.76-2.25-1.41-5.48.79-7.3l14.59-12.04c4.67-3.85,7.88-9.18,9.12-15.1l.52-2.49c1.68-8.07-.28-16.47-5.38-22.95Z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h1 class="text-3xl font-bold">
|
||||
Welcome to PhyrePanel!
|
||||
</h1>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-xl">
|
||||
The simplest way to manage your websites.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="flex flex-col bg-gray-50 justify-center h-screen text-center">
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold">
|
||||
%DOMAIN%
|
||||
</h1>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<p class="text-xl">
|
||||
Welcome to PhyrePanel! <br />
|
||||
The simplest way to manage your websites.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,11 +0,0 @@
|
|||
server {
|
||||
|
||||
server_name %SERVER_NAME% www.%SERVER_NAME%;
|
||||
|
||||
root %SERVER_ROOT%;
|
||||
charset utf-8;
|
||||
|
||||
location / {
|
||||
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 305 KiB |
|
@ -1,54 +0,0 @@
|
|||
rm -rf /usr/local/phyre/update/web-panel-latest
|
||||
rm -rf /usr/local/phyre/update/phyre-web-panel.zip
|
||||
|
||||
wget https://github.com/CloudVisionApps/PhyrePanelWebDist/raw/main/phyre-web-panel.zip
|
||||
ls -la
|
||||
unzip -o phyre-web-panel.zip -d /usr/local/phyre/update/web-panel-latest
|
||||
|
||||
rm -rf /usr/local/phyre/web/vendor
|
||||
rm -rf /usr/local/phyre/web/composer.lock
|
||||
rm -rf /usr/local/phyre/web/routes
|
||||
rm -rf /usr/local/phyre/web/public
|
||||
rm -rf /usr/local/phyre/web/resources
|
||||
rm -rf /usr/local/phyre/web/database
|
||||
rm -rf /usr/local/phyre/web/config
|
||||
rm -rf /usr/local/phyre/web/app
|
||||
rm -rf /usr/local/phyre/web/bootstrap
|
||||
rm -rf /usr/local/phyre/web/lang
|
||||
rm -rf /usr/local/phyre/web/Modules
|
||||
rm -rf /usr/local/phyre/web/thirdparty
|
||||
|
||||
cp -r /usr/local/phyre/update/web-panel-latest/vendor /usr/local/phyre/web/vendor
|
||||
cp /usr/local/phyre/update/web-panel-latest/composer.lock /usr/local/phyre/web/composer.lock
|
||||
cp -r /usr/local/phyre/update/web-panel-latest/routes /usr/local/phyre/web/routes
|
||||
cp -r /usr/local/phyre/update/web-panel-latest/public /usr/local/phyre/web/public
|
||||
cp -r /usr/local/phyre/update/web-panel-latest/resources /usr/local/phyre/web/resources
|
||||
cp -r /usr/local/phyre/update/web-panel-latest/database /usr/local/phyre/web/database
|
||||
cp -r /usr/local/phyre/update/web-panel-latest/config /usr/local/phyre/web/config
|
||||
cp -r /usr/local/phyre/update/web-panel-latest/app /usr/local/phyre/web/app
|
||||
cp -r /usr/local/phyre/update/web-panel-latest/bootstrap /usr/local/phyre/web/bootstrap
|
||||
cp -r /usr/local/phyre/update/web-panel-latest/lang /usr/local/phyre/web/lang
|
||||
cp -r /usr/local/phyre/update/web-panel-latest/Modules /usr/local/phyre/web/Modules
|
||||
cp -r /usr/local/phyre/update/web-panel-latest/thirdparty /usr/local/phyre/web/thirdparty
|
||||
|
||||
cp -r /usr/local/phyre/update/web-panel-latest/db-migrate.sh /usr/local/phyre/web/db-migrate.sh
|
||||
chmod +x /usr/local/phyre/web/db-migrate.sh
|
||||
#
|
||||
cd /usr/local/phyre/web
|
||||
#
|
||||
#
|
||||
#
|
||||
#PHYRE_PHP=/usr/local/phyre/php/bin/php
|
||||
##
|
||||
#$PHYRE_PHP -v
|
||||
#$PHYRE_PHP -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
|
||||
#$PHYRE_PHP ./composer-setup.php
|
||||
#$PHYRE_PHP -r "unlink('composer-setup.php');"
|
||||
|
||||
#rm -rf composer.lock
|
||||
#COMPOSER_ALLOW_SUPERUSER=1 $PHYRE_PHP composer.phar i --no-interaction --no-progress
|
||||
#COMPOSER_ALLOW_SUPERUSER=1 $PHYRE_PHP composer.phar dump-autoload --no-interaction
|
||||
|
||||
./db-migrate.sh
|
||||
|
||||
service phyre restart
|
|
@ -1 +1 @@
|
|||
0.0.2
|
||||
0.0.1
|
||||
|
|
1
web/.gitignore
vendored
1
web/.gitignore
vendored
|
@ -1,5 +1,6 @@
|
|||
/.phpunit.cache
|
||||
/node_modules
|
||||
/public/build
|
||||
/public/hot
|
||||
/public/storage
|
||||
/storage/*.key
|
||||
|
|
BIN
web/Modules/.DS_Store
vendored
BIN
web/Modules/.DS_Store
vendored
Binary file not shown.
BIN
web/Modules/LetsEncrypt/.DS_Store
vendored
BIN
web/Modules/LetsEncrypt/.DS_Store
vendored
Binary file not shown.
Binary file not shown.
|
@ -1,9 +0,0 @@
|
|||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArRmu5WOZsz50RBvtUU05
|
||||
wZ66jQrAjmJ4t9Kj2+iaynX5OY05d9dH9v+JF9x6dCo+D6dSJLcAyA4/Cosq3TW/
|
||||
rDVSY9eIUsuxr4OlmguFLfHa9vML9Ot1f/z/4uxXhUuG1w15TkqhIvxbHdMes0mH
|
||||
5nA54uHVki5RSQrN08ebawBkxRbp/gG7qvMPxNhBdyTwZ6T7TUJSDWqZYzS6XcjR
|
||||
F1qzOhucAo1lqT7B2XBGYdsEHngZNTVlc4VAdj2ZajOSJdEYsOoxXGV20JFS22lr
|
||||
I1a4Sp6jm9stBuagttfsI5c2kTplfpMbGEDsj+jeNwY7rFfghy4d0G1xZQKarcBO
|
||||
iQIDAQAB
|
||||
-----END PUBLIC KEY-----
|
|
@ -1,66 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\LetsEncrypt\App\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class LetsEncryptController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('letsencrypt::index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('letsencrypt::create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the specified resource.
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
return view('letsencrypt::show');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
return view('letsencrypt::edit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, $id): RedirectResponse
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\LetsEncrypt\App\Providers;
|
||||
|
||||
use App\Events\HostingAccountIsCreated;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Modules\LetsEncrypt\LetsEncryptApacheVirtualHostConfig;
|
||||
use Modules\LetsEncrypt\Listeners\HostingAccountIsCreatedListener;
|
||||
use Modules\LetsEncrypt\Providers\Filament\AdminPanelProvider;
|
||||
|
||||
class LetsEncryptServiceProvider extends ServiceProvider
|
||||
{
|
||||
protected string $moduleName = 'LetsEncrypt';
|
||||
|
||||
protected string $moduleNameLower = 'letsencrypt';
|
||||
|
||||
/**
|
||||
* Boot the application events.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
$this->registerCommands();
|
||||
$this->registerCommandSchedules();
|
||||
$this->registerTranslations();
|
||||
$this->registerConfig();
|
||||
$this->registerViews();
|
||||
$this->loadMigrationsFrom(module_path($this->moduleName, 'Database/migrations'));
|
||||
|
||||
// Event::listen(HostingAccountIsCreated::class,HostingAccountIsCreatedListener::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
$this->app->register(RouteServiceProvider::class);
|
||||
$this->app->register(AdminPanelProvider::class);
|
||||
|
||||
app()->virtualHostManager->registerConfig(LetsEncryptApacheVirtualHostConfig::class, $this->moduleNameLower);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register commands in the format of Command::class
|
||||
*/
|
||||
protected function registerCommands(): void
|
||||
{
|
||||
// $this->commands([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register command Schedules.
|
||||
*/
|
||||
protected function registerCommandSchedules(): void
|
||||
{
|
||||
// $this->app->booted(function () {
|
||||
// $schedule = $this->app->make(Schedule::class);
|
||||
// $schedule->command('inspire')->hourly();
|
||||
// });
|
||||
}
|
||||
|
||||
/**
|
||||
* Register translations.
|
||||
*/
|
||||
public function registerTranslations(): void
|
||||
{
|
||||
$langPath = resource_path('lang/modules/'.$this->moduleNameLower);
|
||||
|
||||
if (is_dir($langPath)) {
|
||||
$this->loadTranslationsFrom($langPath, $this->moduleNameLower);
|
||||
$this->loadJsonTranslationsFrom($langPath);
|
||||
} else {
|
||||
$this->loadTranslationsFrom(module_path($this->moduleName, 'lang'), $this->moduleNameLower);
|
||||
$this->loadJsonTranslationsFrom(module_path($this->moduleName, 'lang'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register config.
|
||||
*/
|
||||
protected function registerConfig(): void
|
||||
{
|
||||
$this->publishes([module_path($this->moduleName, 'config/config.php') => config_path($this->moduleNameLower.'.php')], 'config');
|
||||
$this->mergeConfigFrom(module_path($this->moduleName, 'config/config.php'), $this->moduleNameLower);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register views.
|
||||
*/
|
||||
public function registerViews(): void
|
||||
{
|
||||
$viewPath = resource_path('views/modules/'.$this->moduleNameLower);
|
||||
$sourcePath = module_path($this->moduleName, 'resources/views');
|
||||
|
||||
$this->publishes([$sourcePath => $viewPath], ['views', $this->moduleNameLower.'-module-views']);
|
||||
|
||||
$this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), $this->moduleNameLower);
|
||||
|
||||
$componentNamespace = str_replace('/', '\\', config('modules.namespace').'\\'.$this->moduleName.'\\'.config('modules.paths.generator.component-class.path'));
|
||||
Blade::componentNamespace($componentNamespace, $this->moduleNameLower);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the services provided by the provider.
|
||||
*/
|
||||
public function provides(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
private function getPublishableViewPaths(): array
|
||||
{
|
||||
$paths = [];
|
||||
foreach (config('view.paths') as $path) {
|
||||
if (is_dir($path.'/modules/'.$this->moduleNameLower)) {
|
||||
$paths[] = $path.'/modules/'.$this->moduleNameLower;
|
||||
}
|
||||
}
|
||||
|
||||
return $paths;
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\LetsEncrypt\App\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The module namespace to assume when generating URLs to actions.
|
||||
*/
|
||||
protected string $moduleNamespace = 'Modules\LetsEncrypt\App\Http\Controllers';
|
||||
|
||||
/**
|
||||
* Called before routes are registered.
|
||||
*
|
||||
* Register any model bindings or pattern based filters.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
parent::boot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the routes for the application.
|
||||
*/
|
||||
public function map(): void
|
||||
{
|
||||
$this->mapApiRoutes();
|
||||
|
||||
$this->mapWebRoutes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the "web" routes for the application.
|
||||
*
|
||||
* These routes all receive session state, CSRF protection, etc.
|
||||
*/
|
||||
protected function mapWebRoutes(): void
|
||||
{
|
||||
Route::middleware('web')
|
||||
->namespace($this->moduleNamespace)
|
||||
->group(module_path('LetsEncrypt', '/routes/web.php'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the "api" routes for the application.
|
||||
*
|
||||
* These routes are typically stateless.
|
||||
*/
|
||||
protected function mapApiRoutes(): void
|
||||
{
|
||||
Route::prefix('api')
|
||||
->middleware('api')
|
||||
->namespace($this->moduleNamespace)
|
||||
->group(module_path('LetsEncrypt', '/routes/api.php'));
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\LetsEncrypt\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class LetsEncryptDatabaseSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// $this->call([]);
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\LetsEncrypt\Clusters;
|
||||
|
||||
use Filament\Clusters\Cluster;
|
||||
|
||||
class LetsEncrypt extends Cluster
|
||||
{
|
||||
protected static ?string $navigationIcon = 'heroicon-o-squares-2x2';
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\LetsEncrypt;
|
||||
|
||||
use App\VirtualHosts\ApacheVirtualHostConfigBase;
|
||||
|
||||
class LetsEncryptApacheVirtualHostConfig extends ApacheVirtualHostConfigBase
|
||||
{
|
||||
public array $phpAdminValueOpenBaseDirs = [
|
||||
'/usr/share/letsencrypt',
|
||||
];
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\LetsEncrypt\Listeners;
|
||||
|
||||
use App\Actions\ApacheWebsiteApplySSLVirtualHost;
|
||||
use App\ApiClient;
|
||||
use App\Events\HostingAccountIsCreated;
|
||||
use App\FileManagerApi;
|
||||
use App\Models\DomainSslCertificate;
|
||||
use App\Models\HostingPlan;
|
||||
use App\Settings;
|
||||
use App\ShellApi;
|
||||
|
||||
class HostingAccountIsCreatedListener
|
||||
{
|
||||
/**
|
||||
* Create the event listener.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*/
|
||||
public function handle(HostingAccountIsCreated $event): void
|
||||
{
|
||||
$findWebsite = \App\Models\Domain::where('id', $event->model->id)->first();
|
||||
if (! $findWebsite) {
|
||||
return;
|
||||
}
|
||||
|
||||
$findHostingPlan = HostingPlan::where('id', $findWebsite->hosting_plan_id)->first();
|
||||
if (! $findHostingPlan) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! in_array('letsencrypt', $findHostingPlan->additional_services)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$generalSettings = Settings::general();
|
||||
|
||||
$acmeConfigYaml = view('letsencrypt::actions.acme-config-yaml', [
|
||||
'domain' => $event->model->domain,
|
||||
'domainRoot' => $event->model->domain_root,
|
||||
'domainPublic' => $event->model->domain_public,
|
||||
'email' => $generalSettings['master_email'],
|
||||
'country' => $generalSettings['master_country'],
|
||||
'locality' => $generalSettings['master_locality'],
|
||||
'organization' => $generalSettings['organization_name'],
|
||||
])->render();
|
||||
|
||||
$fmApi = new FileManagerApi();
|
||||
$fmApi->filePutContents($event->model->domain_root.'/acme-config.yaml', $acmeConfigYaml);
|
||||
|
||||
$amePHPPharFile = base_path().'/Modules/LetsEncrypt/Actions/acmephp.phar';
|
||||
|
||||
$phyrePHP = ApiClient::getPhyrePHP();
|
||||
|
||||
$command = $phyrePHP.' '.$amePHPPharFile.' run '.$event->model->domain_root.'/acme-config.yaml';
|
||||
ShellApi::exec($command);
|
||||
|
||||
$validateCertificates = [];
|
||||
$sslCertificateFilePath = '/root/.acmephp/master/certs/'.$event->model->domain.'/public/cert.pem';
|
||||
$sslCertificateKeyFilePath = '/root/.acmephp/master/certs/'.$event->model->domain.'/private/key.private.pem';
|
||||
$sslCertificateChainFilePath = '/root/.acmephp/master/certs/'.$event->model->domain.'/public/fullchain.pem';
|
||||
|
||||
$sslCertificateFileContent = $fmApi->fileGetContents($sslCertificateFilePath);
|
||||
$sslCertificateKeyFileContent = $fmApi->fileGetContents($sslCertificateKeyFilePath);
|
||||
$sslCertificateChainFileContent = $fmApi->fileGetContents($sslCertificateChainFilePath);
|
||||
|
||||
if (! empty($sslCertificateChainFileContent)) {
|
||||
$validateCertificates['certificate'] = $sslCertificateFileContent;
|
||||
}
|
||||
if (! empty($sslCertificateKeyFileContent)) {
|
||||
$validateCertificates['private_key'] = $sslCertificateKeyFileContent;
|
||||
}
|
||||
if (! empty($sslCertificateChainFileContent)) {
|
||||
$validateCertificates['certificate_chain'] = $sslCertificateChainFileContent;
|
||||
}
|
||||
if (count($validateCertificates) !== 3) {
|
||||
// Cant get all certificates
|
||||
return;
|
||||
}
|
||||
|
||||
$websiteSslCertificate = new DomainSslCertificate();
|
||||
$websiteSslCertificate->domain = $event->model->domain;
|
||||
$websiteSslCertificate->certificate = $validateCertificates['certificate'];
|
||||
$websiteSslCertificate->private_key = $validateCertificates['private_key'];
|
||||
$websiteSslCertificate->certificate_chain = $validateCertificates['certificate_chain'];
|
||||
$websiteSslCertificate->customer_id = $event->model->customer_id;
|
||||
$websiteSslCertificate->is_active = 1;
|
||||
$websiteSslCertificate->is_wildcard = 0;
|
||||
$websiteSslCertificate->is_auto_renew = 1;
|
||||
$websiteSslCertificate->provider = 'letsencrypt';
|
||||
$websiteSslCertificate->save();
|
||||
|
||||
$applySSLVirtualHost = new ApacheWebsiteApplySSLVirtualHost();
|
||||
$applySSLVirtualHost->setDomain($event->model->domain);
|
||||
$applySSLVirtualHost->setDomainRoot($event->model->domain_root);
|
||||
$applySSLVirtualHost->setDomainPublic($event->model->domain_public);
|
||||
$applySSLVirtualHost->setSslCertificateFilePath($sslCertificateFilePath);
|
||||
$applySSLVirtualHost->setSslCertificateKeyFilePath($sslCertificateKeyFilePath);
|
||||
$applySSLVirtualHost->setSslCertificateChainFilePath($sslCertificateChainFilePath);
|
||||
$applySSLVirtualHost->handle();
|
||||
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\LetsEncrypt\Providers\Filament;
|
||||
|
||||
use Filament\Http\Middleware\Authenticate;
|
||||
use Filament\Http\Middleware\DisableBladeIconComponents;
|
||||
use Filament\Http\Middleware\DispatchServingFilamentEvent;
|
||||
use Filament\Pages;
|
||||
use Filament\Panel;
|
||||
use Filament\PanelProvider;
|
||||
use Filament\Support\Colors\Color;
|
||||
use Filament\Widgets;
|
||||
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies;
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
|
||||
use Illuminate\Routing\Middleware\SubstituteBindings;
|
||||
use Illuminate\Session\Middleware\AuthenticateSession;
|
||||
use Illuminate\Session\Middleware\StartSession;
|
||||
use Illuminate\View\Middleware\ShareErrorsFromSession;
|
||||
|
||||
class AdminPanelProvider extends PanelProvider
|
||||
{
|
||||
private string $module = 'LetsEncrypt';
|
||||
|
||||
public function panel(Panel $panel): Panel
|
||||
{
|
||||
$moduleNamespace = $this->getModuleNamespace();
|
||||
|
||||
return $panel
|
||||
->id('Lets Encrypt ::admin')
|
||||
->path('admin/modules/letsencrypt')
|
||||
->colors([
|
||||
'primary' => Color::Violet,
|
||||
])
|
||||
->discoverResources(in: module_path($this->module, 'Filament/Admin/Resources'), for: "$moduleNamespace\\Filament\\Admin\\Resources")
|
||||
->discoverPages(in: module_path($this->module, 'Filament/Admin/Pages'), for: "$moduleNamespace\\Filament\\Admin\\Pages")
|
||||
->pages([
|
||||
Pages\Dashboard::class,
|
||||
])
|
||||
->discoverWidgets(in: module_path($this->module, 'Filament/Admin/Widgets'), for: "$moduleNamespace\\Filament\\Admin\\Widgets")
|
||||
->widgets([
|
||||
Widgets\AccountWidget::class,
|
||||
Widgets\FilamentInfoWidget::class,
|
||||
])
|
||||
->middleware([
|
||||
EncryptCookies::class,
|
||||
AddQueuedCookiesToResponse::class,
|
||||
StartSession::class,
|
||||
AuthenticateSession::class,
|
||||
ShareErrorsFromSession::class,
|
||||
VerifyCsrfToken::class,
|
||||
SubstituteBindings::class,
|
||||
DisableBladeIconComponents::class,
|
||||
DispatchServingFilamentEvent::class,
|
||||
])
|
||||
->authMiddleware([
|
||||
Authenticate::class,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getModuleNamespace(): string
|
||||
{
|
||||
return config('modules.namespace').'\\'.$this->module;
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
{
|
||||
"name": "nwidart/letsencrypt",
|
||||
"description": "",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Widart",
|
||||
"email": "n.widart@gmail.com"
|
||||
}
|
||||
],
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [],
|
||||
"aliases": {
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Modules\\LetsEncrypt\\": "",
|
||||
"Modules\\LetsEncrypt\\App\\": "app/",
|
||||
"Modules\\LetsEncrypt\\Database\\Factories\\": "database/factories/",
|
||||
"Modules\\LetsEncrypt\\Database\\Seeders\\": "database/seeders/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Modules\\LetsEncrypt\\Tests\\": "tests/"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'name' => 'LetsEncrypt',
|
||||
];
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"name": "LetsEncrypt",
|
||||
"alias": "letsencrypt",
|
||||
"description": "",
|
||||
"keywords": [],
|
||||
"priority": 0,
|
||||
"providers": [
|
||||
"Modules\\LetsEncrypt\\App\\Providers\\LetsEncryptServiceProvider",
|
||||
"Modules\\LetsEncrypt\\Providers\\Filament\\AdminPanelProvider"
|
||||
],
|
||||
"files": []
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"axios": "^1.1.2",
|
||||
"laravel-vite-plugin": "^0.7.5",
|
||||
"sass": "^1.69.5",
|
||||
"postcss": "^8.3.7",
|
||||
"vite": "^4.0.0"
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
contact_email: {{ $email }}
|
||||
|
||||
defaults:
|
||||
distinguished_name:
|
||||
country: {{ $country }}
|
||||
locality: {{ $locality }}
|
||||
organization_name: {{ $organization }}
|
||||
solver: http
|
||||
|
||||
certificates:
|
||||
- domain: {{ $domain }}
|
||||
solver:
|
||||
name: http-file
|
||||
adapter: local
|
||||
root: {{ $domainPublic }}
|
|
@ -1,7 +0,0 @@
|
|||
@extends('letsencrypt::layouts.master')
|
||||
|
||||
@section('content')
|
||||
<h1>Hello World</h1>
|
||||
|
||||
<p>Module: {!! config('letsencrypt.name') !!}</p>
|
||||
@endsection
|
|
@ -1,29 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
|
||||
<title>LetsEncrypt Module - {{ config('app.name', 'Laravel') }}</title>
|
||||
|
||||
<meta name="description" content="{{ $description ?? '' }}">
|
||||
<meta name="keywords" content="{{ $keywords ?? '' }}">
|
||||
<meta name="author" content="{{ $author ?? '' }}">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.bunny.net">
|
||||
<link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />
|
||||
|
||||
{{-- Vite CSS --}}
|
||||
{{-- {{ module_vite('build-letsencrypt', 'resources/assets/sass/app.scss') }} --}}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@yield('content')
|
||||
|
||||
{{-- Vite JS --}}
|
||||
{{-- {{ module_vite('build-letsencrypt', 'resources/assets/js/app.js') }} --}}
|
||||
</body>
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| API Routes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you can register API routes for your application. These
|
||||
| routes are loaded by the RouteServiceProvider within a group which
|
||||
| is assigned the "api" middleware group. Enjoy building your API!
|
||||
|
|
||||
*/
|
||||
|
||||
Route::middleware(['auth:sanctum'])->prefix('v1')->name('api.')->group(function () {
|
||||
Route::get('letsencrypt', fn (Request $request) => $request->user())->name('letsencrypt');
|
||||
});
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Modules\LetsEncrypt\App\Http\Controllers\LetsEncryptController;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Web Routes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you can register web routes for your application. These
|
||||
| routes are loaded by the RouteServiceProvider within a group which
|
||||
| contains the "web" middleware group. Now create something great!
|
||||
|
|
||||
*/
|
||||
|
||||
Route::group([], function () {
|
||||
Route::resource('letsencrypt', LetsEncryptController::class)->names('letsencrypt');
|
||||
});
|
|
@ -1,26 +0,0 @@
|
|||
import { defineConfig } from 'vite';
|
||||
import laravel from 'laravel-vite-plugin';
|
||||
|
||||
export default defineConfig({
|
||||
build: {
|
||||
outDir: '../../public/build-letsencrypt',
|
||||
emptyOutDir: true,
|
||||
manifest: true,
|
||||
},
|
||||
plugins: [
|
||||
laravel({
|
||||
publicDirectory: '../../public',
|
||||
buildDirectory: 'build-letsencrypt',
|
||||
input: [
|
||||
__dirname + '/resources/assets/sass/app.scss',
|
||||
__dirname + '/resources/assets/js/app.js'
|
||||
],
|
||||
refresh: true,
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
//export const paths = [
|
||||
// 'Modules/$STUDLY_NAME$/resources/assets/sass/app.scss',
|
||||
// 'Modules/$STUDLY_NAME$/resources/assets/js/app.js',
|
||||
//];
|
|
@ -1,66 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber\App\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class MicroweberController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('microweber::index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
return view('microweber::create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the specified resource.
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
return view('microweber::show');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
return view('microweber::edit');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, $id): RedirectResponse
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber\App\Models;
|
||||
|
||||
use App\Models\Domain;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class MicroweberInstallation extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public function domain()
|
||||
{
|
||||
return $this->hasOne(Domain::class, 'id', 'domain_id');
|
||||
}
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber\App\Providers;
|
||||
|
||||
use App\Events\DomainIsCreated;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Modules\Microweber\Listeners\DomainIsCreatedListener;
|
||||
use Modules\Microweber\MicroweberApacheVirtualHostConfig;
|
||||
|
||||
class MicroweberServiceProvider extends ServiceProvider
|
||||
{
|
||||
protected string $moduleName = 'Microweber';
|
||||
|
||||
protected string $moduleNameLower = 'microweber';
|
||||
|
||||
/**
|
||||
* Boot the application events.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
$this->registerCommands();
|
||||
$this->registerCommandSchedules();
|
||||
$this->registerTranslations();
|
||||
$this->registerConfig();
|
||||
$this->registerViews();
|
||||
$this->loadMigrationsFrom(module_path($this->moduleName, 'Database/migrations'));
|
||||
|
||||
Event::listen(DomainIsCreated::class, DomainIsCreatedListener::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the service provider.
|
||||
*/
|
||||
public function register(): void
|
||||
{
|
||||
$this->app->register(RouteServiceProvider::class);
|
||||
|
||||
app()->virtualHostManager->registerConfig(MicroweberApacheVirtualHostConfig::class, $this->moduleNameLower);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register commands in the format of Command::class
|
||||
*/
|
||||
protected function registerCommands(): void
|
||||
{
|
||||
// $this->commands([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register command Schedules.
|
||||
*/
|
||||
protected function registerCommandSchedules(): void
|
||||
{
|
||||
// $this->app->booted(function () {
|
||||
// $schedule = $this->app->make(Schedule::class);
|
||||
// $schedule->command('inspire')->hourly();
|
||||
// });
|
||||
}
|
||||
|
||||
/**
|
||||
* Register translations.
|
||||
*/
|
||||
public function registerTranslations(): void
|
||||
{
|
||||
$langPath = resource_path('lang/modules/'.$this->moduleNameLower);
|
||||
|
||||
if (is_dir($langPath)) {
|
||||
$this->loadTranslationsFrom($langPath, $this->moduleNameLower);
|
||||
$this->loadJsonTranslationsFrom($langPath);
|
||||
} else {
|
||||
$this->loadTranslationsFrom(module_path($this->moduleName, 'lang'), $this->moduleNameLower);
|
||||
$this->loadJsonTranslationsFrom(module_path($this->moduleName, 'lang'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register config.
|
||||
*/
|
||||
protected function registerConfig(): void
|
||||
{
|
||||
$this->publishes([module_path($this->moduleName, 'config/config.php') => config_path($this->moduleNameLower.'.php')], 'config');
|
||||
$this->mergeConfigFrom(module_path($this->moduleName, 'config/config.php'), $this->moduleNameLower);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register views.
|
||||
*/
|
||||
public function registerViews(): void
|
||||
{
|
||||
$viewPath = resource_path('views/modules/'.$this->moduleNameLower);
|
||||
$sourcePath = module_path($this->moduleName, 'resources/views');
|
||||
|
||||
$this->publishes([$sourcePath => $viewPath], ['views', $this->moduleNameLower.'-module-views']);
|
||||
|
||||
$this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), $this->moduleNameLower);
|
||||
|
||||
$componentNamespace = str_replace('/', '\\', config('modules.namespace').'\\'.$this->moduleName.'\\'.config('modules.paths.generator.component-class.path'));
|
||||
Blade::componentNamespace($componentNamespace, $this->moduleNameLower);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the services provided by the provider.
|
||||
*/
|
||||
public function provides(): array
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
private function getPublishableViewPaths(): array
|
||||
{
|
||||
$paths = [];
|
||||
foreach (config('view.paths') as $path) {
|
||||
if (is_dir($path.'/modules/'.$this->moduleNameLower)) {
|
||||
$paths[] = $path.'/modules/'.$this->moduleNameLower;
|
||||
}
|
||||
}
|
||||
|
||||
return $paths;
|
||||
}
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber\App\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The module namespace to assume when generating URLs to actions.
|
||||
*/
|
||||
protected string $moduleNamespace = 'Modules\Microweber\App\Http\Controllers';
|
||||
|
||||
/**
|
||||
* Called before routes are registered.
|
||||
*
|
||||
* Register any model bindings or pattern based filters.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
parent::boot();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the routes for the application.
|
||||
*/
|
||||
public function map(): void
|
||||
{
|
||||
$this->mapApiRoutes();
|
||||
|
||||
$this->mapWebRoutes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the "web" routes for the application.
|
||||
*
|
||||
* These routes all receive session state, CSRF protection, etc.
|
||||
*/
|
||||
protected function mapWebRoutes(): void
|
||||
{
|
||||
Route::middleware('web')
|
||||
->namespace($this->moduleNamespace)
|
||||
->group(module_path('Microweber', '/routes/web.php'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the "api" routes for the application.
|
||||
*
|
||||
* These routes are typically stateless.
|
||||
*/
|
||||
protected function mapApiRoutes(): void
|
||||
{
|
||||
Route::prefix('api')
|
||||
->middleware('api')
|
||||
->namespace($this->moduleNamespace)
|
||||
->group(module_path('Microweber', '/routes/api.php'));
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber\Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class MicroweberDatabaseSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
// $this->call([]);
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('microweber_installations', function (Blueprint $table) {
|
||||
$table->id();
|
||||
|
||||
$table->bigInteger('domain_id')->nullable();
|
||||
|
||||
$table->string('app_version')->nullable();
|
||||
$table->string('installation_type')->nullable();
|
||||
$table->string('installation_path')->nullable();
|
||||
$table->string('template')->nullable();
|
||||
$table->string('template_screenshot_url')->nullable();
|
||||
|
||||
$table->string('db_version')->nullable();
|
||||
$table->string('db_engine')->nullable();
|
||||
$table->string('db_host')->nullable();
|
||||
$table->string('db_port')->nullable();
|
||||
$table->string('db_name')->nullable();
|
||||
$table->string('db_user')->nullable();
|
||||
$table->string('db_password')->nullable();
|
||||
$table->string('db_prefix')->nullable();
|
||||
|
||||
$table->string('admin_email')->nullable();
|
||||
$table->string('admin_password')->nullable();
|
||||
$table->string('admin_username')->nullable();
|
||||
$table->string('admin_first_name')->nullable();
|
||||
$table->string('admin_last_name')->nullable();
|
||||
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('microweber_installations');
|
||||
}
|
||||
};
|
|
@ -1,133 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber\Filament\Clusters\Microweber\Pages;
|
||||
|
||||
use Filament\Forms\Components\Section;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Modules\Microweber\Filament\Clusters\MicroweberCluster;
|
||||
use Outerweb\FilamentSettings\Filament\Pages\Settings as BaseSettings;
|
||||
|
||||
class Settings extends BaseSettings
|
||||
{
|
||||
protected static ?string $navigationGroup = 'Microweber';
|
||||
|
||||
protected static ?string $cluster = MicroweberCluster::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-cog';
|
||||
|
||||
protected static ?int $navigationSort = 3;
|
||||
|
||||
public function schema(): array
|
||||
{
|
||||
return [
|
||||
|
||||
Section::make('Settings')
|
||||
->schema([
|
||||
|
||||
Select::make('microweber.default_installation_template')
|
||||
->options([
|
||||
'default' => 'Default',
|
||||
'big' => 'BIG',
|
||||
])
|
||||
->label('Default Installation template'),
|
||||
|
||||
Select::make('microweber.default_installation_language')
|
||||
->options([
|
||||
'en' => 'English',
|
||||
'bg' => 'Bulgarian',
|
||||
])
|
||||
->label('Default Installation language'),
|
||||
|
||||
Select::make('microweber.default_installation_type')
|
||||
->options([
|
||||
'sym-linked' => 'Sym-Linked (saves a big amount of disk space)',
|
||||
'standalone' => 'Standalone',
|
||||
])
|
||||
->label('Default Installation type'),
|
||||
|
||||
Select::make('microweber.show_installing_app_notifications')
|
||||
->options([
|
||||
'no' => 'No',
|
||||
'yes' => 'Yes',
|
||||
])
|
||||
->label('Show installing app notifications'),
|
||||
|
||||
Select::make('microweber.instantly_install_ssl_certificate')
|
||||
->options([
|
||||
'no' => 'No',
|
||||
'yes' => 'Yes',
|
||||
])
|
||||
->label('Instantly install SSL certificate'),
|
||||
|
||||
Select::make('microweber.allow_customers_to_choose_installation_type')
|
||||
->options([
|
||||
'yes' => 'Yes',
|
||||
'no' => 'No',
|
||||
])
|
||||
->label('Allow customers to choose installation type'),
|
||||
|
||||
Select::make('microweber.allow_customers_to_choose_installation_database_driver')
|
||||
->options([
|
||||
'yes' => 'Yes',
|
||||
'no' => 'No',
|
||||
])
|
||||
->label('Allow customers to choose installation database driver'),
|
||||
|
||||
Select::make('microweber.database_driver')
|
||||
->options([
|
||||
'mysql' => 'MySQL',
|
||||
'sqlite' => 'SQLite',
|
||||
])
|
||||
->label('Database Driver'),
|
||||
|
||||
Select::make('microweber.update_app_channel')
|
||||
->options([
|
||||
'stable' => 'Stable',
|
||||
'beta' => 'Beta',
|
||||
'development' => 'Development',
|
||||
])
|
||||
->label('Update App Channel'),
|
||||
|
||||
Select::make('microweber.update_app_automatically')
|
||||
->options([
|
||||
'no' => 'No',
|
||||
'yes' => 'Yes',
|
||||
])
|
||||
->label('Update App Automatically'),
|
||||
|
||||
Select::make('microweber.update_templates_automatically')
|
||||
->options([
|
||||
'no' => 'No',
|
||||
'yes' => 'Yes',
|
||||
])
|
||||
->label('Update Templates Automatically'),
|
||||
|
||||
Select::make('microweber.website_manager')
|
||||
->options([
|
||||
'whmcs' => 'WHMCS',
|
||||
'microweber_saas' => 'Microweber SAAS',
|
||||
])
|
||||
->label('Website manager'),
|
||||
|
||||
TextInput::make('microweber.website_manager_url')
|
||||
->label('Website Manager Url'),
|
||||
|
||||
Select::make('microweber.get_package_manager_urls_from_website_manager')
|
||||
->options([
|
||||
'no' => 'No',
|
||||
'yes' => 'Yes',
|
||||
])
|
||||
->label('Get package manager urls from website manager'),
|
||||
|
||||
Select::make('microweber.allow_resellers_to_use_their_own_white_label')
|
||||
->options([
|
||||
'no' => 'No',
|
||||
'yes' => 'Yes',
|
||||
])
|
||||
->label('Allow resellers to use their own White Label'),
|
||||
|
||||
]),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber\Filament\Clusters\Microweber\Pages;
|
||||
|
||||
use App\ShellApi;
|
||||
use Filament\Pages\Page;
|
||||
use MicroweberPackages\ComposerClient\Client;
|
||||
use MicroweberPackages\SharedServerScripts\MicroweberAppPathHelper;
|
||||
use MicroweberPackages\SharedServerScripts\MicroweberDownloader;
|
||||
use MicroweberPackages\SharedServerScripts\MicroweberModuleConnectorsDownloader;
|
||||
use MicroweberPackages\SharedServerScripts\MicroweberTemplatesDownloader;
|
||||
use Modules\Microweber\Filament\Clusters\MicroweberCluster;
|
||||
|
||||
class Version extends Page
|
||||
{
|
||||
protected static ?string $navigationGroup = 'Microweber';
|
||||
|
||||
protected static ?string $cluster = MicroweberCluster::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected static string $view = 'microweber::filament.admin.pages.version';
|
||||
|
||||
protected static ?int $navigationSort = 1;
|
||||
|
||||
public $currentVersionOfApp = 0;
|
||||
|
||||
public $latestVersionOfApp = 0;
|
||||
|
||||
public $latestDownloadDateOfApp = 0;
|
||||
|
||||
public $supportedTemplates = [];
|
||||
|
||||
public $supportedLanguages = [];
|
||||
|
||||
protected function getViewData(): array
|
||||
{
|
||||
$release = $this->__getMicroweberDownloaderInstance()->getRelease();
|
||||
|
||||
$sharedPath = new MicroweberAppPathHelper();
|
||||
$sharedPath->setPath(config('microweber.sharedPaths.app'));
|
||||
|
||||
$this->supportedLanguages = $sharedPath->getSupportedLanguages();
|
||||
$this->supportedTemplates = $sharedPath->getSupportedTemplates();
|
||||
$this->latestVersionOfApp = $this->__getMicroweberDownloaderInstance()->getVersion();
|
||||
$this->currentVersionOfApp = $sharedPath->getCurrentVersion();
|
||||
$this->latestDownloadDateOfApp = $sharedPath->getCreatedAt();
|
||||
|
||||
return [
|
||||
'appVersion' => $this->currentVersionOfApp,
|
||||
'latestAppVersion' => $this->latestVersionOfApp,
|
||||
'latestAppDownloadDate' => $this->latestDownloadDateOfApp,
|
||||
'totalAppTemplates' => count($this->supportedTemplates),
|
||||
'appTemplates' => $this->supportedTemplates,
|
||||
'supportedLanguages' => $this->supportedLanguages,
|
||||
'supportedTemplates' => $this->supportedTemplates,
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
public function checkForUpdates()
|
||||
{
|
||||
$sharedAppPath = config('microweber.sharedPaths.app');
|
||||
|
||||
if (! is_dir(dirname($sharedAppPath))) {
|
||||
mkdir(dirname($sharedAppPath));
|
||||
}
|
||||
|
||||
$shellPath = '/usr/local/phyre/web/vendor/microweber-packages/shared-server-scripts/shell-scripts';
|
||||
ShellApi::exec('chmod +x '.$shellPath.'/*');
|
||||
|
||||
// Download core app
|
||||
$status = $this->__getMicroweberDownloaderInstance()
|
||||
->download(config('microweber.sharedPaths.app'));
|
||||
|
||||
// Download modules
|
||||
$modulesDownloader = new MicroweberModuleConnectorsDownloader();
|
||||
$modulesDownloader->setComposerClient($this->__getComposerClientInstance());
|
||||
$status = $modulesDownloader->download(config('microweber.sharedPaths.modules'));
|
||||
|
||||
// Download templates
|
||||
$templatesDownloader = new MicroweberTemplatesDownloader();
|
||||
$templatesDownloader->setComposerClient($this->__getComposerLicensedInstance());
|
||||
$status = $templatesDownloader->download(config('microweber.sharedPaths.templates'));
|
||||
|
||||
}
|
||||
|
||||
private function __getComposerClientInstance()
|
||||
{
|
||||
// The module connector must have own instance of composer client
|
||||
$composerClient = new Client();
|
||||
$composerClient->packageServers = [
|
||||
'https://market.microweberapi.com/packages/microweberserverpackages/packages.json',
|
||||
];
|
||||
|
||||
return $composerClient;
|
||||
}
|
||||
|
||||
private function __getComposerLicensedInstance()
|
||||
{
|
||||
$composerClientLicensed = new Client();
|
||||
// if (Option::getOption('license_key_status', 'whitelabel_license') == 'valid') {
|
||||
// $composerClientLicensed->addLicense([
|
||||
// 'local_key' => Option::getOption('license_key', 'whitelabel_license')
|
||||
// ]);
|
||||
// }
|
||||
|
||||
return $composerClientLicensed;
|
||||
}
|
||||
|
||||
private function __getMicroweberDownloaderInstance()
|
||||
{
|
||||
$coreDownloader = new MicroweberDownloader();
|
||||
|
||||
$updateAppChannel = 'stable';
|
||||
if ($updateAppChannel == 'stable') {
|
||||
$coreDownloader->setReleaseSource(MicroweberDownloader::STABLE_RELEASE);
|
||||
} else {
|
||||
$coreDownloader->setReleaseSource(MicroweberDownloader::DEV_RELEASE);
|
||||
}
|
||||
|
||||
$coreDownloader->setComposerClient($this->__getComposerClientInstance());
|
||||
|
||||
return $coreDownloader;
|
||||
}
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber\Filament\Clusters\Microweber\Pages;
|
||||
|
||||
use Filament\Forms\Components\Checkbox;
|
||||
use Filament\Forms\Components\Section;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Modules\Microweber\Filament\Clusters\MicroweberCluster;
|
||||
use Outerweb\FilamentSettings\Filament\Pages\Settings as BaseSettings;
|
||||
|
||||
class Whitelabel extends BaseSettings
|
||||
{
|
||||
protected static ?string $navigationGroup = 'Microweber';
|
||||
|
||||
protected static ?string $cluster = MicroweberCluster::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-puzzle-piece';
|
||||
|
||||
protected static ?int $navigationSort = 2;
|
||||
|
||||
protected static ?string $navigationLabel = 'Whitelabel';
|
||||
|
||||
public static function getNavigationLabel(): string
|
||||
{
|
||||
return self::$navigationLabel;
|
||||
}
|
||||
|
||||
public function getTitle(): string
|
||||
{
|
||||
return self::$navigationLabel;
|
||||
}
|
||||
|
||||
public function schema(): array
|
||||
{
|
||||
return [
|
||||
Section::make('Whitelabel')
|
||||
->schema([
|
||||
|
||||
TextInput::make('whitelabel_license_key')
|
||||
->label('License Key'),
|
||||
|
||||
TextInput::make('microweber.whitelabel.brand_name')
|
||||
->label('Brand Name'),
|
||||
|
||||
TextInput::make('microweber.whitelabel.brand_favicon')
|
||||
->label('Brand Favicon'),
|
||||
|
||||
TextInput::make('microweber.whitelabel.admin_login_white_label_url')
|
||||
->label('Admin login - White Label URL?'),
|
||||
|
||||
Checkbox::make('microweber.whitelabel.enable_support_links')
|
||||
->label('Enable support links?'),
|
||||
|
||||
TextInput::make('microweber.whitelabel.enable_support_links')
|
||||
->label('Enable support links'),
|
||||
|
||||
Textarea::make('microweber.whitelabel.powered_by_text')
|
||||
->label('Enter "Powered by" text'),
|
||||
|
||||
Checkbox::make('microweber.whitelabel.hide_powered_by_link')
|
||||
->label('Hide "Powered by" link'),
|
||||
|
||||
TextInput::make('microweber.whitelabel.logo_admin_panel')
|
||||
->label('Logo for Admin panel (size: 180x35px)'),
|
||||
|
||||
TextInput::make('microweber.whitelabel.logo_live_edit_toolbar')
|
||||
->label('Logo for Live-Edit toolbar (size: 50x50px)'),
|
||||
|
||||
TextInput::make('microweber.whitelabel.logo_login_screen')
|
||||
->label('Logo for Login screen (max width: 290px)'),
|
||||
|
||||
Checkbox::make('microweber.whitelabel.disable_microweber_marketplace')
|
||||
->label('Disable Microweber Marketplace'),
|
||||
|
||||
TextInput::make('microweber.whitelabel.external_login_server_button_text')
|
||||
->label('External Login Server Button Text'),
|
||||
|
||||
Checkbox::make('microweber.whitelabel.enable_external_login_server')
|
||||
->label('Enable External Login Server'),
|
||||
|
||||
Checkbox::make('microweber.whitelabel.enable_microweber_service_links')
|
||||
->label('Enable Microweber Service Links'),
|
||||
|
||||
Textarea::make('microweber.whitelabel.admin_colors_sass')
|
||||
->label('Enter "Admin colors" sass'),
|
||||
|
||||
]),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber\Filament\Clusters\Microweber\Resources;
|
||||
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Resources\Resource;
|
||||
use Filament\Tables;
|
||||
use Filament\Tables\Table;
|
||||
use Modules\Microweber\App\Models\MicroweberInstallation;
|
||||
use Modules\Microweber\Filament\Clusters\Microweber\Resources\InstallationResource\Pages\ListInstallations;
|
||||
use Modules\Microweber\Filament\Clusters\MicroweberCluster;
|
||||
|
||||
class InstallationResource extends Resource
|
||||
{
|
||||
protected static ?string $model = MicroweberInstallation::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||
|
||||
protected static ?string $navigationGroup = 'Microweber';
|
||||
|
||||
protected static ?string $cluster = MicroweberCluster::class;
|
||||
|
||||
protected static ?string $label = 'Installations';
|
||||
|
||||
protected static ?int $navigationSort = 0;
|
||||
|
||||
public static function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->schema([
|
||||
//
|
||||
]);
|
||||
}
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
|
||||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('website.domain')->label('Domain'),
|
||||
Tables\Columns\TextColumn::make('app_version')->label('Version'),
|
||||
Tables\Columns\TextColumn::make('installation_type')->label('Type'),
|
||||
// Tables\Columns\TextColumn::make('installation_path')->label('Path'),
|
||||
Tables\Columns\TextColumn::make('template')->label('Template'),
|
||||
// Tables\Columns\TextColumn::make('admin_email')->label('Admin Email'),
|
||||
|
||||
])
|
||||
->filters([
|
||||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
|
||||
public static function getRelations(): array
|
||||
{
|
||||
return [
|
||||
//
|
||||
];
|
||||
}
|
||||
|
||||
public static function getPages(): array
|
||||
{
|
||||
return [
|
||||
'index' => ListInstallations::route('/'),
|
||||
// 'create' => Pages\CreateInstallation::route('/create'),
|
||||
// 'edit' => Pages\EditInstallation::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber\Filament\Clusters\Microweber\Resources\InstallationResource\Pages;
|
||||
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
use Modules\Microweber\Filament\Clusters\Microweber\Resources\InstallationResource;
|
||||
|
||||
class CreateInstallation extends CreateRecord
|
||||
{
|
||||
protected static string $resource = InstallationResource::class;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber\Filament\Clusters\Microweber\Resources\InstallationResource\Pages;
|
||||
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\EditRecord;
|
||||
use Modules\Microweber\Filament\Admin\Resources\InstallationResource;
|
||||
|
||||
class EditInstallation extends EditRecord
|
||||
{
|
||||
protected static string $resource = InstallationResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\DeleteAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber\Filament\Clusters\Microweber\Resources\InstallationResource\Pages;
|
||||
|
||||
use App\Models\Domain;
|
||||
use Filament\Actions;
|
||||
use Filament\Resources\Pages\ListRecords;
|
||||
use MicroweberPackages\SharedServerScripts\MicroweberInstallationsScanner;
|
||||
use Modules\Microweber\App\Models\MicroweberInstallation;
|
||||
use Modules\Microweber\Filament\Clusters\Microweber\Resources\InstallationResource;
|
||||
|
||||
class ListInstallations extends ListRecords
|
||||
{
|
||||
protected static string $resource = InstallationResource::class;
|
||||
|
||||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
Actions\Action::make('Scan for installations')->action('scanForInstallations'),
|
||||
];
|
||||
}
|
||||
|
||||
public function scanForInstallations()
|
||||
{
|
||||
$findDomains = Domain::all();
|
||||
foreach ($findDomains as $domain) {
|
||||
|
||||
$scan = new MicroweberInstallationsScanner();
|
||||
$scan->setPath($domain->domain_public);
|
||||
|
||||
$installations = $scan->scanRecusrive();
|
||||
|
||||
if (! empty($installations)) {
|
||||
foreach ($installations as $installation) {
|
||||
|
||||
$findInstallation = MicroweberInstallation::where('installation_path', $installation['path'])
|
||||
->where('domain_id', $domain->id)
|
||||
->first();
|
||||
|
||||
if (! $findInstallation) {
|
||||
$findInstallation = new MicroweberInstallation();
|
||||
$findInstallation->domain_id = $domain->id;
|
||||
$findInstallation->installation_path = $installation['path'];
|
||||
}
|
||||
|
||||
$findInstallation->app_version = $installation['version'];
|
||||
$findInstallation->template = $installation['app_details']['template'];
|
||||
|
||||
if ($installation['is_symlink']) {
|
||||
$findInstallation->installation_type = 'symlink';
|
||||
} else {
|
||||
$findInstallation->installation_type = 'standalone';
|
||||
}
|
||||
|
||||
$findInstallation->save();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$getAppInstallations = MicroweberInstallation::get();
|
||||
if ($getAppInstallations != null) {
|
||||
foreach ($getAppInstallations as $appInstallation) {
|
||||
if (! is_file($appInstallation['installation_path'].'/config/microweber.php')) {
|
||||
$appInstallation->delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber\Filament\Clusters;
|
||||
|
||||
use Filament\Clusters\Cluster;
|
||||
|
||||
class MicroweberCluster extends Cluster
|
||||
{
|
||||
protected static ?string $navigationIcon = 'heroicon-o-squares-2x2';
|
||||
|
||||
protected static ?string $navigationGroup = 'Server Management';
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber\Listeners;
|
||||
|
||||
use App\Events\DomainIsCreated;
|
||||
use App\Models\Domain;
|
||||
use App\Models\HostingPlan;
|
||||
use App\Models\HostingSubscription;
|
||||
use Modules\Microweber\App\Models\MicroweberInstallation;
|
||||
|
||||
class DomainIsCreatedListener
|
||||
{
|
||||
/**
|
||||
* Create the event listener.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*/
|
||||
public function handle(DomainIsCreated $event): void
|
||||
{
|
||||
$findDomain = Domain::where('id', $event->model->id)->first();
|
||||
if (! $findDomain) {
|
||||
return;
|
||||
}
|
||||
$findHostingSubscription = HostingSubscription::where('id', $findDomain->hosting_subscription_id)->first();
|
||||
if (! $findHostingSubscription) {
|
||||
return;
|
||||
}
|
||||
$findHostingPlan = HostingPlan::where('id', $findHostingSubscription->hosting_plan_id)->first();
|
||||
if (! $findHostingPlan) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (! in_array('microweber', $findHostingPlan->additional_services)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// $phyreShellExecutor = new \Modules\Microweber\Shell\Adapters\PhyreShellExecutor();
|
||||
|
||||
$installationType = 'symlink';
|
||||
$installationLanguage = 'bg';
|
||||
$installationTemplate = 'shopmag';
|
||||
|
||||
$install = new \MicroweberPackages\SharedServerScripts\MicroweberInstaller();
|
||||
// $install->setShellExecutor($phyreShellExecutor);
|
||||
$install->setChownUser($findDomain->domain_username);
|
||||
$install->enableChownAfterInstall();
|
||||
|
||||
$install->setPath($findDomain->domain_public);
|
||||
$install->setSourcePath(config('microweber.sharedPaths.app'));
|
||||
|
||||
$install->setLanguage($installationLanguage);
|
||||
$install->setTemplate($installationTemplate);
|
||||
|
||||
// $install->setStandaloneInstallation();
|
||||
$install->setSymlinkInstallation();
|
||||
$install->setDatabaseDriver('sqlite');
|
||||
|
||||
$install->setAdminEmail('bojotjo@abv.bg');
|
||||
$install->setAdminUsername('bojotjo');
|
||||
$install->setAdminPassword('bojotjo');
|
||||
|
||||
$status = $install->run();
|
||||
|
||||
if (isset($status['success']) && $status['success']) {
|
||||
|
||||
$findInstallation = MicroweberInstallation::where('installation_path', $findDomain->domain_public)
|
||||
->where('domain_id', $findDomain->id)
|
||||
->first();
|
||||
|
||||
if (! $findInstallation) {
|
||||
$findInstallation = new MicroweberInstallation();
|
||||
$findInstallation->domain_id = $findDomain->id;
|
||||
$findInstallation->installation_path = $findDomain->domain_public;
|
||||
}
|
||||
|
||||
$findInstallation->app_version = 'latest';
|
||||
$findInstallation->template = $installationTemplate;
|
||||
|
||||
if ($installationType == 'symlink') {
|
||||
$findInstallation->installation_type = 'symlink';
|
||||
} else {
|
||||
$findInstallation->installation_type = 'standalone';
|
||||
}
|
||||
|
||||
$findInstallation->save();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber;
|
||||
|
||||
use App\VirtualHosts\ApacheVirtualHostConfigBase;
|
||||
|
||||
class MicroweberApacheVirtualHostConfig extends ApacheVirtualHostConfigBase
|
||||
{
|
||||
public array $phpAdminValueOpenBaseDirs = [
|
||||
'/usr/share/microweber',
|
||||
];
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber\Providers\Filament;
|
||||
|
||||
use Filament\Http\Middleware\Authenticate;
|
||||
use Filament\Http\Middleware\DisableBladeIconComponents;
|
||||
use Filament\Http\Middleware\DispatchServingFilamentEvent;
|
||||
use Filament\Pages;
|
||||
use Filament\Panel;
|
||||
use Filament\PanelProvider;
|
||||
use Filament\Support\Colors\Color;
|
||||
use Filament\Widgets;
|
||||
use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse;
|
||||
use Illuminate\Cookie\Middleware\EncryptCookies;
|
||||
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken;
|
||||
use Illuminate\Routing\Middleware\SubstituteBindings;
|
||||
use Illuminate\Session\Middleware\AuthenticateSession;
|
||||
use Illuminate\Session\Middleware\StartSession;
|
||||
use Illuminate\View\Middleware\ShareErrorsFromSession;
|
||||
|
||||
class AdminPanelProvider extends PanelProvider
|
||||
{
|
||||
private string $module = 'Microweber';
|
||||
|
||||
public function panel(Panel $panel): Panel
|
||||
{
|
||||
$moduleNamespace = $this->getModuleNamespace();
|
||||
|
||||
return $panel
|
||||
->id('microweber::admin')
|
||||
->path('microweber/admin')
|
||||
->colors([
|
||||
'primary' => Color::Teal,
|
||||
])
|
||||
->discoverResources(in: module_path($this->module, 'Filament/Admin/Resources'), for: "$moduleNamespace\\Filament\\Admin\\Resources")
|
||||
->discoverPages(in: module_path($this->module, 'Filament/Admin/Pages'), for: "$moduleNamespace\\Filament\\Admin\\Pages")
|
||||
->pages([
|
||||
Pages\Dashboard::class,
|
||||
])
|
||||
->discoverWidgets(in: module_path($this->module, 'Filament/Admin/Widgets'), for: "$moduleNamespace\\Filament\\Admin\\Widgets")
|
||||
->widgets([
|
||||
Widgets\AccountWidget::class,
|
||||
Widgets\FilamentInfoWidget::class,
|
||||
])
|
||||
->middleware([
|
||||
EncryptCookies::class,
|
||||
AddQueuedCookiesToResponse::class,
|
||||
StartSession::class,
|
||||
AuthenticateSession::class,
|
||||
ShareErrorsFromSession::class,
|
||||
VerifyCsrfToken::class,
|
||||
SubstituteBindings::class,
|
||||
DisableBladeIconComponents::class,
|
||||
DispatchServingFilamentEvent::class,
|
||||
])
|
||||
->authMiddleware([
|
||||
Authenticate::class,
|
||||
]);
|
||||
}
|
||||
|
||||
protected function getModuleNamespace(): string
|
||||
{
|
||||
return config('modules.namespace').'\\'.$this->module;
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber\Shell\Adapters;
|
||||
|
||||
use App\ShellApi;
|
||||
use MicroweberPackages\SharedServerScripts\Shell\Adapters\IShellExecutor;
|
||||
|
||||
class PhyreShellExecutor implements IShellExecutor
|
||||
{
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function executeFile(string $file, array $args)
|
||||
{
|
||||
$output = ShellApi::exec($file, $args);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
public function executeCommand(array $command, $path, $args)
|
||||
{
|
||||
$commandAsLine = implode(' ', $command);
|
||||
|
||||
// dd([
|
||||
// 'command' => $command,
|
||||
// 'path' => $path,
|
||||
// 'args' => $args,
|
||||
// 'commandAsLine' => $commandAsLine
|
||||
// ]);
|
||||
return ShellApi::exec($commandAsLine);
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
{
|
||||
"name": "phyre/microweber",
|
||||
"description": "",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bozhidar Slaveykov",
|
||||
"email": "selfworksbg@gmail.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"microweber-packages/composer-client": "^1.9",
|
||||
"microweber-packages/shared-server-scripts": "dev-main"
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [],
|
||||
"aliases": {
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Modules\\Microweber\\": "",
|
||||
"Modules\\Microweber\\App\\": "app/",
|
||||
"Modules\\Microweber\\Database\\Factories\\": "database/factories/",
|
||||
"Modules\\Microweber\\Database\\Seeders\\": "database/seeders/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Modules\\Microweber\\Tests\\": "tests/"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
return [
|
||||
'name' => 'Microweber',
|
||||
'sharedPaths' => [
|
||||
'app' => '/usr/share/microweber/latest',
|
||||
'modules' => '/usr/share/microweber/latest/userfiles/modules',
|
||||
'templates' => '/usr/share/microweber/latest/userfiles/templates',
|
||||
],
|
||||
|
||||
];
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"name": "Microweber",
|
||||
"alias": "microweber",
|
||||
"description": "",
|
||||
"keywords": [],
|
||||
"priority": 0,
|
||||
"providers": [
|
||||
"Modules\\Microweber\\App\\Providers\\MicroweberServiceProvider",
|
||||
"Modules\\Microweber\\Providers\\Filament\\AdminPanelProvider"
|
||||
],
|
||||
"files": []
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
{
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"axios": "^1.1.2",
|
||||
"laravel-vite-plugin": "^0.7.5",
|
||||
"sass": "^1.69.5",
|
||||
"postcss": "^8.3.7",
|
||||
"vite": "^4.0.0"
|
||||
}
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
<x-filament-panels::page>
|
||||
|
||||
<x-filament::card>
|
||||
<h3 class="mb-2 text-xl font-bold tracking-tight text-gray-950 dark:text-white sm:text-2xl">
|
||||
Microweber App Version
|
||||
</h3>
|
||||
<p>
|
||||
Your app version is: {{ $appVersion }}<br>
|
||||
Latest app version is: {{ $latestAppVersion }}<br>
|
||||
Latest app download date: {{ $latestAppDownloadDate }}
|
||||
</p>
|
||||
</x-filament::card>
|
||||
|
||||
<x-filament::card>
|
||||
<h3 class="mb-2 text-xl font-bold tracking-tight text-gray-950 dark:text-white sm:text-2xl">
|
||||
Microweber App Templates
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
Available App Templates ({{ $totalAppTemplates }})
|
||||
</p>
|
||||
|
||||
<div class="mt-4">
|
||||
@foreach ($appTemplates as $appTemplate)
|
||||
<span>{{ $appTemplate['name'] }}</span>
|
||||
@if (!$loop->last)
|
||||
,
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
</x-filament::card>
|
||||
|
||||
|
||||
{{-- <div class="p-4 text-white rounded bg-green-500/90 dark:bg-green-500/30">
|
||||
Your app and templates is up-to-date!
|
||||
</div>--}}
|
||||
|
||||
<x-filament::button wire:click="checkForUpdates" class="w-[16rem]">
|
||||
Check for updates
|
||||
</x-filament::button>
|
||||
|
||||
</x-filament-panels::page>
|
|
@ -1,7 +0,0 @@
|
|||
@extends('microweber::layouts.master')
|
||||
|
||||
@section('content')
|
||||
<h1>Hello World</h1>
|
||||
|
||||
<p>Module: {!! config('microweber.name') !!}</p>
|
||||
@endsection
|
|
@ -1,29 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
|
||||
<title>Microweber Module - {{ config('app.name', 'Laravel') }}</title>
|
||||
|
||||
<meta name="description" content="{{ $description ?? '' }}">
|
||||
<meta name="keywords" content="{{ $keywords ?? '' }}">
|
||||
<meta name="author" content="{{ $author ?? '' }}">
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.bunny.net">
|
||||
<link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />
|
||||
|
||||
{{-- Vite CSS --}}
|
||||
{{-- {{ module_vite('build-microweber', 'resources/assets/sass/app.scss') }} --}}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@yield('content')
|
||||
|
||||
{{-- Vite JS --}}
|
||||
{{-- {{ module_vite('build-microweber', 'resources/assets/js/app.js') }} --}}
|
||||
</body>
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| API Routes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you can register API routes for your application. These
|
||||
| routes are loaded by the RouteServiceProvider within a group which
|
||||
| is assigned the "api" middleware group. Enjoy building your API!
|
||||
|
|
||||
*/
|
||||
|
||||
Route::middleware(['auth:sanctum'])->prefix('v1')->name('api.')->group(function () {
|
||||
Route::get('microweber', fn (Request $request) => $request->user())->name('microweber');
|
||||
});
|
|
@ -1,19 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Modules\Microweber\App\Http\Controllers\MicroweberController;
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Web Routes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here is where you can register web routes for your application. These
|
||||
| routes are loaded by the RouteServiceProvider within a group which
|
||||
| contains the "web" middleware group. Now create something great!
|
||||
|
|
||||
*/
|
||||
|
||||
Route::group([], function () {
|
||||
Route::resource('microweber', MicroweberController::class)->names('microweber');
|
||||
});
|
|
@ -1,26 +0,0 @@
|
|||
import { defineConfig } from 'vite';
|
||||
import laravel from 'laravel-vite-plugin';
|
||||
|
||||
export default defineConfig({
|
||||
build: {
|
||||
outDir: '../../public/build-microweber',
|
||||
emptyOutDir: true,
|
||||
manifest: true,
|
||||
},
|
||||
plugins: [
|
||||
laravel({
|
||||
publicDirectory: '../../public',
|
||||
buildDirectory: 'build-microweber',
|
||||
input: [
|
||||
__dirname + '/resources/assets/sass/app.scss',
|
||||
__dirname + '/resources/assets/js/app.js'
|
||||
],
|
||||
refresh: true,
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
//export const paths = [
|
||||
// 'Modules/$STUDLY_NAME$/resources/assets/sass/app.scss',
|
||||
// 'Modules/$STUDLY_NAME$/resources/assets/js/app.js',
|
||||
//];
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue