Compare commits
54 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
feaf2e2e53 | ||
![]() |
ca2320d814 | ||
![]() |
e4bbe14d22 | ||
![]() |
017cc606e4 | ||
![]() |
253bbc5d29 | ||
![]() |
4dac3e94b6 | ||
![]() |
da16176eb8 | ||
![]() |
0d04d49b22 | ||
![]() |
81644287b5 | ||
![]() |
de9c2d774b | ||
![]() |
0ca205963d | ||
![]() |
ae5147bdb1 | ||
![]() |
f3e462e1c2 | ||
![]() |
7cfd6129ed | ||
![]() |
b50571fc22 | ||
![]() |
419e941397 | ||
![]() |
7fcca4f35a | ||
![]() |
cd6af66256 | ||
![]() |
c05545c631 | ||
![]() |
855b4e31c8 | ||
![]() |
fb866221fd | ||
![]() |
d1575a43a3 | ||
![]() |
e4718323be | ||
![]() |
2fe31c7c30 | ||
![]() |
3068292054 | ||
![]() |
ccb60d378e | ||
![]() |
4a4f18f2f8 | ||
![]() |
e1a423e975 | ||
![]() |
9a3e18468b | ||
![]() |
6891b398c5 | ||
![]() |
eb3f2d2803 | ||
![]() |
e891eed89d | ||
![]() |
ee669c1c65 | ||
![]() |
36a43cf767 | ||
![]() |
96353958aa | ||
![]() |
ef9fb0ce4a | ||
![]() |
126a0977d2 | ||
![]() |
d7ad9b8016 | ||
![]() |
12ff24788f | ||
![]() |
1027cd07b6 | ||
![]() |
0c2e03cdb6 | ||
![]() |
90265e9339 | ||
![]() |
df1e5505b4 | ||
![]() |
74cafabdb9 | ||
![]() |
1f58351010 | ||
![]() |
29d8172110 | ||
![]() |
726202d057 | ||
![]() |
2a6e395514 | ||
![]() |
1cb955b6d6 | ||
![]() |
64b0c73fdc | ||
![]() |
f825d63b91 | ||
![]() |
55c98cf6de | ||
![]() |
71222928b9 | ||
![]() |
ad9f885235 |
|
@ -1,13 +1,99 @@
|
|||
# syntax=docker/dockerfile:1
|
||||
# --------------------------------------------------
|
||||
# 1) Base Image
|
||||
# --------------------------------------------------
|
||||
FROM ubuntu:24.04
|
||||
|
||||
FROM ubuntu:22.04 AS production
|
||||
# So apt doesn't prompt us
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
RUN apt-get update && apt-get install -yq wget
|
||||
RUN ls -la
|
||||
RUN wget https://raw.githubusercontent.com/PhyreApps/PhyrePanel/main/installers/install.sh -O phyre-install.sh
|
||||
RUN chmod +x phyre-install.sh
|
||||
RUN ./phyre-install.sh
|
||||
# --------------------------------------------------
|
||||
# 2) Install base dependencies
|
||||
# --------------------------------------------------
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
ca-certificates \
|
||||
wget \
|
||||
curl \
|
||||
netcat \
|
||||
mysql-client \
|
||||
unzip \
|
||||
gnupg2 \
|
||||
lsb-release \
|
||||
apt-transport-https \
|
||||
software-properties-common \
|
||||
libpng-dev \
|
||||
libwebp-dev \
|
||||
libjpeg-turbo8 \
|
||||
libfreetype6 \
|
||||
supervisor && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY entrypoint.sh /usr/local/phyre/entrypoint.sh
|
||||
# --------------------------------------------------
|
||||
# 3) Install Phyre .deb packages
|
||||
# --------------------------------------------------
|
||||
# 3.1 - Add any system libs needed by Phyre (from your script):
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
openssl \
|
||||
libonig-dev \
|
||||
libzip-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libsodium23 \
|
||||
libpq5 \
|
||||
libssl-dev \
|
||||
zlib1g-dev && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENTRYPOINT ["sh","/usr/local/phyre/entrypoint.sh"]
|
||||
WORKDIR /phyre/install
|
||||
|
||||
# 3.2 - Install Phyre PHP
|
||||
RUN wget -q https://github.com/PhyreApps/PhyrePanelPHP/raw/main/compilators/debian/php/dist/phyre-php-8.2.0-ubuntu-22.04.deb && \
|
||||
dpkg -i phyre-php-8.2.0-ubuntu-22.04.deb || (apt-get install -f -y && dpkg -i phyre-php-8.2.0-ubuntu-22.04.deb) && \
|
||||
rm -f phyre-php-8.2.0-ubuntu-22.04.deb
|
||||
|
||||
# 3.3 - Install Phyre NGINX
|
||||
RUN wget -q https://github.com/PhyreApps/PhyrePanelNGINX/raw/main/compilators/debian/nginx/dist/phyre-nginx-1.24.0-ubuntu-22.04.deb && \
|
||||
dpkg -i phyre-nginx-1.24.0-ubuntu-22.04.deb || (apt-get install -f -y && dpkg -i phyre-nginx-1.24.0-ubuntu-22.04.deb) && \
|
||||
rm -f phyre-nginx-1.24.0-ubuntu-22.04.deb && \
|
||||
ln -s /usr/local/phyre/nginx/sbin/phyre-nginx /usr/local/phyre/nginx/sbin/nginx
|
||||
|
||||
# --------------------------------------------------
|
||||
# 4) Symlink & SSL setup
|
||||
# --------------------------------------------------
|
||||
RUN ln -s /usr/local/phyre/php/bin/php /usr/bin/phyre-php
|
||||
|
||||
RUN mkdir -p /usr/local/phyre/ssl && \
|
||||
wget -q https://raw.githubusercontent.com/PhyreApps/PhyrePanel/refs/heads/main/web/server/ssl/phyre.crt -O /usr/local/phyre/ssl/phyre.crt && \
|
||||
wget -q https://raw.githubusercontent.com/PhyreApps/PhyrePanel/refs/heads/main/web/server/ssl/phyre.key -O /usr/local/phyre/ssl/phyre.key && \
|
||||
chmod 644 /usr/local/phyre/ssl/phyre.crt && \
|
||||
chmod 600 /usr/local/phyre/ssl/phyre.key
|
||||
|
||||
# --------------------------------------------------
|
||||
# 5) Download Phyre Web Panel
|
||||
# --------------------------------------------------
|
||||
RUN wget -q https://github.com/PhyreApps/PhyrePanelWebCompiledVersions/raw/main/phyre-web-panel.zip && \
|
||||
unzip -qq -o phyre-web-panel.zip -d /usr/local/phyre/web && \
|
||||
rm -rf phyre-web-panel.zip
|
||||
|
||||
# --------------------------------------------------
|
||||
# 6) Add a custom entrypoint script
|
||||
# that will configure Phyre and run Nginx in foreground
|
||||
# --------------------------------------------------
|
||||
WORKDIR /usr/local/phyre/web
|
||||
|
||||
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
||||
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||
|
||||
# Supervisord config (optional if you want to manage multiple processes)
|
||||
# (But here we can simply run Phyre Nginx in the foreground)
|
||||
#COPY supervisord.conf /etc/supervisor/conf.d/phyre-supervisor.conf
|
||||
|
||||
# Expose HTTP (80) and HTTPS (8443)
|
||||
EXPOSE 80 8443
|
||||
|
||||
# --------------------------------------------------
|
||||
# 7) Set up final Docker config
|
||||
# --------------------------------------------------
|
||||
# We'll run our entrypoint which configures the panel, then runs Nginx
|
||||
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
|
||||
CMD ["phyre-php", "--version"]
|
||||
|
|
46
docker/docker-compose.yml
Normal file
|
@ -0,0 +1,46 @@
|
|||
version: '3.8'
|
||||
|
||||
services:
|
||||
db:
|
||||
image: mysql:8.0
|
||||
container_name: phyre-db
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: exampleRootPass
|
||||
MYSQL_DATABASE: phyrepanel
|
||||
MYSQL_USER: phyre
|
||||
MYSQL_PASSWORD: examplePhyrePass
|
||||
volumes:
|
||||
- db_data:/var/lib/mysql
|
||||
ports:
|
||||
- "3306:3306"
|
||||
networks:
|
||||
- phyre_net
|
||||
|
||||
phyre-app:
|
||||
build: .
|
||||
container_name: phyre-app
|
||||
depends_on:
|
||||
- db
|
||||
ports:
|
||||
- "8443:8443"
|
||||
- "8080:80"
|
||||
environment:
|
||||
# These environment variables are used by our entrypoint
|
||||
DB_HOST: db
|
||||
DB_PORT: 3306
|
||||
DB_DATABASE: phyrepanel
|
||||
DB_USERNAME: phyre
|
||||
DB_PASSWORD: examplePhyrePass
|
||||
# Additional app settings
|
||||
APP_ENV: local
|
||||
APP_URL: "https://localhost:8443"
|
||||
APP_NAME: PhyrePanel
|
||||
networks:
|
||||
- phyre_net
|
||||
|
||||
volumes:
|
||||
db_data:
|
||||
|
||||
networks:
|
||||
phyre_net:
|
||||
driver: bridge
|
|
@ -1,4 +1,33 @@
|
|||
service mysql start
|
||||
service phyre start
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
tail -f /dev/null
|
||||
# Wait for MySQL to be ready
|
||||
echo "Waiting for database at $DB_HOST:$DB_PORT..."
|
||||
while ! nc -z $DB_HOST $DB_PORT; do
|
||||
sleep 2
|
||||
done
|
||||
echo "Database is up!"
|
||||
|
||||
# Configure environment variables
|
||||
phyre-php artisan phyre:set-ini-settings DB_DATABASE "$DB_DATABASE"
|
||||
phyre-php artisan phyre:set-ini-settings DB_USERNAME "$DB_USERNAME"
|
||||
phyre-php artisan phyre:set-ini-settings DB_PASSWORD "$DB_PASSWORD"
|
||||
phyre-php artisan phyre:set-ini-settings DB_HOST "$DB_HOST"
|
||||
phyre-php artisan phyre:set-ini-settings DB_CONNECTION "mysql"
|
||||
phyre-php artisan phyre:set-ini-settings APP_ENV "$APP_ENV"
|
||||
phyre-php artisan phyre:set-ini-settings APP_URL "$APP_URL"
|
||||
phyre-php artisan phyre:set-ini-settings APP_NAME "$APP_NAME"
|
||||
|
||||
# Generate keys, migrate, and seed
|
||||
phyre-php artisan phyre:key-generate
|
||||
phyre-php artisan migrate --force
|
||||
phyre-php artisan db:seed --force
|
||||
|
||||
# Start Nginx in foreground
|
||||
echo "Starting Nginx..."
|
||||
exec /usr/sbin/service phyre start && /usr/local/phyre/nginx/sbin/nginx -g "daemon off;"
|
||||
#exec /usr/sbin/service phyre start
|
||||
|
||||
# Start Supervisor to manage all processes
|
||||
#echo "Starting Supervisor to manage processes..."
|
||||
#exec /usr/bin/supervisord -c /etc/supervisor/conf.d/phyre-supervisor.conf
|
||||
|
|
25
docker/supervisord.conf
Normal file
|
@ -0,0 +1,25 @@
|
|||
[supervisord]
|
||||
nodaemon=true
|
||||
logfile=/var/log/supervisord.log
|
||||
pidfile=/var/run/supervisord.pid
|
||||
|
||||
[program:php-fpm]
|
||||
command=/bin/bash -c 'if ! ps aux | grep "[p]hp-fpm: master process" > /dev/null; then /usr/local/phyre/php/sbin/phyre-php-fpm --nodaemonize; fi'
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/var/log/php-fpm.log
|
||||
stderr_logfile=/var/log/php-fpm.err.log
|
||||
|
||||
[program:phyre]
|
||||
command=/bin/bash -c 'while ! mysqladmin ping -h "$DB_HOST" --silent; do sleep 2; done; if ! ps aux | grep "[s]ervice phyre" > /dev/null; then /usr/sbin/service phyre start; fi'
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/var/log/phyre.log
|
||||
stderr_logfile=/var/log/phyre.err.log
|
||||
|
||||
[program:phyre-nginx]
|
||||
command=/bin/bash -c 'if ! ps aux | grep "[p]hyre-nginx" > /dev/null; then /usr/local/phyre/nginx/sbin/phyre-nginx -g "daemon off;"; fi'
|
||||
autostart=true
|
||||
autorestart=true
|
||||
stdout_logfile=/var/log/phyre-nginx.log
|
||||
stderr_logfile=/var/log/phyre-nginx.err.log
|
|
@ -11,12 +11,12 @@ cd /usr/local/phyre/web
|
|||
|
||||
|
||||
mysql -uroot -proot <<MYSQL_SCRIPT
|
||||
SET GLOBAL validate_password.policy = LOW;
|
||||
SET GLOBAL validate_password.length = 6;
|
||||
SET GLOBAL validate_password.mixed_case_count = 0;
|
||||
SET GLOBAL validate_password.number_count = 0;
|
||||
SET GLOBAL validate_password.special_char_count = 0;
|
||||
FLUSH PRIVILEGES;
|
||||
SET GLOBAL validate_password.policy = LOW;
|
||||
SET GLOBAL validate_password.length = 6;
|
||||
SET GLOBAL validate_password.mixed_case_count = 0;
|
||||
SET GLOBAL validate_password.number_count = 0;
|
||||
SET GLOBAL validate_password.special_char_count = 0;
|
||||
FLUSH PRIVILEGES;
|
||||
MYSQL_SCRIPT
|
||||
|
||||
# Create MySQL user
|
||||
|
|
|
@ -1,180 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
INSTALL_DIR="/phyre/install"
|
||||
|
||||
apt-get update && apt-get install ca-certificates
|
||||
|
||||
mkdir -p $INSTALL_DIR
|
||||
|
||||
cd $INSTALL_DIR
|
||||
|
||||
DEPENDENCIES_LIST=(
|
||||
"openssl"
|
||||
"jq"
|
||||
"curl"
|
||||
"wget"
|
||||
"unzip"
|
||||
"zip"
|
||||
"tar"
|
||||
"mysql-common"
|
||||
"mysql-server"
|
||||
"mysql-client"
|
||||
"lsb-release"
|
||||
"gnupg2"
|
||||
"ca-certificates"
|
||||
"apt-transport-https"
|
||||
"software-properties-common"
|
||||
"supervisor"
|
||||
"libonig-dev"
|
||||
"libzip-dev"
|
||||
"libcurl4-openssl-dev"
|
||||
"libsodium23"
|
||||
"libpq5"
|
||||
"apache2"
|
||||
"libapache2-mod-ruid2"
|
||||
"libapache2-mod-php"
|
||||
"libssl-dev"
|
||||
"zlib1g-dev"
|
||||
)
|
||||
# Check if the dependencies are installed
|
||||
for DEPENDENCY in "${DEPENDENCIES_LIST[@]}"; do
|
||||
apt install -yq $DEPENDENCY
|
||||
done
|
||||
|
||||
# Start MySQL
|
||||
service mysql start
|
||||
|
||||
mkdir -p /usr/local/phyre/ssl
|
||||
|
||||
wget https://raw.githubusercontent.com/PhyreApps/PhyrePanel/refs/heads/main/web/server/ssl/phyre.crt -O /usr/local/phyre/ssl/phyre.crt
|
||||
wget https://raw.githubusercontent.com/PhyreApps/PhyrePanel/refs/heads/main/web/server/ssl/phyre.key -O /usr/local/phyre/ssl/phyre.key
|
||||
|
||||
sudo chmod 644 /usr/local/phyre/ssl/phyre.crt
|
||||
sudo chmod 600 /usr/local/phyre/ssl/phyre.key
|
||||
|
||||
wget https://raw.githubusercontent.com/PhyreApps/PhyrePanel/main/installers/ubuntu-20.04/greeting.sh -O /etc/profile.d/phyre-greeting.sh
|
||||
|
||||
# Install PHYRE PHP
|
||||
wget https://github.com/PhyreApps/PhyrePanelPHP/raw/main/compilators/debian/php/dist/phyre-php-8.2.0-ubuntu-20.04.deb
|
||||
dpkg -i phyre-php-8.2.0-ubuntu-20.04.deb
|
||||
|
||||
# Install PHYRE NGINX
|
||||
wget https://github.com/PhyreApps/PhyrePanelNGINX/raw/main/compilators/debian/nginx/dist/phyre-nginx-1.24.0-ubuntu-20.04.deb
|
||||
dpkg -i phyre-nginx-1.24.0-ubuntu-20.04.deb
|
||||
|
||||
PHYRE_PHP=/usr/local/phyre/php/bin/php
|
||||
|
||||
ln -s $PHYRE_PHP /usr/bin/phyre-php
|
||||
#!/bin/bash
|
||||
|
||||
HOSTNAME=$(hostname)
|
||||
IP_ADDRESS=$(hostname -I | cut -d " " -f 1)
|
||||
|
||||
DISTRO_VERSION=$(cat /etc/os-release | grep -w "VERSION_ID" | cut -d "=" -f 2)
|
||||
DISTRO_VERSION=${DISTRO_VERSION//\"/} # Remove quotes from version string
|
||||
|
||||
DISTRO_NAME=$(cat /etc/os-release | grep -w "NAME" | cut -d "=" -f 2)
|
||||
DISTRO_NAME=${DISTRO_NAME//\"/} # Remove quotes from name string
|
||||
|
||||
LOG_JSON='{"os": "'$DISTRO_NAME-$DISTRO_VERSION'", "host_name": "'$HOSTNAME'", "ip": "'$IP_ADDRESS'"}'
|
||||
|
||||
curl -s https://phyrepanel.com/api/phyre-installation-log -X POST -H "Content-Type: application/json" -d "$LOG_JSON"
|
||||
#!/bin/bash
|
||||
|
||||
wget https://github.com/PhyreApps/PhyrePanelWebCompiledVersions/raw/main/phyre-web-panel.zip
|
||||
unzip -qq -o phyre-web-panel.zip -d /usr/local/phyre/web
|
||||
rm -rf phyre-web-panel.zip
|
||||
|
||||
chmod 711 /home
|
||||
chmod -R 750 /usr/local/phyre
|
||||
#!/bin/bash
|
||||
|
||||
# Check dir exists
|
||||
if [ ! -d "/usr/local/phyre/web" ]; then
|
||||
echo "PhyrePanel directory not found."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Go to web directory
|
||||
cd /usr/local/phyre/web
|
||||
|
||||
|
||||
mysql -uroot -proot <<MYSQL_SCRIPT
|
||||
SET GLOBAL validate_password.policy = LOW;
|
||||
SET GLOBAL validate_password.length = 6;
|
||||
SET GLOBAL validate_password.mixed_case_count = 0;
|
||||
SET GLOBAL validate_password.number_count = 0;
|
||||
SET GLOBAL validate_password.special_char_count = 0;
|
||||
FLUSH PRIVILEGES;
|
||||
MYSQL_SCRIPT
|
||||
|
||||
# Create MySQL user
|
||||
MYSQL_PHYRE_ROOT_USERNAME="phyre"
|
||||
MYSQL_PHYRE_ROOT_PASSWORD="$(tr -dc a-za-z0-9 </dev/urandom | head -c 32; echo)"
|
||||
|
||||
mysql -uroot -proot <<MYSQL_SCRIPT
|
||||
CREATE USER '$MYSQL_PHYRE_ROOT_USERNAME'@'%' IDENTIFIED BY '$MYSQL_PHYRE_ROOT_PASSWORD';
|
||||
GRANT ALL PRIVILEGES ON *.* TO '$MYSQL_PHYRE_ROOT_USERNAME'@'%' WITH GRANT OPTION;
|
||||
FLUSH PRIVILEGES;
|
||||
MYSQL_SCRIPT
|
||||
|
||||
|
||||
# Create database
|
||||
PHYRE_PANEL_DB_PASSWORD="$(tr -dc a-za-z0-9 </dev/urandom | head -c 32; echo)"
|
||||
PHYRE_PANEL_DB_NAME="phyre$(tr -dc a-za-z0-9 </dev/urandom | head -c 13; echo)"
|
||||
PHYRE_PANEL_DB_USER="phyre$(tr -dc a-za-z0-9 </dev/urandom | head -c 13; echo)"
|
||||
|
||||
mysql -uroot -proot <<MYSQL_SCRIPT
|
||||
CREATE DATABASE $PHYRE_PANEL_DB_NAME;
|
||||
CREATE USER '$PHYRE_PANEL_DB_USER'@'localhost' IDENTIFIED BY '$PHYRE_PANEL_DB_PASSWORD';
|
||||
GRANT ALL PRIVILEGES ON $PHYRE_PANEL_DB_NAME.* TO '$PHYRE_PANEL_DB_USER'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
MYSQL_SCRIPT
|
||||
|
||||
mysql_secure_installation --use-default
|
||||
|
||||
# Change mysql root password
|
||||
MYSQL_ROOT_PASSWORD="$(tr -dc a-za-z0-9 </dev/urandom | head -c 32; echo)"
|
||||
mysql -uroot -proot <<MYSQL_SCRIPT
|
||||
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password by '$MYSQL_ROOT_PASSWORD';
|
||||
FLUSH PRIVILEGES;
|
||||
MYSQL_SCRIPT
|
||||
|
||||
# Save mysql root password
|
||||
echo "$MYSQL_ROOT_PASSWORD" > /root/.mysql_root_password
|
||||
|
||||
# Configure the application
|
||||
phyre-php artisan phyre:set-ini-settings APP_ENV "local"
|
||||
phyre-php artisan phyre:set-ini-settings APP_URL "127.0.0.1:8443"
|
||||
phyre-php artisan phyre:set-ini-settings APP_NAME "PHYRE_PANEL"
|
||||
phyre-php artisan phyre:set-ini-settings DB_DATABASE "$PHYRE_PANEL_DB_NAME"
|
||||
phyre-php artisan phyre:set-ini-settings DB_USERNAME "$PHYRE_PANEL_DB_USER"
|
||||
phyre-php artisan phyre:set-ini-settings DB_PASSWORD "$PHYRE_PANEL_DB_PASSWORD"
|
||||
phyre-php artisan phyre:set-ini-settings DB_CONNECTION "mysql"
|
||||
phyre-php artisan phyre:set-ini-settings MYSQL_ROOT_USERNAME "$MYSQL_PHYRE_ROOT_USERNAME"
|
||||
phyre-php artisan phyre:set-ini-settings MYSQL_ROOT_PASSWORD "$MYSQL_PHYRE_ROOT_PASSWORD"
|
||||
phyre-php artisan phyre:key-generate
|
||||
|
||||
phyre-php artisan migrate
|
||||
phyre-php artisan db:seed
|
||||
|
||||
phyre-php artisan phyre:set-ini-settings APP_ENV "production"
|
||||
|
||||
chmod -R o+w /usr/local/phyre/web/storage/
|
||||
chmod -R o+w /usr/local/phyre/web/bootstrap/cache/
|
||||
|
||||
|
||||
service phyre start
|
||||
|
||||
CURRENT_IP=$(hostname -I | awk '{print $1}')
|
||||
|
||||
echo "PhyrePanel downloaded successfully."
|
||||
|
||||
# Parse argument --dont-ask
|
||||
if [ "$1" == "--dont-ask" ]; then
|
||||
echo "PhyrePanel is now available at https://$CURRENT_IP:8443"
|
||||
exit 0
|
||||
else
|
||||
phyre-php artisan phyre:install-apache
|
||||
phyre-php artisan phyre:setup-master-domain-ssl
|
||||
fi
|
|
@ -1,182 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
INSTALL_DIR="/phyre/install"
|
||||
|
||||
apt-get update && apt-get install ca-certificates
|
||||
|
||||
mkdir -p $INSTALL_DIR
|
||||
|
||||
cd $INSTALL_DIR
|
||||
|
||||
DEPENDENCIES_LIST=(
|
||||
"openssl"
|
||||
"jq"
|
||||
"curl"
|
||||
"wget"
|
||||
"unzip"
|
||||
"zip"
|
||||
"tar"
|
||||
"mysql-common"
|
||||
"mysql-server"
|
||||
"mysql-client"
|
||||
"lsb-release"
|
||||
"gnupg2"
|
||||
"ca-certificates"
|
||||
"apt-transport-https"
|
||||
"software-properties-common"
|
||||
"supervisor"
|
||||
"libonig-dev"
|
||||
"libzip-dev"
|
||||
"libcurl4-openssl-dev"
|
||||
"libsodium23"
|
||||
"libpq5"
|
||||
"apache2"
|
||||
"libapache2-mod-ruid2"
|
||||
"libapache2-mod-php"
|
||||
"libssl-dev"
|
||||
"zlib1g-dev"
|
||||
)
|
||||
# Check if the dependencies are installed
|
||||
for DEPENDENCY in "${DEPENDENCIES_LIST[@]}"; do
|
||||
apt install -yq $DEPENDENCY
|
||||
done
|
||||
|
||||
# Start MySQL
|
||||
service mysql start
|
||||
|
||||
mkdir -p /usr/local/phyre/ssl
|
||||
|
||||
wget https://raw.githubusercontent.com/PhyreApps/PhyrePanel/refs/heads/main/web/server/ssl/phyre.crt -O /usr/local/phyre/ssl/phyre.crt
|
||||
wget https://raw.githubusercontent.com/PhyreApps/PhyrePanel/refs/heads/main/web/server/ssl/phyre.key -O /usr/local/phyre/ssl/phyre.key
|
||||
|
||||
sudo chmod 644 /usr/local/phyre/ssl/phyre.crt
|
||||
sudo chmod 600 /usr/local/phyre/ssl/phyre.key
|
||||
|
||||
wget https://raw.githubusercontent.com/PhyreApps/PhyrePanel/main/installers/ubuntu-22.04/greeting.sh -O /etc/profile.d/phyre-greeting.sh
|
||||
|
||||
# Install PHYRE PHP
|
||||
wget https://github.com/PhyreApps/PhyrePanelPHP/raw/main/compilators/debian/php/dist/phyre-php-8.2.0-ubuntu-22.04.deb
|
||||
dpkg -i phyre-php-8.2.0-ubuntu-22.04.deb
|
||||
|
||||
# Install PHYRE NGINX
|
||||
wget https://github.com/PhyreApps/PhyrePanelNGINX/raw/main/compilators/debian/nginx/dist/phyre-nginx-1.24.0-ubuntu-22.04.deb
|
||||
dpkg -i phyre-nginx-1.24.0-ubuntu-22.04.deb
|
||||
|
||||
PHYRE_PHP=/usr/local/phyre/php/bin/php
|
||||
|
||||
ln -s $PHYRE_PHP /usr/bin/phyre-php
|
||||
|
||||
curl -s https://phyrepanel.com/api/phyre-installation-log -X POST -H "Content-Type: application/json" -d '{"os": "ubuntu-22.04"}'
|
||||
#!/bin/bash
|
||||
|
||||
HOSTNAME=$(hostname)
|
||||
IP_ADDRESS=$(hostname -I | cut -d " " -f 1)
|
||||
|
||||
DISTRO_VERSION=$(cat /etc/os-release | grep -w "VERSION_ID" | cut -d "=" -f 2)
|
||||
DISTRO_VERSION=${DISTRO_VERSION//\"/} # Remove quotes from version string
|
||||
|
||||
DISTRO_NAME=$(cat /etc/os-release | grep -w "NAME" | cut -d "=" -f 2)
|
||||
DISTRO_NAME=${DISTRO_NAME//\"/} # Remove quotes from name string
|
||||
|
||||
LOG_JSON='{"os": "'$DISTRO_NAME-$DISTRO_VERSION'", "host_name": "'$HOSTNAME'", "ip": "'$IP_ADDRESS'"}'
|
||||
|
||||
curl -s https://phyrepanel.com/api/phyre-installation-log -X POST -H "Content-Type: application/json" -d "$LOG_JSON"
|
||||
#!/bin/bash
|
||||
|
||||
wget https://github.com/PhyreApps/PhyrePanelWebCompiledVersions/raw/main/phyre-web-panel.zip
|
||||
unzip -qq -o phyre-web-panel.zip -d /usr/local/phyre/web
|
||||
rm -rf phyre-web-panel.zip
|
||||
|
||||
chmod 711 /home
|
||||
chmod -R 750 /usr/local/phyre
|
||||
#!/bin/bash
|
||||
|
||||
# Check dir exists
|
||||
if [ ! -d "/usr/local/phyre/web" ]; then
|
||||
echo "PhyrePanel directory not found."
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Go to web directory
|
||||
cd /usr/local/phyre/web
|
||||
|
||||
|
||||
mysql -uroot -proot <<MYSQL_SCRIPT
|
||||
SET GLOBAL validate_password.policy = LOW;
|
||||
SET GLOBAL validate_password.length = 6;
|
||||
SET GLOBAL validate_password.mixed_case_count = 0;
|
||||
SET GLOBAL validate_password.number_count = 0;
|
||||
SET GLOBAL validate_password.special_char_count = 0;
|
||||
FLUSH PRIVILEGES;
|
||||
MYSQL_SCRIPT
|
||||
|
||||
# Create MySQL user
|
||||
MYSQL_PHYRE_ROOT_USERNAME="phyre"
|
||||
MYSQL_PHYRE_ROOT_PASSWORD="$(tr -dc a-za-z0-9 </dev/urandom | head -c 32; echo)"
|
||||
|
||||
mysql -uroot -proot <<MYSQL_SCRIPT
|
||||
CREATE USER '$MYSQL_PHYRE_ROOT_USERNAME'@'%' IDENTIFIED BY '$MYSQL_PHYRE_ROOT_PASSWORD';
|
||||
GRANT ALL PRIVILEGES ON *.* TO '$MYSQL_PHYRE_ROOT_USERNAME'@'%' WITH GRANT OPTION;
|
||||
FLUSH PRIVILEGES;
|
||||
MYSQL_SCRIPT
|
||||
|
||||
|
||||
# Create database
|
||||
PHYRE_PANEL_DB_PASSWORD="$(tr -dc a-za-z0-9 </dev/urandom | head -c 32; echo)"
|
||||
PHYRE_PANEL_DB_NAME="phyre$(tr -dc a-za-z0-9 </dev/urandom | head -c 13; echo)"
|
||||
PHYRE_PANEL_DB_USER="phyre$(tr -dc a-za-z0-9 </dev/urandom | head -c 13; echo)"
|
||||
|
||||
mysql -uroot -proot <<MYSQL_SCRIPT
|
||||
CREATE DATABASE $PHYRE_PANEL_DB_NAME;
|
||||
CREATE USER '$PHYRE_PANEL_DB_USER'@'localhost' IDENTIFIED BY '$PHYRE_PANEL_DB_PASSWORD';
|
||||
GRANT ALL PRIVILEGES ON $PHYRE_PANEL_DB_NAME.* TO '$PHYRE_PANEL_DB_USER'@'localhost';
|
||||
FLUSH PRIVILEGES;
|
||||
MYSQL_SCRIPT
|
||||
|
||||
mysql_secure_installation --use-default
|
||||
|
||||
# Change mysql root password
|
||||
MYSQL_ROOT_PASSWORD="$(tr -dc a-za-z0-9 </dev/urandom | head -c 32; echo)"
|
||||
mysql -uroot -proot <<MYSQL_SCRIPT
|
||||
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password by '$MYSQL_ROOT_PASSWORD';
|
||||
FLUSH PRIVILEGES;
|
||||
MYSQL_SCRIPT
|
||||
|
||||
# Save mysql root password
|
||||
echo "$MYSQL_ROOT_PASSWORD" > /root/.mysql_root_password
|
||||
|
||||
# Configure the application
|
||||
phyre-php artisan phyre:set-ini-settings APP_ENV "local"
|
||||
phyre-php artisan phyre:set-ini-settings APP_URL "127.0.0.1:8443"
|
||||
phyre-php artisan phyre:set-ini-settings APP_NAME "PHYRE_PANEL"
|
||||
phyre-php artisan phyre:set-ini-settings DB_DATABASE "$PHYRE_PANEL_DB_NAME"
|
||||
phyre-php artisan phyre:set-ini-settings DB_USERNAME "$PHYRE_PANEL_DB_USER"
|
||||
phyre-php artisan phyre:set-ini-settings DB_PASSWORD "$PHYRE_PANEL_DB_PASSWORD"
|
||||
phyre-php artisan phyre:set-ini-settings DB_CONNECTION "mysql"
|
||||
phyre-php artisan phyre:set-ini-settings MYSQL_ROOT_USERNAME "$MYSQL_PHYRE_ROOT_USERNAME"
|
||||
phyre-php artisan phyre:set-ini-settings MYSQL_ROOT_PASSWORD "$MYSQL_PHYRE_ROOT_PASSWORD"
|
||||
phyre-php artisan phyre:key-generate
|
||||
|
||||
phyre-php artisan migrate
|
||||
phyre-php artisan db:seed
|
||||
|
||||
phyre-php artisan phyre:set-ini-settings APP_ENV "production"
|
||||
|
||||
chmod -R o+w /usr/local/phyre/web/storage/
|
||||
chmod -R o+w /usr/local/phyre/web/bootstrap/cache/
|
||||
|
||||
|
||||
service phyre start
|
||||
|
||||
CURRENT_IP=$(hostname -I | awk '{print $1}')
|
||||
|
||||
echo "PhyrePanel downloaded successfully."
|
||||
|
||||
# Parse argument --dont-ask
|
||||
if [ "$1" == "--dont-ask" ]; then
|
||||
echo "PhyrePanel is now available at https://$CURRENT_IP:8443"
|
||||
exit 0
|
||||
else
|
||||
phyre-php artisan phyre:install-apache
|
||||
phyre-php artisan phyre:setup-master-domain-ssl
|
||||
fi
|
|
@ -102,12 +102,12 @@ cd /usr/local/phyre/web
|
|||
|
||||
|
||||
mysql -uroot -proot <<MYSQL_SCRIPT
|
||||
SET GLOBAL validate_password.policy = LOW;
|
||||
SET GLOBAL validate_password.length = 6;
|
||||
SET GLOBAL validate_password.mixed_case_count = 0;
|
||||
SET GLOBAL validate_password.number_count = 0;
|
||||
SET GLOBAL validate_password.special_char_count = 0;
|
||||
FLUSH PRIVILEGES;
|
||||
SET GLOBAL validate_password.policy = LOW;
|
||||
SET GLOBAL validate_password.length = 6;
|
||||
SET GLOBAL validate_password.mixed_case_count = 0;
|
||||
SET GLOBAL validate_password.number_count = 0;
|
||||
SET GLOBAL validate_password.special_char_count = 0;
|
||||
FLUSH PRIVILEGES;
|
||||
MYSQL_SCRIPT
|
||||
|
||||
# Create MySQL user
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.1.4
|
||||
0.1.7
|
|
@ -4,7 +4,7 @@
|
|||
"description": "",
|
||||
"keywords": [],
|
||||
"priority": 0,
|
||||
"logoIcon": "email-logo",
|
||||
"logoIcon": "Modules/Email/resources/assets/email-svg/logo.svg",
|
||||
"category": "DevOps",
|
||||
"adminUrl": "/admin/email",
|
||||
"providers": [
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 20 20">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="50px" height="50px" viewBox="0 0 20 20">
|
||||
<path fill="currentColor" d="M18 2a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V4c0-1.1.9-2 2-2zm-4.37 9.1L20 16v-2l-5.12-3.9L20 6V4l-10 8L0 4v2l5.12 4.1L0 14v2l6.37-4.9L10 14z" />
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 280 B After Width: | Height: | Size: 284 B |
|
@ -15,4 +15,11 @@ class MicroweberInstallation extends Model
|
|||
return $this->hasOne(Domain::class, 'id', 'domain_id');
|
||||
}
|
||||
|
||||
public function getTemplateAttribute()
|
||||
{
|
||||
if (empty($this->template)) {
|
||||
return 'Default';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ class Version extends Page
|
|||
|
||||
protected static ?string $cluster = MicroweberCluster::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
protected static ?string $navigationIcon = 'mw-mw_logo_small_white';
|
||||
|
||||
protected static string $view = 'microweber::filament.admin.pages.version';
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ class InstallationResource extends Resource
|
|||
{
|
||||
protected static ?string $model = MicroweberInstallation::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-rectangle-stack';
|
||||
protected static ?string $navigationIcon = 'heroicon-o-globe-americas';
|
||||
|
||||
protected static ?string $navigationGroup = 'Microweber';
|
||||
|
||||
|
@ -49,12 +49,13 @@ class InstallationResource extends Resource
|
|||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
|
||||
// Tables\Actions\EditAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
// Tables\Actions\BulkActionGroup::make([
|
||||
// Tables\Actions\DeleteBulkAction::make(),
|
||||
// ]),
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ class ListInstallations extends ListRecords
|
|||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
// Actions\CreateAction::make(),
|
||||
Actions\Action::make('Scan for installations')->action('scanForInstallations'),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -43,7 +43,15 @@ class DomainIsCreatedListener
|
|||
return;
|
||||
}
|
||||
|
||||
if (!in_array('microweber', $findHostingPlan->additional_services)) {
|
||||
$skip = true;
|
||||
if (in_array('microweber', $findHostingPlan->additional_services)) {
|
||||
$skip = false;
|
||||
}
|
||||
if (in_array('microweber_custom', $findHostingPlan->additional_services)) {
|
||||
$skip = false;
|
||||
}
|
||||
|
||||
if ($skip) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -155,11 +163,19 @@ class DomainIsCreatedListener
|
|||
|
||||
$username = Str::random(8);
|
||||
|
||||
$install->setAdminEmail($username . '@'.$emailDomain);
|
||||
$install->setAdminUsername($username);
|
||||
$install->setAdminPassword(Str::random(8));
|
||||
|
||||
$install->setPhpSbin($phpSbin);
|
||||
|
||||
if (in_array('microweber_custom', $findHostingPlan->additional_services)) {
|
||||
$install->setAdminEmail(null);
|
||||
$install->setAdminUsername(null);
|
||||
$install->setAdminPassword(null);
|
||||
} else {
|
||||
$install->setAdminEmail($username . '@'.$emailDomain);
|
||||
$install->setAdminUsername($username);
|
||||
$install->setAdminPassword(Str::random(8));
|
||||
}
|
||||
|
||||
$status = $install->run();
|
||||
|
||||
if (isset($status['success']) && $status['success']) {
|
||||
|
|
44
web/Modules/Microweber/Listeners/DomainIsDeletedListener.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\Microweber\Listeners;
|
||||
|
||||
use App\Events\DomainIsCreated;
|
||||
use App\Events\DomainIsDeleted;
|
||||
use App\Models\Database;
|
||||
use App\Models\DatabaseUser;
|
||||
use App\Models\Domain;
|
||||
use App\Models\HostingPlan;
|
||||
use App\Models\HostingSubscription;
|
||||
use App\Services\HostingSubscriptionService;
|
||||
use App\SupportedApplicationTypes;
|
||||
use Illuminate\Support\Str;
|
||||
use MicroweberPackages\SharedServerScripts\MicroweberWhitelabelSettingsUpdater;
|
||||
use MicroweberPackages\SharedServerScripts\MicroweberWhitelabelWebsiteApply;
|
||||
use Modules\Microweber\App\Actions\MicroweberScanner;
|
||||
use Modules\Microweber\App\Models\MicroweberInstallation;
|
||||
|
||||
class DomainIsDeletedListener
|
||||
{
|
||||
/**
|
||||
* Create the event listener.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the event.
|
||||
*/
|
||||
public function handle(DomainIsDeleted $event): void
|
||||
{
|
||||
|
||||
try {
|
||||
$newMwScan = new MicroweberScanner();
|
||||
$newMwScan->handle();
|
||||
} catch (\Exception $e) {
|
||||
\Log::error($e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -9,7 +9,7 @@
|
|||
],
|
||||
"require": {
|
||||
"microweber-packages/composer-client": "^2.1",
|
||||
"microweber-packages/shared-server-scripts": "^1.0"
|
||||
"microweber-packages/shared-server-scripts": "^1.1"
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
|
|
6
web/Modules/Microweber/composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "33fca0326c53e60447e2cc2780a12cd0",
|
||||
"content-hash": "33409785a55bd5b1d18a3b7db9f4a7d0",
|
||||
"packages": [
|
||||
{
|
||||
"name": "microweber-packages/composer-client",
|
||||
|
@ -55,7 +55,7 @@
|
|||
},
|
||||
{
|
||||
"name": "microweber-packages/shared-server-scripts",
|
||||
"version": "1.0",
|
||||
"version": "1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/microweber-packages/shared-server-scripts.git",
|
||||
|
@ -103,7 +103,7 @@
|
|||
"support": {
|
||||
"email": "support@microweber.com",
|
||||
"issues": "https://github.com/microweber-packages/shared-server-scripts/issues",
|
||||
"source": "https://github.com/microweber-packages/shared-server-scripts/tree/1.0"
|
||||
"source": "https://github.com/microweber-packages/shared-server-scripts/tree/1.1"
|
||||
},
|
||||
"time": "2025-02-07T13:17:21+00:00"
|
||||
},
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"description": "",
|
||||
"keywords": [],
|
||||
"priority": 0,
|
||||
"logoIcon": "mw-mw_logo_small_white",
|
||||
"logoIcon": "Modules/Microweber/resources/assets/mw-svg/mw_logo_small_white.svg",
|
||||
"category": "Content Management",
|
||||
"adminUrl": "/admin/microweber/installations",
|
||||
"providers": [
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generator: Adobe Illustrator 22.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||
<svg version="1.1" width="50px" height="50px" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 50 50" style="enable-background:new 0 0 50 50;" xml:space="preserve">
|
||||
|
||||
<path fill="currentColor" d="M47.5,37.9C47.5,37.9,47.5,37.9,47.5,37.9c-0.4,0.8-0.9,1.5-1.5,2.2c0,0,0,0,0,0c-1.1,1.3-2.5,2.2-4.2,2.7 L25.2,48c-0.7,0.2-1.5,0.1-2.2-0.3c-0.6-0.4-1.1-1.1-1.1-1.9l-3-32.8l0.7,0.1l1.5,0.1l3,0.2c0.9,0.1,1.7,0.8,1.8,1.6l3.1,24.1 l6.3-1.4L31.6,14l0.7,0.1l1.1,0.1l2.1,0.2c0.7,0.1,1.3,0.7,1.5,1.3l3.7,20.8l4.8-1.1l-4.2-20.7c-0.5-2.6-2.9-4.9-5.4-5.2L13.6,6.5 c-0.8-0.1-1.5,0.1-2.1,0.7c-0.6,0.5-0.9,1.3-0.8,2l2,37.2l0.1,2.1l0,0.8C6.4,47.9,1.6,42.7,1.6,35.9L1.4,11.7c0-2.9,1.1-5.4,3-7.1 C6.1,3,8.4,1.9,11,1.4c2.1-0.4,4.4-0.4,6.7,0.1l17.3,3.4c4.9,0.9,9.3,5.4,10.3,10.2l3.1,14.3C49.2,32.3,48.8,35.4,47.5,37.9z"/>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 985 B After Width: | Height: | Size: 1,013 B |
114
web/Modules/SSLManager/App/Console/RenewSSL.php
Normal file
|
@ -0,0 +1,114 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\SSLManager\App\Console;
|
||||
|
||||
use App\Jobs\ApacheBuild;
|
||||
use App\Models\CronJob;
|
||||
use App\Models\Domain;
|
||||
use Illuminate\Console\Command;
|
||||
use Modules\SSLManager\App\Jobs\SecureDomain;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
|
||||
class RenewSSL extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*/
|
||||
protected $signature = 'ssl-manager:renew-ssl';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*/
|
||||
protected $description = 'Renew SSL certificates';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
|
||||
$this->_checkForAutoRenewalCron();
|
||||
|
||||
$getDomains = Domain::where('status', Domain::STATUS_ACTIVE)
|
||||
->get();
|
||||
if ($getDomains->count() > 0) {
|
||||
foreach ($getDomains as $domain) {
|
||||
$checkDomainStatus = $this->_checkForSSL($domain->domain);
|
||||
if ($checkDomainStatus) {
|
||||
$this->info('SSL certificate for ' . $domain->domain . ' is valid');
|
||||
} else {
|
||||
$this->info('SSL certificate for ' . $domain->domain . ' is expired');
|
||||
try {
|
||||
$this->_renewSSL($domain);
|
||||
} catch (\Exception $e) {
|
||||
$this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rebuild Apache configuration
|
||||
$this->info('Rebuilding Apache configuration');
|
||||
$apacheBuild = new ApacheBuild(true);
|
||||
$apacheBuild->handle();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function _renewSSL($domain)
|
||||
{
|
||||
// Renew SSL
|
||||
$this->info('Renewing SSL certificate for ' . $domain->domain);
|
||||
|
||||
$run = new SecureDomain($domain->id);
|
||||
$run->handle();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function _checkForSSL($domain)
|
||||
{
|
||||
|
||||
// Check with CURL
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, "https://" . $domain);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
|
||||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
|
||||
|
||||
$data = curl_exec($ch);
|
||||
|
||||
$sslInfo = curl_getinfo($ch);
|
||||
|
||||
if ($sslInfo['http_code'] == 200) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public function _checkForAutoRenewalCron()
|
||||
{
|
||||
$cronJobCommand = 'phyre-php /usr/local/phyre/web/artisan ssl-manager:renew-ssl';
|
||||
$findCronJob = CronJob::where('command', $cronJobCommand)->first();
|
||||
if (! $findCronJob) {
|
||||
$cronJob = new CronJob();
|
||||
$cronJob->schedule = '0 0 * * *';
|
||||
$cronJob->command = $cronJobCommand;
|
||||
$cronJob->user = 'root';
|
||||
$cronJob->save();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -21,13 +21,13 @@ use Filament\Notifications\Notification;
|
|||
|
||||
class WildcardIssuer extends Page
|
||||
{
|
||||
protected static ?string $navigationGroup = 'SSL Manager';
|
||||
protected static ?string $navigationGroup = 'SSL Manager';
|
||||
|
||||
protected static ?string $navigationIcon = null;
|
||||
|
||||
protected static ?int $navigationSort = 2;
|
||||
protected static ?int $navigationSort = 2;
|
||||
|
||||
public $poolingInstallLog = true;
|
||||
public $poolingInstallLog = true;
|
||||
public $installLog = '';
|
||||
public $installLogFilePath = '/var/www/acme-wildcard-install.log';
|
||||
public $installInstructions = [];
|
||||
|
@ -73,7 +73,7 @@ class WildcardIssuer extends Page
|
|||
public function requestCertificates() {
|
||||
|
||||
$wildcardDomain = $this->wildcardDomain;
|
||||
$wildcardDomain = str_replace('*.', '', $wildcardDomain);
|
||||
$wildcardDomain = str_replace('*.', '', $wildcardDomain);
|
||||
|
||||
if (file_exists($this->installLogFilePath)) {
|
||||
unlink($this->installLogFilePath);
|
||||
|
@ -93,7 +93,7 @@ class WildcardIssuer extends Page
|
|||
|
||||
public function installCertificates()
|
||||
{
|
||||
|
||||
|
||||
$wildcardDomain = $this->wildcardDomain;
|
||||
$wildcardDomain = str_replace('*.', '', $wildcardDomain);
|
||||
|
||||
|
@ -159,7 +159,7 @@ class WildcardIssuer extends Page
|
|||
$acmeChallangeDomain = str_replace('Domain: ', '', $acmeChallangeDomain);
|
||||
$acmeChallangeTxtValue = str_replace('TXT value: ', '', $acmeChallangeTxtValue);
|
||||
$this->installInstructions = [
|
||||
'acmeChallangeDomain' => $acmeChallangeDomain,
|
||||
'acmeChallangeDomain' => $acmeChallangeDomain,
|
||||
'acmeChallangeTxtValue' => $acmeChallangeTxtValue,
|
||||
];
|
||||
$this->poolingInstallLog = false;
|
||||
|
@ -199,7 +199,7 @@ class WildcardIssuer extends Page
|
|||
->default(setting('general.master_email'))
|
||||
->helperText('Email address for notifications')
|
||||
->placeholder('master@example.com'),
|
||||
|
||||
|
||||
|
||||
])->afterValidation(function () {
|
||||
if (file_exists($this->installLogFilePath)) {
|
||||
|
|
|
@ -46,15 +46,24 @@ class CertificateResource extends Resource
|
|||
->sortable(),
|
||||
TextColumn::make('is_active')
|
||||
->badge()
|
||||
->formatStateUsing(function ($state) {
|
||||
return $state ? 'Active' : 'Inactive';
|
||||
})
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('is_wildcard')
|
||||
->badge()
|
||||
->formatStateUsing(function ($state) {
|
||||
return $state ? 'Wildcard' : 'Standard';
|
||||
})
|
||||
->searchable()
|
||||
->sortable(),
|
||||
|
||||
TextColumn::make('provider')
|
||||
->searchable()
|
||||
->formatStateUsing(function ($state) {
|
||||
return strtoupper($state);
|
||||
})
|
||||
->sortable(),
|
||||
|
||||
])
|
||||
|
@ -62,12 +71,13 @@ class CertificateResource extends Resource
|
|||
//
|
||||
])
|
||||
->actions([
|
||||
Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
// Tables\Actions\EditAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
// Tables\Actions\BulkActionGroup::make([
|
||||
// Tables\Actions\DeleteBulkAction::make(),
|
||||
// ]),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -82,8 +92,8 @@ class CertificateResource extends Resource
|
|||
{
|
||||
return [
|
||||
'index' => Pages\ListCertificates::route('/'),
|
||||
'create' => Pages\CreateCertificate::route('/create'),
|
||||
'edit' => Pages\EditCertificate::route('/{record}/edit'),
|
||||
// 'create' => Pages\CreateCertificate::route('/create'),
|
||||
// 'edit' => Pages\EditCertificate::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ class ListCertificates extends ListRecords
|
|||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
// Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
131
web/Modules/SSLManager/App/Jobs/SecureDomain.php
Normal file
|
@ -0,0 +1,131 @@
|
|||
<?php
|
||||
|
||||
namespace Modules\SSLManager\App\Jobs;
|
||||
|
||||
use App\Models\DomainSslCertificate;
|
||||
use App\Settings;
|
||||
|
||||
class SecureDomain
|
||||
{
|
||||
|
||||
public $domainId;
|
||||
|
||||
public function __construct($domainId)
|
||||
{
|
||||
$this->domainId = $domainId;
|
||||
}
|
||||
|
||||
public function handle(): void
|
||||
{
|
||||
|
||||
$findDomain = \App\Models\Domain::where('id', $this->domainId)->first();
|
||||
if (!$findDomain) {
|
||||
throw new \Exception('Domain not found');
|
||||
}
|
||||
$domainName = $findDomain->domain;
|
||||
|
||||
$domainName = trim($domainName);
|
||||
$domainName = str_replace('www.', '', $domainName);
|
||||
if (empty($domainName)) {
|
||||
throw new \Exception('Domain name is empty');
|
||||
}
|
||||
$domainNameWww = 'www.' . $domainName;
|
||||
$domainNameWww = str_replace('www.www.', 'www.', $domainNameWww);
|
||||
|
||||
|
||||
$generalSettings = Settings::general();
|
||||
|
||||
$sslCertificateFilePath = '/etc/ssl-manager/domains/' . $domainName . '/cert.pem';
|
||||
$sslCertificateKeyFilePath = '/etc/ssl-manager/domains/' . $domainName . '/privkey.pem';
|
||||
$sslCertificateChainFilePath = '/etc/ssl-manager/domains/' . $domainName . '/fullchain.pem';
|
||||
if (!is_dir('/etc/ssl-manager/domains/' . $domainName)) {
|
||||
shell_exec('mkdir -p /etc/ssl-manager/domains/' . $domainName);
|
||||
}
|
||||
|
||||
shell_exec('chmod +x /usr/local/phyre/web/Modules/SSLManager/shell/acme.sh');
|
||||
$exec = shell_exec("bash /usr/local/phyre/web/Modules/SSLManager/shell/acme.sh --register-account -m " . $generalSettings['master_email'] . " --server letsencrypt");
|
||||
|
||||
$tmpFile = '/tmp/acme-sh-zerossl-http-secure-command-' . $findDomain->id . '.sh';
|
||||
$certbotHttpSecureCommand = view('sslmanager::actions.acme-sh-http-secure-command', [
|
||||
'domain' => $domainName,
|
||||
'domainNameWww' => $domainNameWww,
|
||||
'domainRoot' => $findDomain->domain_root,
|
||||
'domainPublic' => $findDomain->domain_public,
|
||||
'email' => $generalSettings['master_email'],
|
||||
'country' => $generalSettings['master_country'],
|
||||
'locality' => $generalSettings['master_locality'],
|
||||
'organization' => $generalSettings['organization_name'],
|
||||
])->render();
|
||||
|
||||
file_put_contents($tmpFile, $certbotHttpSecureCommand);
|
||||
shell_exec('chmod +x ' . $tmpFile);
|
||||
|
||||
$exec = shell_exec("bash $tmpFile");
|
||||
unlink($tmpFile);
|
||||
|
||||
//check file
|
||||
$zerSslCert = '/root/.acme.sh/' . $domainName . '_ecc/' . $domainName . '.cer';
|
||||
$zerSslCertKey = '/root/.acme.sh/' . $domainName . '_ecc/' . $domainName . '.key';
|
||||
$zerSslCertIntermediate = '/root/.acme.sh/' . $domainName . '_ecc/ca.cer';
|
||||
$zerSslCertFullChain = '/root/.acme.sh/' . $domainName . '_ecc/fullchain.cer';
|
||||
|
||||
if (!file_exists($zerSslCert)
|
||||
|| !file_exists($zerSslCertKey)
|
||||
|| !file_exists($zerSslCertFullChain)) {
|
||||
// Cant get all certificates
|
||||
throw new \Exception('Cant get certificates with ZeroSSL');
|
||||
}
|
||||
|
||||
|
||||
file_put_contents($sslCertificateFilePath, file_get_contents($zerSslCert));
|
||||
file_put_contents($sslCertificateKeyFilePath, file_get_contents($zerSslCertKey));
|
||||
file_put_contents($sslCertificateChainFilePath, file_get_contents($zerSslCertFullChain));
|
||||
|
||||
|
||||
if (!file_exists($sslCertificateFilePath)
|
||||
|| !file_exists($sslCertificateKeyFilePath)
|
||||
|| !file_exists($sslCertificateChainFilePath)) {
|
||||
// Cant get all certificates
|
||||
throw new \Exception('Cant get all certificates');
|
||||
}
|
||||
|
||||
$sslCertificateFileContent = file_get_contents($sslCertificateFilePath);
|
||||
$sslCertificateKeyFileContent = file_get_contents($sslCertificateKeyFilePath);
|
||||
$sslCertificateChainFileContent = file_get_contents($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
|
||||
throw new \Exception('Cant get all certificates');
|
||||
}
|
||||
|
||||
|
||||
$websiteSslCertificate = DomainSslCertificate::where('domain', $findDomain->domain)->first();
|
||||
|
||||
if (!$websiteSslCertificate) {
|
||||
$websiteSslCertificate = new DomainSslCertificate();
|
||||
$websiteSslCertificate->domain = $findDomain->domain;
|
||||
$websiteSslCertificate->certificate = $validateCertificates['certificate'];
|
||||
$websiteSslCertificate->private_key = $validateCertificates['private_key'];
|
||||
$websiteSslCertificate->certificate_chain = $validateCertificates['certificate_chain'];
|
||||
$websiteSslCertificate->customer_id = $findDomain->customer_id;
|
||||
$websiteSslCertificate->is_active = 1;
|
||||
$websiteSslCertificate->is_wildcard = 0;
|
||||
$websiteSslCertificate->is_auto_renew = 1;
|
||||
}
|
||||
|
||||
$websiteSslCertificate->provider = 'ACME';
|
||||
$websiteSslCertificate->save();
|
||||
|
||||
$findDomain->configureVirtualHost(true);
|
||||
|
||||
}
|
||||
}
|
|
@ -30,16 +30,16 @@ class SSLManagerServiceProvider extends ServiceProvider
|
|||
*/
|
||||
public function register(): void
|
||||
{
|
||||
|
||||
|
||||
// Register Phyre Icons set
|
||||
$this->callAfterResolving(Factory::class, function (Factory $factory) {
|
||||
$factory->add('ssl_manager', [
|
||||
'path' => __DIR__ . '/../../resources/assets/ssl-manager-svg',
|
||||
'prefix' => 'ssl_manager',
|
||||
'prefix' => 'ssl_manager',
|
||||
]);
|
||||
});
|
||||
|
||||
$this->app->register(RouteServiceProvider::class);
|
||||
$this->app->register(RouteServiceProvider::class);
|
||||
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,9 @@ class SSLManagerServiceProvider extends ServiceProvider
|
|||
*/
|
||||
protected function registerCommands(): void
|
||||
{
|
||||
// $this->commands([]);
|
||||
$this->commands([
|
||||
\Modules\SSLManager\App\Console\RenewSSL::class,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -101,6 +103,7 @@ class SSLManagerServiceProvider extends ServiceProvider
|
|||
|
||||
$componentNamespace = str_replace('/', '\\', config('modules.namespace').'\\'.$this->moduleName.'\\'.config('modules.paths.generator.component-class.path'));
|
||||
Blade::componentNamespace($componentNamespace, $this->moduleNameLower);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
"description": "",
|
||||
"keywords": [],
|
||||
"priority": 0,
|
||||
"logoIcon": "ssl_manager-logo",
|
||||
"logoIcon": "/Modules/SSLManager/resources/assets/ssl-manager-svg/logo.svg",
|
||||
"category": "Security",
|
||||
"adminUrl": "/admin/ssl-manager/ssl-manager-certificates",
|
||||
"adminUrl": "/admin/certificates",
|
||||
"providers": [
|
||||
"Modules\\SSLManager\\App\\Providers\\SSLManagerServiceProvider"
|
||||
],
|
||||
"files": []
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg fill="currentColor" width="800px" height="800px" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg fill="currentColor" width="60px" height="60px" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M24.26 32h-16.521c-0.708 0-1.281-0.573-1.281-1.281v-12.224c0-0.708 0.573-1.286 1.281-1.286h1.552v-1.974c0-3.698 3.010-6.708 6.708-6.708s6.708 3.010 6.708 6.708v1.974h1.552c0.708 0 1.281 0.578 1.281 1.286v12.224c0 0.708-0.573 1.281-1.281 1.281zM16.839 25.24c1.521-0.859 0.911-3.182-0.839-3.182-1.745 0.005-2.354 2.318-0.839 3.182v1.656c0 1.115 1.677 1.115 1.677 0zM13.141 17.208h5.724v-1.974c0-1.578-1.286-2.859-2.865-2.859s-2.859 1.281-2.859 2.859zM6.063 15.391h-3.984c-0.651 0-1.172-0.526-1.172-1.172s0.521-1.172 1.172-1.172h3.984c0.646 0 1.172 0.526 1.172 1.172s-0.526 1.172-1.172 1.172zM8.87 9.12c-0.271 0-0.531-0.094-0.74-0.271l-3.156-2.594c-0.5-0.406-0.568-1.146-0.156-1.646 0.406-0.5 1.146-0.573 1.646-0.161l3.156 2.594c0.849 0.698 0.349 2.078-0.75 2.073zM16 6.359c-0.646 0-1.172-0.526-1.172-1.172v-4.016c0-0.646 0.526-1.172 1.172-1.172s1.172 0.526 1.172 1.172v4.016c0 0.646-0.526 1.172-1.172 1.172zM23.13 9.12c-1.104 0-1.599-1.38-0.75-2.078l3.156-2.594c1.208-0.99 2.693 0.818 1.49 1.813l-3.156 2.594c-0.208 0.172-0.469 0.266-0.74 0.266zM29.922 15.391h-4.021c-0.651 0-1.172-0.526-1.172-1.172s0.521-1.172 1.172-1.172h4.021c0.651 0 1.172 0.526 1.172 1.172s-0.521 1.172-1.172 1.172z"/>
|
||||
</svg>
|
||||
</svg>
|
||||
|
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1 @@
|
|||
/usr/local/phyre/web/Modules/SSLManager/shell/acme.sh --issue -d {{$domain}} -d www.{{$domain}} --webroot {{$domainPublic}} --server letsencrypt
|
8053
web/Modules/SSLManager/shell/acme.sh
Normal file
|
@ -4,7 +4,7 @@
|
|||
"description": "",
|
||||
"keywords": [],
|
||||
"priority": 0,
|
||||
"logoIcon": "heroicon-o-command-line",
|
||||
"logoIcon": "Modules/Terminal/resources/assets/terminal-svg/logo.svg",
|
||||
"category": "DevOps",
|
||||
"adminUrl": "/admin/terminal",
|
||||
"providers": [
|
||||
|
|
120
web/Modules/Terminal/resources/assets/terminal-svg/logo.svg
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
|
||||
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="50px" height="50px"
|
||||
viewBox="0 0 30 30"
|
||||
version="1.1"
|
||||
id="svg822"
|
||||
inkscape:version="0.92.4 (f8dce91, 2019-08-02)"
|
||||
sodipodi:docname="terminal.svg">
|
||||
<defs
|
||||
id="defs816">
|
||||
<inkscape:path-effect
|
||||
only_selected="false"
|
||||
apply_with_weight="true"
|
||||
apply_no_weight="true"
|
||||
helper_size="0"
|
||||
steps="2"
|
||||
weight="33.333333"
|
||||
is_visible="true"
|
||||
id="path-effect1025"
|
||||
effect="bspline" />
|
||||
<inkscape:path-effect
|
||||
only_selected="false"
|
||||
apply_with_weight="true"
|
||||
apply_no_weight="true"
|
||||
helper_size="0"
|
||||
steps="2"
|
||||
weight="33.333333"
|
||||
is_visible="true"
|
||||
id="path-effect1021"
|
||||
effect="bspline" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="17.833333"
|
||||
inkscape:cx="15.855957"
|
||||
inkscape:cy="16.664315"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="true"
|
||||
units="px"
|
||||
inkscape:window-width="1366"
|
||||
inkscape:window-height="713"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
showguides="false"
|
||||
inkscape:guide-bbox="true">
|
||||
<sodipodi:guide
|
||||
position="21.126168,22.794393"
|
||||
orientation="1,0"
|
||||
id="guide1575"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="22.682243,23.285047"
|
||||
orientation="1,0"
|
||||
id="guide1635"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="22.682243,7.6455921"
|
||||
orientation="0,1"
|
||||
id="guide1639"
|
||||
inkscape:locked="false" />
|
||||
<sodipodi:guide
|
||||
position="18.859863,18.859863"
|
||||
orientation="1,0"
|
||||
id="guide1242"
|
||||
inkscape:locked="false" />
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid1103" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata819">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>
|
||||
|
||||
</dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-289.0625)">
|
||||
<ellipse
|
||||
fill="currentColor"
|
||||
cy="301.98773"
|
||||
cx="16.607477"
|
||||
id="circle863"
|
||||
style="opacity:1;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
r="6" />
|
||||
<path
|
||||
fill="currentColor"
|
||||
style="opacity:1;fill-opacity:1;stroke:none;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 5 3 C 3.892 3 3 3.892 3 5 L 3 25 C 3 26.108 3.892 27 5 27 L 25 27 C 26.108 27 27 26.108 27 25 L 27 5 C 27 3.892 26.108 3 25 3 L 5 3 z M 6.875 8.3964844 L 13.394531 12.421875 L 13.394531 14.056641 L 6.9257812 18.082031 L 6 16.734375 L 11.761719 13.248047 L 6 9.7949219 L 6.875 8.3964844 z M 15.578125 20.052734 L 24 20.052734 L 24 21.603516 L 15.578125 21.603516 L 15.578125 20.052734 z "
|
||||
transform="translate(0,289.0625)"
|
||||
id="rect901" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.7 KiB |
|
@ -54,7 +54,11 @@ class RunRepair extends Command
|
|||
$this->fixPhpMyAdmin();
|
||||
|
||||
// Overwrite supervisor config file
|
||||
$minWorkersCount = 1;
|
||||
$workersCount = (int) setting('general.supervisor_workers_count');
|
||||
if ($workersCount < $minWorkersCount) {
|
||||
$workersCount = $minWorkersCount;
|
||||
}
|
||||
$supervisorConf = view('actions.samples.ubuntu.supervisor-conf', [
|
||||
'workersCount' => $workersCount
|
||||
])->render();
|
||||
|
@ -75,6 +79,8 @@ class RunRepair extends Command
|
|||
|
||||
$this->fixApacheErrors();
|
||||
|
||||
echo shell_exec('phyre-php /usr/local/phyre/web/artisan ssl-manager:renew-ssl');
|
||||
|
||||
}
|
||||
|
||||
public function fixPhpMyAdmin()
|
||||
|
|
|
@ -73,11 +73,11 @@ class SetupMasterDomainSSL extends Command
|
|||
file_put_contents('/var/www/html/index.html', view('actions/samples/apache/html/app-index')->render());
|
||||
|
||||
// Register ACME account
|
||||
$acmeCommand = "bash /usr/local/phyre/web/Modules/LetsEncrypt/shell/acme.sh --register-account -m $this->masterEmail";
|
||||
$acmeCommand = "bash /usr/local/phyre/web/Modules/SSLManager/shell/acme.sh --register-account -m $this->masterEmail";
|
||||
$acmeCommand = shell_exec($acmeCommand);
|
||||
|
||||
// Issue SSL certificate
|
||||
$acmeCommand = "bash /usr/local/phyre/web/Modules/LetsEncrypt/shell/acme.sh --issue -d '$this->masterDomain' --webroot /var/www/html";
|
||||
$acmeCommand = "bash /usr/local/phyre/web/Modules/SSLManager/shell/acme.sh --issue -d '$this->masterDomain' --webroot /var/www/html";
|
||||
$acmeCommand = shell_exec($acmeCommand);
|
||||
|
||||
$issued = false;
|
||||
|
|
35
web/app/Events/DomainIsDeleted.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace App\Events;
|
||||
|
||||
use Illuminate\Broadcasting\InteractsWithSockets;
|
||||
use Illuminate\Broadcasting\PrivateChannel;
|
||||
use Illuminate\Foundation\Events\Dispatchable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class DomainIsDeleted
|
||||
{
|
||||
use Dispatchable, InteractsWithSockets, SerializesModels;
|
||||
|
||||
public $model;
|
||||
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*/
|
||||
public function __construct($model)
|
||||
{
|
||||
$this->model = $model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the channels the event should broadcast on.
|
||||
*
|
||||
* @return array<int, \Illuminate\Broadcasting\Channel>
|
||||
*/
|
||||
public function broadcastOn(): array
|
||||
{
|
||||
return [
|
||||
new PrivateChannel('channel-name'),
|
||||
];
|
||||
}
|
||||
}
|
251
web/app/Filament/Pages/CreateHostingSubscription.php
Normal file
|
@ -0,0 +1,251 @@
|
|||
<?php
|
||||
|
||||
namespace App\Filament\Pages;
|
||||
|
||||
use App\Jobs\ApacheBuild;
|
||||
use App\Models\Domain;
|
||||
use App\Models\HostingSubscription;
|
||||
use Carbon\Carbon;
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\Checkbox;
|
||||
use Filament\Forms\Components\Hidden;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Wizard;
|
||||
use Filament\Forms\Form;
|
||||
use Filament\Forms\Get;
|
||||
use Filament\Notifications\Notification;
|
||||
use Filament\Pages\Page;
|
||||
use Filament\Support\Exceptions\Halt;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\HtmlString;
|
||||
|
||||
class CreateHostingSubscription extends Page
|
||||
{
|
||||
protected static ?string $navigationIcon = 'heroicon-o-document-text';
|
||||
|
||||
protected static string $view = 'filament.pages.create-hosting-subscription';
|
||||
|
||||
protected static ?string $navigationGroup = 'Hosting Services';
|
||||
|
||||
protected static bool $shouldRegisterNavigation = false;
|
||||
|
||||
protected static ?string $slug = 'hosting-subscriptions/create';
|
||||
|
||||
protected static ?string $title = 'Create Hosting Account';
|
||||
|
||||
public $state = [];
|
||||
|
||||
public function verifyDomain($domain)
|
||||
{
|
||||
|
||||
$verifyPHPContent = <<<EOT
|
||||
<?php
|
||||
if (isset(\$_GET['verified'])) {
|
||||
echo 'Domain verified';
|
||||
}
|
||||
?>
|
||||
EOT;
|
||||
;
|
||||
$file = fopen("/var/www/html/verify.php", "w") or die("Unable to open file!");
|
||||
fwrite($file, $verifyPHPContent);
|
||||
fclose($file);
|
||||
|
||||
$errors = [];
|
||||
|
||||
// Check if domain is pointing to the server
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, "http://$domain/verify.php?verified=1");
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
$result = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
|
||||
if ($result !== 'Domain verified') {
|
||||
$errors[] = 'Domain not pointing to the server';
|
||||
}
|
||||
|
||||
// Check if www. domain is pointing to the server
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, "http://www.$domain/verify.php?verified=1");
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
$result = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
|
||||
if ($result !== 'Domain verified') {
|
||||
$errors[] = 'www. domain not pointing to the server';
|
||||
}
|
||||
|
||||
return [
|
||||
'errors' => $errors,
|
||||
'domain' => $domain
|
||||
];
|
||||
|
||||
}
|
||||
|
||||
public function form(Form $form): Form
|
||||
{
|
||||
return $form
|
||||
->statePath('state')
|
||||
->schema([
|
||||
Wizard::make([
|
||||
Wizard\Step::make('Validation')
|
||||
->schema([
|
||||
TextInput::make('domain')
|
||||
->required()
|
||||
->regex('/^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i')
|
||||
->disabled(function ($record) {
|
||||
if (isset($record->exists)) {
|
||||
return $record->exists;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
->suffixIcon('heroicon-m-globe-alt')
|
||||
->columnSpanFull(),
|
||||
])->afterValidation(function () {
|
||||
|
||||
$domain = $this->state['domain'];
|
||||
// validate domain
|
||||
if (!filter_var($domain, FILTER_VALIDATE_DOMAIN)) {
|
||||
$this->addError('domain', 'Invalid domain name');
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify domain if pointing to the server
|
||||
$verify = $this->verifyDomain($domain);
|
||||
if (isset($verify['errors']) && count($verify['errors']) > 0) {
|
||||
$this->replaceMountedAction('firstVerifyDomain', ['domain' => $domain]);
|
||||
throw new Halt();
|
||||
}
|
||||
|
||||
}),
|
||||
Wizard\Step::make('Customer Information')
|
||||
->schema([
|
||||
Select::make('customer_id')
|
||||
->label('Customer')
|
||||
->options(
|
||||
\App\Models\Customer::all()->pluck('name', 'id')
|
||||
)
|
||||
->required()->columnSpanFull(),
|
||||
]),
|
||||
Wizard\Step::make('Building Hosting Account')
|
||||
->schema([
|
||||
|
||||
Select::make('hosting_plan_id')
|
||||
->label('Hosting Plan')
|
||||
->options(
|
||||
\App\Models\HostingPlan::all()->pluck('name', 'id')
|
||||
)
|
||||
->required()->columnSpanFull(),
|
||||
|
||||
Checkbox::make('advanced')
|
||||
->live()
|
||||
->columnSpanFull(),
|
||||
|
||||
TextInput::make('system_username')
|
||||
->hidden(fn(Get $get): bool => !$get('advanced'))
|
||||
->disabled(function ($record) {
|
||||
if (isset($record->exists)) {
|
||||
return $record->exists;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
->suffixIcon('heroicon-m-user'),
|
||||
|
||||
TextInput::make('system_password')
|
||||
->hidden(fn(Get $get): bool => !$get('advanced'))
|
||||
->disabled(function ($record) {
|
||||
if (isset($record->exists)) {
|
||||
return $record->exists;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
->suffixIcon('heroicon-m-lock-closed'),
|
||||
]),
|
||||
])
|
||||
->submitAction(new HtmlString(Blade::render(<<<BLADE
|
||||
<x-filament::button
|
||||
wire:loading.attr="disabled"
|
||||
wire:click="createHostingAccount"
|
||||
>
|
||||
Create Hosting Account
|
||||
</x-filament::button>
|
||||
BLADE)))
|
||||
->columnSpanFull(),
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
public function createHostingAccount()
|
||||
{
|
||||
$domain = $this->state['domain'];
|
||||
$findDomain = Domain::where('domain', $domain)->first();
|
||||
if ($findDomain) {
|
||||
$this->replaceMountedAction('errorModal', ['message' => 'Domain already exists']);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!empty($this->state['system_username'])) {
|
||||
$findHostingSubscription = HostingSubscription::where('system_username', $this->state['system_username'])->first();
|
||||
if ($findHostingSubscription) {
|
||||
$this->replaceMountedAction('errorModal', ['message' => 'System username already exists']);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$hostingSubscription = new HostingSubscription();
|
||||
$hostingSubscription->customer_id = $this->state['customer_id'];
|
||||
$hostingSubscription->hosting_plan_id = $this->state['hosting_plan_id'];
|
||||
$hostingSubscription->domain = $domain;
|
||||
|
||||
if (isset($this->state['system_username'])) {
|
||||
$hostingSubscription->system_username = $this->state['system_username'];
|
||||
}
|
||||
|
||||
if (isset($this->state['system_password'])) {
|
||||
$hostingSubscription->system_password = $this->state['system_password'];
|
||||
}
|
||||
|
||||
$hostingSubscription->setup_date = Carbon::now();
|
||||
$hostingSubscription->save();
|
||||
|
||||
ApacheBuild::dispatchSync();
|
||||
|
||||
return redirect(route('filament.admin.resources.hosting-subscriptions.index'));
|
||||
|
||||
}
|
||||
|
||||
public function errorModalAction(): Action
|
||||
{
|
||||
|
||||
return Action::make('error')
|
||||
->modalContent(view('filament.pages.create-hosting-subscription.error-modal', [
|
||||
'domain' => $this->state['domain']
|
||||
]))
|
||||
->modalSubmitActionLabel('Ok');
|
||||
}
|
||||
|
||||
public function firstVerifyDomainAction(): Action
|
||||
{
|
||||
|
||||
// Get current server IP
|
||||
$serverIp = shell_exec("hostname -I | cut -d' ' -f1");
|
||||
$serverIp = trim($serverIp);
|
||||
|
||||
return Action::make('Verifying Domain')
|
||||
->modalContent(view('filament.pages.create-hosting-subscription.verify-domain-modal', [
|
||||
'domain' => $this->state['domain'],
|
||||
'serverIp' =>$serverIp
|
||||
]))
|
||||
->modalSubmitActionLabel('Continue');
|
||||
}
|
||||
|
||||
}
|
|
@ -66,6 +66,7 @@ class Modules extends Page
|
|||
if ($findModule) {
|
||||
$findModule->delete();
|
||||
}
|
||||
shell_exec('phyre-php /usr/local/phyre/web/artisan module:disable ' . $module);
|
||||
}
|
||||
|
||||
public function openInstallModal($module)
|
||||
|
@ -100,6 +101,8 @@ class Modules extends Page
|
|||
|
||||
$this->installLogPulling = false;
|
||||
|
||||
shell_exec('phyre-php /usr/local/phyre/web/artisan module:enable ' . $module);
|
||||
|
||||
$moduleInfo = ModulesManager::getModuleInfo($module);
|
||||
if (isset($moduleInfo['adminUrl'])) {
|
||||
return $this->redirect($moduleInfo['adminUrl']);
|
||||
|
|
|
@ -22,6 +22,11 @@ class RepairTool extends Page
|
|||
session()->flash('message', 'RunRepair command executed successfully.');
|
||||
}
|
||||
|
||||
public function runRenewSSL()
|
||||
{
|
||||
Artisan::call('ssl-manager:renew-ssl');
|
||||
session()->flash('message', 'RenewSSL command executed successfully.');
|
||||
}
|
||||
public function runDomainRepair()
|
||||
{
|
||||
Artisan::call('phyre:run-domain-repair');
|
||||
|
|
|
@ -331,7 +331,7 @@ class DomainResource extends Resource
|
|||
->color('gray')
|
||||
->url(fn ($record): string => 'http://'.$record->domain, true),
|
||||
|
||||
Tables\Actions\EditAction::make(),
|
||||
// Tables\Actions\EditAction::make(),
|
||||
|
||||
])
|
||||
->filters([
|
||||
|
@ -362,8 +362,8 @@ class DomainResource extends Resource
|
|||
{
|
||||
return [
|
||||
'index' => Pages\ListDomains::route('/'),
|
||||
'create' => Pages\CreateDomain::route('/create'),
|
||||
'edit' => Pages\EditDomain::route('/{record}/edit'),
|
||||
// 'create' => Pages\CreateDomain::route('/create'),
|
||||
// 'edit' => Pages\EditDomain::route('/{record}/edit'),
|
||||
// 'view' => Pages\ViewDomain::route('/{record}'),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ class ListDomains extends ListRecords
|
|||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
// Actions\CreateAction::make(),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -212,7 +212,9 @@ class HostingPlanResource extends Resource
|
|||
Forms\Components\Select::make('additional_services')
|
||||
->label('Additional Services')
|
||||
->options([
|
||||
'microweber' => 'Microweber',
|
||||
'microweber' => 'Microweber (Auto Install)',
|
||||
'microweber_custom' => 'Microweber (Custom Install)',
|
||||
|
||||
// 'wordpress' => 'WordPress',
|
||||
// 'opencart' => 'OpenCart',
|
||||
])
|
||||
|
|
|
@ -20,16 +20,17 @@ use Filament\Tables\Table;
|
|||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\HtmlString;
|
||||
use Filament\Forms\Components\Wizard;
|
||||
|
||||
class HostingSubscriptionResource extends Resource
|
||||
{
|
||||
protected static ?string $model = HostingSubscription::class;
|
||||
|
||||
protected static ?string $navigationIcon = 'heroicon-o-star';
|
||||
protected static ?string $navigationIcon = 'heroicon-o-server-stack';
|
||||
|
||||
protected static ?string $navigationGroup = 'Hosting Services';
|
||||
|
||||
protected static ?string $label = 'Subscriptions';
|
||||
protected static ?string $label = 'Hosting Accounts';
|
||||
|
||||
protected static ?int $navigationSort = 2;
|
||||
|
||||
|
@ -40,74 +41,7 @@ class HostingSubscriptionResource extends Resource
|
|||
return $form
|
||||
->schema([
|
||||
|
||||
Section::make('Hosting Subscription Information')->schema([
|
||||
|
||||
// Forms\Components\Placeholder::make('Website Link')
|
||||
// ->hidden(function ($record) {
|
||||
// if (isset($record->exists)) {
|
||||
// return false;
|
||||
// } else {
|
||||
// return true;
|
||||
// }
|
||||
// })
|
||||
// ->content(fn($record) => new HtmlString('
|
||||
// <a href="http://' . $record->domain . '" target="_blank" class="text-sm font-medium text-primary-600 dark:text-primary-400">
|
||||
// http://' . $record->domain . '
|
||||
// </a>')),
|
||||
|
||||
Forms\Components\TextInput::make('domain')
|
||||
->required()
|
||||
->regex('/^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/i')
|
||||
->disabled(function ($record) {
|
||||
if (isset($record->exists)) {
|
||||
return $record->exists;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
->suffixIcon('heroicon-m-globe-alt')
|
||||
->columnSpanFull(),
|
||||
|
||||
Forms\Components\Select::make('customer_id')
|
||||
->label('Customer')
|
||||
->options(
|
||||
\App\Models\Customer::all()->pluck('name', 'id')
|
||||
)
|
||||
->required()->columnSpanFull(),
|
||||
|
||||
Forms\Components\Select::make('hosting_plan_id')
|
||||
->label('Hosting Plan')
|
||||
->options(
|
||||
\App\Models\HostingPlan::all()->pluck('name', 'id')
|
||||
)
|
||||
->required()->columnSpanFull(),
|
||||
|
||||
Forms\Components\Checkbox::make('advanced')
|
||||
->live()
|
||||
->columnSpanFull(),
|
||||
|
||||
Forms\Components\TextInput::make('system_username')
|
||||
->hidden(fn(Forms\Get $get): bool => !$get('advanced'))
|
||||
->disabled(function ($record) {
|
||||
if (isset($record->exists)) {
|
||||
return $record->exists;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
->suffixIcon('heroicon-m-user'),
|
||||
|
||||
Forms\Components\TextInput::make('system_password')
|
||||
->hidden(fn(Forms\Get $get): bool => !$get('advanced'))
|
||||
->disabled(function ($record) {
|
||||
if (isset($record->exists)) {
|
||||
return $record->exists;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
->suffixIcon('heroicon-m-lock-closed'),
|
||||
]),
|
||||
|
||||
]);
|
||||
}
|
||||
|
@ -176,13 +110,13 @@ class HostingSubscriptionResource extends Resource
|
|||
->icon('heroicon-m-arrow-top-right-on-square')
|
||||
->color('gray')
|
||||
->url(fn($record): string => 'http://' . $record->domain, true),
|
||||
Tables\Actions\EditAction::make(),
|
||||
// Tables\Actions\EditAction::make(),
|
||||
Tables\Actions\DeleteAction::make(),
|
||||
])
|
||||
->bulkActions([
|
||||
Tables\Actions\BulkActionGroup::make([
|
||||
Tables\Actions\DeleteBulkAction::make(),
|
||||
]),
|
||||
// Tables\Actions\BulkActionGroup::make([
|
||||
// Tables\Actions\DeleteBulkAction::make(),
|
||||
// ]),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -205,8 +139,7 @@ class HostingSubscriptionResource extends Resource
|
|||
{
|
||||
return [
|
||||
'index' => Pages\ListHostingSubscriptions::route('/'),
|
||||
'create' => Pages\CreateHostingSubscription::route('/create'),
|
||||
'edit' => Pages\EditHostingSubscription::route('/{record}/edit'),
|
||||
// 'edit' => Pages\EditHostingSubscription::route('/{record}/edit'),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Filament\Resources\HostingSubscriptionResource\Pages;
|
||||
|
||||
use App\Filament\Resources\HostingSubscriptionResource;
|
||||
use Filament\Resources\Pages\CreateRecord;
|
||||
|
||||
class CreateHostingSubscription extends CreateRecord
|
||||
{
|
||||
protected static string $resource = HostingSubscriptionResource::class;
|
||||
}
|
|
@ -13,7 +13,10 @@ class ListHostingSubscriptions extends ListRecords
|
|||
protected function getHeaderActions(): array
|
||||
{
|
||||
return [
|
||||
Actions\CreateAction::make(),
|
||||
Actions\Action::make('create')
|
||||
->label('Create Hosting Account')
|
||||
->icon('heroicon-o-plus')
|
||||
->url(route('filament.admin.pages.hosting-subscriptions.create'))
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace App\Models;
|
|||
|
||||
use App\Actions\ApacheWebsiteDelete;
|
||||
use App\Events\DomainIsCreated;
|
||||
use App\Events\DomainIsDeleted;
|
||||
use App\Events\ModelDomainDeleting;
|
||||
use App\Jobs\ApacheBuild;
|
||||
use App\Models\Scopes\CustomerHostingSubscriptionScope;
|
||||
|
@ -11,7 +12,9 @@ use App\ShellApi;
|
|||
use App\VirtualHosts\DTO\ApacheVirtualHostSettings;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Modules\Docker\App\Models\DockerContainer;
|
||||
use Modules\SSLManager\App\Jobs\SecureDomain;
|
||||
|
||||
// use Modules\Docker\App\Models\DockerContainer;
|
||||
|
||||
class Domain extends Model
|
||||
{
|
||||
|
@ -84,7 +87,19 @@ class Domain extends Model
|
|||
|
||||
$model->configureVirtualHost(true);
|
||||
|
||||
ApacheBuild::dispatch();
|
||||
try {
|
||||
$build = new ApacheBuild();
|
||||
$build->handle();
|
||||
} catch (\Exception $e) {
|
||||
// $this->error($e->getMessage());
|
||||
}
|
||||
|
||||
try {
|
||||
$run = new SecureDomain($model->id);
|
||||
$run->handle();
|
||||
} catch (\Exception $e) {
|
||||
// $this->error($e->getMessage());
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
@ -108,6 +123,8 @@ class Domain extends Model
|
|||
|
||||
ApacheBuild::dispatch();
|
||||
|
||||
event(new DomainIsDeleted($model));
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -147,6 +164,8 @@ class Domain extends Model
|
|||
}
|
||||
}
|
||||
|
||||
$this->server_application_type = 'apache_php';
|
||||
|
||||
if ($this->is_installed_default_app_template == null) {
|
||||
$this->is_installed_default_app_template = 1;
|
||||
$this->saveQuietly();
|
||||
|
@ -233,6 +252,7 @@ class Domain extends Model
|
|||
$appType = 'php';
|
||||
$appVersion = '8.3';
|
||||
|
||||
|
||||
if ($this->server_application_type == 'apache_php') {
|
||||
if (isset($this->server_application_settings['php_version'])) {
|
||||
$appVersion = $this->server_application_settings['php_version'];
|
||||
|
@ -325,17 +345,17 @@ class Domain extends Model
|
|||
}
|
||||
|
||||
}
|
||||
if ($this->server_application_type == 'apache_docker') {
|
||||
if (isset($this->server_application_settings['docker_container_id'])) {
|
||||
$findDockerContainer = DockerContainer::where('id', $this->server_application_settings['docker_container_id'])
|
||||
->first();
|
||||
if ($findDockerContainer) {
|
||||
$apacheVirtualHostBuilder->setProxyPass('http://127.0.0.1:' . $findDockerContainer->external_port . '/');
|
||||
$apacheVirtualHostBuilder->setAppType('docker');
|
||||
$apacheVirtualHostBuilder->setAppVersion($appVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
// if ($this->server_application_type == 'apache_docker') {
|
||||
// if (isset($this->server_application_settings['docker_container_id'])) {
|
||||
// $findDockerContainer = DockerContainer::where('id', $this->server_application_settings['docker_container_id'])
|
||||
// ->first();
|
||||
// if ($findDockerContainer) {
|
||||
// $apacheVirtualHostBuilder->setProxyPass('http://127.0.0.1:' . $findDockerContainer->external_port . '/');
|
||||
// $apacheVirtualHostBuilder->setAppType('docker');
|
||||
// $apacheVirtualHostBuilder->setAppVersion($appVersion);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
$virtualHostSettings = $apacheVirtualHostBuilder->getSettings();
|
||||
|
|
|
@ -1,437 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Actions\ApacheWebsiteDelete;
|
||||
use App\Events\DomainIsCreated;
|
||||
use App\Events\ModelDomainDeleting;
|
||||
use App\ShellApi;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Modules\Docker\App\Models\DockerContainer;
|
||||
|
||||
class Domain extends Model
|
||||
{
|
||||
|
||||
public const STATUS_ACTIVE = 'active';
|
||||
public const STATUS_SUSPENDED = 'suspended';
|
||||
public const STATUS_DELETED = 'deleted';
|
||||
public const STATUS_DEACTIVATED = 'deactivated';
|
||||
|
||||
protected $fillable = [
|
||||
'domain',
|
||||
'domain_root',
|
||||
'ip',
|
||||
'hosting_subscription_id',
|
||||
'server_application_type',
|
||||
'server_application_settings',
|
||||
'status'
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'server_application_settings' => 'array',
|
||||
];
|
||||
|
||||
protected static function booted(): void
|
||||
{
|
||||
static::addGlobalScope('customer', function (Builder $query) {
|
||||
if (auth()->check() && auth()->guard()->name == 'web_customer') {
|
||||
$query->whereHas('hostingSubscription', function ($query) {
|
||||
$query->where('customer_id', auth()->user()->id);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static function boot()
|
||||
{
|
||||
parent::boot();
|
||||
|
||||
static::created(function ($model) {
|
||||
|
||||
$findHostingSubscription = HostingSubscription::where('id', $model->hosting_subscription_id)->first();
|
||||
if (! $findHostingSubscription) {
|
||||
return;
|
||||
}
|
||||
|
||||
$findHostingPlan = HostingPlan::where('id', $findHostingSubscription->hosting_plan_id)->first();
|
||||
if (! $findHostingPlan) {
|
||||
return;
|
||||
}
|
||||
|
||||
$model->server_application_type = $findHostingPlan->default_server_application_type;
|
||||
$model->server_application_settings = $findHostingPlan->default_server_application_settings;
|
||||
|
||||
if ($model->is_main == 1) {
|
||||
// $allDomainsRoot = '/home/'.$this->user.'/public_html';
|
||||
$model->domain_root = '/home/'.$findHostingSubscription->system_username;
|
||||
$model->domain_public = '/home/'.$findHostingSubscription->system_username.'/public_html';
|
||||
$model->home_root = '/home/'.$findHostingSubscription->system_username;
|
||||
} else {
|
||||
// $allDomainsRoot = '/home/'.$model->user.'/domains';
|
||||
$model->domain_root = '/home/'.$findHostingSubscription->system_username.'/domains/'.$model->domain;
|
||||
$model->domain_public = $model->domain_root.'/public_html';
|
||||
$model->home_root = '/home/'.$findHostingSubscription->user;
|
||||
}
|
||||
|
||||
$model->save();
|
||||
|
||||
$model->configureVirtualHost();
|
||||
|
||||
event(new DomainIsCreated($model));
|
||||
|
||||
});
|
||||
|
||||
static::updating(function ($model) {
|
||||
$model->configureVirtualHost();
|
||||
});
|
||||
|
||||
static::saved(function ($model) {
|
||||
$model->configureVirtualHost();
|
||||
});
|
||||
|
||||
static::deleting(function ($model) {
|
||||
|
||||
if (empty($model->domain_public)) {
|
||||
return;
|
||||
}
|
||||
$findHostingSubscription = HostingSubscription::where('id', $model->hosting_subscription_id)->first();
|
||||
if (! $findHostingSubscription) {
|
||||
return;
|
||||
}
|
||||
|
||||
ShellApi::safeDelete($model->domain_root, ['/home/' . $findHostingSubscription->system_username]);
|
||||
|
||||
$whiteListedPathsForDelete = [
|
||||
'/etc/apache2/sites-available',
|
||||
'/etc/apache2/sites-enabled',
|
||||
];
|
||||
|
||||
$apacheConf = '/etc/apache2/sites-available/'.$model->domain.'.conf';
|
||||
ShellApi::safeDelete($apacheConf, $whiteListedPathsForDelete);
|
||||
|
||||
$apacheConfEnabled = '/etc/apache2/sites-enabled/'.$model->domain.'.conf';
|
||||
ShellApi::safeDelete($apacheConfEnabled, $whiteListedPathsForDelete);
|
||||
|
||||
// SSL
|
||||
$apacheSSLConf = '/etc/apache2/sites-available/'.$model->domain.'-ssl.conf';
|
||||
ShellApi::safeDelete($apacheSSLConf, $whiteListedPathsForDelete);
|
||||
|
||||
$apacheSSLConfEnabled = '/etc/apache2/sites-enabled/'.$model->domain.'-ssl.conf';
|
||||
ShellApi::safeDelete($apacheSSLConfEnabled, $whiteListedPathsForDelete);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public function hostingSubscription()
|
||||
{
|
||||
return $this->belongsTo(HostingSubscription::class);
|
||||
}
|
||||
|
||||
public function configureVirtualHost($reloadApache = true)
|
||||
{
|
||||
$findHostingSubscription = \App\Models\HostingSubscription::where('id', $this->hosting_subscription_id)
|
||||
->first();
|
||||
if (!$findHostingSubscription) {
|
||||
throw new \Exception('Hosting subscription not found');
|
||||
}
|
||||
|
||||
$findHostingPlan = \App\Models\HostingPlan::where('id', $findHostingSubscription->hosting_plan_id)
|
||||
->first();
|
||||
if (!$findHostingPlan) {
|
||||
throw new \Exception('Hosting plan not found');
|
||||
}
|
||||
|
||||
if (empty($this->domain_root)) {
|
||||
throw new \Exception('Domain root not found');
|
||||
}
|
||||
|
||||
if (!is_dir($this->domain_root)) {
|
||||
mkdir($this->domain_root, 0711, true);
|
||||
}
|
||||
if (!is_dir($this->domain_public)) {
|
||||
mkdir($this->domain_public, 0755, true);
|
||||
}
|
||||
if (!is_dir($this->home_root)) {
|
||||
mkdir($this->home_root, 0711, true);
|
||||
}
|
||||
|
||||
if ($this->is_installed_default_app_template == null) {
|
||||
$this->is_installed_default_app_template = 1;
|
||||
$this->save();
|
||||
if ($this->server_application_type == 'apache_php') {
|
||||
if (!is_file($this->domain_public . '/index.php')) {
|
||||
$indexContent = view('actions.samples.apache.php.app-php-sample')->render();
|
||||
file_put_contents($this->domain_public . '/index.php', $indexContent);
|
||||
}
|
||||
if (!is_dir($this->domain_public . '/templates')) {
|
||||
mkdir($this->domain_public . '/templates', 0755, true);
|
||||
}
|
||||
if (!is_file($this->domain_public . '/templates/index.html')) {
|
||||
$indexContent = view('actions.samples.apache.php.app-index-html')->render();
|
||||
file_put_contents($this->domain_public . '/templates/index.html', $indexContent);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->server_application_type == 'apache_nodejs') {
|
||||
if (!is_file($this->domain_public . '/app.js')) {
|
||||
$indexContent = view('actions.samples.apache.nodejs.app-nodejs-sample')->render();
|
||||
file_put_contents($this->domain_public . '/app.js', $indexContent);
|
||||
}
|
||||
if (!is_dir($this->domain_public . '/templates')) {
|
||||
mkdir($this->domain_public . '/templates', 0755, true);
|
||||
}
|
||||
if (!is_file($this->domain_public . '/templates/index.html')) {
|
||||
$indexContent = view('actions.samples.apache.nodejs.app-index-html')->render();
|
||||
file_put_contents($this->domain_public . '/templates/index.html', $indexContent);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->server_application_type == 'apache_python') {
|
||||
if (!is_file($this->domain_public . '/app.py')) {
|
||||
$indexContent = view('actions.samples.apache.python.app-python-sample')->render();
|
||||
file_put_contents($this->domain_public . '/app.py', $indexContent);
|
||||
}
|
||||
if (!is_file($this->domain_public . '/passenger_wsgi.py')) {
|
||||
$indexContent = view('actions.samples.apache.python.app-passanger-wsgi-sample')->render();
|
||||
file_put_contents($this->domain_public . '/passenger_wsgi.py', $indexContent);
|
||||
}
|
||||
if (!is_dir($this->domain_public . '/templates')) {
|
||||
mkdir($this->domain_public . '/templates', 0755, true);
|
||||
}
|
||||
if (!is_file($this->domain_public . '/templates/index.html')) {
|
||||
$indexContent = view('actions.samples.apache.python.app-index-html')->render();
|
||||
file_put_contents($this->domain_public . '/templates/index.html', $indexContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$webUserGroup = $findHostingSubscription->system_username;
|
||||
|
||||
// Fix file permissions
|
||||
shell_exec('chown -R '.$findHostingSubscription->system_username.':'.$webUserGroup.' '.$this->home_root);
|
||||
shell_exec('chown -R '.$findHostingSubscription->system_username.':'.$webUserGroup.' '.$this->domain_root);
|
||||
shell_exec('chown -R '.$findHostingSubscription->system_username.':'.$webUserGroup.' '.$this->domain_public);
|
||||
|
||||
shell_exec('chmod -R 0711 '.$this->home_root);
|
||||
shell_exec('chmod -R 0711 '.$this->domain_root);
|
||||
shell_exec('chmod -R 775 '.$this->domain_public);
|
||||
|
||||
if (!is_dir($this->domain_root.'/logs/apache2')) {
|
||||
shell_exec('mkdir -p '.$this->domain_root.'/logs/apache2');
|
||||
}
|
||||
shell_exec('chown -R '.$findHostingSubscription->system_username.':'.$webUserGroup.' '.$this->domain_root.'/logs/apache2');
|
||||
shell_exec('chmod -R 775 '.$this->domain_root.'/logs/apache2');
|
||||
|
||||
if (!is_file($this->domain_root.'/logs/apache2/bytes.log')) {
|
||||
shell_exec('touch '.$this->domain_root.'/logs/apache2/bytes.log');
|
||||
}
|
||||
if (!is_file($this->domain_root.'/logs/apache2/access.log')) {
|
||||
shell_exec('touch '.$this->domain_root.'/logs/apache2/access.log');
|
||||
}
|
||||
if (!is_file($this->domain_root.'/logs/apache2/error.log')) {
|
||||
shell_exec('touch '.$this->domain_root.'/logs/apache2/error.log');
|
||||
}
|
||||
|
||||
shell_exec('chmod -R 775 '.$this->domain_root.'/logs/apache2/bytes.log');
|
||||
shell_exec('chmod -R 775 '.$this->domain_root.'/logs/apache2/access.log');
|
||||
shell_exec('chmod -R 775 '.$this->domain_root.'/logs/apache2/error.log');
|
||||
|
||||
$appType = 'php';
|
||||
$appVersion = '8.3';
|
||||
|
||||
if ($this->server_application_type == 'apache_php') {
|
||||
if (isset($this->server_application_settings['php_version'])) {
|
||||
$appVersion = $this->server_application_settings['php_version'];
|
||||
}
|
||||
if (!is_dir($this->domain_public . '/cgi-bin')) {
|
||||
mkdir($this->domain_public . '/cgi-bin', 0755, true);
|
||||
}
|
||||
file_put_contents($this->domain_public . '/cgi-bin/php', '#!/usr/bin/php-cgi' . $appVersion . ' -cphp' . $appVersion . '-cgi.ini');
|
||||
shell_exec('chown '.$findHostingSubscription->system_username.':'.$webUserGroup.' '.$this->domain_public . '/cgi-bin/php');
|
||||
shell_exec('chmod -f 751 '.$this->domain_public . '/cgi-bin/php');
|
||||
}
|
||||
|
||||
$apacheVirtualHostBuilder = new \App\VirtualHosts\ApacheVirtualHostBuilder();
|
||||
$apacheVirtualHostBuilder->setDomain($this->domain);
|
||||
$apacheVirtualHostBuilder->setDomainPublic($this->domain_public);
|
||||
$apacheVirtualHostBuilder->setDomainRoot($this->domain_root);
|
||||
$apacheVirtualHostBuilder->setHomeRoot($this->home_root);
|
||||
$apacheVirtualHostBuilder->setUser($findHostingSubscription->system_username);
|
||||
$apacheVirtualHostBuilder->setUserGroup($webUserGroup);
|
||||
|
||||
if ($this->status == self::STATUS_SUSPENDED) {
|
||||
$suspendedPath = '/var/www/html/suspended';
|
||||
if (!is_dir($suspendedPath)) {
|
||||
mkdir($suspendedPath, 0755, true);
|
||||
}
|
||||
if (!is_file($suspendedPath . '/index.html')) {
|
||||
$suspendedPageHtmlPath = base_path('resources/views/actions/samples/apache/html/app-suspended-page.html');
|
||||
file_put_contents($suspendedPath . '/index.html', file_get_contents($suspendedPageHtmlPath));
|
||||
}
|
||||
$apacheVirtualHostBuilder->setDomainRoot($suspendedPath);
|
||||
$apacheVirtualHostBuilder->setDomainPublic($suspendedPath);
|
||||
} else if ($this->status == self::STATUS_DEACTIVATED) {
|
||||
$deactivatedPath = '/var/www/html/deactivated';
|
||||
if (!is_dir($deactivatedPath)) {
|
||||
mkdir($deactivatedPath, 0755, true);
|
||||
}
|
||||
if (!is_file($deactivatedPath . '/index.html')) {
|
||||
$deactivatedPageHtmlPath = base_path('resources/views/actions/samples/apache/html/app-deactivated-page.html');
|
||||
file_put_contents($deactivatedPath . '/index.html', file_get_contents($deactivatedPageHtmlPath));
|
||||
}
|
||||
$apacheVirtualHostBuilder->setDomainRoot($deactivatedPath);
|
||||
$apacheVirtualHostBuilder->setDomainPublic($deactivatedPath);
|
||||
} else {
|
||||
|
||||
$apacheVirtualHostBuilder->setEnableLogs(true);
|
||||
$apacheVirtualHostBuilder->setAdditionalServices($findHostingPlan->additional_services);
|
||||
$apacheVirtualHostBuilder->setAppType($appType);
|
||||
$apacheVirtualHostBuilder->setAppVersion($appVersion);
|
||||
|
||||
if ($this->server_application_type == 'apache_nodejs') {
|
||||
$apacheVirtualHostBuilder->setAppType('nodejs');
|
||||
$apacheVirtualHostBuilder->setPassengerAppRoot($this->domain_public);
|
||||
$apacheVirtualHostBuilder->setPassengerAppType('node');
|
||||
$apacheVirtualHostBuilder->setPassengerStartupFile('app.js');
|
||||
|
||||
if (isset($this->server_application_settings['nodejs_version'])) {
|
||||
$apacheVirtualHostBuilder->setAppVersion($this->server_application_settings['nodejs_version']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->server_application_type == 'apache_python') {
|
||||
$apacheVirtualHostBuilder->setAppType('python');
|
||||
$apacheVirtualHostBuilder->setPassengerAppRoot($this->domain_public);
|
||||
$apacheVirtualHostBuilder->setPassengerAppType('python');
|
||||
|
||||
if (isset($this->server_application_settings['python_version'])) {
|
||||
$apacheVirtualHostBuilder->setAppVersion($this->server_application_settings['python_version']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->server_application_type == 'apache_ruby') {
|
||||
$apacheVirtualHostBuilder->setAppType('ruby');
|
||||
$apacheVirtualHostBuilder->setPassengerAppRoot($this->domain_public);
|
||||
$apacheVirtualHostBuilder->setPassengerAppType('ruby');
|
||||
|
||||
if (isset($this->server_application_settings['ruby_version'])) {
|
||||
$apacheVirtualHostBuilder->setAppVersion($this->server_application_settings['ruby_version']);
|
||||
}
|
||||
|
||||
}
|
||||
if ($this->server_application_type == 'apache_docker') {
|
||||
if (isset($this->server_application_settings['docker_container_id'])) {
|
||||
$findDockerContainer = DockerContainer::where('id', $this->server_application_settings['docker_container_id'])
|
||||
->first();
|
||||
if ($findDockerContainer) {
|
||||
$apacheVirtualHostBuilder->setProxyPass('http://127.0.0.1:' . $findDockerContainer->external_port . '/');
|
||||
$apacheVirtualHostBuilder->setAppType('docker');
|
||||
$apacheVirtualHostBuilder->setAppVersion($appVersion);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$apacheBaseConfig = $apacheVirtualHostBuilder->buildConfig();
|
||||
|
||||
if (!empty($apacheBaseConfig)) {
|
||||
file_put_contents('/etc/apache2/sites-available/'.$this->domain.'.conf', $apacheBaseConfig);
|
||||
|
||||
// check symlink exists
|
||||
$symlinkExists = file_exists('/etc/apache2/sites-enabled/'.$this->domain.'.conf');
|
||||
if (!$symlinkExists) {
|
||||
shell_exec('ln -s /etc/apache2/sites-available/' . $this->domain . '.conf /etc/apache2/sites-enabled/' . $this->domain . '.conf');
|
||||
}
|
||||
}
|
||||
|
||||
$catchMainDomain = '';
|
||||
$domainExp = explode('.', $this->domain);
|
||||
if (count($domainExp) > 0) {
|
||||
unset($domainExp[0]);
|
||||
$catchMainDomain = implode('.', $domainExp);
|
||||
}
|
||||
|
||||
$findDomainSSLCertificate = null;
|
||||
|
||||
$findMainDomainSSLCertificate = \App\Models\DomainSslCertificate::where('domain', $this->domain)
|
||||
->first();
|
||||
if ($findMainDomainSSLCertificate) {
|
||||
$findDomainSSLCertificate = $findMainDomainSSLCertificate;
|
||||
} else {
|
||||
$findDomainSSLCertificateWildcard = \App\Models\DomainSslCertificate::where('domain', '*.' . $this->domain)
|
||||
->where('is_wildcard', 1)
|
||||
->first();
|
||||
if ($findDomainSSLCertificateWildcard) {
|
||||
$findDomainSSLCertificate = $findDomainSSLCertificateWildcard;
|
||||
} else {
|
||||
$findMainDomainWildcardSSLCertificate = \App\Models\DomainSslCertificate::where('domain', '*.'.$catchMainDomain)
|
||||
->first();
|
||||
if ($findMainDomainWildcardSSLCertificate) {
|
||||
$findDomainSSLCertificate = $findMainDomainWildcardSSLCertificate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($findDomainSSLCertificate) {
|
||||
|
||||
$sslCertificateFile = $this->home_root . '/certs/' . $this->domain . '/public/cert.pem';
|
||||
$sslCertificateKeyFile = $this->home_root . '/certs/' . $this->domain . '/private/key.private.pem';
|
||||
$sslCertificateChainFile = $this->home_root . '/certs/' . $this->domain . '/public/fullchain.pem';
|
||||
|
||||
if (!empty($findDomainSSLCertificate->certificate)) {
|
||||
if (!is_dir($this->home_root . '/certs/' . $this->domain . '/public')) {
|
||||
mkdir($this->home_root . '/certs/' . $this->domain . '/public', 0755, true);
|
||||
}
|
||||
file_put_contents($sslCertificateFile, $findDomainSSLCertificate->certificate);
|
||||
}
|
||||
if (!empty($findDomainSSLCertificate->private_key)) {
|
||||
if (!is_dir($this->home_root . '/certs/' . $this->domain . '/private')) {
|
||||
mkdir($this->home_root . '/certs/' . $this->domain . '/private', 0755, true);
|
||||
}
|
||||
file_put_contents($sslCertificateKeyFile, $findDomainSSLCertificate->private_key);
|
||||
}
|
||||
if (!empty($findDomainSSLCertificate->certificate_chain)) {
|
||||
if (!is_dir($this->home_root . '/certs/' . $this->domain . '/public')) {
|
||||
mkdir($this->home_root . '/certs/' . $this->domain . '/public', 0755, true);
|
||||
}
|
||||
file_put_contents($sslCertificateChainFile, $findDomainSSLCertificate->certificate_chain);
|
||||
}
|
||||
|
||||
$apacheVirtualHostBuilder->setPort(443);
|
||||
$apacheVirtualHostBuilder->setSSLCertificateFile($sslCertificateFile);
|
||||
$apacheVirtualHostBuilder->setSSLCertificateKeyFile($sslCertificateKeyFile);
|
||||
$apacheVirtualHostBuilder->setSSLCertificateChainFile($sslCertificateChainFile);
|
||||
|
||||
$apacheBaseConfigWithSSL = $apacheVirtualHostBuilder->buildConfig();
|
||||
if (!empty($apacheBaseConfigWithSSL)) {
|
||||
|
||||
// Add SSL options conf file
|
||||
$apache2SSLOptionsSample = view('actions.samples.ubuntu.apache2-ssl-options-conf')->render();
|
||||
$apache2SSLOptionsFilePath = '/etc/apache2/phyre/options-ssl-apache.conf';
|
||||
|
||||
if (!file_exists($apache2SSLOptionsFilePath)) {
|
||||
if (!is_dir('/etc/apache2/phyre')) {
|
||||
mkdir('/etc/apache2/phyre');
|
||||
}
|
||||
file_put_contents($apache2SSLOptionsFilePath, $apache2SSLOptionsSample);
|
||||
}
|
||||
|
||||
file_put_contents('/etc/apache2/sites-available/'.$this->domain.'-ssl.conf', $apacheBaseConfigWithSSL);
|
||||
|
||||
if (!is_link('/etc/apache2/sites-enabled/' . $this->domain . '-ssl.conf')) {
|
||||
shell_exec('ln -s /etc/apache2/sites-available/' . $this->domain . '-ssl.conf /etc/apache2/sites-enabled/' . $this->domain . '-ssl.conf');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Reload apache
|
||||
if ($reloadApache) {
|
||||
shell_exec('systemctl reload apache2');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -61,12 +61,21 @@ class ModulesManager
|
|||
if ($findModule) {
|
||||
$installed = 1;
|
||||
}
|
||||
|
||||
// $iconUrl = route('module.icon.render', ['module' => $module]);
|
||||
|
||||
$iconRendered = '';
|
||||
if (file_exists(base_path($logoIcon))) {
|
||||
$iconRendered = file_get_contents(base_path($logoIcon));
|
||||
}
|
||||
|
||||
return [
|
||||
'name' => $module,
|
||||
'description' => 'A drag and drop website builder and a powerful next-generation CMS.',
|
||||
'description' => '',
|
||||
'url' => $url,
|
||||
'adminUrl' => $adminUrl,
|
||||
'iconUrl' => url('images/modules/' . $module . '.png'),
|
||||
// 'iconUrl' => $iconUrl,
|
||||
'iconRendered'=>$iconRendered,
|
||||
'logoIcon' => $logoIcon,
|
||||
'category' => $category,
|
||||
'installed'=>$installed,
|
||||
|
|
|
@ -35,7 +35,6 @@ class AdminPanelProvider extends PanelProvider
|
|||
{
|
||||
public function panel(Panel $panel): Panel
|
||||
{
|
||||
|
||||
$panel->default()
|
||||
->darkMode(true)
|
||||
->id('admin')
|
||||
|
@ -49,13 +48,15 @@ class AdminPanelProvider extends PanelProvider
|
|||
->unsavedChangesAlerts()
|
||||
->globalSearch(true)
|
||||
->databaseNotifications()
|
||||
->font('Albert Sans')
|
||||
->font('Exo 2')
|
||||
->sidebarWidth('15rem')
|
||||
// ->brandLogo(fn () => view('filament.admin.logo'))
|
||||
->navigationGroups([
|
||||
'Hosting Services' => NavigationGroup::make()->label('Hosting Services'),
|
||||
// 'Docker' => NavigationGroup::make()->label('Docker'),
|
||||
'SSL Manager'=> NavigationGroup::make()->label('SSL Manager')->icon('ssl_manager-logo'),
|
||||
'SSL Manager'=> NavigationGroup::make()->label('SSL Manager')
|
||||
// ->icon('ssl_manager-logo')
|
||||
,
|
||||
'Server Management' => NavigationGroup::make()->label('Server Management'),
|
||||
])
|
||||
->discoverResources(in: app_path('Filament/Resources'), for: 'App\\Filament\\Resources')
|
||||
|
@ -98,7 +99,7 @@ class AdminPanelProvider extends PanelProvider
|
|||
$defaultColor = Color::Yellow;
|
||||
$brandLogo = null;
|
||||
$brandName = null;
|
||||
$isAppInstalled = file_exists(storage_path('installed'));
|
||||
$isAppInstalled = file_exists(storage_path('installed'));
|
||||
if ($isAppInstalled && !(php_sapi_name() === 'cli' || php_sapi_name() === 'phpdbg')) {
|
||||
if (setting('general.brand_logo_url')) {
|
||||
$brandLogo = setting('general.brand_logo_url');
|
||||
|
@ -152,7 +153,7 @@ class AdminPanelProvider extends PanelProvider
|
|||
} else {
|
||||
$panel->brandLogo(asset('images/phyre-logo.svg'));
|
||||
}
|
||||
|
||||
|
||||
$panel->brandLogoHeight('2.2rem')
|
||||
->colors([
|
||||
'primary'=>$defaultColor,
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
"guzzlehttp/guzzle": "^7.2",
|
||||
"jaocero/radio-deck": "^1.2",
|
||||
"jelix/inifile": "^3.4",
|
||||
"laravel/framework": "^10.10",
|
||||
"laravel/sanctum": "^3.3",
|
||||
"laravel/framework": "^11.0",
|
||||
"laravel/sanctum": "^4.0",
|
||||
"laravel/tinker": "^2.8",
|
||||
"leandrocfe/filament-apex-charts": "^3.1",
|
||||
"mkocansey/bladewind": "^2.4",
|
||||
|
@ -32,7 +32,7 @@
|
|||
"riodwanto/filament-ace-editor": "^1.0",
|
||||
"spatie/ssh": "^1.10",
|
||||
"stechstudio/filament-impersonate": "^3.8",
|
||||
"symfony/process": "^6.3",
|
||||
"symfony/process": "^7.2",
|
||||
"symfony/yaml": "^7.0",
|
||||
"torann/geoip": "^3.0",
|
||||
"wikimedia/composer-merge-plugin": "^2.1",
|
||||
|
@ -44,7 +44,7 @@
|
|||
"laravel/pint": "^1.15",
|
||||
"laravel/sail": "^1.18",
|
||||
"mockery/mockery": "^1.4.4",
|
||||
"nunomaduro/collision": "^7.0",
|
||||
"nunomaduro/collision": "^8.5",
|
||||
"phpunit/phpunit": "^10.1",
|
||||
"spatie/laravel-ignition": "^2.0"
|
||||
},
|
||||
|
|
1423
web/composer.lock
generated
263
web/package-lock.json
generated
|
@ -13,14 +13,14 @@
|
|||
"@xterm/xterm": "^5.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"@tailwindcss/typography": "^0.5.12",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"axios": "^1.6.1",
|
||||
"laravel-vite-plugin": "^0.8.0",
|
||||
"postcss": "^8.4.38",
|
||||
"postcss": "^8.5.2",
|
||||
"postcss-nesting": "^12.1.1",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"tippy.js": "^6.3.7",
|
||||
"vite": "^4.0.0"
|
||||
}
|
||||
|
@ -510,22 +510,24 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/forms": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz",
|
||||
"integrity": "sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==",
|
||||
"version": "0.5.10",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.10.tgz",
|
||||
"integrity": "sha512-utI1ONF6uf/pPNO68kmN1b8rEwNXv3czukalo8VtJH8ksIkZXr3Q3VYudZLkCsDd4Wku120uF02hYK25XGPorw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mini-svg-data-uri": "^1.2.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1"
|
||||
"tailwindcss": ">=3.0.0 || >= 3.0.0-alpha.1 || >= 4.0.0-alpha.20 || >= 4.0.0-beta.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/typography": {
|
||||
"version": "0.5.12",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.12.tgz",
|
||||
"integrity": "sha512-CNwpBpconcP7ppxmuq3qvaCxiRWnbhANpY/ruH4L5qs2GCiVDJXde/pjj2HWPV1+Q4G9+V/etrwUYopdcjAlyg==",
|
||||
"version": "0.5.16",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.16.tgz",
|
||||
"integrity": "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"lodash.castarray": "^4.4.0",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
|
@ -533,7 +535,7 @@
|
|||
"postcss-selector-parser": "6.0.10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"tailwindcss": ">=3.0.0 || insiders"
|
||||
"tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@xterm/addon-canvas": {
|
||||
|
@ -637,9 +639,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/autoprefixer": {
|
||||
"version": "10.4.19",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz",
|
||||
"integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==",
|
||||
"version": "10.4.20",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz",
|
||||
"integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
@ -655,12 +657,13 @@
|
|||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"browserslist": "^4.23.0",
|
||||
"caniuse-lite": "^1.0.30001599",
|
||||
"browserslist": "^4.23.3",
|
||||
"caniuse-lite": "^1.0.30001646",
|
||||
"fraction.js": "^4.3.7",
|
||||
"normalize-range": "^0.1.2",
|
||||
"picocolors": "^1.0.0",
|
||||
"picocolors": "^1.0.1",
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
},
|
||||
"bin": {
|
||||
|
@ -712,21 +715,22 @@
|
|||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
"fill-range": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/browserslist": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
|
||||
"integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
|
||||
"version": "4.24.4",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
|
||||
"integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
@ -742,11 +746,12 @@
|
|||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"caniuse-lite": "^1.0.30001587",
|
||||
"electron-to-chromium": "^1.4.668",
|
||||
"node-releases": "^2.0.14",
|
||||
"update-browserslist-db": "^1.0.13"
|
||||
"caniuse-lite": "^1.0.30001688",
|
||||
"electron-to-chromium": "^1.5.73",
|
||||
"node-releases": "^2.0.19",
|
||||
"update-browserslist-db": "^1.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"browserslist": "cli.js"
|
||||
|
@ -765,9 +770,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001605",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001605.tgz",
|
||||
"integrity": "sha512-nXwGlFWo34uliI9z3n6Qc0wZaf7zaZWA1CPZ169La5mV3I/gem7bst0vr5XQH5TJXZIMfDeZyOrZnSlVzKxxHQ==",
|
||||
"version": "1.0.30001700",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001700.tgz",
|
||||
"integrity": "sha512-2S6XIXwaE7K7erT8dY+kLQcpa5ms63XlRkMkReXjle+kf6c5g38vyMl+Z5y8dSxOFDhcFe+nxnn261PLxBSQsQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
@ -782,7 +787,8 @@
|
|||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
]
|
||||
],
|
||||
"license": "CC-BY-4.0"
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "3.6.0",
|
||||
|
@ -913,10 +919,11 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.4.724",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.724.tgz",
|
||||
"integrity": "sha512-RTRvkmRkGhNBPPpdrgtDKvmOEYTrPlXDfc0J/Nfq5s29tEahAwhiX4mmhNzj6febWMleulxVYPh7QwCSL/EldA==",
|
||||
"dev": true
|
||||
"version": "1.5.102",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.102.tgz",
|
||||
"integrity": "sha512-eHhqaja8tE/FNpIiBrvBjFV/SSKpyWHLvxuR9dPTdo+3V9ppdLmFB7ZZQ98qNovcngPLYIz0oOBF9P0FfZef5Q==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "9.2.2",
|
||||
|
@ -962,10 +969,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
|
||||
"integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
|
||||
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
|
@ -1008,10 +1016,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
|
@ -1210,6 +1219,7 @@
|
|||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
|
@ -1239,10 +1249,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/jiti": {
|
||||
"version": "1.21.0",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz",
|
||||
"integrity": "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==",
|
||||
"version": "1.21.7",
|
||||
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
|
||||
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"jiti": "bin/jiti.js"
|
||||
}
|
||||
|
@ -1264,12 +1275,16 @@
|
|||
}
|
||||
},
|
||||
"node_modules/lilconfig": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
|
||||
"integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
|
||||
"integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antonk52"
|
||||
}
|
||||
},
|
||||
"node_modules/lines-and-columns": {
|
||||
|
@ -1315,12 +1330,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
||||
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"braces": "^3.0.2",
|
||||
"braces": "^3.0.3",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
|
@ -1393,9 +1409,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.7",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
|
||||
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
|
||||
"version": "3.3.8",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz",
|
||||
"integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1403,6 +1419,7 @@
|
|||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
|
@ -1411,10 +1428,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/node-releases": {
|
||||
"version": "2.0.14",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
|
||||
"integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
|
||||
"dev": true
|
||||
"version": "2.0.19",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
|
||||
"integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/normalize-path": {
|
||||
"version": "3.0.0",
|
||||
|
@ -1484,10 +1502,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
||||
"dev": true
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
|
@ -1520,9 +1539,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.38",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
|
||||
"integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
|
||||
"version": "8.5.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz",
|
||||
"integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1538,10 +1557,11 @@
|
|||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.7",
|
||||
"picocolors": "^1.0.0",
|
||||
"source-map-js": "^1.2.0"
|
||||
"nanoid": "^3.3.8",
|
||||
"picocolors": "^1.1.1",
|
||||
"source-map-js": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
|
@ -1618,42 +1638,38 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-load-config/node_modules/lilconfig": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz",
|
||||
"integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antonk52"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-nested": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz",
|
||||
"integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==",
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
|
||||
"integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"postcss-selector-parser": "^6.0.11"
|
||||
"postcss-selector-parser": "^6.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.2.14"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-nested/node_modules/postcss-selector-parser": {
|
||||
"version": "6.0.16",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz",
|
||||
"integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==",
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
|
||||
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
|
@ -1912,10 +1928,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
|
||||
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
@ -2051,33 +2068,34 @@
|
|||
}
|
||||
},
|
||||
"node_modules/tailwindcss": {
|
||||
"version": "3.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz",
|
||||
"integrity": "sha512-U7sxQk/n397Bmx4JHbJx/iSOOv5G+II3f1kpLpY2QeUv5DcPdcTsYLlusZfq1NthHS1c1cZoyFmmkex1rzke0A==",
|
||||
"version": "3.4.17",
|
||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz",
|
||||
"integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@alloc/quick-lru": "^5.2.0",
|
||||
"arg": "^5.0.2",
|
||||
"chokidar": "^3.5.3",
|
||||
"chokidar": "^3.6.0",
|
||||
"didyoumean": "^1.2.2",
|
||||
"dlv": "^1.1.3",
|
||||
"fast-glob": "^3.3.0",
|
||||
"fast-glob": "^3.3.2",
|
||||
"glob-parent": "^6.0.2",
|
||||
"is-glob": "^4.0.3",
|
||||
"jiti": "^1.21.0",
|
||||
"lilconfig": "^2.1.0",
|
||||
"micromatch": "^4.0.5",
|
||||
"jiti": "^1.21.6",
|
||||
"lilconfig": "^3.1.3",
|
||||
"micromatch": "^4.0.8",
|
||||
"normalize-path": "^3.0.0",
|
||||
"object-hash": "^3.0.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"postcss": "^8.4.23",
|
||||
"picocolors": "^1.1.1",
|
||||
"postcss": "^8.4.47",
|
||||
"postcss-import": "^15.1.0",
|
||||
"postcss-js": "^4.0.1",
|
||||
"postcss-load-config": "^4.0.1",
|
||||
"postcss-nested": "^6.0.1",
|
||||
"postcss-selector-parser": "^6.0.11",
|
||||
"resolve": "^1.22.2",
|
||||
"sucrase": "^3.32.0"
|
||||
"postcss-load-config": "^4.0.2",
|
||||
"postcss-nested": "^6.2.0",
|
||||
"postcss-selector-parser": "^6.1.2",
|
||||
"resolve": "^1.22.8",
|
||||
"sucrase": "^3.35.0"
|
||||
},
|
||||
"bin": {
|
||||
"tailwind": "lib/cli.js",
|
||||
|
@ -2088,10 +2106,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/tailwindcss/node_modules/postcss-selector-parser": {
|
||||
"version": "6.0.16",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz",
|
||||
"integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==",
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
|
||||
"integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
|
@ -2135,6 +2154,7 @@
|
|||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
|
@ -2149,9 +2169,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/update-browserslist-db": {
|
||||
"version": "1.0.13",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
|
||||
"integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz",
|
||||
"integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
@ -2167,9 +2187,10 @@
|
|||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"escalade": "^3.1.1",
|
||||
"picocolors": "^1.0.0"
|
||||
"escalade": "^3.2.0",
|
||||
"picocolors": "^1.1.1"
|
||||
},
|
||||
"bin": {
|
||||
"update-browserslist-db": "cli.js"
|
||||
|
|
|
@ -6,14 +6,14 @@
|
|||
"build": "vite build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/forms": "^0.5.7",
|
||||
"@tailwindcss/typography": "^0.5.12",
|
||||
"autoprefixer": "^10.4.19",
|
||||
"@tailwindcss/forms": "^0.5.10",
|
||||
"@tailwindcss/typography": "^0.5.16",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"axios": "^1.6.1",
|
||||
"laravel-vite-plugin": "^0.8.0",
|
||||
"postcss": "^8.4.38",
|
||||
"postcss": "^8.5.2",
|
||||
"postcss-nesting": "^12.1.1",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"tailwindcss": "^3.4.17",
|
||||
"tippy.js": "^6.3.7",
|
||||
"vite": "^4.0.0"
|
||||
},
|
||||
|
|
1
web/public/build/assets/app-0fd9001c.css
Normal file
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"resources/css/app.css": {
|
||||
"file": "assets/app-4e206fd3.css",
|
||||
"file": "assets/app-0fd9001c.css",
|
||||
"isEntry": true,
|
||||
"src": "resources/css/app.css"
|
||||
},
|
||||
|
|
|
@ -1 +1 @@
|
|||
function i({state:a,splitKeys:n}){return{newTag:"",state:a,createTag:function(){if(this.newTag=this.newTag.trim(),this.newTag!==""){if(this.state.includes(this.newTag)){this.newTag="";return}this.state.push(this.newTag),this.newTag=""}},deleteTag:function(t){this.state=this.state.filter(e=>e!==t)},reorderTags:function(t){let e=this.state.splice(t.oldIndex,1)[0];this.state.splice(t.newIndex,0,e),this.state=[...this.state]},input:{["x-on:blur"]:"createTag()",["x-model"]:"newTag",["x-on:keydown"](t){["Enter",...n].includes(t.key)&&(t.preventDefault(),t.stopPropagation(),this.createTag())},["x-on:paste"](){this.$nextTick(()=>{if(n.length===0){this.createTag();return}let t=n.map(e=>e.replace(/[/\-\\^$*+?.()|[\]{}]/g,"\\$&")).join("|");this.newTag.split(new RegExp(t,"g")).forEach(e=>{this.newTag=e,this.createTag()})})}}}}export{i as default};
|
||||
function i({state:a,splitKeys:n}){return{newTag:"",state:a,createTag:function(){if(this.newTag=this.newTag.trim(),this.newTag!==""){if(this.state.includes(this.newTag)){this.newTag="";return}this.state.push(this.newTag),this.newTag=""}},deleteTag:function(t){this.state=this.state.filter(e=>e!==t)},reorderTags:function(t){let e=this.state.splice(t.oldIndex,1)[0];this.state.splice(t.newIndex,0,e),this.state=[...this.state]},input:{"x-on:blur":"createTag()","x-model":"newTag","x-on:keydown"(t){["Enter",...n].includes(t.key)&&(t.preventDefault(),t.stopPropagation(),this.createTag())},"x-on:paste"(){this.$nextTick(()=>{if(n.length===0){this.createTag();return}let t=n.map(e=>e.replace(/[/\-\\^$*+?.()|[\]{}]/g,"\\$&")).join("|");this.newTag.split(new RegExp(t,"g")).forEach(e=>{this.newTag=e,this.createTag()})})}}}}export{i as default};
|
||||
|
|
|
@ -1 +1 @@
|
|||
function m({state:r,statePath:o,placeholder:s,aceUrl:a,extensions:n,config:h={},options:c={},darkTheme:l,disableDarkTheme:d}){return{state:r,statePath:o,placeholder:s,options:c,darkTheme:l,disableDarkTheme:d,editor:null,observer:null,async init(){if(!await this.importAceEditor(a)){console.error("Failed to load the ACE editor core.");return}await this.importExtensions(n)||console.error("Failed to load ACE editor extensions."),this.configureAce(h),this.initializeEditor(),this.applyInitialTheme(),this.observeDarkModeChanges()},async importAceEditor(t){try{return await import(t),!0}catch(e){return console.error("Error importing the ACE editor core:",e),!1}},async importExtensions(t){try{let e=Object.values(t).map(i=>import(i));return await Promise.all(e),!0}catch(e){return console.error("Error importing ACE editor extensions:",e),!1}},configureAce(t){Object.entries(t).forEach(([e,i])=>ace.config.set(e,i))},initializeEditor(){this.editor=ace.edit(this.$refs.aceCodeEditor),this.editor.setOptions(this.options),this.editor.setValue(this.state?this.state:this.placeholder),this.editor.session.on("change",()=>{this.state=this.editor.getValue()})},applyInitialTheme(){this.disableDarkTheme?this.editor.setTheme(this.options.theme):this.setTheme()},observeDarkModeChanges(){if(this.disableDarkTheme)return;let t=document.querySelector("html");this.observer=new MutationObserver(()=>this.setTheme()),this.observer.observe(t,{attributes:!0,attributeFilter:["class"]})},setTheme(){let e=document.querySelector("html").classList.contains("dark")?this.darkTheme:this.options.theme;this.editor&&this.editor.setTheme(e)}}}export{m as default};
|
||||
function m({state:r,statePath:s,placeholder:o,aceUrl:a,extensions:n,config:h={},options:c={},darkTheme:l,disableDarkTheme:d}){return{state:r,statePath:s,placeholder:o,options:c,darkTheme:l,disableDarkTheme:d,editor:null,observer:null,async init(){if(!await this.importAceEditor(a)){console.error("Failed to load the ACE editor core.");return}await this.importExtensions(n)||console.error("Failed to load ACE editor extensions."),this.configureAce(h),this.initializeEditor(),this.applyInitialTheme(),this.observeDarkModeChanges()},async importAceEditor(t){try{return await import(t),!0}catch(e){return console.error("Error importing the ACE editor core:",e),!1}},async importExtensions(t){try{let e=Object.values(t).map(i=>import(i));return await Promise.all(e),!0}catch(e){return console.error("Error importing ACE editor extensions:",e),!1}},configureAce(t){Object.entries(t).forEach(([e,i])=>ace.config.set(e,i))},initializeEditor(){this.editor=ace.edit(this.$refs.aceCodeEditor),this.editor.setOptions(this.options),this.editor.session.setValue(this.state?this.state:this.placeholder),this.editor.session.on("change",()=>{this.state=this.editor.getValue()})},applyInitialTheme(){this.disableDarkTheme?this.editor.setTheme(this.options.theme):this.setTheme()},observeDarkModeChanges(){if(this.disableDarkTheme)return;let t=document.querySelector("html");this.observer=new MutationObserver(()=>this.setTheme()),this.observer.observe(t,{attributes:!0,attributeFilter:["class"]})},setTheme(){let e=document.querySelector("html").classList.contains("dark")?this.darkTheme:this.options.theme;this.editor&&this.editor.setTheme(e)}}}export{m as default};
|
||||
|
|
|
@ -1,7 +1,69 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@import '/vendor/filament/filament/resources/css/theme.css';
|
||||
|
||||
/*.fi-sidebar {
|
||||
background-color: rgba(255, 255, 255, 0.07) !important;
|
||||
}*/
|
||||
body {
|
||||
font-family: var(--font-family) !important;
|
||||
}
|
||||
|
||||
.fi-sidebar-item .fi-sidebar-item-button {
|
||||
@apply rounded-lg;
|
||||
}
|
||||
|
||||
.fi-sidebar-item-active .fi-sidebar-item-button {
|
||||
@apply rounded-lg ; /* bg-[#e5e9f0] */
|
||||
}
|
||||
|
||||
.fi-input-wrp {
|
||||
@apply ring-1 ;
|
||||
}
|
||||
|
||||
|
||||
.fi-ta-ctn {
|
||||
@apply shadow-md rounded-2xl border-none ring-0 dark:ring-1; /*rounded-none*/
|
||||
}
|
||||
|
||||
|
||||
.fi-section, .fi-wi-stats-overview-stat {
|
||||
@apply shadow-md rounded-2xl border-none ring-0 dark:ring-1;
|
||||
}
|
||||
|
||||
|
||||
.fi-topbar .fi-tenant-menu {
|
||||
@apply lg:!hidden;
|
||||
}
|
||||
|
||||
.fi-tenant-menu {
|
||||
@apply rounded-lg mt-4;
|
||||
}
|
||||
|
||||
.fi-global-search-field .fi-input-wrp, .fi-ta-search-field .fi-input-wrp {
|
||||
@apply rounded-full;
|
||||
}
|
||||
|
||||
.fi-global-search-field .fi-input-wrp {
|
||||
@apply ring-4;
|
||||
}
|
||||
|
||||
.fi-global-search-field .fi-input-wrp .fi-input-wrp-prefix {
|
||||
@apply rounded-full ps-2 mr-2;
|
||||
}
|
||||
|
||||
.fi-btn:not(.fi-btn-group .fi-btn) {
|
||||
@apply rounded-full;
|
||||
}
|
||||
|
||||
.fi-btn-group > .fi-btn:first-of-type {
|
||||
@apply rounded-s-full;
|
||||
}
|
||||
|
||||
.fi-btn-group > .fi-btn:last-of-type {
|
||||
@apply rounded-e-full;
|
||||
}
|
||||
|
||||
.fi-btn-group {
|
||||
@apply rounded-full;
|
||||
}
|
||||
|
||||
|
||||
.fi-badge {
|
||||
@apply rounded-xl;
|
||||
}
|
||||
|
|
15
web/resources/css/login.css
Normal file
|
@ -0,0 +1,15 @@
|
|||
.fi-simple-layout {
|
||||
> .fi-simple-main-ctn {
|
||||
@apply bg-[#4880FF] dark:bg-[var(--ds-dark-bg-primary-color)];
|
||||
@apply bg-[url(/vendor/nuxtifyts/dash-stack-theme/dash-stack-shape.svg)];
|
||||
@apply bg-no-repeat bg-cover;
|
||||
|
||||
> .fi-simple-main {
|
||||
@apply bg-white dark:bg-[var(--ds-dark-bg-secondary-color)] rounded-3xl;
|
||||
|
||||
.fi-simple-header-heading {
|
||||
@apply text-2xl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<x-filament-panels::page>
|
||||
|
||||
<div>
|
||||
{{$this->form}}
|
||||
</div>
|
||||
|
||||
</x-filament-panels::page>
|
|
@ -0,0 +1,15 @@
|
|||
<div>
|
||||
|
||||
@php
|
||||
$args = $this->error->getArguments();
|
||||
@endphp
|
||||
|
||||
@if(isset($args['message']))
|
||||
|
||||
<h4 class="text-red-500">
|
||||
{{ $args['message'] }}
|
||||
</h4>
|
||||
|
||||
@endif
|
||||
|
||||
</div>
|
|
@ -0,0 +1,50 @@
|
|||
<div>
|
||||
|
||||
<h2 class="text-2xl font-semibold text-gray-900 mb-4">
|
||||
Your domain must be verified before you can proceed.
|
||||
</h2>
|
||||
|
||||
<p class="mb-4">To link your domain to our server, follow these steps:</p>
|
||||
<ol class="list-decimal pl-6 mb-4">
|
||||
<li>Log in to your domain registrar's <strong>DNS Management Panel</strong>.</li>
|
||||
<li>Locate the option to manage <strong>DNS Records</strong> or <strong>Zone Editor</strong>.</li>
|
||||
<li>Add a new <strong>A Record</strong> with the following details:</li>
|
||||
</ol>
|
||||
|
||||
<div class="overflow-x-auto bg-white dark:bg-white/5 shadow-md rounded-lg">
|
||||
<table class="min-w-full text-left table-auto">
|
||||
<thead>
|
||||
<tr class="bg-primary-500 dark:bg-white/5 text-white">
|
||||
<th class="py-2 px-4">Record Type</th>
|
||||
<th class="py-2 px-4">Host/Name</th>
|
||||
<th class="py-2 px-4">Value (IP Address)</th>
|
||||
<th class="py-2 px-4">TTL</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="border-b">
|
||||
<td class="py-2 px-4">A</td>
|
||||
<td class="py-2 px-4">@ (or {{$domain}})</td>
|
||||
<td class="py-2 px-4"><strong>{{$serverIp}}</strong></td>
|
||||
<td class="py-2 px-4">300 (or default)</td>
|
||||
</tr>
|
||||
<tr class="border-b">
|
||||
<td class="py-2 px-4">A</td>
|
||||
<td class="py-2 px-4">www</td>
|
||||
<td class="py-2 px-4"><strong>{{$serverIp}}</strong></td>
|
||||
<td class="py-2 px-4">300 (or default)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<p class="mt-4"><strong>4.</strong> Save the changes and wait for DNS propagation (may take a few minutes to several hours).</p>
|
||||
<p class="mt-2"><strong>5.</strong> Verify by checking your domain with this command:</p>
|
||||
|
||||
<pre class="bg-gray-200 dark:bg-white/5 p-2 rounded-md my-2"><code>nslookup {{$domain}}</code></pre>
|
||||
<p>or</p>
|
||||
<pre class="bg-gray-200 dark:bg-white/5 p-2 rounded-md my-2"><code>dig A {{$domain}} +short</code></pre>
|
||||
|
||||
<p class="mt-4"><strong>🔹 Note:</strong> If you want to set up a subdomain (e.g., <code>app.{{$domain}}</code>), use <code>app</code> in the <strong>Host/Name</strong> field instead of <code>@</code>.</p>
|
||||
|
||||
</div>
|
|
@ -41,8 +41,10 @@
|
|||
<div class="sm:flex gap-3 px-6 py-6 rounded-xl bg-white shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10">
|
||||
<div class="">
|
||||
<div class="flex flex-col items-center w-16">
|
||||
<x-filament::icon :icon="$module['logoIcon']"
|
||||
class="w-12 h-12 text-primary-500"/>
|
||||
|
||||
|
||||
{!! $module['iconRendered'] !!}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-between items-center w-full">
|
||||
|
|
|
@ -1,56 +1,59 @@
|
|||
<x-filament-panels::page>
|
||||
|
||||
<style>
|
||||
.repair-tool-wrapper {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||
grid-gap: 10px;
|
||||
}
|
||||
.repair-tool-action {
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
padding: 20px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
margin: 10px;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
gap: 20px;
|
||||
}
|
||||
.repair-tool-action:hover {
|
||||
background: #f9f9f9;
|
||||
box-shadow: 0px 0px 3px #ccc;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div>
|
||||
@if (session()->has('message'))
|
||||
<div class="alert alert-success">
|
||||
<div class="p-4 mb-4 text-sm rounded-lg bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200">
|
||||
{{ session('message') }}
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="repair-tool-wrapper">
|
||||
<div wire:click="runRepair" class="repair-tool-action">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="50%" viewBox="0 0 512 512"><path fill="currentColor" d="m241.406 21l-15.22 34.75a182 182 0 0 0-23.467 2.97l-23.282-30.064l-25.094 8.532l-.125 38.25c-10.63 5.464-20.817 12.07-30.44 19.78L88.313 79.25L70.156 98.563L88.312 133a180.6 180.6 0 0 0-15.218 26.094l-38.938 1.062l-7.906 25.28l31.438 23.158c-1.505 9.38-2.24 18.858-2.282 28.344L20.5 254.625l3.656 26.25l38.313 7.5a182 182 0 0 0 8.5 23.5L45.72 343.22l14.093 22.436l39.25-9.187a185 185 0 0 0 7.718 8.53a187 187 0 0 0 17.72 16.125l-7.625 39.313l22.938 13.25l29.968-26.094a179.4 179.4 0 0 0 26.407 8.312l9.782 38.406l26.405 2.157l15.875-36.22c10.97-.66 21.904-2.3 32.656-4.938l25.22 29.22l24.593-9.844l-.72-14.813l-57.406-43.53c-16.712 4.225-34.042 5.356-51.063 3.436c-31.754-3.58-62.27-17.92-86.218-42.686c-54.738-56.614-53.173-146.67 3.438-201.406c27.42-26.513 62.69-39.963 98-40.344c37.59-.406 75.214 13.996 103.438 43.187c45.935 47.512 52.196 118.985 19.562 173.095l31.97 24.25a181 181 0 0 0 10.75-19.375l38.655-1.063l7.906-25.28l-31.217-23a183 183 0 0 0 2.28-28.594l34.688-17.625l-3.655-26.25l-38.28-7.5a182 182 0 0 0-12.75-32.125l22.81-31.594l-15.25-21.657l-37.56 10.906c-.472-.5-.93-1.007-1.408-1.5a185 185 0 0 0-18.937-17.064l7.188-37.125L334 43.78l-28.5 24.814c-9.226-3.713-18.702-6.603-28.313-8.75l-9.343-36.688zM183.25 174.5c-10.344.118-20.597 2.658-30 7.28l45.22 34.314c13.676 10.376 17.555 30.095 7.06 43.937c-10.498 13.85-30.656 15.932-44.53 5.408l-45.188-34.282c-4.627 24.793 4.135 51.063 25.594 67.344c19.245 14.597 43.944 17.33 65.22 9.688l4.78-1.72l4.03 3.063l135.19 102.564l4.03 3.062l-.344 5.063c-1.637 22.55 7.59 45.61 26.844 60.217c21.46 16.28 49.145 17.63 71.78 6.5l-45.186-34.28c-13.874-10.526-17.282-30.506-6.78-44.344c10.5-13.84 30.537-15.405 44.217-5.032l45.188 34.283c4.616-24.784-4.11-51.067-25.563-67.344c-19.313-14.658-43.817-17.562-64.968-10.033l-4.75 1.688l-4.03-3.063l-135.19-102.562l-4.03-3.063l.344-5.03c1.55-22.387-7.85-45.194-27.157-59.845c-12.544-9.516-27.222-13.978-41.78-13.812zm43.563 90.25l163.875 124.344L379.406 404L215.5 279.625z"/></svg>
|
||||
<div>
|
||||
Run Repair
|
||||
<div class="repair-tool-wrapper max-w[15rem] flex flex-col gap-4 p-6 bg-white dark:bg-gray-800 rounded-lg shadow-md">
|
||||
<!-- Repair Tool Action 1 -->
|
||||
<div wire:click="runRepair" class="repair-tool-action flex items-center space-x-3 p-4 border-2 border-primary-500 dark:border-primary-700 rounded-lg cursor-pointer transition-all hover:border-primary-600 dark:hover:border-primary-800 dark:text-white disabled:opacity-50 disabled:cursor-not-allowed" wire:loading.attr="disabled">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="50%" viewBox="0 0 512 512" class="h-8 w-8">
|
||||
<path fill="currentColor" d="m241.406 21l-15.22 34.75a182 182 0 0 0-23.467 2.97l-23.282-30.064l-25.094 8.532l-.125 38.25c-10.63 5.464-20.817 12.07-30.44 19.78L88.313 79.25L70.156 98.563L88.312 133a180.6 180.6 0 0 0-15.218 26.094l-38.938 1.062l-7.906 25.28l31.438 23.158c-1.505 9.38-2.24 18.858-2.282 28.344L20.5 254.625l3.656 26.25l38.313 7.5a182 182 0 0 0 8.5 23.5L45.72 343.22l14.093 22.436l39.25-9.187a185 185 0 0 0 7.718 8.53a187 187 0 0 0 17.72 16.125l-7.625 39.313l22.938 13.25l29.968-26.094a179.4 179.4 0 0 0 26.407 8.312l9.782 38.406l26.405 2.157l15.875-36.22c10.97-.66 21.904-2.3 32.656-4.938l25.22 29.22l24.593-9.844l-.72-14.813l-57.406-43.53c-16.712 4.225-34.042 5.356-51.063 3.436c-31.754-3.58-62.27-17.92-86.218-42.686c-54.738-56.614-53.173-146.67 3.438-201.406c27.42-26.513 62.69-39.963 98-40.344c37.59-.406 75.214 13.996 103.438 43.187c45.935 47.512 52.196 118.985 19.562 173.095l31.97 24.25a181 181 0 0 0 10.75-19.375l38.655-1.063l7.906-25.28l-31.217-23a183 183 0 0 0 2.28-28.594l34.688-17.625l-3.655-26.25l-38.28-7.5a182 182 0 0 0-12.75-32.125l22.81-31.594l-15.25-21.657l-37.56 10.906c-.472-.5-.93-1.007-1.408-1.5a185 185 0 0 0-18.937-17.064l7.188-37.125L334 43.78l-28.5 24.814c-9.226-3.713-18.702-6.603-28.313-8.75l-9.343-36.688zM183.25 174.5c-10.344.118-20.597 2.658-30 7.28l45.22 34.314c13.676 10.376 17.555 30.095 7.06 43.937c-10.498 13.85-30.656 15.932-44.53 5.408l-45.188-34.282c-4.627 24.793 4.135 51.063 25.594 67.344c19.245 14.597 43.944 17.33 65.22 9.688l4.78-1.72l4.03 3.063l135.19 102.564l4.03 3.062l-.344 5.063c-1.637 22.55 7.59 45.61 26.844 60.217c21.46 16.28 49.145 17.63 71.78 6.5l-45.186-34.28c-13.874-10.526-17.282-30.506-6.78-44.344c10.5-13.84 30.537-15.405 44.217-5.032l45.188 34.283c4.616-24.784-4.11-51.067-25.563-67.344c-19.313-14.658-43.817-17.562-64.968-10.033l-4.75 1.688l-4.03-3.063l-135.19-102.562l-4.03-3.063l.344-5.03c1.55-22.387-7.85-45.194-27.157-59.845c-12.544-9.516-27.222-13.978-41.78-13.812zm43.563 90.25l163.875 124.344L379.406 404L215.5 279.625z"/>
|
||||
</svg>
|
||||
<div>
|
||||
Run Repair
|
||||
</div>
|
||||
|
||||
<!-- Loading Spinner -->
|
||||
<div wire:loading wire:target="runRepair" class="ml-2 spinner-border animate-spin h-5 w-5 border-t-2 dark:border-white border-primary-700 rounded-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div wire:click="runDomainRepair" class="repair-tool-action">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="50%" viewBox="0 0 24 24"><path fill="currentColor" d="M2 14a1 1 0 1 1-2 0a1 1 0 0 1 2 0" opacity="0.5"/><path fill="currentColor" d="M6.719 10.262a1.73 1.73 0 0 0-2.458 0a1.757 1.757 0 0 0 0 2.476a1.73 1.73 0 0 0 2.458 0a.75.75 0 0 1 1.062 1.059a3.23 3.23 0 0 1-4.583 0a3.257 3.257 0 0 1 0-4.594a3.23 3.23 0 0 1 4.583 0a.75.75 0 0 1-1.062 1.059M8.5 11.5a3.25 3.25 0 1 1 6.5 0a3.25 3.25 0 0 1-6.5 0m3.25-1.75a1.75 1.75 0 1 0 0 3.5a1.75 1.75 0 0 0 0-3.5M18 8.25c-1.395 0-2.5 1.15-2.5 2.536V14a.75.75 0 0 0 1.5 0v-3.214c0-.587.462-1.036 1-1.036s1 .45 1 1.036V14a.75.75 0 0 0 1.5 0v-3.214c0-.587.462-1.036 1-1.036s1 .45 1 1.036V14a.75.75 0 0 0 1.5 0v-3.214C24 9.4 22.895 8.25 21.5 8.25c-.686 0-1.301.278-1.75.725A2.47 2.47 0 0 0 18 8.25"/></svg>
|
||||
<div>
|
||||
Run Domain Repair
|
||||
|
||||
<!-- Repair Tool Action 2 -->
|
||||
<div wire:click="runDomainRepair" class="repair-tool-action flex items-center space-x-3 p-4 border-2 border-primary-500 dark:border-primary-700 rounded-lg cursor-pointer transition-all hover:border-primary-600 dark:hover:border-primary-800 dark:text-white disabled:opacity-50 disabled:cursor-not-allowed" wire:loading.attr="disabled">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="50%" viewBox="0 0 24 24" class="h-8 w-8">
|
||||
<path fill="currentColor" d="M2 14a1 1 0 1 1-2 0a1 1 0 0 1 2 0" opacity="0.5"/>
|
||||
<path fill="currentColor" d="M6.719 10.262a1.73 1.73 0 0 0-2.458 0a1.757 1.757 0 0 0 0 2.476a1.73 1.73 0 0 0 2.458 0a.75.75 0 0 1 1.062 1.059a3.23 3.23 0 0 1-4.583 0a3.257 3.257 0 0 1 0-4.594a3.23 3.23 0 0 1 4.583 0a.75.75 0 0 1-1.062 1.059M8.5 11.5a3.25 3.25 0 1 1 6.5 0a3.25 3.25 0 0 1-6.5 0m3.25-1.75a1.75 1.75 0 1 0 0 3.5a1.75 1.75 0 0 0 0-3.5M18 8.25c-1.395 0-2.5 1.15-2.5 2.536V14a.75.75 0 0 0 1.5 0v-3.214c0-.587.462-1.036 1-1.036s1 .45 1 1.036V14a.75.75 0 0 0 1.5 0v-3.214c0-.587.462-1.036 1-1.036s1 .45 1 1.036V14a.75.75 0 0 0 1.5 0v-3.214C24 9.4 22.895 8.25 21.5 8.25c-.686 0-1.301.278-1.75.725A2.47 2.47 0 0 0 18 8.25"/>
|
||||
</svg>
|
||||
<div>
|
||||
Run Domain Repair
|
||||
</div>
|
||||
|
||||
<!-- Loading Spinner -->
|
||||
<div wire:loading wire:target="runDomainRepair" class="ml-2 spinner-border animate-spin h-5 w-5 border-t-2 dark:border-white border-primary-700 rounded-full"></div>
|
||||
</div>
|
||||
|
||||
<!-- Repair Tool Action 3 -->
|
||||
<div wire:click="runRenewSSL" class="repair-tool-action flex items-center space-x-3 p-4 border-2 border-primary-500 dark:border-primary-700 rounded-lg cursor-pointer transition-all hover:border-primary-600 dark:hover:border-primary-800 dark:text-white disabled:opacity-50 disabled:cursor-not-allowed" wire:loading.attr="disabled">
|
||||
<svg class="h-8 w-8" fill="currentColor" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||
<title>letsencrypt</title>
|
||||
<path d="M15.986 21.652c0.004-0 0.009-0 0.014-0 0.883 0 1.599 0.716 1.599 1.599 0 0.594-0.323 1.112-0.804 1.387l-0.008 0.004v1.556c-0.003 0.432-0.354 0.781-0.787 0.781s-0.784-0.349-0.787-0.781v-1.556c-0.488-0.28-0.812-0.798-0.812-1.391 0-0.878 0.708-1.591 1.584-1.598h0.001zM2.915 13.187c-0.573 0.044-1.021 0.52-1.021 1.1s0.448 1.056 1.017 1.1l0.004 0h3.747c0.573-0.044 1.021-0.52 1.021-1.1s-0.448-1.056-1.017-1.1l-0.004-0zM25.214 13.184c-0.608 0.002-1.1 0.495-1.1 1.103 0 0.609 0.494 1.103 1.103 1.103 0.030 0 0.059-0.001 0.088-0.003l-0.004 0h3.782c0.573-0.044 1.021-0.52 1.021-1.1s-0.448-1.056-1.017-1.1l-0.004-0h-3.782q-0.044-0.003-0.088-0.003zM15.991 12.555c0.003 0 0.006 0 0.009 0 1.485 0 2.689 1.204 2.689 2.689 0 0 0 0 0 0v0 1.859h-5.379v-1.859c0 0 0-0 0-0 0-1.482 1.199-2.684 2.68-2.689h0.001zM15.975 8.939c-3.472 0.014-6.281 2.831-6.281 6.305v0 1.859h-1.458c-0.665 0.002-1.203 0.54-1.206 1.205v11.483c0.002 0.665 0.541 1.203 1.205 1.205h15.528c0.665-0.002 1.203-0.54 1.205-1.205v-11.485c-0.003-0.664-0.541-1.2-1.205-1.203h-1.46v-1.859c-0-3.482-2.823-6.305-6.305-6.305-0.008 0-0.017 0-0.025 0h0.001zM6.403 4.906c-0 0-0 0-0 0-0.609 0-1.103 0.494-1.103 1.103 0 0.313 0.13 0.596 0.34 0.797l0 0 2.962 2.437c0.188 0.156 0.431 0.25 0.696 0.25 0.002 0 0.003 0 0.004 0h-0v-0.002c0 0 0 0 0 0 0.608 0 1.1-0.493 1.1-1.1 0-0.341-0.155-0.646-0.399-0.848l-0.002-0.001-2.964-2.435c-0.177-0.126-0.397-0.201-0.635-0.201h-0zM25.617 4.889c-0.246 0.001-0.472 0.083-0.654 0.22l0.003-0.002-2.967 2.434c-0.247 0.203-0.402 0.509-0.402 0.851 0 0.608 0.493 1.101 1.101 1.101 0.266 0 0.51-0.094 0.701-0.252l-0.002 0.002 2.963-2.438c0.223-0.202 0.363-0.493 0.363-0.817 0-0.608-0.493-1.1-1.1-1.1-0.002 0-0.004 0-0.006 0h0zM15.989 1.004c-0.576 0.006-1.046 0.452-1.089 1.017l-0 0.004v3.775c0.004 0.605 0.495 1.094 1.1 1.094 0.604 0 1.095-0.487 1.1-1.090v-3.779c-0.044-0.573-0.52-1.021-1.1-1.021-0.004 0-0.007 0-0.011 0h0.001z"></path>
|
||||
</svg>
|
||||
<div>
|
||||
Run Renew SSL
|
||||
</div>
|
||||
|
||||
<!-- Loading Spinner -->
|
||||
<div wire:loading wire:target="runRenewSSL" class="ml-2 spinner-border animate-spin h-5 w-5 border-t-2 dark:border-white border-primary-700 rounded-full"></div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -147,10 +147,32 @@
|
|||
<x-filament-panels::unsaved-action-changes-alert />
|
||||
|
||||
<div class="text-sm dark:text-white/40 text-center mb-4">
|
||||
© 2023-2024 <a href="#" class="hover:underline"> PHYRE - Web Hosting Panel ™</a>. All Rights Reserved.
|
||||
<br />
|
||||
<div style="width: 700px; margin: 0 auto;">
|
||||
PhyrePanel is currently in beta, so some features may not work as expected.
|
||||
<br />
|
||||
If you'd like to support development and help resolve issues, consider <a href="https://www.buymeacoffee.com/phyre">buying a coffee. ☕ </a>
|
||||
</div>
|
||||
|
||||
@php
|
||||
$primaryColor = 'FFDD00';
|
||||
try {
|
||||
if (setting('general.brand_primary_color')) {
|
||||
$primaryColor = setting('general.brand_primary_color');
|
||||
$primaryColor = str_replace('#', '', $primaryColor);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
//
|
||||
}
|
||||
@endphp
|
||||
|
||||
<a href="https://www.buymeacoffee.com/phyre" style="display: inline-block;margin: 15px 0px;">
|
||||
<img src="https://img.buymeacoffee.com/button-api/?text=Support Phyre Panel&emoji=&slug=phyre&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff" alt="Support Phyre Panel" style="height: 30px !important; ">
|
||||
<img src="https://img.buymeacoffee.com/button-api/?text=Support Phyre Panel&emoji=&slug=phyre&button_colour={{$primaryColor}}&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff" alt="Support Phyre Panel" style="height: 30px !important; ">
|
||||
</a>
|
||||
<br />
|
||||
<div>
|
||||
© 2023-2024 <a href="#" class="hover:underline"> PHYRE - Web Hosting Panel ™</a>. All Rights Reserved.
|
||||
<br />
|
||||
<br />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -34,3 +34,24 @@ Route::get('backup/download', [\App\Http\Controllers\BackupDownloadController::c
|
|||
|
||||
Route::get('/customers/{id}/login-with-token', [\App\Http\Controllers\Api\CustomersController::class, 'loginWithToken'])
|
||||
->name('customers.login-with-token');
|
||||
//
|
||||
//
|
||||
//Route::get('module/{module}/icon', function ($module) {
|
||||
//
|
||||
// $moduleInfo = \App\ModulesManager::getModuleInfo($module);
|
||||
// if (empty($moduleInfo)) {
|
||||
// return response()->json(['error' => 'Module not found'], 404);
|
||||
// }
|
||||
// if (!isset($moduleInfo['logoIcon'])) {
|
||||
// return response()->json(['error' => 'Module icon not found'], 404);
|
||||
// }
|
||||
// if (!file_exists(base_path($moduleInfo['logoIcon']))) {
|
||||
// return response()->json(['error' => 'Module icon not found'], 404);
|
||||
// }
|
||||
//
|
||||
// $icon = file_get_contents(base_path($moduleInfo['logoIcon']));
|
||||
//
|
||||
// return response($icon)->header('Content-Type', 'image/svg+xml');
|
||||
//
|
||||
//
|
||||
//})->name('module.icon.render');
|
||||
|
|
|
@ -9,4 +9,36 @@ export default {
|
|||
'./vendor/filament/**/*.blade.php',
|
||||
'./vendor/jaocero/radio-deck/resources/views/**/*.blade.php',
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
secondary: {
|
||||
50: 'rgba(var(--secondary-50), <alpha-value>)',
|
||||
100: 'rgba(var(--secondary-100), <alpha-value>)',
|
||||
200: 'rgba(var(--secondary-200), <alpha-value>)',
|
||||
300: 'rgba(var(--secondary-300), <alpha-value>)',
|
||||
400: 'rgba(var(--secondary-400), <alpha-value>)',
|
||||
500: 'rgba(var(--secondary-500), <alpha-value>)',
|
||||
600: 'rgba(var(--secondary-600), <alpha-value>)',
|
||||
700: 'rgba(var(--secondary-700), <alpha-value>)',
|
||||
800: 'rgba(var(--secondary-800), <alpha-value>)',
|
||||
900: 'rgba(var(--secondary-900), <alpha-value>)',
|
||||
950: 'rgba(var(--secondary-950), <alpha-value>)',
|
||||
},
|
||||
polarnight: {
|
||||
50: "#e5e9f0", // Lightest (pale version of #2E3440)
|
||||
100: "#d1d7e0", // Light shade of #2E3440
|
||||
200: "#a7b1c5", // Lighter shade of #3B4252
|
||||
300: "#8c9ab3", // Lighter shade of #3B4252
|
||||
400: "#71829b", // Lighter shade of #434C5E
|
||||
500: "#4c566a", // Base color (#4C566A)
|
||||
600: "#434c5e", // Darker shade of #434C5E
|
||||
700: "#3b4252", // Darker shade of #3B4252
|
||||
800: "#2e3440", // Base color (#2E3440)
|
||||
900: "#232831", // Darker shade of #2E3440
|
||||
950: "#1b2027" // Darkest shade, almost black
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -54,9 +54,9 @@ dpkg -i /usr/local/phyre/update/nginx/phyre-nginx-1.24.0-$OS_LOWER-$OS_VERSION.d
|
|||
printf "Updating the panel...\n"
|
||||
wget https://raw.githubusercontent.com/PhyreApps/PhyrePanelNGINX/main/compilators/debian/nginx/nginx.conf -O /usr/local/phyre/nginx/conf/nginx.conf
|
||||
#
|
||||
mkdir -p /usr/local/phyre/ssl
|
||||
cp /usr/local/phyre/web/server/ssl/phyre.crt /usr/local/phyre/ssl/phyre.crt
|
||||
cp /usr/local/phyre/web/server/ssl/phyre.key /usr/local/phyre/ssl/phyre.key
|
||||
# mkdir -p /usr/local/phyre/ssl
|
||||
# cp /usr/local/phyre/web/server/ssl/phyre.crt /usr/local/phyre/ssl/phyre.crt
|
||||
# cp /usr/local/phyre/web/server/ssl/phyre.key /usr/local/phyre/ssl/phyre.key
|
||||
|
||||
systemctl restart phyre
|
||||
#systemctl status phyre
|
||||
|
|