Compare commits
99 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
52f6fefed0 | ||
|
|
840555df42 | ||
|
|
9aa867e8aa | ||
|
|
d70b39f445 | ||
|
|
33055ecbf9 | ||
|
|
2e39fbce77 | ||
|
|
1b3b020d52 | ||
|
|
33d805ee82 | ||
|
|
57c02dd51c | ||
|
|
5b6bb98860 | ||
|
|
c01112a6c1 | ||
|
|
064b0967fc | ||
|
|
9f4c59abec | ||
|
|
d8547a0a3d | ||
|
|
9c51bd602b | ||
|
|
bc3f504ca3 | ||
|
|
761cbb7828 | ||
|
|
01fe3eb4cb | ||
|
|
f03dd8122b | ||
|
|
cfda2a6bf8 | ||
|
|
74ce668221 | ||
|
|
5a18d24464 | ||
|
|
5125862f80 | ||
|
|
fa791857ec | ||
|
|
24ad29ea99 | ||
|
|
cdfb972bd0 | ||
|
|
1985ce6ff8 | ||
|
|
d84eb65d55 | ||
|
|
16474fb5d0 | ||
|
|
186138b884 | ||
|
|
9ca6e37e39 | ||
|
|
866e182c31 | ||
|
|
739b9c97d7 | ||
|
|
0a43c5aa67 | ||
|
|
35bd4524e6 | ||
|
|
eba91d5f1d | ||
|
|
d764836244 | ||
|
|
b1b4a71c3e | ||
|
|
fb74b43d64 | ||
|
|
2a24506c15 | ||
|
|
f436c056e0 | ||
|
|
77b58de7ef | ||
|
|
f5a5367e3e | ||
|
|
b811a7ae41 | ||
|
|
d96dff1144 | ||
|
|
169ca11030 | ||
|
|
b25b7588a9 | ||
|
|
46cccdb708 | ||
|
|
7d9b34ecc9 | ||
|
|
a13879f2df | ||
|
|
1e8c0f85d5 | ||
|
|
2a181c9a77 | ||
|
|
1698f1162e | ||
|
|
cba50ecc59 | ||
|
|
908f191ac8 | ||
|
|
5a5dbea05b | ||
|
|
950f2e6c7a | ||
|
|
ec7be1bf63 | ||
|
|
5c4afe8f80 | ||
|
|
ececb3486b | ||
|
|
bebdea9c20 | ||
|
|
b8188c91be | ||
|
|
0b516d02c5 | ||
|
|
82dd87703f | ||
|
|
63b828d46b | ||
|
|
7d005f7e4a | ||
|
|
5750c1ae94 | ||
|
|
7eff0cb66d | ||
|
|
eff859a864 | ||
|
|
64dea61ec9 | ||
|
|
0b169df679 | ||
|
|
e72b68f8d6 | ||
|
|
f1414c1dcb | ||
|
|
7086098536 | ||
|
|
fb35d58a65 | ||
|
|
9120efe1c6 | ||
|
|
564672b436 | ||
|
|
cc8873ec31 | ||
|
|
fa90b96682 | ||
|
|
f1c7845b8d | ||
|
|
be244cde60 | ||
|
|
2dc2409d3f | ||
|
|
32fa6a8a52 | ||
|
|
ec790b41f1 | ||
|
|
b8337bed19 | ||
|
|
73e308f15a | ||
|
|
3e50237846 | ||
|
|
33b64625d9 | ||
|
|
c2c6ef8e51 | ||
|
|
a153753dc5 | ||
|
|
e965a53c18 | ||
|
|
1a7f76ea69 | ||
|
|
fe7307d655 | ||
|
|
411f85b43b | ||
|
|
4303d14e64 | ||
|
|
b7c3e06590 | ||
|
|
8fd8b806b1 | ||
|
|
2786626a3f | ||
|
|
8279817d8c |
45
.devcontainer/.env.devcontainer
Normal file
45
.devcontainer/.env.devcontainer
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
APP_DEBUG=true
|
||||||
|
APP_ENV=development
|
||||||
|
APP_FALLBACK_LOCALE=en
|
||||||
|
|
||||||
|
DB_CONNECTION=mysql
|
||||||
|
DB_HOST=127.0.0.1
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=blessingskin
|
||||||
|
DB_USERNAME=username
|
||||||
|
DB_PASSWORD=secret
|
||||||
|
DB_PREFIX=
|
||||||
|
|
||||||
|
# Hash Algorithm for Passwords
|
||||||
|
#
|
||||||
|
# Available values:
|
||||||
|
# - BCRYPT, ARGON2I, PHP_PASSWORD_HASH
|
||||||
|
# - MD5, SALTED2MD5
|
||||||
|
# - SHA256, SALTED2SHA256
|
||||||
|
# - SHA512, SALTED2SHA512
|
||||||
|
#
|
||||||
|
# New sites are *highly* recommended to use BCRYPT.
|
||||||
|
#
|
||||||
|
PWD_METHOD=BCRYPT
|
||||||
|
APP_KEY=base64:JaytOHG/JlLgulTVAhiS0tRqnAfCkQydbdP6VRmoAMY=
|
||||||
|
|
||||||
|
MAIL_MAILER=smtp
|
||||||
|
MAIL_HOST=
|
||||||
|
MAIL_PORT=465
|
||||||
|
MAIL_USERNAME=
|
||||||
|
MAIL_PASSWORD=
|
||||||
|
MAIL_ENCRYPTION=
|
||||||
|
MAIL_FROM_ADDRESS=
|
||||||
|
MAIL_FROM_NAME=
|
||||||
|
|
||||||
|
CACHE_DRIVER=file
|
||||||
|
SESSION_DRIVER=file
|
||||||
|
QUEUE_CONNECTION=sync
|
||||||
|
|
||||||
|
REDIS_CLIENT=phpredis
|
||||||
|
REDIS_HOST=127.0.0.1
|
||||||
|
REDIS_PASSWORD=null
|
||||||
|
REDIS_PORT=6379
|
||||||
|
|
||||||
|
PLUGINS_DIR=null
|
||||||
|
PLUGINS_URL=null
|
||||||
|
|
@ -14,6 +14,9 @@ RUN docker-php-ext-install mysqli pdo pdo_mysql gd zip
|
||||||
ARG NODE_VERSION="none"
|
ARG NODE_VERSION="none"
|
||||||
RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
|
RUN if [ "${NODE_VERSION}" != "none" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
|
||||||
|
|
||||||
|
# Enable Apache rewrite module
|
||||||
|
RUN a2enmod rewrite
|
||||||
|
|
||||||
# [Optional] Uncomment this section to install additional OS packages.
|
# [Optional] Uncomment this section to install additional OS packages.
|
||||||
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
|
||||||
# && apt-get -y install --no-install-recommends <your-package-list-here>
|
# && apt-get -y install --no-install-recommends <your-package-list-here>
|
||||||
|
|
|
||||||
13
.devcontainer/blessing-skin.apache.conf
Normal file
13
.devcontainer/blessing-skin.apache.conf
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
Listen 8080
|
||||||
|
|
||||||
|
<Directory /workspace/public/>
|
||||||
|
Options Indexes FollowSymLinks
|
||||||
|
AllowOverride All
|
||||||
|
Require all granted
|
||||||
|
</Directory>
|
||||||
|
|
||||||
|
<VirtualHost *:8080>
|
||||||
|
DocumentRoot /workspace/public
|
||||||
|
ErrorLog /workspace/storage/logs/apache-error.log
|
||||||
|
CustomLog /workspace/storage/logs/apache-access.log combined
|
||||||
|
</VirtualHost>
|
||||||
|
|
@ -2,30 +2,33 @@
|
||||||
// https://github.com/microsoft/vscode-dev-containers/tree/v0.231.6/containers/php-mariadb
|
// https://github.com/microsoft/vscode-dev-containers/tree/v0.231.6/containers/php-mariadb
|
||||||
// Update the VARIANT arg in docker-compose.yml to pick a PHP version
|
// Update the VARIANT arg in docker-compose.yml to pick a PHP version
|
||||||
{
|
{
|
||||||
"name": "PHP & MariaDB (Community)",
|
"name": "PHP & MariaDB (Community)",
|
||||||
"dockerComposeFile": "docker-compose.yml",
|
"dockerComposeFile": "docker-compose.yml",
|
||||||
"service": "app",
|
"service": "app",
|
||||||
"workspaceFolder": "/workspace",
|
"workspaceFolder": "/workspace",
|
||||||
|
|
||||||
// Set *default* container specific settings.json values on container create.
|
// Set *default* container specific settings.json values on container create.
|
||||||
"settings": { },
|
"settings": {},
|
||||||
|
|
||||||
// Add the IDs of extensions you want installed when the container is created.
|
// Add the IDs of extensions you want installed when the container is created.
|
||||||
"extensions": [
|
"extensions": [
|
||||||
"xdebug.php-debug",
|
"xdebug.php-debug",
|
||||||
"bmewburn.vscode-intelephense-client",
|
"bmewburn.vscode-intelephense-client",
|
||||||
"mrmlnc.vscode-apache"
|
"mrmlnc.vscode-apache"
|
||||||
],
|
],
|
||||||
|
|
||||||
// For use with PHP or Apache (e.g.php -S localhost:8080 or apache2ctl start)
|
// For use with PHP or Apache (e.g.php -S localhost:8080 or apache2ctl start)
|
||||||
"forwardPorts": [8080, 3306],
|
"forwardPorts": [8080, 3306],
|
||||||
|
|
||||||
// Use 'postCreateCommand' to run commands after the container is created.
|
// Use 'postCreateCommand' to run commands after the container is created.
|
||||||
"postCreateCommand": "cp .env.example .env && sudo chmod a+x \"$(pwd)\" && sudo rm -rf /var/www/html && sudo ln -s \"$(pwd)/public\" /var/www/html && composer install && yarn install",
|
"postCreateCommand": "sudo truncate -s 0 /etc/apache2/ports.conf && sudo rm -f /etc/apache2/sites-enabled/000-default.conf && sudo ln -sf /workspace/.devcontainer/blessing-skin.apache.conf /etc/apache2/sites-enabled/ && ln -sf .devcontainer/.env.devcontainer .env && composer install && yarn install",
|
||||||
|
|
||||||
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
// Start apache2 after the container is started
|
||||||
"remoteUser": "vscode",
|
"postStartCommand": "apache2ctl start && echo '\\n👉 \\e[0;32mPlease run '\\'yarn build\\'' to build the frontend. Application is available on port 8080.\\e[0m 👈\\n'",
|
||||||
"features": {
|
|
||||||
"powershell": "latest"
|
// Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
|
||||||
}
|
"remoteUser": "vscode",
|
||||||
|
"features": {
|
||||||
|
"powershell": "latest"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@
|
||||||
coverage/
|
coverage/
|
||||||
node_modules/
|
node_modules/
|
||||||
plugins/**
|
plugins/**
|
||||||
public/sw.js
|
|
||||||
public/meta.js
|
|
||||||
public/app/*
|
public/app/*
|
||||||
public/lang/*
|
public/lang/*
|
||||||
public/plugins/**
|
public/plugins/**
|
||||||
|
|
|
||||||
68
.env.testing
68
.env.testing
|
|
@ -35,3 +35,71 @@ PLUGINS_URL=
|
||||||
TEXTURES_DIR=
|
TEXTURES_DIR=
|
||||||
|
|
||||||
JWT_SECRET=1tdM3gXarxYI4KlAHMBo238iC2tEb4I3EtBlZTQQXvInXIt7V2ix7hJ1KTvxCKZW
|
JWT_SECRET=1tdM3gXarxYI4KlAHMBo238iC2tEb4I3EtBlZTQQXvInXIt7V2ix7hJ1KTvxCKZW
|
||||||
|
|
||||||
|
PASSPORT_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
|
||||||
|
MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQC6q6SCprX3yfOE
|
||||||
|
DFBnfFk3R+33qvoe26nYQkavKfv7zA9KQxCBNHEsFKOQ6ui+ViebVHAIHBPm2518
|
||||||
|
REVMLN2JONvXbPETV6gJO/b6FFwo2Aow/GbTnesLhWEAPW11ei0/hBbjWF9hQZ/n
|
||||||
|
x3YsFk0xtml2iPDijfUohwp50iFyCQylw4S5Sy3vuVdM063dkxvECsU6wmHDev9C
|
||||||
|
PxFZGl3W2iLSwttYl7xmlwll8xuqxDQUJpJbOxrPeDKdDI1ikarSqA1c8bV1YLT+
|
||||||
|
CHxB7T5b1EPeaYRmeLl+wyd/ZxeBWWgDLBusi5wPFpSEIVxu1RzTYarOXEpD+XNV
|
||||||
|
Ohpb7LxpbJx8YRJru1B6CBouVO2pqoCEM21GtG7zSDNtaY+yVcj9Kf2SIbfz0e6a
|
||||||
|
SLAcyOT0q3aId4+z9q8TAfPVV7y0D7B3PaOz/3pMC+jHDjCRwQkN/DR7ODUKEjCd
|
||||||
|
UjsveGHtseBa3qBoKWcg39ZvwYeDF0P/cFa/yOqw5JxyWhbjk95YdPaSixdUyyMG
|
||||||
|
XkFTOrnBREVtBAfdTOG6WTFcIlyJK+ST0cJXVcrjFonbmJCCwTJqxz9t+935CfTt
|
||||||
|
CzLLPdONU16jZJ7j1cVoWb4L8o0OA+FBSawBxFOKyhFlh3+HKRnSCZSDqaSDsYUf
|
||||||
|
M3IupiGUcByhpZ9mNqhnLeivIXwapwIDAQABAoICAFu27F+S2DH0A9S7lh+aPV1H
|
||||||
|
VniKhVR2+aZ6va7fUmJ++n4yoB/TK82MIGcZu5uUyeXr4RVi8jZJbcF565BHNNtw
|
||||||
|
V7cq2/F0bmeHEkwBh9w7dRpnUIAlhS/GawfKpoaDLksYM4SkzUwECbQ/0GRN2sST
|
||||||
|
ipKGKtAtDihI3RFIeE1Ge/PPsdy2Ps4bAnUJRdHpLsmtvwSlL5JzUonyYawlI7jl
|
||||||
|
uRlTSqDnAFZpW+E+xjerKalC4EK5se0AceGuoqKszkCs98/UJCMVDigH9EER9sL4
|
||||||
|
chYLQtVz+DN7X+MdPDO9wThZygkHGPhi0DpxB7CevYhv4pN8TbLDE3Lq1ruWf2T3
|
||||||
|
7ts21ymjVIiOayBA9l86P0FSS/lP9KF53LyeNkOJKUy5On6xHoW5IKlrMJdmGwFH
|
||||||
|
B4yaR7bw5vxErhpMTzcYJVWqjCbo+PBJhdy7x+2XrrBLs9X0hfS/jeeAIuRlzju1
|
||||||
|
9xe3zO6U41sDjkCkrUavOn57DL6jh9LMgxT8cZkSdrP6rpawEyjPUi5kMbbQkv0j
|
||||||
|
eWiqz0vozJN5HcVpj36F5kqZyCnIojmeo4FCKdn7n/wvyGYQPSAekVpV80KzoJ2j
|
||||||
|
GQ440Q7Sgozj/Lw4cCPgG3/MA1Dwu+TUuaddFjBH2oqZ2X0bCqVCEVWhfmaD4z2R
|
||||||
|
I9C9nLvpxoMtcCHkG1VFAoIBAQDfawcBHMPxZQOy/qTqXZd7YR3bzGgd/SkLEWwg
|
||||||
|
PtDGKe36tDf3E/RGRij4HGl9v/fA7N/CufW0tJY7Ii/cn7yYdZg/dzaCoYIZbICl
|
||||||
|
CytWtsM0iH3XPuY3UpgsOwML0xK8hdD1U7qBKk5rnjF9Q9vKrB8ATR9hM0bPaGtr
|
||||||
|
Bqfx8A+kj6wqRpA8jbN0kZxJVv0/LgZSCrH3qUjHfXoYYtLhMBZd8UydyvyETo/1
|
||||||
|
Z44WS9oNqX8mBUvHjsuOQx3+eFPOr69QPIo06QMxytSEzMilgz40QUBWF68gKwGi
|
||||||
|
NYdUfR3IXVTmvJhYH2mQWqMKVk+KJFd2UanjKbBCOKrDSG4TAoIBAQDV5LMp/ztd
|
||||||
|
YQvMCWJzUrpazGqkoEGli/qxWb/pDpemgQT++lt6PBRQmmLKXZfNp9VJdZdP6+lF
|
||||||
|
ypGcA8tACY93m7Fk4wtewXG+0oTxmBkWqSiiO3ExoBQTxXLoZ9GwKt/exaM25QJ1
|
||||||
|
O2livxrYFFJbUe1YRqQENIURYk13RgeIaWS0gd9vp/yp0EhZAvGUPHFjKRsLjw7Y
|
||||||
|
gZDJ+lXj2pXg9THUzkhVDm+fM6blIsLcvf7qc8yKQI3nwZr00e/ba7xSNF8AhpdP
|
||||||
|
rxw59vm1RzsngZpZOK0Z1143gFRtGhhVWtvmhCvJo1EOssFu01ixE0bNq5nRIIJo
|
||||||
|
O/mY7NC9bCOdAoIBAEBfcyYz5pUwGM/DJTtN+i6XfeXt0HYLkn7Y50GnN7pRLHuW
|
||||||
|
36U2P6Tb5EQQ06hi3nzdA1/0+sG1Yq/pGsdD0zBOea6Xp8IdzQGMTMjBHhyfDkGd
|
||||||
|
rjyNqAF6r9PWsPsANx7Qo7N8C3nZ+bxyWSoRmkucKlaI4ii8gIOUP5cX1N4V4Dv3
|
||||||
|
FZEcwcRgw7srlU9gXBmPJk0PPdXxFcI8+if6mW4+z8MDmqLAcN+iT0JTMxJjipFz
|
||||||
|
K+qFjh8Smr4Dwqmme+dKoYXJ27yBAuWe3nrhElL2LL8bqfDkZBYtrgvRxotmfWVU
|
||||||
|
1vigkHibnGv2YZHB6qsP649w2jVUtq9t6m3X+bcCggEAEKDqCN7N17GewCsOm1aY
|
||||||
|
JEz2EXxf/iXGxJjsoYq/4XLwV35RNEyNa8LE4WSrU5KzszVQISd/CCz6av2khIL5
|
||||||
|
w1u4S9aW4LP7StGFAl9HvApEnXAvmaMPTIYyK70+gQqkQuZsjOz65vBKfiHLTXcu
|
||||||
|
++h/ojhDsgv/OF3DFf28wi8nZB0gqMaPjwghR8JB07trOUFN1/U0O0K/ZeRvXvp0
|
||||||
|
YnvNdvTejLZFmUPjuracHZsrwUBla24fWiAkEtprYkya5G0r4ZeVFd3QPPVlbmFu
|
||||||
|
SOD7heoxEuw6Z+gzKBQ6RhB9PguSd+eZeqINBbeqkoGkJIMtvyNe4AmhmvD2PXO1
|
||||||
|
xQKCAQAx12vD3q2+DHrpJ4fKGp1RbCxFIOYgXcBJ6zCozVZXpLUa54IBTLyQyDNF
|
||||||
|
D8+Wq5b1IbCnxBn55tsgq/CSLkVHigVfUDGnAt3lD+ggLdZmu7ayQY0BNe1quF5M
|
||||||
|
EgkOE0uYtq+2p+u4gxRB+gnQd1YIlPs0U0mrawbzV5ZX2vR5Ry1XpBno75JpnUbN
|
||||||
|
3D9DuIDVLuqsKJcx6KClWef2PzJB2uN7jDf4UnCtp5QCFB1GNt+5AzCNh9Bozas8
|
||||||
|
OflASrSn64AeyCZycCplmRY/F4BnH++7YI0Q/mjawByW7qYoHkFzmKuUcgakh200
|
||||||
|
y/ieeWy8Vunl0e4T4Bz/0zInBifn
|
||||||
|
-----END PRIVATE KEY-----"
|
||||||
|
|
||||||
|
PASSPORT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----
|
||||||
|
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuqukgqa198nzhAxQZ3xZ
|
||||||
|
N0ft96r6Htup2EJGryn7+8wPSkMQgTRxLBSjkOrovlYnm1RwCBwT5tudfERFTCzd
|
||||||
|
iTjb12zxE1eoCTv2+hRcKNgKMPxm053rC4VhAD1tdXotP4QW41hfYUGf58d2LBZN
|
||||||
|
MbZpdojw4o31KIcKedIhcgkMpcOEuUst77lXTNOt3ZMbxArFOsJhw3r/Qj8RWRpd
|
||||||
|
1toi0sLbWJe8ZpcJZfMbqsQ0FCaSWzsaz3gynQyNYpGq0qgNXPG1dWC0/gh8Qe0+
|
||||||
|
W9RD3mmEZni5fsMnf2cXgVloAywbrIucDxaUhCFcbtUc02GqzlxKQ/lzVToaW+y8
|
||||||
|
aWycfGESa7tQeggaLlTtqaqAhDNtRrRu80gzbWmPslXI/Sn9kiG389HumkiwHMjk
|
||||||
|
9Kt2iHePs/avEwHz1Ve8tA+wdz2js/96TAvoxw4wkcEJDfw0ezg1ChIwnVI7L3hh
|
||||||
|
7bHgWt6gaClnIN/Wb8GHgxdD/3BWv8jqsOSccloW45PeWHT2kosXVMsjBl5BUzq5
|
||||||
|
wURFbQQH3UzhulkxXCJciSvkk9HCV1XK4xaJ25iQgsEyasc/bfvd+Qn07Qsyyz3T
|
||||||
|
jVNeo2Se49XFaFm+C/KNDgPhQUmsAcRTisoRZYd/hykZ0gmUg6mkg7GFHzNyLqYh
|
||||||
|
lHAcoaWfZjaoZy3oryF8GqcCAwEAAQ==
|
||||||
|
-----END PUBLIC KEY-----"
|
||||||
|
|
|
||||||
11
.github/stale.yml
vendored
11
.github/stale.yml
vendored
|
|
@ -1,11 +0,0 @@
|
||||||
daysUntilStale: 7
|
|
||||||
daysUntilClose: 7
|
|
||||||
exemptLabels:
|
|
||||||
- bug
|
|
||||||
- enhancement
|
|
||||||
staleLabel: stale
|
|
||||||
markComment: >
|
|
||||||
This issue has been automatically marked as stale because it has not had
|
|
||||||
recent activity. It will be closed if no further activity occurs.
|
|
||||||
|
|
||||||
该 issue 在近期内缺少更新或答复,如果仍然缺少更新或响应,issue 将被关闭。
|
|
||||||
43
.github/workflows/CI.yml
vendored
43
.github/workflows/CI.yml
vendored
|
|
@ -20,20 +20,19 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
- name: Setup PHP
|
- name: Setup PHP
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
with:
|
with:
|
||||||
php-version: 8.0
|
php-version: 8.3
|
||||||
coverage: none
|
coverage: none
|
||||||
extensions: mbstring, dom, fileinfo, gd
|
extensions: mbstring, dom, fileinfo, gd, imagick
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: |
|
run: |
|
||||||
composer install --prefer-dist --no-progress
|
composer install --prefer-dist --no-progress
|
||||||
- name: Prepare
|
- name: Prepare
|
||||||
run: |
|
run: |
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
php artisan key:generate
|
|
||||||
mkdir -p resources/views/overrides
|
mkdir -p resources/views/overrides
|
||||||
- name: Validate Twig templates
|
- name: Validate Twig templates
|
||||||
run: php artisan twig:lint -v
|
run: php artisan twig:lint -v
|
||||||
|
|
@ -45,24 +44,24 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
php: ['8.0', '8.1']
|
php: ['8.2', '8.3']
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
- name: Setup PHP only
|
- name: Setup PHP only
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
if: matrix.php != '8.0'
|
if: matrix.php != '8.3'
|
||||||
with:
|
with:
|
||||||
php-version: ${{ matrix.php }}
|
php-version: ${{ matrix.php }}
|
||||||
coverage: none
|
coverage: none
|
||||||
extensions: mbstring, dom, fileinfo, sqlite, gd, zip
|
extensions: mbstring, dom, fileinfo, sqlite, gd, zip, imagick
|
||||||
- name: Setup PHP with Xdebug
|
- name: Setup PHP with Xdebug
|
||||||
uses: shivammathur/setup-php@v2
|
uses: shivammathur/setup-php@v2
|
||||||
if: matrix.php == '8.0'
|
if: matrix.php == '8.3'
|
||||||
with:
|
with:
|
||||||
php-version: ${{ matrix.php }}
|
php-version: ${{ matrix.php }}
|
||||||
coverage: xdebug
|
coverage: xdebug
|
||||||
extensions: mbstring, dom, fileinfo, sqlite, gd, zip
|
extensions: mbstring, dom, fileinfo, sqlite, gd, zip, imagick
|
||||||
- name: Cache Composer dependencies
|
- name: Cache Composer dependencies
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
|
|
@ -72,14 +71,14 @@ jobs:
|
||||||
- name: Install Composer dependencies
|
- name: Install Composer dependencies
|
||||||
run: composer install --no-progress --prefer-dist --optimize-autoloader
|
run: composer install --no-progress --prefer-dist --optimize-autoloader
|
||||||
- name: Run tests only
|
- name: Run tests only
|
||||||
if: matrix.php != '8.0'
|
if: matrix.php != '8.3'
|
||||||
run: ./vendor/bin/phpunit
|
run: ./vendor/bin/phpunit
|
||||||
- name: Run tests with coverage report
|
- name: Run tests with coverage report
|
||||||
if: matrix.php == '8.0'
|
if: matrix.php == '8.3'
|
||||||
run: ./vendor/bin/phpunit --coverage-clover=coverage.xml
|
run: ./vendor/bin/phpunit --coverage-clover=coverage.xml
|
||||||
- name: Upload coverage report
|
- name: Upload coverage report
|
||||||
uses: codecov/codecov-action@v1
|
uses: codecov/codecov-action@v1
|
||||||
if: matrix.php == '8.0' && success()
|
if: matrix.php == '8.3' && success()
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.CODECOV_TOKEN }}
|
token: ${{ secrets.CODECOV_TOKEN }}
|
||||||
name: github-actions
|
name: github-actions
|
||||||
|
|
@ -88,7 +87,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: yarn install --frozen-lockfile
|
run: yarn install --frozen-lockfile
|
||||||
- name: Run checks
|
- name: Run checks
|
||||||
|
|
@ -101,7 +100,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: yarn
|
run: yarn
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
|
|
@ -115,8 +114,14 @@ jobs:
|
||||||
name: Snapshot Build
|
name: Snapshot Build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
- name: Setup PHP
|
||||||
|
uses: shivammathur/setup-php@v2
|
||||||
|
with:
|
||||||
|
php-version: 8.2
|
||||||
|
coverage: none
|
||||||
|
extensions: mbstring, dom, fileinfo, sqlite, gd, zip, imagick
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
- name: Cache Node dependencies
|
- name: Cache Node dependencies
|
||||||
uses: actions/cache@v3
|
uses: actions/cache@v3
|
||||||
with:
|
with:
|
||||||
|
|
@ -138,11 +143,13 @@ jobs:
|
||||||
yarn build
|
yarn build
|
||||||
cp resources/assets/src/images/bg.webp public/app/
|
cp resources/assets/src/images/bg.webp public/app/
|
||||||
cp resources/assets/src/images/favicon.ico public/app/
|
cp resources/assets/src/images/favicon.ico public/app/
|
||||||
- uses: benjlevesque/short-sha@v1.2
|
- uses: benjlevesque/short-sha@v3.0
|
||||||
id: short-sha
|
id: short-sha
|
||||||
- name: Archive release
|
- name: Archive release
|
||||||
run: zip -9 -r blessing-skin-server-${{ steps.short-sha.outputs.sha }}.zip app bootstrap config database plugins public resources/lang resources/views resources/misc/textures routes storage vendor .env.example artisan LICENSE README.md README-zh.md index.html
|
run: zip -9 -r blessing-skin-server-${{ steps.short-sha.outputs.sha }}.zip app bootstrap config database plugins public resources/lang resources/views resources/misc/textures routes storage vendor .env.example artisan LICENSE README.md README-zh.md index.html
|
||||||
- name: Upload artifact
|
- name: Upload artifact
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
|
if-no-files-found: error
|
||||||
|
name: blessing-skin-server-${{ steps.short-sha.outputs.sha }}.zip
|
||||||
path: blessing-skin-server-${{ steps.short-sha.outputs.sha }}.zip
|
path: blessing-skin-server-${{ steps.short-sha.outputs.sha }}.zip
|
||||||
|
|
|
||||||
58
.github/workflows/Release.yml
vendored
58
.github/workflows/Release.yml
vendored
|
|
@ -9,32 +9,32 @@ jobs:
|
||||||
release:
|
release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
- name: Build and create archive
|
- name: Build and create archive
|
||||||
run: ./tools/release.ps1
|
run: ./tools/release.ps1
|
||||||
shell: pwsh
|
shell: pwsh
|
||||||
env:
|
env:
|
||||||
AZURE_TOKEN: ${{ secrets.AZURE_TOKEN }}
|
AZURE_TOKEN: ${{ secrets.AZURE_TOKEN }}
|
||||||
- name: Create Release
|
- name: Create Release
|
||||||
id: create_release
|
id: create_release
|
||||||
uses: actions/create-release@v1
|
uses: actions/create-release@v1
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
tag_name: ${{ github.ref }}
|
tag_name: ${{ github.ref }}
|
||||||
release_name: ${{ github.ref }}
|
release_name: ${{ github.ref }}
|
||||||
prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') || contains(github.ref, 'rc') }}
|
prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') || contains(github.ref, 'rc') }}
|
||||||
- name: Get version
|
- name: Get version
|
||||||
id: get_version
|
id: get_version
|
||||||
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
|
run: echo "VERSION=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_OUTPUT
|
||||||
- name: Upload release asset
|
- name: Upload release asset
|
||||||
id: upload_release_asset
|
id: upload_release_asset
|
||||||
uses: actions/upload-release-asset@v1
|
uses: actions/upload-release-asset@v1
|
||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
with:
|
with:
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||||
asset_path: ./blessing-skin-server-${{ steps.get_version.outputs.VERSION }}.zip
|
asset_path: ./blessing-skin-server-${{ steps.get_version.outputs.VERSION }}.zip
|
||||||
asset_name: blessing-skin-server-${{ steps.get_version.outputs.VERSION }}.zip
|
asset_name: blessing-skin-server-${{ steps.get_version.outputs.VERSION }}.zip
|
||||||
asset_content_type: application/zip
|
asset_content_type: application/zip
|
||||||
|
|
|
||||||
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -25,5 +25,5 @@ storage/options.php
|
||||||
.phpunit.result.cache
|
.phpunit.result.cache
|
||||||
.php-cs-fixer.cache
|
.php-cs-fixer.cache
|
||||||
resources/views/overrides
|
resources/views/overrides
|
||||||
public/sw.js
|
.DS_Store
|
||||||
public/meta.js
|
*/.DS_Store
|
||||||
|
|
@ -8,11 +8,16 @@ $finder = PhpCsFixer\Finder::create()
|
||||||
|
|
||||||
$config = new PhpCsFixer\Config();
|
$config = new PhpCsFixer\Config();
|
||||||
return $config->setRules([
|
return $config->setRules([
|
||||||
'@Symfony' => true,
|
'@Symfony' => true,
|
||||||
'align_multiline_comment' => true,
|
'align_multiline_comment' => true,
|
||||||
'array_syntax' => ['syntax' => 'short'],
|
'array_syntax' => ['syntax' => 'short'],
|
||||||
'increment_style' => ['style' => 'post'],
|
'increment_style' => ['style' => 'post'],
|
||||||
'list_syntax' => ['syntax' => 'short'],
|
'list_syntax' => ['syntax' => 'short'],
|
||||||
'yoda_style' => false,
|
'yoda_style' => false,
|
||||||
])
|
'global_namespace_import' => [
|
||||||
|
'import_constants' => true,
|
||||||
|
'import_functions' => true,
|
||||||
|
'import_classes' => null,
|
||||||
|
],
|
||||||
|
])
|
||||||
->setFinder($finder);
|
->setFinder($finder);
|
||||||
|
|
|
||||||
68
.vscode/launch.json
vendored
68
.vscode/launch.json
vendored
|
|
@ -1,38 +1,34 @@
|
||||||
{
|
{
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"type": "node",
|
"type": "node",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"name": "Launch Jest Tests",
|
"name": "Launch Jest Tests",
|
||||||
"program": "${workspaceFolder}/node_modules/.bin/jest",
|
"program": "${workspaceFolder}/node_modules/.bin/jest",
|
||||||
"args": ["${file}"],
|
"args": ["${file}"],
|
||||||
"internalConsoleOptions": "openOnSessionStart",
|
"internalConsoleOptions": "openOnSessionStart",
|
||||||
"skipFiles": [
|
"skipFiles": ["<node_internals>/**"]
|
||||||
"<node_internals>/**"
|
},
|
||||||
]
|
{
|
||||||
},
|
"type": "php",
|
||||||
{
|
"request": "launch",
|
||||||
"type": "php",
|
"name": "Launch with XDebug",
|
||||||
"request": "launch",
|
"ignore": ["**/vendor/**/*.php"]
|
||||||
"name": "Launch with XDebug",
|
},
|
||||||
"ignore": [
|
{
|
||||||
"**/vendor/**/*.php"
|
"type": "firefox",
|
||||||
]
|
"request": "launch",
|
||||||
},
|
"reAttach": true,
|
||||||
{
|
"name": "Launch with Firefox Debugger",
|
||||||
"type": "firefox",
|
"url": "http://localhost/",
|
||||||
"request": "launch",
|
"webRoot": "${workspaceFolder}",
|
||||||
"reAttach": true,
|
"pathMappings": [
|
||||||
"name": "Launch with Firefox Debugger",
|
{
|
||||||
"url": "http://localhost/",
|
"url": "webpack:///",
|
||||||
"webRoot": "${workspaceFolder}",
|
"path": "${workspaceFolder}/"
|
||||||
"pathMappings": [
|
}
|
||||||
{
|
]
|
||||||
"url": "webpack:///",
|
}
|
||||||
"path": "${workspaceFolder}/"
|
]
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
105
README-zh.md
105
README-zh.md
|
|
@ -40,9 +40,9 @@ Blessing Skin 是一个开源的 PHP 项目,这意味着您可以自由地在
|
||||||
Blessing Skin 对您的服务器有一定的要求。在大多数情况下,下列所需的 PHP 扩展已经开启。
|
Blessing Skin 对您的服务器有一定的要求。在大多数情况下,下列所需的 PHP 扩展已经开启。
|
||||||
|
|
||||||
- 一台支持 URL 重写的主机,Nginx 或 Apache
|
- 一台支持 URL 重写的主机,Nginx 或 Apache
|
||||||
- PHP >= 8.0.2
|
- PHP >= 8.1.0
|
||||||
- 安装并启用如下 PHP 扩展:
|
- 安装并启用如下 PHP 扩展:
|
||||||
- OpenSSL
|
- OpenSSL >= 1.1.1 (TLS 1.3)
|
||||||
- PDO
|
- PDO
|
||||||
- Mbstring
|
- Mbstring
|
||||||
- Tokenizer
|
- Tokenizer
|
||||||
|
|
@ -52,6 +52,7 @@ Blessing Skin 对您的服务器有一定的要求。在大多数情况下,下
|
||||||
- JSON
|
- JSON
|
||||||
- fileinfo
|
- fileinfo
|
||||||
- zip
|
- zip
|
||||||
|
- Imagick
|
||||||
|
|
||||||
## 快速使用
|
## 快速使用
|
||||||
|
|
||||||
|
|
@ -61,105 +62,9 @@ Blessing Skin 对您的服务器有一定的要求。在大多数情况下,下
|
||||||
|
|
||||||
Blessing Skin 提供了强大的插件系统,您可以通过添加多种多样的插件来为您的皮肤站添加功能。
|
Blessing Skin 提供了强大的插件系统,您可以通过添加多种多样的插件来为您的皮肤站添加功能。
|
||||||
|
|
||||||
## 支持并赞助 Blessing Skin
|
|
||||||
|
|
||||||
如果您觉得这个软件对您很有帮助,欢迎通过赞助来支持开发!
|
|
||||||
|
|
||||||
目前可在 [爱发电](https://afdian.net/@blessing-skin) 上赞助。
|
|
||||||
|
|
||||||
### Sponsors
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td align=center>
|
|
||||||
<a href="https://afdian.net/@gao_cai_sheng">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/2aac23481b1b11ea9f6e52540025c377/avatar/96a8b23d98cbac5aa36601db15a27e5e_w512_h512_s234.jpg" width="120" height="120">
|
|
||||||
<br>
|
|
||||||
gao_cai_sheng
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td align=center>
|
|
||||||
<a href="https://afdian.net/@LD_fantasy">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/9bed7bb454f011eb821652540025c377/avatar/cb679e3eac693e0eea2eac527c7954e0_w700_h1307_s137.jpg" width="120" height="120">
|
|
||||||
<br>
|
|
||||||
K_LazyCat
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td align=center>
|
|
||||||
<a href="https://afdian.net/@nmzy2018">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/a66f79d2f5a311e9af4e52540025c377/avatar/98682fb3c5914a39c8986bb1e97b5501_w512_h512_s248.jpg" width="120" height="120">
|
|
||||||
<br>
|
|
||||||
伊南
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td align=center>
|
|
||||||
<a href="">
|
|
||||||
<img src="https://pic1.afdiancdn.com/default/avatar/avatar-blue.png" width="120" height="120">
|
|
||||||
<br>
|
|
||||||
家乐
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td align=center>
|
|
||||||
<a href="https://afdian.net/@oar-01">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/e391f6ccdfa911ebb0e352540025c377/avatar/74da4afa92fa2666c306d43ab7a8804b_w1920_h1080_s338.jpg" width="120" height="120">
|
|
||||||
<br>
|
|
||||||
黄金鞘翅的郡主
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align=center>
|
|
||||||
<a href="https://www.bilibili.plus/caucmc1.orz">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/edde2efc879611e889f552540025c377/avatar/d6a712efd6560b28989ac33f99c8915d_w473_h454_s24.jpg" width="120" height="120">
|
|
||||||
<br>
|
|
||||||
睡觉塞牙
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
### Backers
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td align=center>
|
|
||||||
<a href="https://afdian.net/@ValiantShishu976400">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/178a08963a5e11e9addd52540025c377/avatar/ece9f089aaf2c2f83204a8de11697caf_w350_h350_s16.jpg" width="75" height="75">
|
|
||||||
<br>
|
|
||||||
飒爽师叔
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td align=center>
|
|
||||||
<a href="https://afdian.net/@PAKingdom">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/18ad3338e58a11e9b29352540025c377/avatar/1e8b6476b589ddac545ac1ce13166e59_w584_h797_s59.jpg" width="75" height="75">
|
|
||||||
<br>
|
|
||||||
皮皮帕
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td align=center>
|
|
||||||
<a href="https://afdian.net/@oar-01">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/e391f6ccdfa911ebb0e352540025c377/avatar/74da4afa92fa2666c306d43ab7a8804b_w1920_h1080_s338.jpg" width="75" height="75">
|
|
||||||
<br>
|
|
||||||
黄金鞘翅的郡主
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td align=center>
|
|
||||||
<a href="">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/fc143860efa111ebb3e552540025c377/avatar/6e1d0f3f6ffb80b89b44269f59aa775f_w1080_h1080_s107.jpg" width="75" height="75">
|
|
||||||
<br>
|
|
||||||
♂sudo rm -rf /*[幼稚鬼]
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
## 自行构建
|
## 自行构建
|
||||||
|
|
||||||
详情可阅读 [这里](https://blessing.netlify.com/build.html)。
|
详情可阅读 [这里](https://blessing.netlify.app/build.html)。
|
||||||
|
|
||||||
> 您可以订阅我们的 Telegram 频道 [Blessing Skin News](https://t.me/blessing_skin_news) 来获取最新开发动态。当有新的 Commit 被推送时,我们的机器人将会在频道内发送一条消息来提示您能否拉取最新代码,以及拉取后应该做什么。
|
> 您可以订阅我们的 Telegram 频道 [Blessing Skin News](https://t.me/blessing_skin_news) 来获取最新开发动态。当有新的 Commit 被推送时,我们的机器人将会在频道内发送一条消息来提示您能否拉取最新代码,以及拉取后应该做什么。
|
||||||
|
|
||||||
|
|
@ -171,7 +76,7 @@ Blessing Skin 可支持多种语言,当前支持英语、简体中文和西班
|
||||||
|
|
||||||
## 问题报告
|
## 问题报告
|
||||||
|
|
||||||
请参阅 [报告问题的正确姿势](https://blessing.netlify.com/report.html)。
|
请参阅 [报告问题的正确姿势](https://blessing.netlify.app/report.html)。
|
||||||
|
|
||||||
## 相关链接
|
## 相关链接
|
||||||
|
|
||||||
|
|
|
||||||
103
README.md
103
README.md
|
|
@ -4,7 +4,7 @@
|
||||||
<p align="center"><img src="https://media.githubusercontent.com/media/bs-community/logo/main/logo.png"></p>
|
<p align="center"><img src="https://media.githubusercontent.com/media/bs-community/logo/main/logo.png"></p>
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/bs-community/blessing-skin-server/actions"><img alt="GitHub Workflow Status" src="https://img.shields.io/github/workflow/status/bs-community/blessing-skin-server/CI?style=flat-square"></a>
|
<a href="https://github.com/bs-community/blessing-skin-server/actions"><img alt="GitHub Workflow Status" src="https://img.shields.io/github/actions/workflow/status/bs-community/blessing-skin-server/CI.yml?branch=dev&style=flat-square"></a>
|
||||||
<a href="https://codecov.io/gh/bs-community/blessing-skin-server"><img alt="Codecov" src="https://img.shields.io/codecov/c/github/bs-community/blessing-skin-server?style=flat-square"></a>
|
<a href="https://codecov.io/gh/bs-community/blessing-skin-server"><img alt="Codecov" src="https://img.shields.io/codecov/c/github/bs-community/blessing-skin-server?style=flat-square"></a>
|
||||||
<a href="https://github.com/bs-community/blessing-skin-server/releases"><img alt="GitHub release (latest SemVer including pre-releases)" src="https://img.shields.io/github/v/release/bs-community/blessing-skin-server?include_prereleases&style=flat-square"></a>
|
<a href="https://github.com/bs-community/blessing-skin-server/releases"><img alt="GitHub release (latest SemVer including pre-releases)" src="https://img.shields.io/github/v/release/bs-community/blessing-skin-server?include_prereleases&style=flat-square"></a>
|
||||||
<a href="https://github.com/bs-community/blessing-skin-server/blob/master/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/bs-community/blessing-skin-server?style=flat-square"></a>
|
<a href="https://github.com/bs-community/blessing-skin-server/blob/master/LICENSE"><img alt="GitHub" src="https://img.shields.io/github/license/bs-community/blessing-skin-server?style=flat-square"></a>
|
||||||
|
|
@ -40,9 +40,9 @@ Blessing Skin is an open-source project written in PHP, which means you can depl
|
||||||
Blessing Skin has only a few system requirements. In most cases, these PHP extensions are already enabled.
|
Blessing Skin has only a few system requirements. In most cases, these PHP extensions are already enabled.
|
||||||
|
|
||||||
- Web server with URL rewriting enabled (Nginx or Apache)
|
- Web server with URL rewriting enabled (Nginx or Apache)
|
||||||
- PHP >= 8.0.2
|
- PHP >= 8.1.0
|
||||||
- PHP Extensions
|
- PHP Extensions
|
||||||
- OpenSSL
|
- OpenSSL >= 1.1.1 (TLS 1.3)
|
||||||
- PDO
|
- PDO
|
||||||
- Mbstring
|
- Mbstring
|
||||||
- Tokenizer
|
- Tokenizer
|
||||||
|
|
@ -52,6 +52,7 @@ Blessing Skin has only a few system requirements. In most cases, these PHP exten
|
||||||
- JSON
|
- JSON
|
||||||
- fileinfo
|
- fileinfo
|
||||||
- zip
|
- zip
|
||||||
|
- Imagick
|
||||||
|
|
||||||
## Quick Install
|
## Quick Install
|
||||||
|
|
||||||
|
|
@ -61,102 +62,6 @@ Please read [Installation Guide](https://blessing.netlify.app/en/setup.html).
|
||||||
|
|
||||||
Blessing Skin provides an elegant and powerful plugin system, and you can attach plenty of functions and customization to your site via installing plugins.
|
Blessing Skin provides an elegant and powerful plugin system, and you can attach plenty of functions and customization to your site via installing plugins.
|
||||||
|
|
||||||
## Supporting Blessing Skin
|
|
||||||
|
|
||||||
Welcome to sponsoring Blessing Skin if this software is useful for you!
|
|
||||||
|
|
||||||
Currently you can sponsor us via [爱发电](https://afdian.net/@blessing-skin).
|
|
||||||
|
|
||||||
### Sponsors
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td align=center>
|
|
||||||
<a href="https://afdian.net/@gao_cai_sheng">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/2aac23481b1b11ea9f6e52540025c377/avatar/96a8b23d98cbac5aa36601db15a27e5e_w512_h512_s234.jpg" width="120" height="120">
|
|
||||||
<br>
|
|
||||||
gao_cai_sheng
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td align=center>
|
|
||||||
<a href="https://afdian.net/@LD_fantasy">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/9bed7bb454f011eb821652540025c377/avatar/cb679e3eac693e0eea2eac527c7954e0_w700_h1307_s137.jpg" width="120" height="120">
|
|
||||||
<br>
|
|
||||||
K_LazyCat
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td align=center>
|
|
||||||
<a href="https://afdian.net/@nmzy2018">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/a66f79d2f5a311e9af4e52540025c377/avatar/98682fb3c5914a39c8986bb1e97b5501_w512_h512_s248.jpg" width="120" height="120">
|
|
||||||
<br>
|
|
||||||
伊南
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td align=center>
|
|
||||||
<a href="">
|
|
||||||
<img src="https://pic1.afdiancdn.com/default/avatar/avatar-blue.png" width="120" height="120">
|
|
||||||
<br>
|
|
||||||
家乐
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td align=center>
|
|
||||||
<a href="https://afdian.net/@oar-01">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/e391f6ccdfa911ebb0e352540025c377/avatar/74da4afa92fa2666c306d43ab7a8804b_w1920_h1080_s338.jpg" width="120" height="120">
|
|
||||||
<br>
|
|
||||||
黄金鞘翅的郡主
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td align=center>
|
|
||||||
<a href="https://www.bilibili.plus/caucmc1.orz">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/edde2efc879611e889f552540025c377/avatar/d6a712efd6560b28989ac33f99c8915d_w473_h454_s24.jpg" width="120" height="120">
|
|
||||||
<br>
|
|
||||||
睡觉塞牙
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
### Backers
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td align=center>
|
|
||||||
<a href="https://afdian.net/@ValiantShishu976400">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/178a08963a5e11e9addd52540025c377/avatar/ece9f089aaf2c2f83204a8de11697caf_w350_h350_s16.jpg" width="75" height="75">
|
|
||||||
<br>
|
|
||||||
飒爽师叔
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td align=center>
|
|
||||||
<a href="https://afdian.net/@PAKingdom">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/18ad3338e58a11e9b29352540025c377/avatar/1e8b6476b589ddac545ac1ce13166e59_w584_h797_s59.jpg" width="75" height="75">
|
|
||||||
<br>
|
|
||||||
皮皮帕
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td align=center>
|
|
||||||
<a href="https://afdian.net/@oar-01">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/e391f6ccdfa911ebb0e352540025c377/avatar/74da4afa92fa2666c306d43ab7a8804b_w1920_h1080_s338.jpg" width="75" height="75">
|
|
||||||
<br>
|
|
||||||
黄金鞘翅的郡主
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
<td align=center>
|
|
||||||
<a href="">
|
|
||||||
<img src="https://pic1.afdiancdn.com/user/fc143860efa111ebb3e552540025c377/avatar/6e1d0f3f6ffb80b89b44269f59aa775f_w1080_h1080_s107.jpg" width="75" height="75">
|
|
||||||
<br>
|
|
||||||
♂sudo rm -rf /*[幼稚鬼]
|
|
||||||
</a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
## Build From Source
|
## Build From Source
|
||||||
|
|
||||||
Please refer to [Manual Build](https://blessing.netlify.app/build.html).
|
Please refer to [Manual Build](https://blessing.netlify.app/build.html).
|
||||||
|
|
|
||||||
|
|
@ -53,8 +53,9 @@ class Handler extends ExceptionHandler
|
||||||
})
|
})
|
||||||
->filter(function ($trace) {
|
->filter(function ($trace) {
|
||||||
// @codeCoverageIgnoreStart
|
// @codeCoverageIgnoreStart
|
||||||
$isFromPlugins = !app()->runningUnitTests() &&
|
$isFromPlugins = !app()->runningUnitTests()
|
||||||
Str::contains($trace['file'], resolve('plugins')->getPluginsDirs()->all());
|
&& Str::contains($trace['file'], resolve('plugins')->getPluginsDirs()->all());
|
||||||
|
|
||||||
// @codeCoverageIgnoreEnd
|
// @codeCoverageIgnoreEnd
|
||||||
return Str::startsWith($trace['file'], 'app') || $isFromPlugins;
|
return Str::startsWith($trace['file'], 'app') || $isFromPlugins;
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ class AdminController extends Controller
|
||||||
|
|
||||||
$grouping = fn ($field) => fn ($item) => Carbon::parse($item->$field)->isoFormat('l');
|
$grouping = fn ($field) => fn ($item) => Carbon::parse($item->$field)->isoFormat('l');
|
||||||
$mapping = fn ($item) => count($item);
|
$mapping = fn ($item) => count($item);
|
||||||
$aligning = fn ($data) => fn ($day) => ($data->get($day) ?? 0);
|
$aligning = fn ($data) => fn ($day) => $data->get($day) ?? 0;
|
||||||
|
|
||||||
/** @var Collection */
|
/** @var Collection */
|
||||||
$userRegistration = User::where('register_at', '>=', $oneMonthAgo)
|
$userRegistration = User::where('register_at', '>=', $oneMonthAgo)
|
||||||
|
|
@ -86,7 +86,7 @@ class AdminController extends Controller
|
||||||
Request $request,
|
Request $request,
|
||||||
PluginManager $plugins,
|
PluginManager $plugins,
|
||||||
Filesystem $filesystem,
|
Filesystem $filesystem,
|
||||||
Filter $filter
|
Filter $filter,
|
||||||
) {
|
) {
|
||||||
$db = config('database.connections.'.config('database.default'));
|
$db = config('database.connections.'.config('database.default'));
|
||||||
$dbType = Arr::get([
|
$dbType = Arr::get([
|
||||||
|
|
|
||||||
|
|
@ -8,16 +8,16 @@ use App\Mail\ForgotPassword;
|
||||||
use App\Models\Player;
|
use App\Models\Player;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Rules;
|
use App\Rules;
|
||||||
use Auth;
|
|
||||||
use Blessing\Filter;
|
use Blessing\Filter;
|
||||||
use Blessing\Rejection;
|
use Blessing\Rejection;
|
||||||
use Cache;
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Mail;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Session;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use URL;
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
use Illuminate\Support\Facades\Session;
|
||||||
|
use Illuminate\Support\Facades\URL;
|
||||||
use Vectorface\Whip\Whip;
|
use Vectorface\Whip\Whip;
|
||||||
|
|
||||||
class AuthController extends Controller
|
class AuthController extends Controller
|
||||||
|
|
@ -50,7 +50,7 @@ class AuthController extends Controller
|
||||||
Request $request,
|
Request $request,
|
||||||
Rules\Captcha $captcha,
|
Rules\Captcha $captcha,
|
||||||
Dispatcher $dispatcher,
|
Dispatcher $dispatcher,
|
||||||
Filter $filter
|
Filter $filter,
|
||||||
) {
|
) {
|
||||||
$data = $request->validate([
|
$data = $request->validate([
|
||||||
'identification' => 'required',
|
'identification' => 'required',
|
||||||
|
|
@ -151,7 +151,7 @@ class AuthController extends Controller
|
||||||
Request $request,
|
Request $request,
|
||||||
Rules\Captcha $captcha,
|
Rules\Captcha $captcha,
|
||||||
Dispatcher $dispatcher,
|
Dispatcher $dispatcher,
|
||||||
Filter $filter
|
Filter $filter,
|
||||||
) {
|
) {
|
||||||
$can = $filter->apply('can_register', null);
|
$can = $filter->apply('can_register', null);
|
||||||
if ($can instanceof Rejection) {
|
if ($can instanceof Rejection) {
|
||||||
|
|
@ -176,8 +176,8 @@ class AuthController extends Controller
|
||||||
$dispatcher->dispatch('auth.registration.attempt', [$data]);
|
$dispatcher->dispatch('auth.registration.attempt', [$data]);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
option('register_with_player_name') &&
|
option('register_with_player_name')
|
||||||
Player::where('name', $playerName)->count() > 0
|
&& Player::where('name', $playerName)->count() > 0
|
||||||
) {
|
) {
|
||||||
return json(trans('user.player.add.repeated'), 1);
|
return json(trans('user.player.add.repeated'), 1);
|
||||||
}
|
}
|
||||||
|
|
@ -248,7 +248,7 @@ class AuthController extends Controller
|
||||||
Request $request,
|
Request $request,
|
||||||
Rules\Captcha $captcha,
|
Rules\Captcha $captcha,
|
||||||
Dispatcher $dispatcher,
|
Dispatcher $dispatcher,
|
||||||
Filter $filter
|
Filter $filter,
|
||||||
) {
|
) {
|
||||||
$data = $request->validate([
|
$data = $request->validate([
|
||||||
'email' => 'required|email',
|
'email' => 'required|email',
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,12 @@ namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Texture;
|
use App\Models\Texture;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Auth;
|
|
||||||
use Blessing\Filter;
|
use Blessing\Filter;
|
||||||
use Blessing\Rejection;
|
use Blessing\Rejection;
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class ClosetController extends Controller
|
class ClosetController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -75,7 +75,7 @@ class ClosetController extends Controller
|
||||||
public function add(
|
public function add(
|
||||||
Request $request,
|
Request $request,
|
||||||
Dispatcher $dispatcher,
|
Dispatcher $dispatcher,
|
||||||
Filter $filter
|
Filter $filter,
|
||||||
) {
|
) {
|
||||||
['tid' => $tid, 'name' => $name] = $request->validate([
|
['tid' => $tid, 'name' => $name] = $request->validate([
|
||||||
'tid' => 'required|integer',
|
'tid' => 'required|integer',
|
||||||
|
|
@ -132,7 +132,7 @@ class ClosetController extends Controller
|
||||||
Request $request,
|
Request $request,
|
||||||
Dispatcher $dispatcher,
|
Dispatcher $dispatcher,
|
||||||
Filter $filter,
|
Filter $filter,
|
||||||
$tid
|
$tid,
|
||||||
) {
|
) {
|
||||||
['name' => $name] = $request->validate(['name' => 'required']);
|
['name' => $name] = $request->validate(['name' => 'required']);
|
||||||
/** @var User */
|
/** @var User */
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,15 @@ class ClosetManagementController extends Controller
|
||||||
public function add(Request $request, Dispatcher $dispatcher, User $user)
|
public function add(Request $request, Dispatcher $dispatcher, User $user)
|
||||||
{
|
{
|
||||||
$tid = $request->input('tid');
|
$tid = $request->input('tid');
|
||||||
/** @var Texture */
|
$texture = Texture::find($tid);
|
||||||
$texture = Texture::findOrFail($tid);
|
if (!$texture) {
|
||||||
|
return json(trans('user.closet.add.not-found'), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($user->closet()->where('tid', $request->tid)->count() > 0) {
|
||||||
|
return json(trans('user.closet.add.repeated'), 1);
|
||||||
|
}
|
||||||
|
|
||||||
$name = $texture->name;
|
$name = $texture->name;
|
||||||
|
|
||||||
$dispatcher->dispatch('closet.adding', [$tid, $name, $user]);
|
$dispatcher->dispatch('closet.adding', [$tid, $name, $user]);
|
||||||
|
|
@ -35,10 +42,14 @@ class ClosetManagementController extends Controller
|
||||||
$tid = $request->input('tid');
|
$tid = $request->input('tid');
|
||||||
$dispatcher->dispatch('closet.removing', [$tid, $user]);
|
$dispatcher->dispatch('closet.removing', [$tid, $user]);
|
||||||
|
|
||||||
/** @var Texture */
|
$item = $user->closet()->find($tid);
|
||||||
$texture = Texture::findOrFail($tid);
|
if (empty($item)) {
|
||||||
|
return json(trans('user.closet.remove.non-existent'), 1);
|
||||||
|
}
|
||||||
|
|
||||||
$user->closet()->detach($texture->tid);
|
$user->closet()->detach($tid);
|
||||||
|
|
||||||
|
$texture = Texture::find($tid);
|
||||||
|
|
||||||
$dispatcher->dispatch('closet.removed', [$texture, $user]);
|
$dispatcher->dispatch('closet.removed', [$texture, $user]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -163,6 +163,10 @@ class OptionsController extends Controller
|
||||||
->text('max_upload_file_size')->addon('KB')
|
->text('max_upload_file_size')->addon('KB')
|
||||||
->hint(trans('options.general.max_upload_file_size.hint', ['size' => ini_get('upload_max_filesize')]));
|
->hint(trans('options.general.max_upload_file_size.hint', ['size' => ini_get('upload_max_filesize')]));
|
||||||
|
|
||||||
|
$form->group('max_texture_width')
|
||||||
|
->text('max_texture_width')->addon('px')
|
||||||
|
->hint(trans('options.general.max_texture_width.hint'));
|
||||||
|
|
||||||
$form->select('player_name_rule')
|
$form->select('player_name_rule')
|
||||||
->option('official', trans('options.general.player_name_rule.official'))
|
->option('official', trans('options.general.player_name_rule.official'))
|
||||||
->option('cjk', trans('options.general.player_name_rule.cjk'))
|
->option('cjk', trans('options.general.player_name_rule.cjk'))
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,11 @@ use App\Models\Player;
|
||||||
use App\Models\Texture;
|
use App\Models\Texture;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Rules;
|
use App\Rules;
|
||||||
use Auth;
|
|
||||||
use Blessing\Filter;
|
use Blessing\Filter;
|
||||||
use Blessing\Rejection;
|
use Blessing\Rejection;
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
class PlayerController extends Controller
|
class PlayerController extends Controller
|
||||||
|
|
@ -124,7 +124,7 @@ class PlayerController extends Controller
|
||||||
public function delete(
|
public function delete(
|
||||||
Dispatcher $dispatcher,
|
Dispatcher $dispatcher,
|
||||||
Filter $filter,
|
Filter $filter,
|
||||||
Player $player
|
Player $player,
|
||||||
) {
|
) {
|
||||||
/** @var User */
|
/** @var User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
@ -157,7 +157,7 @@ class PlayerController extends Controller
|
||||||
Request $request,
|
Request $request,
|
||||||
Dispatcher $dispatcher,
|
Dispatcher $dispatcher,
|
||||||
Filter $filter,
|
Filter $filter,
|
||||||
Player $player
|
Player $player,
|
||||||
) {
|
) {
|
||||||
$name = $request->validate([
|
$name = $request->validate([
|
||||||
'name' => [
|
'name' => [
|
||||||
|
|
@ -194,7 +194,7 @@ class PlayerController extends Controller
|
||||||
Request $request,
|
Request $request,
|
||||||
Dispatcher $dispatcher,
|
Dispatcher $dispatcher,
|
||||||
Filter $filter,
|
Filter $filter,
|
||||||
Player $player
|
Player $player,
|
||||||
) {
|
) {
|
||||||
/** @var User */
|
/** @var User */
|
||||||
$user = auth()->user();
|
$user = auth()->user();
|
||||||
|
|
@ -234,7 +234,7 @@ class PlayerController extends Controller
|
||||||
Request $request,
|
Request $request,
|
||||||
Dispatcher $dispatcher,
|
Dispatcher $dispatcher,
|
||||||
Filter $filter,
|
Filter $filter,
|
||||||
Player $player
|
Player $player,
|
||||||
) {
|
) {
|
||||||
$types = $request->input('type', []);
|
$types = $request->input('type', []);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,8 @@ class PlayersManagementController extends Controller
|
||||||
$currentUser = $request->user();
|
$currentUser = $request->user();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$owner->uid !== $currentUser->uid &&
|
$owner->uid !== $currentUser->uid
|
||||||
$owner->permission >= $currentUser->permission
|
&& $owner->permission >= $currentUser->permission
|
||||||
) {
|
) {
|
||||||
return json(trans('admin.players.no-permission'), 1)
|
return json(trans('admin.players.no-permission'), 1)
|
||||||
->setStatusCode(403);
|
->setStatusCode(403);
|
||||||
|
|
@ -44,7 +44,7 @@ class PlayersManagementController extends Controller
|
||||||
public function name(
|
public function name(
|
||||||
Player $player,
|
Player $player,
|
||||||
Request $request,
|
Request $request,
|
||||||
Dispatcher $dispatcher
|
Dispatcher $dispatcher,
|
||||||
) {
|
) {
|
||||||
$name = $request->validate([
|
$name = $request->validate([
|
||||||
'player_name' => [
|
'player_name' => [
|
||||||
|
|
@ -70,7 +70,7 @@ class PlayersManagementController extends Controller
|
||||||
public function owner(
|
public function owner(
|
||||||
Player $player,
|
Player $player,
|
||||||
Request $request,
|
Request $request,
|
||||||
Dispatcher $dispatcher
|
Dispatcher $dispatcher,
|
||||||
) {
|
) {
|
||||||
$uid = $request->validate(['uid' => 'required|integer'])['uid'];
|
$uid = $request->validate(['uid' => 'required|integer'])['uid'];
|
||||||
|
|
||||||
|
|
@ -96,7 +96,7 @@ class PlayersManagementController extends Controller
|
||||||
public function texture(
|
public function texture(
|
||||||
Player $player,
|
Player $player,
|
||||||
Request $request,
|
Request $request,
|
||||||
Dispatcher $dispatcher
|
Dispatcher $dispatcher,
|
||||||
) {
|
) {
|
||||||
$data = $request->validate([
|
$data = $request->validate([
|
||||||
'tid' => 'required|integer',
|
'tid' => 'required|integer',
|
||||||
|
|
@ -123,7 +123,7 @@ class PlayersManagementController extends Controller
|
||||||
|
|
||||||
public function delete(
|
public function delete(
|
||||||
Player $player,
|
Player $player,
|
||||||
Dispatcher $dispatcher
|
Dispatcher $dispatcher,
|
||||||
) {
|
) {
|
||||||
$dispatcher->dispatch('player.deleting', [$player]);
|
$dispatcher->dispatch('player.deleting', [$player]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -77,7 +77,7 @@ class ReportController extends Controller
|
||||||
public function review(
|
public function review(
|
||||||
Report $report,
|
Report $report,
|
||||||
Request $request,
|
Request $request,
|
||||||
Dispatcher $dispatcher
|
Dispatcher $dispatcher,
|
||||||
) {
|
) {
|
||||||
$data = $request->validate([
|
$data = $request->validate([
|
||||||
'action' => ['required', Rule::in(['delete', 'ban', 'reject'])],
|
'action' => ['required', Rule::in(['delete', 'ban', 'reject'])],
|
||||||
|
|
@ -88,9 +88,9 @@ class ReportController extends Controller
|
||||||
|
|
||||||
if ($action == 'reject') {
|
if ($action == 'reject') {
|
||||||
if (
|
if (
|
||||||
$report->informer &&
|
$report->informer
|
||||||
($score = option('reporter_score_modification', 0)) > 0 &&
|
&& ($score = option('reporter_score_modification', 0)) > 0
|
||||||
$report->status == Report::PENDING
|
&& $report->status == Report::PENDING
|
||||||
) {
|
) {
|
||||||
$report->informer->score -= $score;
|
$report->informer->score -= $score;
|
||||||
$report->informer->save();
|
$report->informer->save();
|
||||||
|
|
@ -151,9 +151,9 @@ class ReportController extends Controller
|
||||||
public static function returnScore($report)
|
public static function returnScore($report)
|
||||||
{
|
{
|
||||||
if (
|
if (
|
||||||
$report->status == Report::PENDING &&
|
$report->status == Report::PENDING
|
||||||
($score = option('reporter_score_modification', 0)) < 0 &&
|
&& ($score = option('reporter_score_modification', 0)) < 0
|
||||||
$report->informer
|
&& $report->informer
|
||||||
) {
|
) {
|
||||||
$report->informer->score -= $score;
|
$report->informer->score -= $score;
|
||||||
$report->informer->save();
|
$report->informer->save();
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ class SetupController extends Controller
|
||||||
Request $request,
|
Request $request,
|
||||||
Filesystem $filesystem,
|
Filesystem $filesystem,
|
||||||
Connection $connection,
|
Connection $connection,
|
||||||
DatabaseManager $manager
|
DatabaseManager $manager,
|
||||||
) {
|
) {
|
||||||
if ($request->isMethod('get')) {
|
if ($request->isMethod('get')) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -121,7 +121,7 @@ class SetupController extends Controller
|
||||||
'database/migrations',
|
'database/migrations',
|
||||||
'vendor/laravel/passport/database/migrations',
|
'vendor/laravel/passport/database/migrations',
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$siteUrl = url('/');
|
$siteUrl = url('/');
|
||||||
if (Str::endsWith($siteUrl, '/index.php')) {
|
if (Str::endsWith($siteUrl, '/index.php')) {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Texture;
|
use App\Models\Texture;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Auth;
|
|
||||||
use Blessing\Filter;
|
use Blessing\Filter;
|
||||||
use Blessing\Rejection;
|
use Blessing\Rejection;
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
|
|
@ -12,10 +11,12 @@ use Illuminate\Database\Eloquent\Builder;
|
||||||
use Illuminate\Filesystem\FilesystemAdapter;
|
use Illuminate\Filesystem\FilesystemAdapter;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Http\UploadedFile;
|
use Illuminate\Http\UploadedFile;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
|
use Intervention\Image\Facades\Image;
|
||||||
use League\CommonMark\GithubFlavoredMarkdownConverter;
|
use League\CommonMark\GithubFlavoredMarkdownConverter;
|
||||||
use Storage;
|
|
||||||
|
|
||||||
class SkinlibController extends Controller
|
class SkinlibController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -134,7 +135,7 @@ class SkinlibController extends Controller
|
||||||
->with('texture', $texture)
|
->with('texture', $texture)
|
||||||
->with('grid', $grid)
|
->with('grid', $grid)
|
||||||
->with('extra', [
|
->with('extra', [
|
||||||
'download' => option('allow_downloading_texture'),
|
'download' => (bool) option('allow_downloading_texture'),
|
||||||
'currentUid' => $user ? $user->uid : 0,
|
'currentUid' => $user ? $user->uid : 0,
|
||||||
'admin' => $user && $user->isAdmin(),
|
'admin' => $user && $user->isAdmin(),
|
||||||
'inCloset' => $user && $user->closet()->where('tid', $texture->tid)->count() > 0,
|
'inCloset' => $user && $user->closet()->where('tid', $texture->tid)->count() > 0,
|
||||||
|
|
@ -189,7 +190,7 @@ class SkinlibController extends Controller
|
||||||
public function handleUpload(
|
public function handleUpload(
|
||||||
Request $request,
|
Request $request,
|
||||||
Filter $filter,
|
Filter $filter,
|
||||||
Dispatcher $dispatcher
|
Dispatcher $dispatcher,
|
||||||
) {
|
) {
|
||||||
$file = $request->file('file');
|
$file = $request->file('file');
|
||||||
if ($file && !$file->isValid()) {
|
if ($file && !$file->isValid()) {
|
||||||
|
|
@ -220,6 +221,16 @@ class SkinlibController extends Controller
|
||||||
$type = $data['type'];
|
$type = $data['type'];
|
||||||
$size = getimagesize($file);
|
$size = getimagesize($file);
|
||||||
|
|
||||||
|
$maxWidth = option('max_texture_width', 8192);
|
||||||
|
if ($size[0] > $maxWidth) {
|
||||||
|
$message = trans('skinlib.upload.too-wide', [
|
||||||
|
'width' => $size[0],
|
||||||
|
'maxWidth' => $maxWidth,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return json($message, 1);
|
||||||
|
}
|
||||||
|
|
||||||
if ($size[0] % 64 != 0 || $size[1] % 32 != 0) {
|
if ($size[0] % 64 != 0 || $size[1] % 32 != 0) {
|
||||||
$message = trans('skinlib.upload.invalid-size', [
|
$message = trans('skinlib.upload.invalid-size', [
|
||||||
'type' => $type === 'cape' ? trans('general.cape') : trans('general.skin'),
|
'type' => $type === 'cape' ? trans('general.cape') : trans('general.skin'),
|
||||||
|
|
@ -253,8 +264,17 @@ class SkinlibController extends Controller
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$hash = hash_file('sha256', $file);
|
$image = Image::make($file);
|
||||||
$hash = $filter->apply('uploaded_texture_hash', $hash, [$file]);
|
$imagick = $image->getCore();
|
||||||
|
$imagick->setOption('png:compression-filter', '0');
|
||||||
|
$imagick->setOption('png:compression-level', '9');
|
||||||
|
$imagick->setOption('png:compression-strategy', '0');
|
||||||
|
$imagick->setOption('png:exclude-chunk', 'all');
|
||||||
|
$imagick->stripImage();
|
||||||
|
$sanitized = $image->encode('png')->getEncoded();
|
||||||
|
|
||||||
|
$hash = hash('sha256', $image->encoded);
|
||||||
|
$hash = $filter->apply('uploaded_texture_hash', $hash, [$image]);
|
||||||
|
|
||||||
/** @var User */
|
/** @var User */
|
||||||
$user = Auth::user();
|
$user = Auth::user();
|
||||||
|
|
@ -270,11 +290,11 @@ class SkinlibController extends Controller
|
||||||
return json(trans('skinlib.upload.repeated'), 2, ['tid' => $duplicated->tid]);
|
return json(trans('skinlib.upload.repeated'), 2, ['tid' => $duplicated->tid]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$size = ceil($file->getSize() / 1024);
|
$fileSize = ceil(strlen($sanitized) / 1024);
|
||||||
$isPublic = is_string($data['public'])
|
$isPublic = is_string($data['public'])
|
||||||
? $data['public'] === '1'
|
? $data['public'] === '1'
|
||||||
: $data['public'];
|
: $data['public'];
|
||||||
$cost = $size * (
|
$cost = $fileSize * (
|
||||||
$isPublic
|
$isPublic
|
||||||
? option('score_per_storage')
|
? option('score_per_storage')
|
||||||
: option('private_score_per_storage')
|
: option('private_score_per_storage')
|
||||||
|
|
@ -285,13 +305,13 @@ class SkinlibController extends Controller
|
||||||
return json(trans('skinlib.upload.lack-score'), 1);
|
return json(trans('skinlib.upload.lack-score'), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$dispatcher->dispatch('texture.uploading', [$file, $name, $hash]);
|
$dispatcher->dispatch('texture.uploading', [$image, $name, $hash]);
|
||||||
|
|
||||||
$texture = new Texture();
|
$texture = new Texture();
|
||||||
$texture->name = $name;
|
$texture->name = $name;
|
||||||
$texture->type = $type;
|
$texture->type = $type;
|
||||||
$texture->hash = $hash;
|
$texture->hash = $hash;
|
||||||
$texture->size = $size;
|
$texture->size = $fileSize;
|
||||||
$texture->public = $isPublic;
|
$texture->public = $isPublic;
|
||||||
$texture->uploader = $user->uid;
|
$texture->uploader = $user->uid;
|
||||||
$texture->likes = 1;
|
$texture->likes = 1;
|
||||||
|
|
@ -300,14 +320,14 @@ class SkinlibController extends Controller
|
||||||
/** @var FilesystemAdapter */
|
/** @var FilesystemAdapter */
|
||||||
$disk = Storage::disk('textures');
|
$disk = Storage::disk('textures');
|
||||||
if ($disk->missing($hash)) {
|
if ($disk->missing($hash)) {
|
||||||
$file->storePubliclyAs('', $hash, ['disk' => 'textures']);
|
$disk->put($hash, $sanitized);
|
||||||
}
|
}
|
||||||
|
|
||||||
$user->score -= $cost;
|
$user->score -= $cost;
|
||||||
$user->closet()->attach($texture->tid, ['item_name' => $name]);
|
$user->closet()->attach($texture->tid, ['item_name' => $name]);
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
||||||
$dispatcher->dispatch('texture.uploaded', [$texture, $file]);
|
$dispatcher->dispatch('texture.uploaded', [$texture, $image]);
|
||||||
|
|
||||||
return json(trans('skinlib.upload.success', ['name' => $name]), 0, [
|
return json(trans('skinlib.upload.success', ['name' => $name]), 0, [
|
||||||
'tid' => $texture->tid,
|
'tid' => $texture->tid,
|
||||||
|
|
@ -386,7 +406,7 @@ class SkinlibController extends Controller
|
||||||
Request $request,
|
Request $request,
|
||||||
Dispatcher $dispatcher,
|
Dispatcher $dispatcher,
|
||||||
Filter $filter,
|
Filter $filter,
|
||||||
Texture $texture
|
Texture $texture,
|
||||||
) {
|
) {
|
||||||
$data = $request->validate(['name' => [
|
$data = $request->validate(['name' => [
|
||||||
'required',
|
'required',
|
||||||
|
|
@ -416,7 +436,7 @@ class SkinlibController extends Controller
|
||||||
Request $request,
|
Request $request,
|
||||||
Dispatcher $dispatcher,
|
Dispatcher $dispatcher,
|
||||||
Filter $filter,
|
Filter $filter,
|
||||||
Texture $texture
|
Texture $texture,
|
||||||
) {
|
) {
|
||||||
$data = $request->validate([
|
$data = $request->validate([
|
||||||
'type' => ['required', Rule::in(['steve', 'alex', 'cape'])],
|
'type' => ['required', Rule::in(['steve', 'alex', 'cape'])],
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,11 @@ use App\Models\Player;
|
||||||
use App\Models\Texture;
|
use App\Models\Texture;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Blessing\Minecraft;
|
use Blessing\Minecraft;
|
||||||
use Cache;
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Image;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
use Intervention\Image\Facades\Image;
|
||||||
|
|
||||||
class TextureController extends Controller
|
class TextureController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -71,7 +71,8 @@ class TextureController extends Controller
|
||||||
|
|
||||||
$lastModified = $disk->lastModified($hash);
|
$lastModified = $disk->lastModified($hash);
|
||||||
|
|
||||||
return Image::make($image)
|
// TODO: refactor
|
||||||
|
return \Intervention\Image\ImageManagerStatic::configure(['driver' => 'gd'])->make($image)
|
||||||
->response($usePNG ? 'png' : 'webp', 100)
|
->response($usePNG ? 'png' : 'webp', 100)
|
||||||
->setLastModified(Carbon::createFromTimestamp($lastModified));
|
->setLastModified(Carbon::createFromTimestamp($lastModified));
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +146,8 @@ class TextureController extends Controller
|
||||||
|
|
||||||
$disk = Storage::disk('textures');
|
$disk = Storage::disk('textures');
|
||||||
if (is_null($texture) || $disk->missing($texture->hash)) {
|
if (is_null($texture) || $disk->missing($texture->hash)) {
|
||||||
return Image::make(resource_path("misc/textures/avatar$mode.png"))
|
// TODO: refactor
|
||||||
|
return \Intervention\Image\ImageManagerStatic::configure(['driver' => 'gd'])->make(resource_path("misc/textures/avatar$mode.png"))
|
||||||
->resize($size, $size)
|
->resize($size, $size)
|
||||||
->response($usePNG ? 'png' : 'webp', 100);
|
->response($usePNG ? 'png' : 'webp', 100);
|
||||||
}
|
}
|
||||||
|
|
@ -165,7 +167,8 @@ class TextureController extends Controller
|
||||||
|
|
||||||
$lastModified = Carbon::createFromTimestamp($disk->lastModified($hash));
|
$lastModified = Carbon::createFromTimestamp($disk->lastModified($hash));
|
||||||
|
|
||||||
return Image::make($image)
|
// TODO: refactor
|
||||||
|
return \Intervention\Image\ImageManagerStatic::configure(['driver' => 'gd'])->make($image)
|
||||||
->resize($size, $size)
|
->resize($size, $size)
|
||||||
->response($usePNG ? 'png' : 'webp', 100)
|
->response($usePNG ? 'png' : 'webp', 100)
|
||||||
->setLastModified($lastModified);
|
->setLastModified($lastModified);
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ class TranslationsController extends Controller
|
||||||
Request $request,
|
Request $request,
|
||||||
Application $app,
|
Application $app,
|
||||||
JavaScript $js,
|
JavaScript $js,
|
||||||
LanguageLine $line
|
LanguageLine $line,
|
||||||
) {
|
) {
|
||||||
$data = $request->validate(['text' => 'required|string']);
|
$data = $request->validate(['text' => 'required|string']);
|
||||||
|
|
||||||
|
|
@ -57,7 +57,7 @@ class TranslationsController extends Controller
|
||||||
public function delete(
|
public function delete(
|
||||||
Application $app,
|
Application $app,
|
||||||
JavaScript $js,
|
JavaScript $js,
|
||||||
LanguageLine $line
|
LanguageLine $line,
|
||||||
) {
|
) {
|
||||||
$line->delete();
|
$line->delete();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,16 +6,16 @@ use App\Events\UserProfileUpdated;
|
||||||
use App\Mail\EmailVerification;
|
use App\Mail\EmailVerification;
|
||||||
use App\Models\Texture;
|
use App\Models\Texture;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Auth;
|
|
||||||
use Blessing\Filter;
|
use Blessing\Filter;
|
||||||
use Blessing\Rejection;
|
use Blessing\Rejection;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Contracts\Events\Dispatcher;
|
use Illuminate\Contracts\Events\Dispatcher;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
use Illuminate\Support\Facades\Session;
|
||||||
|
use Illuminate\Support\Facades\URL;
|
||||||
use League\CommonMark\GithubFlavoredMarkdownConverter;
|
use League\CommonMark\GithubFlavoredMarkdownConverter;
|
||||||
use Mail;
|
|
||||||
use Session;
|
|
||||||
use URL;
|
|
||||||
|
|
||||||
class UserController extends Controller
|
class UserController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -330,9 +330,9 @@ class UserController extends Controller
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!$texture->public &&
|
!$texture->public
|
||||||
$user->uid !== $texture->uploader &&
|
&& $user->uid !== $texture->uploader
|
||||||
!$user->isAdmin()
|
&& !$user->isAdmin()
|
||||||
) {
|
) {
|
||||||
return json(trans('skinlib.show.private'), 1);
|
return json(trans('skinlib.show.private'), 1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,8 @@ class UsersManagementController extends Controller
|
||||||
$authUser = $request->user();
|
$authUser = $request->user();
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$targetUser->isNot($authUser) &&
|
$targetUser->isNot($authUser)
|
||||||
$targetUser->permission >= $authUser->permission
|
&& $targetUser->permission >= $authUser->permission
|
||||||
) {
|
) {
|
||||||
return json(trans('admin.users.operations.no-permission'), 1)
|
return json(trans('admin.users.operations.no-permission'), 1)
|
||||||
->setStatusCode(403);
|
->setStatusCode(403);
|
||||||
|
|
@ -134,8 +134,8 @@ class UsersManagementController extends Controller
|
||||||
$permission = (int) $data['permission'];
|
$permission = (int) $data['permission'];
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$permission === User::ADMIN &&
|
$permission === User::ADMIN
|
||||||
$request->user()->permission < User::SUPER_ADMIN
|
&& $request->user()->permission < User::SUPER_ADMIN
|
||||||
) {
|
) {
|
||||||
return json(trans('admin.users.operations.no-permission'), 1)
|
return json(trans('admin.users.operations.no-permission'), 1)
|
||||||
->setStatusCode(403);
|
->setStatusCode(403);
|
||||||
|
|
|
||||||
|
|
@ -11,19 +11,20 @@ class Kernel extends HttpKernel
|
||||||
*
|
*
|
||||||
* These middleware are run during every request to your application.
|
* These middleware are run during every request to your application.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array<int, class-string|string>
|
||||||
*/
|
*/
|
||||||
protected $middleware = [
|
protected $middleware = [
|
||||||
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
|
\Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||||
|
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||||
\Illuminate\Foundation\Http\Middleware\TrimStrings::class,
|
\Illuminate\Foundation\Http\Middleware\TrimStrings::class,
|
||||||
\App\Http\Middleware\ConvertEmptyStringsToNull::class,
|
Middleware\ConvertEmptyStringsToNull::class,
|
||||||
\App\Http\Middleware\DetectLanguagePrefer::class,
|
Middleware\DetectLanguagePrefer::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The application's route middleware groups.
|
* The application's route middleware groups.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array<string, array<int, class-string|string>>
|
||||||
*/
|
*/
|
||||||
protected $middlewareGroups = [
|
protected $middlewareGroups = [
|
||||||
'web' => [
|
'web' => [
|
||||||
|
|
@ -32,39 +33,38 @@ class Kernel extends HttpKernel
|
||||||
\Illuminate\Session\Middleware\StartSession::class,
|
\Illuminate\Session\Middleware\StartSession::class,
|
||||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||||
\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::class,
|
\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::class,
|
||||||
\App\Http\Middleware\EnforceEverGreen::class,
|
Middleware\EnforceEverGreen::class,
|
||||||
\App\Http\Middleware\RedirectToSetup::class,
|
Middleware\RedirectToSetup::class,
|
||||||
'bindings',
|
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
'api' => [
|
'api' => [
|
||||||
'bindings',
|
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||||
],
|
],
|
||||||
|
|
||||||
'authorize' => [
|
'authorize' => [
|
||||||
'auth:web',
|
'auth:web',
|
||||||
\App\Http\Middleware\RejectBannedUser::class,
|
Middleware\RejectBannedUser::class,
|
||||||
\App\Http\Middleware\EnsureEmailFilled::class,
|
Middleware\EnsureEmailFilled::class,
|
||||||
\App\Http\Middleware\FireUserAuthenticated::class,
|
Middleware\FireUserAuthenticated::class,
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The application's route middleware.
|
* The application's middleware aliases.
|
||||||
*
|
*
|
||||||
* These middleware may be assigned to groups or used individually.
|
* Aliases may be used instead of class names to conveniently assign middleware to routes and groups.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array<string, class-string|string>
|
||||||
*/
|
*/
|
||||||
protected $routeMiddleware = [
|
protected $middlewareAliases = [
|
||||||
'auth' => \App\Http\Middleware\Authenticate::class,
|
'auth' => Middleware\Authenticate::class,
|
||||||
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
|
|
||||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
'guest' => Middleware\RedirectIfAuthenticated::class,
|
||||||
'role' => \App\Http\Middleware\CheckRole::class,
|
'role' => Middleware\CheckRole::class,
|
||||||
'setup' => \App\Http\Middleware\CheckInstallation::class,
|
'setup' => Middleware\CheckInstallation::class,
|
||||||
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||||
'verified' => \App\Http\Middleware\CheckUserVerified::class,
|
'verified' => Middleware\CheckUserVerified::class,
|
||||||
'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class,
|
'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class,
|
||||||
'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
|
'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ class Authenticate extends Middleware
|
||||||
'msg' => trans('auth.check.anonymous'),
|
'msg' => trans('auth.check.anonymous'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return '/auth/login';
|
return route('auth.login');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,16 +2,17 @@
|
||||||
|
|
||||||
namespace App\Http\Middleware;
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
use Closure;
|
use Closure;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class CheckRole
|
class CheckRole
|
||||||
{
|
{
|
||||||
protected $roles = [
|
protected $roles = [
|
||||||
'banned' => -1,
|
'banned' => User::BANNED,
|
||||||
'normal' => 0,
|
'normal' => User::NORMAL,
|
||||||
'admin' => 1,
|
'admin' => User::ADMIN,
|
||||||
'super-admin' => 2,
|
'super-admin' => User::SUPER_ADMIN,
|
||||||
];
|
];
|
||||||
|
|
||||||
public function handle(Request $request, Closure $next, $role)
|
public function handle(Request $request, Closure $next, $role)
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@ class DetectLanguagePrefer
|
||||||
?? $request->cookie('locale')
|
?? $request->cookie('locale')
|
||||||
?? $request->getPreferredLanguage();
|
?? $request->getPreferredLanguage();
|
||||||
if (
|
if (
|
||||||
($info = Arr::get(config('locales'), $locale)) &&
|
($info = Arr::get(config('locales'), $locale))
|
||||||
($alias = Arr::get($info, 'alias'))
|
&& ($alias = Arr::get($info, 'alias'))
|
||||||
) {
|
) {
|
||||||
$locale = $alias;
|
$locale = $alias;
|
||||||
}
|
}
|
||||||
|
|
@ -28,7 +28,9 @@ class DetectLanguagePrefer
|
||||||
|
|
||||||
/** @var Response */
|
/** @var Response */
|
||||||
$response = $next($request);
|
$response = $next($request);
|
||||||
$response->cookie('locale', $locale, 120);
|
if (!in_array('api', optional($request->route())->middleware() ?? [])) {
|
||||||
|
$response->cookie('locale', $locale, 120);
|
||||||
|
}
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,16 @@
|
||||||
namespace App\Http\Middleware;
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Closure;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class RejectBannedUser
|
class RejectBannedUser
|
||||||
{
|
{
|
||||||
public function handle($request, Closure $next)
|
public function handle(Request $request, \Closure $next)
|
||||||
{
|
{
|
||||||
|
if ($request->route()->getName() === 'auth.logout') {
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
if ($request->user()->permission == User::BANNED) {
|
if ($request->user()->permission == User::BANNED) {
|
||||||
if ($request->expectsJson()) {
|
if ($request->expectsJson()) {
|
||||||
$response = json(trans('auth.check.banned'), -1);
|
$response = json(trans('auth.check.banned'), -1);
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ class FootComposer
|
||||||
Request $request,
|
Request $request,
|
||||||
JavaScript $javascript,
|
JavaScript $javascript,
|
||||||
Dispatcher $dispatcher,
|
Dispatcher $dispatcher,
|
||||||
Filter $filter
|
Filter $filter,
|
||||||
) {
|
) {
|
||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
$this->javascript = $javascript;
|
$this->javascript = $javascript;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ class HeadComposer
|
||||||
public function __construct(
|
public function __construct(
|
||||||
Dispatcher $dispatcher,
|
Dispatcher $dispatcher,
|
||||||
Request $request,
|
Request $request,
|
||||||
Filter $filter
|
Filter $filter,
|
||||||
) {
|
) {
|
||||||
$this->dispatcher = $dispatcher;
|
$this->dispatcher = $dispatcher;
|
||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,28 @@ class UserMenuComposer
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
$avatarPNG = $this->filter->apply('user_avatar', $avatarPNG, [$user]);
|
$avatarPNG = $this->filter->apply('user_avatar', $avatarPNG, [$user]);
|
||||||
$cli = $this->request->is('admin', 'admin/*');
|
|
||||||
|
$menuItems = [
|
||||||
|
['label' => trans('general.user-center'), 'link' => route('user.home')],
|
||||||
|
['label' => trans('general.profile'), 'link' => route('user.profile.view')],
|
||||||
|
];
|
||||||
|
if ($user->isAdmin()) {
|
||||||
|
array_push(
|
||||||
|
$menuItems,
|
||||||
|
['label' => '', 'link' => '#divider'],
|
||||||
|
['label' => trans('general.admin-panel'), 'link' => route('admin.view')],
|
||||||
|
['label' => trans('general.user-manage'), 'link' => route('admin.users.view')],
|
||||||
|
['label' => trans('general.report-manage'), 'link' => route('admin.reports.view')],
|
||||||
|
['label' => 'Web CLI', 'link' => '#launch-cli'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$menuItems = $this->filter->apply('user_menu', $menuItems, [$user]);
|
||||||
|
|
||||||
$view->with([
|
$view->with([
|
||||||
'user' => $user,
|
'user' => $user,
|
||||||
'avatar' => $avatar,
|
'avatar' => $avatar,
|
||||||
'avatar_png' => $avatarPNG,
|
'avatar_png' => $avatarPNG,
|
||||||
'cli' => $cli,
|
'menu' => $menuItems,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
namespace App\Listeners;
|
namespace App\Listeners;
|
||||||
|
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Event;
|
use Illuminate\Support\Facades\Event;
|
||||||
|
|
||||||
class NotifyFailedPlugin
|
class NotifyFailedPlugin
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ namespace App\Mail;
|
||||||
|
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Mail\Mailable;
|
use Illuminate\Mail\Mailable;
|
||||||
|
use Illuminate\Mail\Mailables\Headers;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
class EmailVerification extends Mailable
|
class EmailVerification extends Mailable
|
||||||
|
|
@ -26,4 +27,13 @@ class EmailVerification extends Mailable
|
||||||
->subject(trans('user.verification.mail.title', ['sitename' => $site_name]))
|
->subject(trans('user.verification.mail.title', ['sitename' => $site_name]))
|
||||||
->view('mails.email-verification');
|
->view('mails.email-verification');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function headers(): Headers
|
||||||
|
{
|
||||||
|
return new Headers(
|
||||||
|
text: [
|
||||||
|
'Auto-Submitted' => 'auto-generated',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ namespace App\Mail;
|
||||||
|
|
||||||
use Illuminate\Bus\Queueable;
|
use Illuminate\Bus\Queueable;
|
||||||
use Illuminate\Mail\Mailable;
|
use Illuminate\Mail\Mailable;
|
||||||
|
use Illuminate\Mail\Mailables\Headers;
|
||||||
use Illuminate\Queue\SerializesModels;
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
class ForgotPassword extends Mailable
|
class ForgotPassword extends Mailable
|
||||||
|
|
@ -26,4 +27,13 @@ class ForgotPassword extends Mailable
|
||||||
->subject(trans('auth.forgot.mail.title', ['sitename' => $site_name]))
|
->subject(trans('auth.forgot.mail.title', ['sitename' => $site_name]))
|
||||||
->view('mails.password-reset');
|
->view('mails.password-reset');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function headers(): Headers
|
||||||
|
{
|
||||||
|
return new Headers(
|
||||||
|
text: [
|
||||||
|
'Auto-Submitted' => 'auto-generated',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Events\PlayerProfileUpdated;
|
use App\Events\PlayerProfileUpdated;
|
||||||
use App\Models;
|
|
||||||
use DateTimeInterface;
|
use DateTimeInterface;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
@ -57,17 +56,17 @@ class Player extends Model
|
||||||
|
|
||||||
public function user()
|
public function user()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Models\User::class, 'uid');
|
return $this->belongsTo(User::class, 'uid');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function skin()
|
public function skin()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Models\Texture::class, 'tid_skin');
|
return $this->belongsTo(Texture::class, 'tid_skin');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function cape()
|
public function cape()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Models\Texture::class, 'tid_cape');
|
return $this->belongsTo(Texture::class, 'tid_cape');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getModelAttribute()
|
public function getModelAttribute()
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,6 @@ class SiteMessage extends Notification implements ShouldQueue
|
||||||
/**
|
/**
|
||||||
* Get the notification's delivery channels.
|
* Get the notification's delivery channels.
|
||||||
*
|
*
|
||||||
* @param mixed $notifiable
|
|
||||||
*
|
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function via($notifiable)
|
public function via($notifiable)
|
||||||
|
|
@ -37,8 +35,6 @@ class SiteMessage extends Notification implements ShouldQueue
|
||||||
/**
|
/**
|
||||||
* Get the array representation of the notification.
|
* Get the array representation of the notification.
|
||||||
*
|
*
|
||||||
* @param mixed $notifiable
|
|
||||||
*
|
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function toArray($notifiable)
|
public function toArray($notifiable)
|
||||||
|
|
|
||||||
|
|
@ -9,25 +9,21 @@ class ScopeObserver
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Handle the Scope "saved" event.
|
* Handle the Scope "saved" event.
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function saved()
|
public function saved(): void
|
||||||
{
|
{
|
||||||
$this->refreshCachedScopes();
|
$this->refreshCachedScopes();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the Scope "deleted" event.
|
* Handle the Scope "deleted" event.
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function deleted()
|
public function deleted(): void
|
||||||
{
|
{
|
||||||
$this->refreshCachedScopes();
|
$this->refreshCachedScopes();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function refreshCachedScopes()
|
protected function refreshCachedScopes(): void
|
||||||
{
|
{
|
||||||
Cache::forget('scopes');
|
Cache::forget('scopes');
|
||||||
Cache::rememberForever('scopes', function () {
|
Cache::rememberForever('scopes', function () {
|
||||||
|
|
|
||||||
|
|
@ -10,14 +10,14 @@ use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
class AppServiceProvider extends ServiceProvider
|
class AppServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
public function register()
|
public function register(): void
|
||||||
{
|
{
|
||||||
$this->app->singleton('cipher', 'App\Services\Cipher\\'.config('secure.cipher'));
|
$this->app->singleton('cipher', 'App\Services\Cipher\\'.config('secure.cipher'));
|
||||||
$this->app->singleton(Services\Option::class);
|
$this->app->singleton(Services\Option::class);
|
||||||
$this->app->alias(Services\Option::class, 'options');
|
$this->app->alias(Services\Option::class, 'options');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function boot(Request $request)
|
public function boot(Request $request): void
|
||||||
{
|
{
|
||||||
Paginator::useBootstrap();
|
Paginator::useBootstrap();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,31 +2,27 @@
|
||||||
|
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use App\Models\Scope;
|
||||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Laravel\Passport\Passport;
|
use Laravel\Passport\Passport;
|
||||||
|
|
||||||
class AuthServiceProvider extends ServiceProvider
|
class AuthServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The policy mappings for the application.
|
* The model to policy mappings for the application.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array<class-string, class-string>
|
||||||
*/
|
*/
|
||||||
protected $policies = [
|
protected $policies = [
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register any authentication / authorization services.
|
* Register any authentication / authorization services.
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function boot()
|
public function boot(): void
|
||||||
{
|
{
|
||||||
$this->registerPolicies();
|
|
||||||
|
|
||||||
Passport::routes();
|
|
||||||
|
|
||||||
$defaultScopes = [
|
$defaultScopes = [
|
||||||
'User.Read' => 'auth.oauth.scope.user.read',
|
'User.Read' => 'auth.oauth.scope.user.read',
|
||||||
'Notification.Read' => 'auth.oauth.scope.notification.read',
|
'Notification.Read' => 'auth.oauth.scope.notification.read',
|
||||||
|
|
@ -45,7 +41,19 @@ class AuthServiceProvider extends ServiceProvider
|
||||||
'ReportsManagement.ReadWrite' => 'auth.oauth.scope.reports-management.readwrite',
|
'ReportsManagement.ReadWrite' => 'auth.oauth.scope.reports-management.readwrite',
|
||||||
];
|
];
|
||||||
|
|
||||||
$scopes = Cache::get('scopes', []);
|
/*
|
||||||
|
* Return empty scopes if running unit tests or before installation.
|
||||||
|
* In these cases, migrations aren’t run yet, so DB queries will fail.
|
||||||
|
* OAuth isn’t tested in unit tests, so returning empty scopes should be fine...?
|
||||||
|
* Maybe the best approach is to run migrations before bootstrap in tests,
|
||||||
|
* but this seems impossible for DB_DATABASE=:memory:;
|
||||||
|
* Or change how scopes are registered so they don't depend on the database,
|
||||||
|
* but that may introduce BREAKING CHANGES and plugin incompatibility.
|
||||||
|
* PRs welcome for better solutions!
|
||||||
|
*/
|
||||||
|
$scopes = (app()->runningUnitTests() || !Storage::disk('root')->exists('storage/install.lock')) ? [] : Cache::rememberForever('scopes', function () {
|
||||||
|
return Scope::pluck('description', 'name')->toArray();
|
||||||
|
});
|
||||||
|
|
||||||
Passport::tokensCan(array_merge($defaultScopes, $scopes));
|
Passport::tokensCan(array_merge($defaultScopes, $scopes));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,11 @@ use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvi
|
||||||
|
|
||||||
class EventServiceProvider extends ServiceProvider
|
class EventServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
// The event listener mappings for the application.
|
/**
|
||||||
|
* The event to listener mappings for the application.
|
||||||
|
*
|
||||||
|
* @var array<class-string, array<int, class-string>>
|
||||||
|
*/
|
||||||
protected $listen = [
|
protected $listen = [
|
||||||
'App\Events\PluginWasEnabled' => [
|
'App\Events\PluginWasEnabled' => [
|
||||||
Listeners\CopyPluginAssets::class,
|
Listeners\CopyPluginAssets::class,
|
||||||
|
|
@ -44,10 +48,8 @@ class EventServiceProvider extends ServiceProvider
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register any events for your application.
|
* Register any events for your application.
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
*/
|
||||||
public function boot()
|
public function boot(): void
|
||||||
{
|
{
|
||||||
Scope::observe(ScopeObserver::class);
|
Scope::observe(ScopeObserver::class);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,13 @@ use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
class PluginServiceProvider extends ServiceProvider
|
class PluginServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
public function register()
|
public function register(): void
|
||||||
{
|
{
|
||||||
$this->app->singleton(PluginManager::class);
|
$this->app->singleton(PluginManager::class);
|
||||||
$this->app->alias(PluginManager::class, 'plugins');
|
$this->app->alias(PluginManager::class, 'plugins');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function boot(PluginManager $plugins)
|
public function boot(PluginManager $plugins): void
|
||||||
{
|
{
|
||||||
$plugins->boot();
|
$plugins->boot();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,8 @@ namespace App\Providers;
|
||||||
use App\Events\ConfigureRoutes;
|
use App\Events\ConfigureRoutes;
|
||||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||||
use Illuminate\Routing\Router;
|
use Illuminate\Routing\Router;
|
||||||
|
use Illuminate\Support\Facades\Route;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Laravel\Passport\Passport;
|
|
||||||
use Route;
|
|
||||||
|
|
||||||
class RouteServiceProvider extends ServiceProvider
|
class RouteServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
|
|
@ -20,7 +19,7 @@ class RouteServiceProvider extends ServiceProvider
|
||||||
/**
|
/**
|
||||||
* Define the routes for the application.
|
* Define the routes for the application.
|
||||||
*/
|
*/
|
||||||
public function map(Router $router)
|
public function map(Router $router): void
|
||||||
{
|
{
|
||||||
$this->mapStaticRoutes($router);
|
$this->mapStaticRoutes($router);
|
||||||
|
|
||||||
|
|
@ -28,10 +27,9 @@ class RouteServiceProvider extends ServiceProvider
|
||||||
|
|
||||||
$this->mapApiRoutes();
|
$this->mapApiRoutes();
|
||||||
|
|
||||||
Passport::routes();
|
|
||||||
foreach ($router->getRoutes()->getRoutesByName() as $name => $route) {
|
foreach ($router->getRoutes()->getRoutesByName() as $name => $route) {
|
||||||
if (Str::startsWith($name, ['passport.authorizations', 'passport.tokens', 'passport.clients'])) {
|
if (Str::startsWith($name, ['passport.authorizations', 'passport.tokens', 'passport.clients'])) {
|
||||||
$route->middleware('verified');
|
$route->middleware(['auth', 'verified']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,7 +40,7 @@ class RouteServiceProvider extends ServiceProvider
|
||||||
* Define the "web" routes for the application.
|
* Define the "web" routes for the application.
|
||||||
* These routes all receive session state, CSRF protection, etc.
|
* These routes all receive session state, CSRF protection, etc.
|
||||||
*/
|
*/
|
||||||
protected function mapWebRoutes(Router $router)
|
protected function mapWebRoutes(Router $router): void
|
||||||
{
|
{
|
||||||
Route::middleware(['web'])
|
Route::middleware(['web'])
|
||||||
->namespace($this->namespace)
|
->namespace($this->namespace)
|
||||||
|
|
@ -53,7 +51,7 @@ class RouteServiceProvider extends ServiceProvider
|
||||||
* Define the "static" routes for the application.
|
* Define the "static" routes for the application.
|
||||||
* These routes will not load session, etc.
|
* These routes will not load session, etc.
|
||||||
*/
|
*/
|
||||||
protected function mapStaticRoutes(Router $router)
|
protected function mapStaticRoutes(Router $router): void
|
||||||
{
|
{
|
||||||
Route::namespace($this->namespace)
|
Route::namespace($this->namespace)
|
||||||
->group(base_path('routes/static.php'));
|
->group(base_path('routes/static.php'));
|
||||||
|
|
@ -63,7 +61,7 @@ class RouteServiceProvider extends ServiceProvider
|
||||||
* Define the "api" routes for the application.
|
* Define the "api" routes for the application.
|
||||||
* These routes are typically stateless.
|
* These routes are typically stateless.
|
||||||
*/
|
*/
|
||||||
protected function mapApiRoutes()
|
protected function mapApiRoutes(): void
|
||||||
{
|
{
|
||||||
Route::prefix('api')
|
Route::prefix('api')
|
||||||
->middleware(
|
->middleware(
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@
|
||||||
namespace App\Providers;
|
namespace App\Providers;
|
||||||
|
|
||||||
use App\Http\View\Composers;
|
use App\Http\View\Composers;
|
||||||
|
use Illuminate\Support\Facades\View;
|
||||||
use Illuminate\Support\ServiceProvider;
|
use Illuminate\Support\ServiceProvider;
|
||||||
use View;
|
|
||||||
|
|
||||||
class ViewServiceProvider extends ServiceProvider
|
class ViewServiceProvider extends ServiceProvider
|
||||||
{
|
{
|
||||||
public function boot()
|
public function boot(): void
|
||||||
{
|
{
|
||||||
View::composer([
|
View::composer([
|
||||||
'home',
|
'home',
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,10 @@ use App\Events;
|
||||||
use App\Notifications;
|
use App\Notifications;
|
||||||
use Blessing\Filter;
|
use Blessing\Filter;
|
||||||
use Closure;
|
use Closure;
|
||||||
use Event;
|
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
|
use Illuminate\Support\Facades\Event;
|
||||||
|
use Illuminate\Support\Facades\Notification;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Notification;
|
|
||||||
|
|
||||||
class Hook
|
class Hook
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
use DB;
|
|
||||||
use Illuminate\Database\QueryException;
|
use Illuminate\Database\QueryException;
|
||||||
use Illuminate\Filesystem\Filesystem;
|
use Illuminate\Filesystem\Filesystem;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class Option
|
class Option
|
||||||
{
|
{
|
||||||
|
|
@ -20,13 +20,14 @@ class Option
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
if (!file_exists(storage_path('install.lock')) || app()->runningUnitTests()) {
|
||||||
$this->items = DB::table('options')
|
|
||||||
->get()
|
|
||||||
->mapWithKeys(fn ($item) => [$item->option_name => $item->option_value]);
|
|
||||||
} catch (QueryException $e) {
|
|
||||||
$this->items = collect();
|
$this->items = collect();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->items = DB::table('options')
|
||||||
|
->get()
|
||||||
|
->mapWithKeys(fn ($item) => [$item->option_name => $item->option_value]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get($key, $default = null, $raw = false)
|
public function get($key, $default = null, $raw = false)
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Services\Facades\Option;
|
||||||
use BadMethodCallException;
|
use BadMethodCallException;
|
||||||
use Illuminate\Support\Arr;
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Option;
|
|
||||||
use ReflectionClass;
|
use ReflectionClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -38,7 +38,7 @@ class OptionForm
|
||||||
|
|
||||||
protected $hookBefore;
|
protected $hookBefore;
|
||||||
protected $hookAfter;
|
protected $hookAfter;
|
||||||
protected $alwaysCallback = null;
|
protected $alwaysCallback;
|
||||||
|
|
||||||
protected $renderWithoutTable = false;
|
protected $renderWithoutTable = false;
|
||||||
protected $renderInputTagsOnly = false;
|
protected $renderInputTagsOnly = false;
|
||||||
|
|
@ -59,7 +59,7 @@ class OptionForm
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws \BadMethodCallException
|
* @throws BadMethodCallException
|
||||||
*/
|
*/
|
||||||
public function __call(string $method, array $params): OptionFormItem
|
public function __call(string $method, array $params): OptionFormItem
|
||||||
{
|
{
|
||||||
|
|
@ -105,7 +105,6 @@ class OptionForm
|
||||||
* Add a piece of data to the option form.
|
* Add a piece of data to the option form.
|
||||||
*
|
*
|
||||||
* @param string|array $key
|
* @param string|array $key
|
||||||
* @param mixed $value
|
|
||||||
*/
|
*/
|
||||||
public function with($key, $value = null): self
|
public function with($key, $value = null): self
|
||||||
{
|
{
|
||||||
|
|
@ -204,7 +203,7 @@ class OptionForm
|
||||||
/**
|
/**
|
||||||
* Handle the HTTP post request and update modified options.
|
* Handle the HTTP post request and update modified options.
|
||||||
*/
|
*/
|
||||||
public function handle(callable $callback = null): self
|
public function handle(?callable $callback = null): self
|
||||||
{
|
{
|
||||||
$request = request();
|
$request = request();
|
||||||
$allPostData = $request->all();
|
$allPostData = $request->all();
|
||||||
|
|
@ -352,7 +351,7 @@ class OptionFormItem
|
||||||
|
|
||||||
public $format;
|
public $format;
|
||||||
|
|
||||||
public $value = null;
|
public $value;
|
||||||
|
|
||||||
public $disabled;
|
public $disabled;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ class PluginManager
|
||||||
Application $app,
|
Application $app,
|
||||||
Option $option,
|
Option $option,
|
||||||
Dispatcher $dispatcher,
|
Dispatcher $dispatcher,
|
||||||
Filesystem $filesystem
|
Filesystem $filesystem,
|
||||||
) {
|
) {
|
||||||
$this->app = $app;
|
$this->app = $app;
|
||||||
$this->option = $option;
|
$this->option = $option;
|
||||||
|
|
@ -366,7 +366,7 @@ class PluginManager
|
||||||
*/
|
*/
|
||||||
public function formatUnresolved(
|
public function formatUnresolved(
|
||||||
Collection $unsatisfied,
|
Collection $unsatisfied,
|
||||||
Collection $conflicts
|
Collection $conflicts,
|
||||||
): array {
|
): array {
|
||||||
$unsatisfied = $unsatisfied->map(function ($detail, $name) {
|
$unsatisfied = $unsatisfied->map(function ($detail, $name) {
|
||||||
if ($name === 'blessing-skin-server') {
|
if ($name === 'blessing-skin-server') {
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ class JavaScript
|
||||||
public function __construct(
|
public function __construct(
|
||||||
Filesystem $filesystem,
|
Filesystem $filesystem,
|
||||||
Repository $cache,
|
Repository $cache,
|
||||||
PluginManager $plugins
|
PluginManager $plugins,
|
||||||
) {
|
) {
|
||||||
$this->filesystem = $filesystem;
|
$this->filesystem = $filesystem;
|
||||||
$this->cache = $cache;
|
$this->cache = $cache;
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,15 @@ use Spatie\TranslationLoader\TranslationLoaderManager;
|
||||||
|
|
||||||
class Loader extends TranslationLoaderManager
|
class Loader extends TranslationLoaderManager
|
||||||
{
|
{
|
||||||
protected function loadPath($path, $locale, $group)
|
protected function loadPaths(array $paths, $locale, $group)
|
||||||
{
|
{
|
||||||
$translations = parent::loadPath($path, $locale, $group);
|
return collect($paths)
|
||||||
|
->reduce(function ($output, $path) use ($locale, $group) {
|
||||||
|
if ($this->files->exists($full = "{$path}/{$locale}/{$group}.yml")) {
|
||||||
|
$output = resolve(Yaml::class)->parse($full);
|
||||||
|
}
|
||||||
|
|
||||||
$full = "{$path}/{$locale}/{$group}.yml";
|
return $output;
|
||||||
|
}, []);
|
||||||
return count($translations) === 0 && $this->files->exists($full)
|
|
||||||
? resolve(Yaml::class)->parse($full)
|
|
||||||
: [];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,21 +52,11 @@ if (!function_exists('option')) {
|
||||||
* Get / set the specified option value.
|
* Get / set the specified option value.
|
||||||
*
|
*
|
||||||
* If an array is passed as the key, we will assume you want to set an array of values.
|
* If an array is passed as the key, we will assume you want to set an array of values.
|
||||||
*
|
|
||||||
* @param array|string $key
|
|
||||||
* @param mixed $default
|
|
||||||
* @param bool $raw return raw value without convertion
|
|
||||||
*
|
|
||||||
* @return mixed
|
|
||||||
*/
|
*/
|
||||||
function option($key = null, $default = null, $raw = false)
|
function option(string|array $key, mixed $default = null, bool $raw = false)
|
||||||
{
|
{
|
||||||
$options = app('options');
|
$options = app('options');
|
||||||
|
|
||||||
if (is_null($key)) {
|
|
||||||
return $options;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_array($key)) {
|
if (is_array($key)) {
|
||||||
$options->set($key);
|
$options->set($key);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,27 +29,7 @@ ini_set('display_errors', true);
|
||||||
file_put_contents($envPath, preg_replace('/APP_KEY\s*=\s*/', 'APP_KEY='.$key."\n\n", $envFile));
|
file_put_contents($envPath, preg_replace('/APP_KEY\s*=\s*/', 'APP_KEY='.$key."\n\n", $envFile));
|
||||||
}
|
}
|
||||||
|
|
||||||
$requiredFunctions = ['symlink', 'readlink', 'putenv', 'realpath'];
|
$requiredVersion = '8.1.0';
|
||||||
$disabledFunctions = preg_split('/,\s*/', ini_get('disable_functions'));
|
|
||||||
foreach ($requiredFunctions as $fn) {
|
|
||||||
if (in_array($fn, $disabledFunctions)) {
|
|
||||||
die_with_utf8_encoding(
|
|
||||||
'[Error] Please don\'t disable built-in function "'.$fn.'", which is specified in "php.ini" file.<br>'.
|
|
||||||
"[错误] 请不要在 php.ini 中禁用 $fn 函数。".
|
|
||||||
'<strong>我们不建议使用您使用宝塔等面板软件,因为容易引起兼容性问题。</strong>'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!empty(ini_get('open_basedir'))) {
|
|
||||||
die_with_utf8_encoding(
|
|
||||||
'[Error] Please disable "open_basedir" option by editing "php.ini" file.<br>'.
|
|
||||||
'[错误] 请修改 php.ini 以关闭 "open_basedir" 选项。'.
|
|
||||||
'<strong>我们不建议使用您使用宝塔等面板软件,因为容易引起兼容性问题。</strong>'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$requiredVersion = '8.0.2';
|
|
||||||
preg_match('/(\d+\.\d+\.\d+)/', PHP_VERSION, $matches);
|
preg_match('/(\d+\.\d+\.\d+)/', PHP_VERSION, $matches);
|
||||||
$version = $matches[1];
|
$version = $matches[1];
|
||||||
if (version_compare($version, $requiredVersion, '<')) {
|
if (version_compare($version, $requiredVersion, '<')) {
|
||||||
|
|
@ -71,6 +51,7 @@ ini_set('display_errors', true);
|
||||||
'json',
|
'json',
|
||||||
'fileinfo',
|
'fileinfo',
|
||||||
'zip',
|
'zip',
|
||||||
|
'imagick',
|
||||||
],
|
],
|
||||||
'write_permission' => [
|
'write_permission' => [
|
||||||
'bootstrap/cache',
|
'bootstrap/cache',
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,10 @@
|
||||||
"description": "A web application brings your custom skins back in offline Minecraft servers.",
|
"description": "A web application brings your custom skins back in offline Minecraft servers.",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.0.2",
|
"php": "^8.1",
|
||||||
"ext-ctype": "*",
|
"ext-ctype": "*",
|
||||||
"ext-gd": "*",
|
"ext-gd": "*",
|
||||||
|
"ext-imagick": "*",
|
||||||
"ext-json": "*",
|
"ext-json": "*",
|
||||||
"ext-mbstring": "*",
|
"ext-mbstring": "*",
|
||||||
"ext-openssl": "*",
|
"ext-openssl": "*",
|
||||||
|
|
@ -18,35 +19,35 @@
|
||||||
"blessing/texture-renderer": "^0.2",
|
"blessing/texture-renderer": "^0.2",
|
||||||
"composer/ca-bundle": "^1.2",
|
"composer/ca-bundle": "^1.2",
|
||||||
"composer/semver": "^3.2",
|
"composer/semver": "^3.2",
|
||||||
"doctrine/dbal": "^2.10",
|
"doctrine/dbal": "^3.0",
|
||||||
"doctrine/inflector": "^1.3",
|
"doctrine/inflector": "^2.0",
|
||||||
"facade/ignition": "^2.0",
|
"spatie/laravel-ignition": "^2.0",
|
||||||
"gregwar/captcha": "1.*",
|
"gregwar/captcha": "1.*",
|
||||||
"guzzlehttp/guzzle": "^7.0",
|
"guzzlehttp/guzzle": "^7.0",
|
||||||
"intervention/image": "^2.7",
|
"intervention/image": "^2.7",
|
||||||
"laravel/framework": "^8.0",
|
"laravel/framework": "^10.0",
|
||||||
"laravel/passport": "^10.0",
|
"laravel/passport": "^11.0",
|
||||||
"lorisleiva/laravel-search-string": "^1.0",
|
"lorisleiva/laravel-search-string": "^1.0",
|
||||||
"nesbot/carbon": "^2.0",
|
"nesbot/carbon": "^2.0",
|
||||||
"nunomaduro/collision": "^5.0",
|
"nunomaduro/collision": "^7.0",
|
||||||
"rcrowe/twigbridge": "^0.12",
|
"rcrowe/twigbridge": "^0.14",
|
||||||
"spatie/laravel-translation-loader": "^2.6",
|
"spatie/laravel-translation-loader": "^2.7",
|
||||||
"symfony/process": "^5.0",
|
"symfony/process": "^6.0",
|
||||||
"symfony/yaml": "^5.0",
|
"symfony/yaml": "^5.0",
|
||||||
"twig/twig": "^2.11",
|
"twig/twig": "^3.0",
|
||||||
"vectorface/whip": "^0.3.2"
|
"vectorface/whip": "^0.4.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"barryvdh/laravel-debugbar": "^3.5",
|
"barryvdh/laravel-debugbar": "^3.5",
|
||||||
"barryvdh/laravel-ide-helper": "^2.10",
|
"barryvdh/laravel-ide-helper": "^2.10",
|
||||||
"fakerphp/faker": "^1.13",
|
"fakerphp/faker": "^1.13",
|
||||||
"friendsofphp/php-cs-fixer": "^3.0",
|
"friendsofphp/php-cs-fixer": "^3.13",
|
||||||
"laravel/browser-kit-testing": "^6.1",
|
"laravel/browser-kit-testing": "^7.0",
|
||||||
"laravel/tinker": "^2.4",
|
"laravel/tinker": "^2.4",
|
||||||
"mockery/mockery": "^1.4",
|
"mockery/mockery": "^1.4",
|
||||||
"phpunit/phpunit": "^9.4",
|
"phpunit/phpunit": "^10.0",
|
||||||
"symfony/css-selector": "^5.0",
|
"symfony/css-selector": "^6.2",
|
||||||
"symfony/dom-crawler": "^5.0"
|
"symfony/dom-crawler": "^6.2"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
|
|
@ -70,6 +71,7 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
|
"optimize-autoloader": true,
|
||||||
"preferred-install": "dist",
|
"preferred-install": "dist",
|
||||||
"sort-packages": true
|
"sort-packages": true
|
||||||
},
|
},
|
||||||
|
|
|
||||||
24283
composer.lock
generated
24283
composer.lock
generated
File diff suppressed because it is too large
Load Diff
102
config/app.php
102
config/app.php
|
|
@ -1,5 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Facade;
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
@ -9,6 +12,7 @@ return [
|
||||||
| Version of Blessing Skin Server.
|
| Version of Blessing Skin Server.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'version' => '6.0.2',
|
'version' => '6.0.2',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -19,12 +23,24 @@ return [
|
||||||
| Where to get information of new versions.
|
| Where to get information of new versions.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'update_source' => env(
|
'update_source' => env(
|
||||||
'UPDATE_SOURCE',
|
'UPDATE_SOURCE',
|
||||||
'https://dev.azure.com/blessing-skin/51010f6d-9f99-40f1-a262-0a67f788df32/_apis/git/'.
|
'https://dev.azure.com/blessing-skin/51010f6d-9f99-40f1-a262-0a67f788df32/_apis/git/'.
|
||||||
'repositories/a9ff8df7-6dc3-4ff8-bb22-4871d3a43936/Items?path=%2Fupdate.json'
|
'repositories/a9ff8df7-6dc3-4ff8-bb22-4871d3a43936/Items?path=%2Fupdate.json'
|
||||||
),
|
),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Application Name
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This value is the name of your application. This value is used when the
|
||||||
|
| framework needs to place the application's name in a notification or
|
||||||
|
| any other location as required by the application or its packages.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
'name' => env('APP_NAME', 'blessing_skin'),
|
'name' => env('APP_NAME', 'blessing_skin'),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -133,6 +149,24 @@ return [
|
||||||
|
|
||||||
'cipher' => 'AES-256-CBC',
|
'cipher' => 'AES-256-CBC',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Maintenance Mode Driver
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| These configuration options determine the driver used to determine and
|
||||||
|
| manage Laravel's "maintenance mode" status. The "cache" driver will
|
||||||
|
| allow maintenance mode to be controlled across multiple machines.
|
||||||
|
|
|
||||||
|
| Supported drivers: "file", "cache"
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'maintenance' => [
|
||||||
|
'driver' => 'file',
|
||||||
|
// 'store' => 'redis',
|
||||||
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Autoloaded Service Providers
|
| Autoloaded Service Providers
|
||||||
|
|
@ -144,29 +178,10 @@ return [
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'providers' => [
|
'providers' => ServiceProvider::defaultProviders()->merge([
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Laravel Framework Service Providers...
|
* Package Service Providers...
|
||||||
*/
|
*/
|
||||||
Illuminate\Auth\AuthServiceProvider::class,
|
|
||||||
Illuminate\Bus\BusServiceProvider::class,
|
|
||||||
Illuminate\Cache\CacheServiceProvider::class,
|
|
||||||
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
|
|
||||||
Illuminate\Cookie\CookieServiceProvider::class,
|
|
||||||
Illuminate\Database\DatabaseServiceProvider::class,
|
|
||||||
Illuminate\Encryption\EncryptionServiceProvider::class,
|
|
||||||
Illuminate\Filesystem\FilesystemServiceProvider::class,
|
|
||||||
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
|
|
||||||
Illuminate\Hashing\HashServiceProvider::class,
|
|
||||||
Illuminate\Mail\MailServiceProvider::class,
|
|
||||||
Illuminate\Notifications\NotificationServiceProvider::class,
|
|
||||||
Illuminate\Pagination\PaginationServiceProvider::class,
|
|
||||||
Illuminate\Queue\QueueServiceProvider::class,
|
|
||||||
Illuminate\Redis\RedisServiceProvider::class,
|
|
||||||
Illuminate\Session\SessionServiceProvider::class,
|
|
||||||
Illuminate\Validation\ValidationServiceProvider::class,
|
|
||||||
Illuminate\View\ViewServiceProvider::class,
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Application Service Providers...
|
* Application Service Providers...
|
||||||
|
|
@ -177,7 +192,7 @@ return [
|
||||||
App\Providers\PluginServiceProvider::class,
|
App\Providers\PluginServiceProvider::class,
|
||||||
App\Providers\RouteServiceProvider::class,
|
App\Providers\RouteServiceProvider::class,
|
||||||
App\Providers\ViewServiceProvider::class,
|
App\Providers\ViewServiceProvider::class,
|
||||||
],
|
])->toArray(),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
@ -190,44 +205,7 @@ return [
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'aliases' => [
|
'aliases' => Facade::defaultAliases()->merge([
|
||||||
|
'Option' => App\Services\Facades\Option::class,
|
||||||
'App' => Illuminate\Support\Facades\App::class,
|
])->toArray(),
|
||||||
'Artisan' => Illuminate\Support\Facades\Artisan::class,
|
|
||||||
'Auth' => Illuminate\Support\Facades\Auth::class,
|
|
||||||
'Blade' => Illuminate\Support\Facades\Blade::class,
|
|
||||||
'Cache' => Illuminate\Support\Facades\Cache::class,
|
|
||||||
'Config' => Illuminate\Support\Facades\Config::class,
|
|
||||||
'Cookie' => Illuminate\Support\Facades\Cookie::class,
|
|
||||||
'Crypt' => Illuminate\Support\Facades\Crypt::class,
|
|
||||||
'DB' => Illuminate\Support\Facades\DB::class,
|
|
||||||
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
|
|
||||||
'Event' => Illuminate\Support\Facades\Event::class,
|
|
||||||
'File' => Illuminate\Support\Facades\File::class,
|
|
||||||
'Gate' => Illuminate\Support\Facades\Gate::class,
|
|
||||||
'Hash' => Illuminate\Support\Facades\Hash::class,
|
|
||||||
'Http' => Illuminate\Support\Facades\Http::class,
|
|
||||||
'Lang' => Illuminate\Support\Facades\Lang::class,
|
|
||||||
'Log' => Illuminate\Support\Facades\Log::class,
|
|
||||||
'Mail' => Illuminate\Support\Facades\Mail::class,
|
|
||||||
'Notification' => Illuminate\Support\Facades\Notification::class,
|
|
||||||
'Password' => Illuminate\Support\Facades\Password::class,
|
|
||||||
'Queue' => Illuminate\Support\Facades\Queue::class,
|
|
||||||
'Redirect' => Illuminate\Support\Facades\Redirect::class,
|
|
||||||
'Request' => Illuminate\Support\Facades\Request::class,
|
|
||||||
'Response' => Illuminate\Support\Facades\Response::class,
|
|
||||||
'Route' => Illuminate\Support\Facades\Route::class,
|
|
||||||
'Schema' => Illuminate\Support\Facades\Schema::class,
|
|
||||||
'Session' => Illuminate\Support\Facades\Session::class,
|
|
||||||
'Storage' => Illuminate\Support\Facades\Storage::class,
|
|
||||||
'URL' => Illuminate\Support\Facades\URL::class,
|
|
||||||
'Validator' => Illuminate\Support\Facades\Validator::class,
|
|
||||||
'View' => Illuminate\Support\Facades\View::class,
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Blessing Skin
|
|
||||||
*/
|
|
||||||
'Option' => App\Services\Facades\Option::class,
|
|
||||||
],
|
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Authentication Defaults
|
| Authentication Defaults
|
||||||
|
|
@ -103,5 +102,4 @@ return [
|
||||||
'expire' => 60,
|
'expire' => 60,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Default Broadcaster
|
| Default Broadcaster
|
||||||
|
|
@ -11,7 +10,7 @@ return [
|
||||||
| framework when an event needs to be broadcast. You may set this to
|
| framework when an event needs to be broadcast. You may set this to
|
||||||
| any of the connections defined in the "connections" array below.
|
| any of the connections defined in the "connections" array below.
|
||||||
|
|
|
|
||||||
| Supported: "pusher", "redis", "log", "null"
|
| Supported: "pusher", "ably", "redis", "log", "null"
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -29,7 +28,6 @@ return [
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'connections' => [
|
'connections' => [
|
||||||
|
|
||||||
'pusher' => [
|
'pusher' => [
|
||||||
'driver' => 'pusher',
|
'driver' => 'pusher',
|
||||||
'key' => env('PUSHER_APP_KEY'),
|
'key' => env('PUSHER_APP_KEY'),
|
||||||
|
|
@ -37,8 +35,20 @@ return [
|
||||||
'app_id' => env('PUSHER_APP_ID'),
|
'app_id' => env('PUSHER_APP_ID'),
|
||||||
'options' => [
|
'options' => [
|
||||||
'cluster' => env('PUSHER_APP_CLUSTER'),
|
'cluster' => env('PUSHER_APP_CLUSTER'),
|
||||||
'useTLS' => true,
|
'host' => env('PUSHER_HOST') ?: 'api-'.env('PUSHER_APP_CLUSTER', 'mt1').'.pusher.com',
|
||||||
|
'port' => env('PUSHER_PORT', 443),
|
||||||
|
'scheme' => env('PUSHER_SCHEME', 'https'),
|
||||||
|
'encrypted' => true,
|
||||||
|
'useTLS' => env('PUSHER_SCHEME', 'https') === 'https',
|
||||||
],
|
],
|
||||||
|
'client_options' => [
|
||||||
|
// Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
'ably' => [
|
||||||
|
'driver' => 'ably',
|
||||||
|
'key' => env('ABLY_KEY'),
|
||||||
],
|
],
|
||||||
|
|
||||||
'redis' => [
|
'redis' => [
|
||||||
|
|
@ -53,7 +63,5 @@ return [
|
||||||
'null' => [
|
'null' => [
|
||||||
'driver' => 'null',
|
'driver' => 'null',
|
||||||
],
|
],
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Default Cache Store
|
| Default Cache Store
|
||||||
|
|
@ -13,9 +12,6 @@ return [
|
||||||
| using this caching library. This connection is used when another is
|
| using this caching library. This connection is used when another is
|
||||||
| not explicitly specified when executing a given caching function.
|
| not explicitly specified when executing a given caching function.
|
||||||
|
|
|
|
||||||
| Supported: "apc", "array", "database", "file",
|
|
||||||
| "memcached", "redis", "dynamodb"
|
|
||||||
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'default' => env('CACHE_DRIVER', 'file'),
|
'default' => env('CACHE_DRIVER', 'file'),
|
||||||
|
|
@ -29,10 +25,12 @@ return [
|
||||||
| well as their drivers. You may even define multiple stores for the
|
| well as their drivers. You may even define multiple stores for the
|
||||||
| same cache driver to group types of items stored in your caches.
|
| same cache driver to group types of items stored in your caches.
|
||||||
|
|
|
|
||||||
|
| Supported drivers: "apc", "array", "database", "file",
|
||||||
|
| "memcached", "redis", "dynamodb", "octane", "null"
|
||||||
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'stores' => [
|
'stores' => [
|
||||||
|
|
||||||
'apc' => [
|
'apc' => [
|
||||||
'driver' => 'apc',
|
'driver' => 'apc',
|
||||||
],
|
],
|
||||||
|
|
@ -46,11 +44,13 @@ return [
|
||||||
'driver' => 'database',
|
'driver' => 'database',
|
||||||
'table' => 'cache',
|
'table' => 'cache',
|
||||||
'connection' => null,
|
'connection' => null,
|
||||||
|
'lock_connection' => null,
|
||||||
],
|
],
|
||||||
|
|
||||||
'file' => [
|
'file' => [
|
||||||
'driver' => 'file',
|
'driver' => 'file',
|
||||||
'path' => storage_path('framework/cache/data'),
|
'path' => storage_path('framework/cache/data'),
|
||||||
|
'lock_path' => storage_path('framework/cache/data'),
|
||||||
],
|
],
|
||||||
|
|
||||||
'memcached' => [
|
'memcached' => [
|
||||||
|
|
@ -75,6 +75,7 @@ return [
|
||||||
'redis' => [
|
'redis' => [
|
||||||
'driver' => 'redis',
|
'driver' => 'redis',
|
||||||
'connection' => 'cache',
|
'connection' => 'cache',
|
||||||
|
'lock_connection' => 'default',
|
||||||
],
|
],
|
||||||
|
|
||||||
'dynamodb' => [
|
'dynamodb' => [
|
||||||
|
|
@ -86,6 +87,9 @@ return [
|
||||||
'endpoint' => env('DYNAMODB_ENDPOINT'),
|
'endpoint' => env('DYNAMODB_ENDPOINT'),
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'octane' => [
|
||||||
|
'driver' => 'octane',
|
||||||
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -93,12 +97,11 @@ return [
|
||||||
| Cache Key Prefix
|
| Cache Key Prefix
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| When utilizing a RAM based store such as APC or Memcached, there might
|
| When utilizing the APC, database, memcached, Redis, or DynamoDB cache
|
||||||
| be other applications utilizing the same cache. So, we'll specify a
|
| stores there might be other applications using the same cache. For
|
||||||
| value to get prefixed to all our keys so we can avoid collisions.
|
| that reason, you may prefix every cache key to avoid collisions.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'blessing_skin'), '_').'_cache'),
|
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'blessing_skin'), '_').'_cache_'),
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Default Database Connection Name
|
| Default Database Connection Name
|
||||||
|
|
@ -34,7 +33,6 @@ return [
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'connections' => [
|
'connections' => [
|
||||||
|
|
||||||
'sqlite' => [
|
'sqlite' => [
|
||||||
'driver' => 'sqlite',
|
'driver' => 'sqlite',
|
||||||
'url' => env('DATABASE_URL'),
|
'url' => env('DATABASE_URL'),
|
||||||
|
|
@ -56,7 +54,7 @@ return [
|
||||||
'collation' => 'utf8mb4_unicode_ci',
|
'collation' => 'utf8mb4_unicode_ci',
|
||||||
'prefix' => env('DB_PREFIX', ''),
|
'prefix' => env('DB_PREFIX', ''),
|
||||||
'prefix_indexes' => true,
|
'prefix_indexes' => true,
|
||||||
'strict' => false,
|
'strict' => true,
|
||||||
'engine' => null,
|
'engine' => null,
|
||||||
'options' => extension_loaded('pdo_mysql') ? array_filter([
|
'options' => extension_loaded('pdo_mysql') ? array_filter([
|
||||||
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
|
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
|
||||||
|
|
@ -74,7 +72,7 @@ return [
|
||||||
'charset' => 'utf8',
|
'charset' => 'utf8',
|
||||||
'prefix' => env('DB_PREFIX', ''),
|
'prefix' => env('DB_PREFIX', ''),
|
||||||
'prefix_indexes' => true,
|
'prefix_indexes' => true,
|
||||||
'schema' => 'public',
|
'search_path' => 'public',
|
||||||
'sslmode' => 'prefer',
|
'sslmode' => 'prefer',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|
@ -89,8 +87,9 @@ return [
|
||||||
'charset' => 'utf8',
|
'charset' => 'utf8',
|
||||||
'prefix' => env('DB_PREFIX', ''),
|
'prefix' => env('DB_PREFIX', ''),
|
||||||
'prefix_indexes' => true,
|
'prefix_indexes' => true,
|
||||||
|
// 'encrypt' => env('DB_ENCRYPT', 'yes'),
|
||||||
|
// 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'),
|
||||||
],
|
],
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -118,7 +117,6 @@ return [
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'redis' => [
|
'redis' => [
|
||||||
|
|
||||||
'client' => env('REDIS_CLIENT', 'phpredis'),
|
'client' => env('REDIS_CLIENT', 'phpredis'),
|
||||||
|
|
||||||
'options' => [
|
'options' => [
|
||||||
|
|
@ -129,7 +127,8 @@ return [
|
||||||
'default' => [
|
'default' => [
|
||||||
'url' => env('REDIS_URL'),
|
'url' => env('REDIS_URL'),
|
||||||
'host' => env('REDIS_HOST', '127.0.0.1'),
|
'host' => env('REDIS_HOST', '127.0.0.1'),
|
||||||
'password' => env('REDIS_PASSWORD', null),
|
'username' => env('REDIS_USERNAME'),
|
||||||
|
'password' => env('REDIS_PASSWORD'),
|
||||||
'port' => env('REDIS_PORT', '6379'),
|
'port' => env('REDIS_PORT', '6379'),
|
||||||
'database' => env('REDIS_DB', '0'),
|
'database' => env('REDIS_DB', '0'),
|
||||||
],
|
],
|
||||||
|
|
@ -137,11 +136,10 @@ return [
|
||||||
'cache' => [
|
'cache' => [
|
||||||
'url' => env('REDIS_URL'),
|
'url' => env('REDIS_URL'),
|
||||||
'host' => env('REDIS_HOST', '127.0.0.1'),
|
'host' => env('REDIS_HOST', '127.0.0.1'),
|
||||||
'password' => env('REDIS_PASSWORD', null),
|
'username' => env('REDIS_USERNAME'),
|
||||||
|
'password' => env('REDIS_PASSWORD'),
|
||||||
'port' => env('REDIS_PORT', '6379'),
|
'port' => env('REDIS_PORT', '6379'),
|
||||||
'database' => env('REDIS_CACHE_DB', '1'),
|
'database' => env('REDIS_CACHE_DB', '1'),
|
||||||
],
|
],
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Debugbar Settings
|
| Debugbar Settings
|
||||||
|
|
@ -16,7 +15,8 @@ return [
|
||||||
|
|
||||||
'enabled' => env('DEBUGBAR_ENABLED', null),
|
'enabled' => env('DEBUGBAR_ENABLED', null),
|
||||||
'except' => [
|
'except' => [
|
||||||
//
|
'telescope*',
|
||||||
|
'horizon*',
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -32,13 +32,57 @@ return [
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
'storage' => [
|
'storage' => [
|
||||||
'enabled' => true,
|
'enabled' => true,
|
||||||
'driver' => 'file', // redis, file, pdo, custom
|
'driver' => 'file', // redis, file, pdo, socket, custom
|
||||||
'path' => storage_path('debugbar'), // For file driver
|
'path' => storage_path('debugbar'), // For file driver
|
||||||
'connection' => null, // Leave null for default connection (Redis/PDO)
|
'connection' => null, // Leave null for default connection (Redis/PDO)
|
||||||
'provider' => '', // Instance of StorageInterface for custom driver
|
'provider' => '', // Instance of StorageInterface for custom driver
|
||||||
|
'hostname' => '127.0.0.1', // Hostname to use with the "socket" driver
|
||||||
|
'port' => 2304, // Port to use with the "socket" driver
|
||||||
],
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Editor
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Choose your preferred editor to use when clicking file name.
|
||||||
|
|
|
||||||
|
| Supported: "phpstorm", "vscode", "vscode-insiders", "vscode-remote",
|
||||||
|
| "vscode-insiders-remote", "vscodium", "textmate", "emacs",
|
||||||
|
| "sublime", "atom", "nova", "macvim", "idea", "netbeans",
|
||||||
|
| "xdebug", "espresso"
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'editor' => env('DEBUGBAR_EDITOR', 'phpstorm'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Remote Path Mapping
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| If you are using a remote dev server, like Laravel Homestead, Docker, or
|
||||||
|
| even a remote VPS, it will be necessary to specify your path mapping.
|
||||||
|
|
|
||||||
|
| Leaving one, or both of these, empty or null will not trigger the remote
|
||||||
|
| URL changes and Debugbar will treat your editor links as local files.
|
||||||
|
|
|
||||||
|
| "remote_sites_path" is an absolute base path for your sites or projects
|
||||||
|
| in Homestead, Vagrant, Docker, or another remote development server.
|
||||||
|
|
|
||||||
|
| Example value: "/home/vagrant/Code"
|
||||||
|
|
|
||||||
|
| "local_sites_path" is an absolute base path for your sites or projects
|
||||||
|
| on your local computer where your IDE or code editor is running on.
|
||||||
|
|
|
||||||
|
| Example values: "/Users/<name>/Code", "C:\Users\<name>\Documents\Code"
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'remote_sites_path' => env('DEBUGBAR_REMOTE_SITES_PATH', ''),
|
||||||
|
'local_sites_path' => env('DEBUGBAR_LOCAL_SITES_PATH', ''),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Vendors
|
| Vendors
|
||||||
|
|
@ -47,7 +91,7 @@ return [
|
||||||
| Vendor files are included by default, but can be set to false.
|
| Vendor files are included by default, but can be set to false.
|
||||||
| This can also be set to 'js' or 'css', to only include javascript or css vendor files.
|
| This can also be set to 'js' or 'css', to only include javascript or css vendor files.
|
||||||
| Vendor files are for css: font-awesome (including fonts) and highlight.js (css files)
|
| Vendor files are for css: font-awesome (including fonts) and highlight.js (css files)
|
||||||
| and for js: jquery and and highlight.js
|
| and for js: jquery and highlight.js
|
||||||
| So if you want syntax highlighting, set it to true.
|
| So if you want syntax highlighting, set it to true.
|
||||||
| jQuery is set to not conflict with existing jQuery scripts.
|
| jQuery is set to not conflict with existing jQuery scripts.
|
||||||
|
|
|
|
||||||
|
|
@ -64,6 +108,9 @@ return [
|
||||||
| you can use this option to disable sending the data through the headers.
|
| you can use this option to disable sending the data through the headers.
|
||||||
|
|
|
|
||||||
| Optionally, you can also send ServerTiming headers on ajax requests for the Chrome DevTools.
|
| Optionally, you can also send ServerTiming headers on ajax requests for the Chrome DevTools.
|
||||||
|
|
|
||||||
|
| Note for your request to be identified as ajax requests they must either send the header
|
||||||
|
| X-Requested-With with the value XMLHttpRequest (most JS libraries send this), or have application/json as a Accept header.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'capture_ajax' => true,
|
'capture_ajax' => true,
|
||||||
|
|
@ -101,27 +148,29 @@ return [
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'collectors' => [
|
'collectors' => [
|
||||||
'phpinfo' => true, // Php version
|
'phpinfo' => true, // Php version
|
||||||
'messages' => true, // Messages
|
'messages' => true, // Messages
|
||||||
'time' => true, // Time Datalogger
|
'time' => true, // Time Datalogger
|
||||||
'memory' => true, // Memory usage
|
'memory' => true, // Memory usage
|
||||||
'exceptions' => true, // Exception displayer
|
'exceptions' => true, // Exception displayer
|
||||||
'log' => true, // Logs from Monolog (merged in messages if enabled)
|
'log' => true, // Logs from Monolog (merged in messages if enabled)
|
||||||
'db' => true, // Show database (PDO) queries and bindings
|
'db' => true, // Show database (PDO) queries and bindings
|
||||||
'views' => true, // Views with their data
|
'views' => true, // Views with their data
|
||||||
'route' => true, // Current route information
|
'route' => true, // Current route information
|
||||||
'auth' => true, // Display Laravel authentication status
|
'auth' => false, // Display Laravel authentication status
|
||||||
'gate' => false, // Display Laravel Gate checks
|
'gate' => true, // Display Laravel Gate checks
|
||||||
'session' => true, // Display session data
|
'session' => true, // Display session data
|
||||||
'symfony_request' => true, // Only one can be enabled..
|
'symfony_request' => true, // Only one can be enabled..
|
||||||
'mail' => false, // Catch mail messages
|
'mail' => true, // Catch mail messages
|
||||||
'laravel' => false, // Laravel version and environment
|
'laravel' => false, // Laravel version and environment
|
||||||
'events' => true, // All events fired
|
'events' => false, // All events fired
|
||||||
'default_request' => false, // Regular or special Symfony request logger
|
'default_request' => false, // Regular or special Symfony request logger
|
||||||
'logs' => false, // Add the latest log messages
|
'logs' => false, // Add the latest log messages
|
||||||
'files' => false, // Show the included files
|
'files' => false, // Show the included files
|
||||||
'config' => false, // Display config settings
|
'config' => false, // Display config settings
|
||||||
'cache' => false, // Display cache events
|
'cache' => false, // Display cache events
|
||||||
|
'models' => true, // Display models
|
||||||
|
'livewire' => true, // Display Livewire (when available)
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -138,20 +187,26 @@ return [
|
||||||
'show_name' => true, // Also show the users name/email in the debugbar
|
'show_name' => true, // Also show the users name/email in the debugbar
|
||||||
],
|
],
|
||||||
'db' => [
|
'db' => [
|
||||||
'with_params' => true, // Render SQL with the parameters substituted
|
'with_params' => true, // Render SQL with the parameters substituted
|
||||||
'backtrace' => true, // Use a backtrace to find the origin of the query in your files.
|
'backtrace' => true, // Use a backtrace to find the origin of the query in your files.
|
||||||
'timeline' => false, // Add the queries to the timeline
|
'backtrace_exclude_paths' => [], // Paths to exclude from backtrace. (in addition to defaults)
|
||||||
|
'timeline' => false, // Add the queries to the timeline
|
||||||
|
'duration_background' => true, // Show shaded background on each query relative to how long it took to execute.
|
||||||
'explain' => [ // Show EXPLAIN output on queries
|
'explain' => [ // Show EXPLAIN output on queries
|
||||||
'enabled' => false,
|
'enabled' => false,
|
||||||
'types' => ['SELECT'], // ['SELECT', 'INSERT', 'UPDATE', 'DELETE']; for MySQL 5.6.3+
|
'types' => ['SELECT'], // Deprecated setting, is always only SELECT
|
||||||
],
|
],
|
||||||
'hints' => true, // Show hints for common mistakes
|
'hints' => false, // Show hints for common mistakes
|
||||||
|
'show_copy' => false, // Show copy button next to the query,
|
||||||
|
'slow_threshold' => false, // Only track queries that last longer than this time in ms
|
||||||
],
|
],
|
||||||
'mail' => [
|
'mail' => [
|
||||||
'full_log' => false,
|
'full_log' => false,
|
||||||
],
|
],
|
||||||
'views' => [
|
'views' => [
|
||||||
'data' => false, //Note: Can slow down the application, because the data can be quite large..
|
'timeline' => false, // Add the views to the timeline (Experimental)
|
||||||
|
'data' => false, // Note: Can slow down the application, because the data can be quite large..
|
||||||
|
'exclude_paths' => [], // Add the paths which you don't want to appear in the views
|
||||||
],
|
],
|
||||||
'route' => [
|
'route' => [
|
||||||
'label' => true, // show complete route on bar
|
'label' => true, // show complete route on bar
|
||||||
|
|
@ -198,4 +253,24 @@ return [
|
||||||
| To override default domain, specify it as a non-empty value.
|
| To override default domain, specify it as a non-empty value.
|
||||||
*/
|
*/
|
||||||
'route_domain' => null,
|
'route_domain' => null,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| DebugBar theme
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Switches between light and dark theme. If set to auto it will respect system preferences
|
||||||
|
| Possible values: auto, light, dark
|
||||||
|
*/
|
||||||
|
'theme' => env('DEBUGBAR_THEME', 'auto'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Backtrace stack limit
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| By default, the DebugBar limits the number of frames returned by the 'debug_backtrace()' function.
|
||||||
|
| If you need larger stacktraces, you can increase this number. Setting it to 0 will result in no limit.
|
||||||
|
*/
|
||||||
|
'debug_backtrace_limit' => 50,
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Default Filesystem Disk
|
| Default Filesystem Disk
|
||||||
|
|
@ -42,7 +41,6 @@ return [
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'disks' => [
|
'disks' => [
|
||||||
|
|
||||||
'local' => [
|
'local' => [
|
||||||
'driver' => 'local',
|
'driver' => 'local',
|
||||||
'root' => storage_path('app'),
|
'root' => storage_path('app'),
|
||||||
|
|
@ -61,7 +59,5 @@ return [
|
||||||
'testing' => [
|
'testing' => [
|
||||||
'driver' => 'memory',
|
'driver' => 'memory',
|
||||||
],
|
],
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Default Hash Driver
|
| Default Hash Driver
|
||||||
|
|
@ -44,9 +43,8 @@ return [
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'argon' => [
|
'argon' => [
|
||||||
'memory' => 1024,
|
'memory' => 65536,
|
||||||
'threads' => 2,
|
'threads' => 1,
|
||||||
'time' => 2,
|
'time' => 4,
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
20
config/image.php
Normal file
20
config/image.php
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Image Driver
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Intervention Image supports "GD Library" and "Imagick" to process images
|
||||||
|
| internally. You may choose one of them according to your PHP
|
||||||
|
| configuration. By default PHP's "GD Library" implementation is used.
|
||||||
|
|
|
||||||
|
| Supported: "gd", "imagick"
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'driver' => 'imagick'
|
||||||
|
|
||||||
|
];
|
||||||
|
|
@ -10,7 +10,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| JWT Authentication Secret
|
| JWT Authentication Secret
|
||||||
|
|
@ -45,7 +44,6 @@ return [
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'keys' => [
|
'keys' => [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Public Key
|
| Public Key
|
||||||
|
|
@ -82,7 +80,6 @@ return [
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'passphrase' => env('JWT_PASSPHRASE'),
|
'passphrase' => env('JWT_PASSPHRASE'),
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -265,7 +262,6 @@ return [
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'providers' => [
|
'providers' => [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| JWT Provider
|
| JWT Provider
|
||||||
|
|
@ -298,7 +294,5 @@ return [
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,
|
'storage' => Tymon\JWTAuth\Providers\Storage\Illuminate::class,
|
||||||
|
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ return [
|
||||||
],
|
],
|
||||||
'es_ES' => [
|
'es_ES' => [
|
||||||
'name' => 'Español',
|
'name' => 'Español',
|
||||||
'short_name' => 'es'
|
'short_name' => 'es',
|
||||||
],
|
],
|
||||||
'ru' => [
|
'ru' => [
|
||||||
'alias' => 'ru_RU',
|
'alias' => 'ru_RU',
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@
|
||||||
use Monolog\Handler\NullHandler;
|
use Monolog\Handler\NullHandler;
|
||||||
use Monolog\Handler\StreamHandler;
|
use Monolog\Handler\StreamHandler;
|
||||||
use Monolog\Handler\SyslogUdpHandler;
|
use Monolog\Handler\SyslogUdpHandler;
|
||||||
|
use Monolog\Processor\PsrLogMessageProcessor;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Default Log Channel
|
| Default Log Channel
|
||||||
|
|
@ -19,6 +19,22 @@ return [
|
||||||
|
|
||||||
'default' => env('LOG_CHANNEL', 'daily'),
|
'default' => env('LOG_CHANNEL', 'daily'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Deprecations Log Channel
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option controls the log channel that should be used to log warnings
|
||||||
|
| regarding deprecated PHP and library features. This allows you to get
|
||||||
|
| your application ready for upcoming major versions of dependencies.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'deprecations' => [
|
||||||
|
'channel' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),
|
||||||
|
'trace' => false,
|
||||||
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Log Channels
|
| Log Channels
|
||||||
|
|
@ -44,14 +60,16 @@ return [
|
||||||
'single' => [
|
'single' => [
|
||||||
'driver' => 'single',
|
'driver' => 'single',
|
||||||
'path' => storage_path('logs/laravel.log'),
|
'path' => storage_path('logs/laravel.log'),
|
||||||
'level' => 'debug',
|
'level' => env('LOG_LEVEL', 'debug'),
|
||||||
|
'replace_placeholders' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'daily' => [
|
'daily' => [
|
||||||
'driver' => 'daily',
|
'driver' => 'daily',
|
||||||
'path' => storage_path('logs/laravel.log'),
|
'path' => storage_path('logs/laravel.log'),
|
||||||
'level' => 'debug',
|
'level' => env('LOG_LEVEL', 'debug'),
|
||||||
'days' => 14,
|
'days' => 14,
|
||||||
|
'replace_placeholders' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'slack' => [
|
'slack' => [
|
||||||
|
|
@ -59,36 +77,44 @@ return [
|
||||||
'url' => env('LOG_SLACK_WEBHOOK_URL'),
|
'url' => env('LOG_SLACK_WEBHOOK_URL'),
|
||||||
'username' => 'Laravel Log',
|
'username' => 'Laravel Log',
|
||||||
'emoji' => ':boom:',
|
'emoji' => ':boom:',
|
||||||
'level' => 'critical',
|
'level' => env('LOG_LEVEL', 'critical'),
|
||||||
|
'replace_placeholders' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'papertrail' => [
|
'papertrail' => [
|
||||||
'driver' => 'monolog',
|
'driver' => 'monolog',
|
||||||
'level' => 'debug',
|
'level' => env('LOG_LEVEL', 'debug'),
|
||||||
'handler' => SyslogUdpHandler::class,
|
'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class),
|
||||||
'handler_with' => [
|
'handler_with' => [
|
||||||
'host' => env('PAPERTRAIL_URL'),
|
'host' => env('PAPERTRAIL_URL'),
|
||||||
'port' => env('PAPERTRAIL_PORT'),
|
'port' => env('PAPERTRAIL_PORT'),
|
||||||
|
'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'),
|
||||||
],
|
],
|
||||||
|
'processors' => [PsrLogMessageProcessor::class],
|
||||||
],
|
],
|
||||||
|
|
||||||
'stderr' => [
|
'stderr' => [
|
||||||
'driver' => 'monolog',
|
'driver' => 'monolog',
|
||||||
|
'level' => env('LOG_LEVEL', 'debug'),
|
||||||
'handler' => StreamHandler::class,
|
'handler' => StreamHandler::class,
|
||||||
'formatter' => env('LOG_STDERR_FORMATTER'),
|
'formatter' => env('LOG_STDERR_FORMATTER'),
|
||||||
'with' => [
|
'with' => [
|
||||||
'stream' => 'php://stderr',
|
'stream' => 'php://stderr',
|
||||||
],
|
],
|
||||||
|
'processors' => [PsrLogMessageProcessor::class],
|
||||||
],
|
],
|
||||||
|
|
||||||
'syslog' => [
|
'syslog' => [
|
||||||
'driver' => 'syslog',
|
'driver' => 'syslog',
|
||||||
'level' => 'debug',
|
'level' => env('LOG_LEVEL', 'debug'),
|
||||||
|
'facility' => LOG_USER,
|
||||||
|
'replace_placeholders' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'errorlog' => [
|
'errorlog' => [
|
||||||
'driver' => 'errorlog',
|
'driver' => 'errorlog',
|
||||||
'level' => 'debug',
|
'level' => env('LOG_LEVEL', 'debug'),
|
||||||
|
'replace_placeholders' => true,
|
||||||
],
|
],
|
||||||
|
|
||||||
'null' => [
|
'null' => [
|
||||||
|
|
@ -100,5 +126,4 @@ return [
|
||||||
'path' => storage_path('logs/laravel.log'),
|
'path' => storage_path('logs/laravel.log'),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Default Mailer
|
| Default Mailer
|
||||||
|
|
@ -28,19 +27,22 @@ return [
|
||||||
| sending an e-mail. You will specify which one you are using for your
|
| sending an e-mail. You will specify which one you are using for your
|
||||||
| mailers below. You are free to add additional mailers as required.
|
| mailers below. You are free to add additional mailers as required.
|
||||||
|
|
|
|
||||||
| Supported: "smtp", "sendmail", "mailgun", "ses",
|
| Supported: "smtp", "sendmail", "mailgun", "ses", "ses-v2",
|
||||||
| "postmark", "log", "array"
|
| "postmark", "log", "array", "failover"
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'mailers' => [
|
'mailers' => [
|
||||||
'smtp' => [
|
'smtp' => [
|
||||||
'transport' => 'smtp',
|
'transport' => 'smtp',
|
||||||
|
'url' => env('MAIL_URL'),
|
||||||
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
|
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
|
||||||
'port' => env('MAIL_PORT', 587),
|
'port' => env('MAIL_PORT', 587),
|
||||||
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
|
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
|
||||||
'username' => env('MAIL_USERNAME'),
|
'username' => env('MAIL_USERNAME'),
|
||||||
'password' => env('MAIL_PASSWORD'),
|
'password' => env('MAIL_PASSWORD'),
|
||||||
|
'timeout' => null,
|
||||||
|
'local_domain' => env('MAIL_EHLO_DOMAIN'),
|
||||||
],
|
],
|
||||||
|
|
||||||
'ses' => [
|
'ses' => [
|
||||||
|
|
@ -49,15 +51,21 @@ return [
|
||||||
|
|
||||||
'mailgun' => [
|
'mailgun' => [
|
||||||
'transport' => 'mailgun',
|
'transport' => 'mailgun',
|
||||||
|
// 'client' => [
|
||||||
|
// 'timeout' => 5,
|
||||||
|
// ],
|
||||||
],
|
],
|
||||||
|
|
||||||
'postmark' => [
|
'postmark' => [
|
||||||
'transport' => 'postmark',
|
'transport' => 'postmark',
|
||||||
|
// 'client' => [
|
||||||
|
// 'timeout' => 5,
|
||||||
|
// ],
|
||||||
],
|
],
|
||||||
|
|
||||||
'sendmail' => [
|
'sendmail' => [
|
||||||
'transport' => 'sendmail',
|
'transport' => 'sendmail',
|
||||||
'path' => '/usr/sbin/sendmail -bs',
|
'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'),
|
||||||
],
|
],
|
||||||
|
|
||||||
'log' => [
|
'log' => [
|
||||||
|
|
@ -68,6 +76,14 @@ return [
|
||||||
'array' => [
|
'array' => [
|
||||||
'transport' => 'array',
|
'transport' => 'array',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'failover' => [
|
||||||
|
'transport' => 'failover',
|
||||||
|
'mailers' => [
|
||||||
|
'smtp',
|
||||||
|
'log',
|
||||||
|
],
|
||||||
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -104,5 +120,4 @@ return [
|
||||||
resource_path('views/vendor/mail'),
|
resource_path('views/vendor/mail'),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ $menu['admin'] = [
|
||||||
['title' => 'general.status', 'link' => 'admin/status', 'icon' => 'fa-battery-three-quarters'],
|
['title' => 'general.status', 'link' => 'admin/status', 'icon' => 'fa-battery-three-quarters'],
|
||||||
['title' => 'general.plugin-manage', 'link' => 'admin/plugins/manage', 'icon' => 'fa-plug'],
|
['title' => 'general.plugin-manage', 'link' => 'admin/plugins/manage', 'icon' => 'fa-plug'],
|
||||||
['title' => 'general.plugin-market', 'link' => 'admin/plugins/market', 'icon' => 'fa-shopping-bag'],
|
['title' => 'general.plugin-market', 'link' => 'admin/plugins/market', 'icon' => 'fa-shopping-bag'],
|
||||||
['title' => 'general.plugin-configs', 'id' => 'plugin-configs', 'icon' => 'fa-cogs', 'children' => []],
|
['title' => 'general.plugin-configs', 'id' => 'plugin-configs', 'icon' => 'fa-cogs', 'children' => []],
|
||||||
['title' => 'general.check-update', 'link' => 'admin/update', 'icon' => 'fa-arrow-up'],
|
['title' => 'general.check-update', 'link' => 'admin/update', 'icon' => 'fa-arrow-up'],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,56 +1,56 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'site_url' => '',
|
'site_url' => '',
|
||||||
'site_name' => 'Blessing Skin',
|
'site_name' => 'Blessing Skin',
|
||||||
'site_description' => 'Open-source PHP Minecraft Skin Hosting Service',
|
'site_description' => 'Open-source PHP Minecraft Skin Hosting Service',
|
||||||
'register_with_player_name' => 'true',
|
'register_with_player_name' => 'true',
|
||||||
'require_verification' => 'false',
|
'require_verification' => 'false',
|
||||||
'regs_per_ip' => '3',
|
'regs_per_ip' => '3',
|
||||||
'announcement' => 'Welcome to Blessing Skin {version}!',
|
'announcement' => 'Welcome to Blessing Skin {version}!',
|
||||||
'home_pic_url' => './app/bg.webp',
|
'home_pic_url' => './app/bg.webp',
|
||||||
'custom_css' => '',
|
'custom_css' => '',
|
||||||
'custom_js' => '',
|
'custom_js' => '',
|
||||||
'player_name_rule' => 'official',
|
'player_name_rule' => 'official',
|
||||||
'custom_player_name_regexp' => '',
|
'custom_player_name_regexp' => '',
|
||||||
'player_name_length_min' => '3',
|
'player_name_length_min' => '3',
|
||||||
'player_name_length_max' => '16',
|
'player_name_length_max' => '16',
|
||||||
'user_initial_score' => '1000',
|
'user_initial_score' => '1000',
|
||||||
'sign_gap_time' => '24',
|
'sign_gap_time' => '24',
|
||||||
'sign_score' => '10,100',
|
'sign_score' => '10,100',
|
||||||
'score_per_storage' => 'true',
|
'score_per_storage' => 'true',
|
||||||
'private_score_per_storage' => '10',
|
'private_score_per_storage' => '10',
|
||||||
'return_score' => 'true',
|
'return_score' => 'true',
|
||||||
'score_per_player' => '100',
|
'score_per_player' => '100',
|
||||||
'sign_after_zero' => 'false',
|
'sign_after_zero' => 'false',
|
||||||
'version' => '',
|
'version' => '',
|
||||||
'copyright_text' => '<b>Copyright © {year} <a href="{site_url}">{site_name}</a>.</b> All rights reserved.',
|
'copyright_text' => '<b>Copyright © {year} <a href="{site_url}">{site_name}</a>.</b> All rights reserved.',
|
||||||
'auto_del_invalid_texture' => 'false',
|
'auto_del_invalid_texture' => 'false',
|
||||||
'allow_downloading_texture' => 'true',
|
'allow_downloading_texture' => 'true',
|
||||||
'texture_name_regexp' => '',
|
'texture_name_regexp' => '',
|
||||||
'cache_expire_time' => '31536000',
|
'cache_expire_time' => '31536000',
|
||||||
'max_upload_file_size' => '1024',
|
'max_upload_file_size' => '1024',
|
||||||
'force_ssl' => 'false',
|
'force_ssl' => 'false',
|
||||||
'auto_detect_asset_url' => 'true',
|
'auto_detect_asset_url' => 'true',
|
||||||
'plugins_enabled' => '',
|
'plugins_enabled' => '',
|
||||||
'copyright_prefer' => '0',
|
'copyright_prefer' => '0',
|
||||||
'score_per_closet_item' => '0',
|
'score_per_closet_item' => '0',
|
||||||
'favicon_url' => 'app/favicon.ico',
|
'favicon_url' => 'app/favicon.ico',
|
||||||
'score_award_per_texture' => '0',
|
'score_award_per_texture' => '0',
|
||||||
'take_back_scores_after_deletion' => 'true',
|
'take_back_scores_after_deletion' => 'true',
|
||||||
'score_award_per_like' => '0',
|
'score_award_per_like' => '0',
|
||||||
'meta_keywords' => '',
|
'meta_keywords' => '',
|
||||||
'meta_description' => '',
|
'meta_description' => '',
|
||||||
'meta_extras' => '',
|
'meta_extras' => '',
|
||||||
'cdn_address' => '',
|
'cdn_address' => '',
|
||||||
'recaptcha_sitekey' => '',
|
'recaptcha_sitekey' => '',
|
||||||
'recaptcha_secretkey' => '',
|
'recaptcha_secretkey' => '',
|
||||||
'recaptcha_invisible' => 'false',
|
'recaptcha_invisible' => 'false',
|
||||||
'reporter_score_modification' => '0',
|
'reporter_score_modification' => '0',
|
||||||
'reporter_reward_score' => '0',
|
'reporter_reward_score' => '0',
|
||||||
'content_policy' => '',
|
'content_policy' => '',
|
||||||
'transparent_navbar' => 'false',
|
'transparent_navbar' => 'false',
|
||||||
'status_code_for_private' => '403',
|
'status_code_for_private' => '403',
|
||||||
'navbar_color' => 'cyan',
|
'navbar_color' => 'cyan',
|
||||||
'sidebar_color' => 'dark-maroon',
|
'sidebar_color' => 'dark-maroon',
|
||||||
];
|
];
|
||||||
|
|
|
||||||
62
config/passport.php
Normal file
62
config/passport.php
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Passport Guard
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify which authentication guard Passport will use when
|
||||||
|
| authenticating users. This value should correspond with one of your
|
||||||
|
| guards that is already present in your "auth" configuration file.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'guard' => 'web',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Encryption Keys
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Passport uses encryption keys while generating secure access tokens for
|
||||||
|
| your application. By default, the keys are stored as local files but
|
||||||
|
| can be set via environment variables when that is more convenient.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'private_key' => env('PASSPORT_PRIVATE_KEY'),
|
||||||
|
|
||||||
|
'public_key' => env('PASSPORT_PUBLIC_KEY'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Client UUIDs
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| By default, Passport uses auto-incrementing primary keys when assigning
|
||||||
|
| IDs to clients. However, if Passport is installed using the provided
|
||||||
|
| --uuids switch, this will be set to "true" and UUIDs will be used.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'client_uuids' => false,
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Personal Access Client
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| If you enable client hashing, you should set the personal access client
|
||||||
|
| ID and unhashed secret within your environment file. The values will
|
||||||
|
| get used while issuing fresh personal access tokens to your users.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'personal_access_client' => [
|
||||||
|
'id' => env('PASSPORT_PERSONAL_ACCESS_CLIENT_ID'),
|
||||||
|
'secret' => env('PASSPORT_PERSONAL_ACCESS_CLIENT_SECRET'),
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
||||||
|
|
@ -33,7 +33,7 @@ return [
|
||||||
*/
|
*/
|
||||||
'registry' => env(
|
'registry' => env(
|
||||||
'PLUGINS_REGISTRY',
|
'PLUGINS_REGISTRY',
|
||||||
'https://gplane.coding.net/p/blessing-skin-plugins-dist/d/blessing-skin-plugins-dist/git/raw/master/registry_{lang}.json'
|
'https://bs-plugins.littleservice.cn/registry_{lang}.json'
|
||||||
),
|
),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Default Queue Connection Name
|
| Default Queue Connection Name
|
||||||
|
|
@ -29,7 +28,6 @@ return [
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'connections' => [
|
'connections' => [
|
||||||
|
|
||||||
'sync' => [
|
'sync' => [
|
||||||
'driver' => 'sync',
|
'driver' => 'sync',
|
||||||
],
|
],
|
||||||
|
|
@ -39,6 +37,7 @@ return [
|
||||||
'table' => 'jobs',
|
'table' => 'jobs',
|
||||||
'queue' => 'default',
|
'queue' => 'default',
|
||||||
'retry_after' => 90,
|
'retry_after' => 90,
|
||||||
|
'after_commit' => false,
|
||||||
],
|
],
|
||||||
|
|
||||||
'beanstalkd' => [
|
'beanstalkd' => [
|
||||||
|
|
@ -47,6 +46,7 @@ return [
|
||||||
'queue' => 'default',
|
'queue' => 'default',
|
||||||
'retry_after' => 90,
|
'retry_after' => 90,
|
||||||
'block_for' => 0,
|
'block_for' => 0,
|
||||||
|
'after_commit' => false,
|
||||||
],
|
],
|
||||||
|
|
||||||
'sqs' => [
|
'sqs' => [
|
||||||
|
|
@ -54,9 +54,10 @@ return [
|
||||||
'key' => env('AWS_ACCESS_KEY_ID'),
|
'key' => env('AWS_ACCESS_KEY_ID'),
|
||||||
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
||||||
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
|
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
|
||||||
'queue' => env('SQS_QUEUE', 'your-queue-name'),
|
'queue' => env('SQS_QUEUE', 'default'),
|
||||||
'suffix' => env('SQS_SUFFIX'),
|
'suffix' => env('SQS_SUFFIX'),
|
||||||
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
|
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
|
||||||
|
'after_commit' => false,
|
||||||
],
|
],
|
||||||
|
|
||||||
'redis' => [
|
'redis' => [
|
||||||
|
|
@ -65,8 +66,24 @@ return [
|
||||||
'queue' => env('REDIS_QUEUE', 'default'),
|
'queue' => env('REDIS_QUEUE', 'default'),
|
||||||
'retry_after' => 90,
|
'retry_after' => 90,
|
||||||
'block_for' => null,
|
'block_for' => null,
|
||||||
|
'after_commit' => false,
|
||||||
],
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Job Batching
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The following options configure the database and table that store job
|
||||||
|
| batching information. These options can be updated to any database
|
||||||
|
| connection and table which has been defined by your application.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'batching' => [
|
||||||
|
'database' => env('DB_CONNECTION', 'mysql'),
|
||||||
|
'table' => 'job_batches',
|
||||||
],
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -81,9 +98,8 @@ return [
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'failed' => [
|
'failed' => [
|
||||||
'driver' => env('QUEUE_FAILED_DRIVER', 'database'),
|
'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'),
|
||||||
'database' => env('DB_CONNECTION', 'mysql'),
|
'database' => env('DB_CONNECTION', 'mysql'),
|
||||||
'table' => 'failed_jobs',
|
'table' => 'failed_jobs',
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -10,5 +10,5 @@ return [
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
'cipher' => env('PWD_METHOD', 'BCRYPT'),
|
'cipher' => env('PWD_METHOD', 'BCRYPT'),
|
||||||
'salt' => env('SALT', ''),
|
'salt' => env('SALT', ''),
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Third Party Services
|
| Third Party Services
|
||||||
|
|
@ -18,6 +17,7 @@ return [
|
||||||
'domain' => env('MAILGUN_DOMAIN'),
|
'domain' => env('MAILGUN_DOMAIN'),
|
||||||
'secret' => env('MAILGUN_SECRET'),
|
'secret' => env('MAILGUN_SECRET'),
|
||||||
'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
|
'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'),
|
||||||
|
'scheme' => 'https',
|
||||||
],
|
],
|
||||||
|
|
||||||
'postmark' => [
|
'postmark' => [
|
||||||
|
|
@ -29,5 +29,4 @@ return [
|
||||||
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
||||||
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
|
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
|
||||||
],
|
],
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Default Session Driver
|
| Default Session Driver
|
||||||
|
|
@ -70,7 +69,7 @@ return [
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'connection' => env('SESSION_CONNECTION', null),
|
'connection' => env('SESSION_CONNECTION'),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
@ -90,13 +89,15 @@ return [
|
||||||
| Session Cache Store
|
| Session Cache Store
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
|
||||||
| When using the "apc", "memcached", or "dynamodb" session drivers you may
|
| While using one of the framework's cache driven session backends you may
|
||||||
| list a cache store that should be used for these sessions. This value
|
| list a cache store that should be used for these sessions. This value
|
||||||
| must match with one of the application's configured cache "stores".
|
| must match with one of the application's configured cache "stores".
|
||||||
|
|
|
|
||||||
|
| Affects: "apc", "dynamodb", "memcached", "redis"
|
||||||
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'store' => env('SESSION_STORE', null),
|
'store' => env('SESSION_STORE'),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
@ -148,7 +149,7 @@ return [
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'domain' => env('SESSION_DOMAIN', null),
|
'domain' => env('SESSION_DOMAIN'),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
@ -157,7 +158,7 @@ return [
|
||||||
|
|
|
|
||||||
| By setting this option to true, session cookies will only be sent back
|
| By setting this option to true, session cookies will only be sent back
|
||||||
| to the server if the browser has a HTTPS connection. This will keep
|
| to the server if the browser has a HTTPS connection. This will keep
|
||||||
| the cookie from being sent to you if it can not be done securely.
|
| the cookie from being sent to you when it can't be done securely.
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -183,12 +184,11 @@ return [
|
||||||
|
|
|
|
||||||
| This option determines how your cookies behave when cross-site requests
|
| This option determines how your cookies behave when cross-site requests
|
||||||
| take place, and can be used to mitigate CSRF attacks. By default, we
|
| take place, and can be used to mitigate CSRF attacks. By default, we
|
||||||
| do not enable this as other CSRF protection services are in place.
|
| will set this value to "lax" since this is a secure default value.
|
||||||
|
|
|
|
||||||
| Supported: "lax", "strict", "none"
|
| Supported: "lax", "strict", "none", null
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'same_site' => 'lax',
|
'same_site' => 'lax',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Language lines will be fetched by these loaders. You can put any class here that implements
|
* Language lines will be fetched by these loaders. You can put any class here that implements
|
||||||
* the Spatie\TranslationLoader\TranslationLoaders\TranslationLoader-interface.
|
* the Spatie\TranslationLoader\TranslationLoaders\TranslationLoader-interface.
|
||||||
|
|
@ -20,5 +19,4 @@ return [
|
||||||
* This is the translation manager which overrides the default Laravel `translation.loader`
|
* This is the translation manager which overrides the default Laravel `translation.loader`
|
||||||
*/
|
*/
|
||||||
'translation_manager' => App\Services\Translations\Loader::class,
|
'translation_manager' => App\Services\Translations\Loader::class,
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,10 @@
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Configuration options for Twig.
|
* Configuration options for Twig.
|
||||||
*/
|
*/
|
||||||
return [
|
return [
|
||||||
|
|
||||||
'twig' => [
|
'twig' => [
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
@ -34,7 +33,6 @@ return [
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
'environment' => [
|
'environment' => [
|
||||||
|
|
||||||
// When set to true, the generated templates have a __toString() method
|
// When set to true, the generated templates have a __toString() method
|
||||||
// that you can use to display the generated nodes.
|
// that you can use to display the generated nodes.
|
||||||
// default: false
|
// default: false
|
||||||
|
|
@ -44,10 +42,6 @@ return [
|
||||||
// default: utf-8
|
// default: utf-8
|
||||||
'charset' => 'utf-8',
|
'charset' => 'utf-8',
|
||||||
|
|
||||||
// The base template class to use for generated templates.
|
|
||||||
// default: TwigBridge\Twig\Template
|
|
||||||
'base_template_class' => 'TwigBridge\Twig\Template',
|
|
||||||
|
|
||||||
// An absolute path where to store the compiled templates, or false to disable caching. If null
|
// An absolute path where to store the compiled templates, or false to disable caching. If null
|
||||||
// then the cache file path is used.
|
// then the cache file path is used.
|
||||||
// default: cache file storage path
|
// default: cache file storage path
|
||||||
|
|
@ -73,6 +67,19 @@ return [
|
||||||
'optimizations' => -1,
|
'optimizations' => -1,
|
||||||
],
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Safe Classes
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| When set, the output of the `__string` method of the following classes will not be escaped.
|
||||||
|
| default: Laravel's Htmlable, which the HtmlString class implements.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
'safe_classes' => [
|
||||||
|
\Illuminate\Contracts\Support\Htmlable::class => ['html'],
|
||||||
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Global variables
|
| Global variables
|
||||||
|
|
@ -86,7 +93,6 @@ return [
|
||||||
],
|
],
|
||||||
|
|
||||||
'extensions' => [
|
'extensions' => [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Extensions
|
| Extensions
|
||||||
|
|
@ -98,21 +104,21 @@ return [
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
'enabled' => [
|
'enabled' => [
|
||||||
'Twig\Extension\StringLoaderExtension',
|
'TwigBridge\Extension\Laravel\Event',
|
||||||
|
|
||||||
'TwigBridge\Extension\Loader\Facades',
|
'TwigBridge\Extension\Loader\Facades',
|
||||||
'TwigBridge\Extension\Loader\Filters',
|
'TwigBridge\Extension\Loader\Filters',
|
||||||
'TwigBridge\Extension\Loader\Functions',
|
'TwigBridge\Extension\Loader\Functions',
|
||||||
|
'TwigBridge\Extension\Loader\Globals',
|
||||||
|
|
||||||
'TwigBridge\Extension\Laravel\Auth',
|
'TwigBridge\Extension\Laravel\Auth',
|
||||||
'TwigBridge\Extension\Laravel\Config',
|
'TwigBridge\Extension\Laravel\Config',
|
||||||
'TwigBridge\Extension\Laravel\Dump',
|
'TwigBridge\Extension\Laravel\Dump',
|
||||||
// 'TwigBridge\Extension\Laravel\Input',
|
'TwigBridge\Extension\Laravel\Input',
|
||||||
'TwigBridge\Extension\Laravel\Session',
|
'TwigBridge\Extension\Laravel\Session',
|
||||||
// 'TwigBridge\Extension\Laravel\Str',
|
'TwigBridge\Extension\Laravel\Str',
|
||||||
'TwigBridge\Extension\Laravel\Translator',
|
'TwigBridge\Extension\Laravel\Translator',
|
||||||
'TwigBridge\Extension\Laravel\Url',
|
'TwigBridge\Extension\Laravel\Url',
|
||||||
// 'TwigBridge\Extension\Laravel\Model',
|
'TwigBridge\Extension\Laravel\Model',
|
||||||
// 'TwigBridge\Extension\Laravel\Gate',
|
// 'TwigBridge\Extension\Laravel\Gate',
|
||||||
|
|
||||||
// 'TwigBridge\Extension\Laravel\Form',
|
// 'TwigBridge\Extension\Laravel\Form',
|
||||||
|
|
@ -177,7 +183,12 @@ return [
|
||||||
| </code>
|
| </code>
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
'functions' => [],
|
'functions' => [
|
||||||
|
'elixir',
|
||||||
|
'head',
|
||||||
|
'last',
|
||||||
|
'mix',
|
||||||
|
],
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| View Storage Paths
|
| View Storage Paths
|
||||||
|
|
@ -33,5 +32,4 @@ return [
|
||||||
'VIEW_COMPILED_PATH',
|
'VIEW_COMPILED_PATH',
|
||||||
realpath(storage_path('framework/views'))
|
realpath(storage_path('framework/views'))
|
||||||
),
|
),
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
class CreateAllTables extends Migration
|
class CreateAllTables extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Services\Facades\Option;
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class ImportOptions extends Migration
|
class ImportOptions extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use Illuminate\Database\Migrations\Migration;
|
use Illuminate\Database\Migrations\Migration;
|
||||||
use Illuminate\Database\Schema\Blueprint;
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
class AddVerificationToUsersTable extends Migration
|
class AddVerificationToUsersTable extends Migration
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use App\Services\Facades\Option;
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
|
||||||
|
return new class extends Migration {
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Option::set('max_texture_width', 8192);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
14
package.json
14
package.json
|
|
@ -23,12 +23,13 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/react": "^11.0.0",
|
"@emotion/react": "^11.0.0",
|
||||||
"@emotion/styled": "^11.0.0",
|
"@emotion/styled": "^11.0.0",
|
||||||
|
"@fortawesome/fontawesome-free": "^6.3.0",
|
||||||
"@hot-loader/react-dom": "^17.0.0",
|
"@hot-loader/react-dom": "^17.0.0",
|
||||||
"@tweenjs/tween.js": "^18.5.0",
|
"@tweenjs/tween.js": "^18.5.0",
|
||||||
"admin-lte": "^3.2.0",
|
"admin-lte": "^3.2.0",
|
||||||
"blessing-skin-shell": "^0.3.4",
|
"blessing-skin-shell": "^0.3.4",
|
||||||
"bootstrap": "^4.6.1",
|
"bootstrap": "^4.6.1",
|
||||||
"cac": "^6.6.1",
|
"cac": "6.6.1",
|
||||||
"cli-spinners": "^2.5.0",
|
"cli-spinners": "^2.5.0",
|
||||||
"clsx": "^1.1.1",
|
"clsx": "^1.1.1",
|
||||||
"echarts": "^5.1.2",
|
"echarts": "^5.1.2",
|
||||||
|
|
@ -44,15 +45,13 @@
|
||||||
"react-draggable": "^4.4.2",
|
"react-draggable": "^4.4.2",
|
||||||
"react-hot-loader": "^4.12.21",
|
"react-hot-loader": "^4.12.21",
|
||||||
"react-loading-skeleton": "^2.1.1",
|
"react-loading-skeleton": "^2.1.1",
|
||||||
|
"react-use": "^17.4.0",
|
||||||
"reaptcha": "^1.7.2",
|
"reaptcha": "^1.7.2",
|
||||||
"rxjs": "^6.5.5",
|
"rxjs": "^6.5.5",
|
||||||
"skinview-utils": "^0.5.5",
|
"skinview-utils": "^0.5.5",
|
||||||
"skinview3d": "^2.2.1",
|
"skinview3d": "^3.0.0-alpha.1",
|
||||||
"spectre.css": "^0.5.8",
|
"spectre.css": "^0.5.8",
|
||||||
"use-immer": "^0.4.2",
|
"use-immer": "^0.4.2",
|
||||||
"workbox-expiration": "^5.1.3",
|
|
||||||
"workbox-routing": "^5.1.3",
|
|
||||||
"workbox-strategies": "^5.1.3",
|
|
||||||
"xterm": "^4.6.0",
|
"xterm": "^4.6.0",
|
||||||
"xterm-addon-fit": "^0.4.0"
|
"xterm-addon-fit": "^0.4.0"
|
||||||
},
|
},
|
||||||
|
|
@ -152,12 +151,13 @@
|
||||||
"/node_modules/",
|
"/node_modules/",
|
||||||
"<rootDir>/resources/assets/tests/(views|components)/.*\\.ts$"
|
"<rootDir>/resources/assets/tests/(views|components)/.*\\.ts$"
|
||||||
],
|
],
|
||||||
"maxWorkers": 1,
|
"maxWorkers": "50%",
|
||||||
"globals": {
|
"globals": {
|
||||||
"ts-jest": {
|
"ts-jest": {
|
||||||
"tsconfig": "<rootDir>/resources/assets/tests/tsconfig.json",
|
"tsconfig": "<rootDir>/resources/assets/tests/tsconfig.json",
|
||||||
"isolatedModules": true
|
"isolatedModules": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
25
phpunit.xml
25
phpunit.xml
|
|
@ -1,22 +1,23 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" colors="true" backupStaticAttributes="false" convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" bootstrap="vendor/autoload.php" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
<coverage processUncoveredFiles="true">
|
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
|
||||||
|
bootstrap="vendor/autoload.php"
|
||||||
|
colors="true"
|
||||||
|
>
|
||||||
|
<testsuites>
|
||||||
|
<testsuite name="Application Test Suite">
|
||||||
|
<directory suffix="Test.php">./tests</directory>
|
||||||
|
</testsuite>
|
||||||
|
</testsuites>
|
||||||
|
<source>
|
||||||
<include>
|
<include>
|
||||||
<directory suffix=".php">./app</directory>
|
<directory suffix=".php">./app</directory>
|
||||||
</include>
|
</include>
|
||||||
<exclude>
|
<exclude>
|
||||||
<directory suffix=".php">./app/Services/Cipher</directory>
|
<directory suffix=".php">./app/Services/Cipher</directory>
|
||||||
</exclude>
|
</exclude>
|
||||||
</coverage>
|
</source>
|
||||||
<testsuites>
|
|
||||||
<testsuite name="Application Test Suite">
|
|
||||||
<directory suffix="Test.php">./tests</directory>
|
|
||||||
</testsuite>
|
|
||||||
</testsuites>
|
|
||||||
<php>
|
<php>
|
||||||
<env name="APP_ENV" value="testing"/>
|
<env name="APP_ENV" value="testing" />
|
||||||
</php>
|
</php>
|
||||||
<listeners>
|
|
||||||
<listener class="NunoMaduro\Collision\Adapters\Phpunit\Printer"/>
|
|
||||||
</listeners>
|
|
||||||
</phpunit>
|
</phpunit>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
/** @jsxImportSource @emotion/react */
|
/** @jsxImportSource @emotion/react */
|
||||||
import React, { useState, useEffect, useRef } from 'react'
|
import React, { useState, useEffect, useRef } from 'react'
|
||||||
|
import { useMeasure } from 'react-use'
|
||||||
import { css } from '@emotion/react'
|
import { css } from '@emotion/react'
|
||||||
import styled from '@emotion/styled'
|
import styled from '@emotion/styled'
|
||||||
import * as skinview3d from 'skinview3d'
|
import * as skinview3d from 'skinview3d'
|
||||||
|
|
@ -26,17 +27,12 @@ interface Props {
|
||||||
initPositionZ?: number
|
initPositionZ?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
type AnimationHandles = {
|
const animationFactories = [
|
||||||
walk: skinview3d.SubAnimationHandle | null
|
() => new skinview3d.WalkingAnimation(),
|
||||||
run: skinview3d.SubAnimationHandle | null
|
() => new skinview3d.RunningAnimation(),
|
||||||
rotate: skinview3d.SubAnimationHandle | null
|
() => new skinview3d.FlyingAnimation(),
|
||||||
}
|
() => new skinview3d.IdleAnimation(),
|
||||||
|
]
|
||||||
const animationHandles: AnimationHandles = {
|
|
||||||
walk: null,
|
|
||||||
run: null,
|
|
||||||
rotate: null,
|
|
||||||
}
|
|
||||||
|
|
||||||
const ActionButton = styled.i`
|
const ActionButton = styled.i`
|
||||||
display: inline;
|
display: inline;
|
||||||
|
|
@ -48,13 +44,17 @@ const ActionButton = styled.i`
|
||||||
`
|
`
|
||||||
|
|
||||||
const cssViewer = css`
|
const cssViewer = css`
|
||||||
|
flex: 1 1 auto;
|
||||||
${breakpoints.greaterThan(breakpoints.Breakpoint.lg)} {
|
${breakpoints.greaterThan(breakpoints.Breakpoint.lg)} {
|
||||||
min-height: 500px;
|
min-height: 500px;
|
||||||
}
|
}
|
||||||
|
min-height: 300px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
canvas {
|
canvas {
|
||||||
cursor: move;
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
@ -63,10 +63,9 @@ const Viewer: React.FC<Props> = (props) => {
|
||||||
|
|
||||||
const viewRef: React.MutableRefObject<skinview3d.SkinViewer> = useRef(null!)
|
const viewRef: React.MutableRefObject<skinview3d.SkinViewer> = useRef(null!)
|
||||||
const containerRef = useRef<HTMLCanvasElement>(null)
|
const containerRef = useRef<HTMLCanvasElement>(null)
|
||||||
const animationHandlesRef = useRef(animationHandles)
|
|
||||||
|
|
||||||
const [paused, setPaused] = useState(false)
|
const [paused, setPaused] = useState(false)
|
||||||
const [running, setRunning] = useState(false)
|
const [animation, setAnimation] = useState(0)
|
||||||
const [bgPicture, setBgPicture] = useState(-1)
|
const [bgPicture, setBgPicture] = useState(-1)
|
||||||
|
|
||||||
const indicator = (() => {
|
const indicator = (() => {
|
||||||
|
|
@ -83,36 +82,39 @@ const Viewer: React.FC<Props> = (props) => {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const container = containerRef.current!
|
const container = containerRef.current!
|
||||||
const viewer = new skinview3d.FXAASkinViewer({
|
const viewer = new skinview3d.SkinViewer({
|
||||||
canvas: container,
|
canvas: container,
|
||||||
width: container.clientWidth,
|
width: container.clientWidth,
|
||||||
height: container.clientHeight,
|
height: container.clientHeight,
|
||||||
skin: props.skin || SkinSteve,
|
skin: props.skin || SkinSteve,
|
||||||
cape: props.cape || '',
|
cape: props.cape || undefined,
|
||||||
model: props.isAlex ? 'slim' : 'default',
|
model: props.isAlex ? 'slim' : 'default',
|
||||||
zoom: initPositionZ / 100,
|
zoom: initPositionZ / 100,
|
||||||
})
|
})
|
||||||
|
viewer.autoRotate = true
|
||||||
|
|
||||||
if (document.body.classList.contains('dark-mode')) {
|
if (document.body.classList.contains('dark-mode')) {
|
||||||
viewer.background = '#6c757d'
|
viewer.background = '#6c757d'
|
||||||
}
|
}
|
||||||
|
|
||||||
const rotate = viewer.animations.add(skinview3d.RotatingAnimation)
|
|
||||||
animationHandlesRef.current.rotate = rotate
|
|
||||||
|
|
||||||
const control = skinview3d.createOrbitControls(viewer)
|
|
||||||
|
|
||||||
viewRef.current = viewer
|
viewRef.current = viewer
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
control.dispose()
|
|
||||||
viewer.dispose()
|
viewer.dispose()
|
||||||
}
|
}
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
const [containerWrapperRef, containerMeasure] = useMeasure<HTMLDivElement>()
|
||||||
|
useEffect(() => {
|
||||||
|
viewRef.current.setSize(containerMeasure.width, containerMeasure.height)
|
||||||
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const viewer = viewRef.current
|
const viewer = viewRef.current
|
||||||
viewer.loadSkin(props.skin || SkinSteve, props.isAlex ? 'slim' : 'default')
|
viewer.loadSkin(props.skin || SkinSteve, {
|
||||||
|
model: props.isAlex ? 'slim' : 'default',
|
||||||
|
})
|
||||||
}, [props.skin, props.isAlex])
|
}, [props.skin, props.isAlex])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -125,52 +127,63 @@ const Viewer: React.FC<Props> = (props) => {
|
||||||
}, [props.cape])
|
}, [props.cape])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handles = animationHandlesRef.current
|
const viewer = viewRef.current
|
||||||
if (running) {
|
const factory = animationFactories[animation]
|
||||||
handles.walk?.resetAndRemove()
|
if (factory === undefined) {
|
||||||
handles.walk = null
|
viewer.animation = null
|
||||||
|
|
||||||
const run = viewRef.current.animations.add(skinview3d.RunningAnimation)
|
|
||||||
run.speed = 0.6
|
|
||||||
handles.run = run
|
|
||||||
} else {
|
} else {
|
||||||
handles.run?.resetAndRemove()
|
const newAnimation = factory()
|
||||||
handles.run = null
|
newAnimation.paused = paused // Perseve `paused` state
|
||||||
|
viewer.animation = newAnimation
|
||||||
const walk = viewRef.current.animations.add(skinview3d.WalkingAnimation)
|
|
||||||
handles.walk = walk
|
|
||||||
}
|
}
|
||||||
}, [running])
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [animation])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
viewRef.current.animations.paused = paused
|
const currentAnimation = viewRef.current.animation
|
||||||
|
if (currentAnimation !== null) {
|
||||||
|
currentAnimation.paused = paused
|
||||||
|
}
|
||||||
}, [paused])
|
}, [paused])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
viewRef.current.loadBackground(backgrounds[bgPicture]!)
|
const viewer = viewRef.current
|
||||||
|
const backgroundUrl = backgrounds[bgPicture]
|
||||||
|
if (backgroundUrl === undefined) {
|
||||||
|
viewer.background = null
|
||||||
|
} else {
|
||||||
|
viewer.loadBackground(backgroundUrl)
|
||||||
|
}
|
||||||
}, [bgPicture])
|
}, [bgPicture])
|
||||||
|
|
||||||
const togglePause = () => {
|
const togglePause = () => {
|
||||||
setPaused((paused) => !paused)
|
setPaused((paused) => {
|
||||||
|
if (paused) {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
viewRef.current.autoRotate = false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const toggleRun = () => {
|
const toggleAnimation = () => {
|
||||||
setRunning((running) => !running)
|
setAnimation((index) => (index + 1) % animationFactories.length)
|
||||||
|
setPaused(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
const toggleRotate = () => {
|
const toggleRotate = () => {
|
||||||
const handles = animationHandlesRef.current
|
const viewer = viewRef.current
|
||||||
if (handles.rotate) {
|
viewer.autoRotate = !viewer.autoRotate
|
||||||
handles.rotate.paused = !handles.rotate.paused
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleReset = () => {
|
const toggleBackEquippment = () => {
|
||||||
const handles = animationHandlesRef.current
|
const player = viewRef.current.playerObject
|
||||||
handles.walk?.resetAndRemove()
|
if (player.backEquipment === 'cape') {
|
||||||
handles.run?.resetAndRemove()
|
player.backEquipment = 'elytra'
|
||||||
handles.rotate?.resetAndRemove()
|
} else {
|
||||||
viewRef.current.animations.paused = true
|
player.backEquipment = 'cape'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const setWhite = () => {
|
const setWhite = () => {
|
||||||
|
|
@ -213,38 +226,42 @@ const Viewer: React.FC<Props> = (props) => {
|
||||||
</h3>
|
</h3>
|
||||||
<div>
|
<div>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
className={`fas fa-${running ? 'walking' : 'running'}`}
|
className={`fas fa-tablet ${props.cape ? '' : 'd-none'}`}
|
||||||
data-toggle="tooltip"
|
data-toggle="tooltip"
|
||||||
data-placement="bottom"
|
data-placement="bottom"
|
||||||
title={`${t('general.walk')} / ${t('general.run')}`}
|
title={t('general.switchCapeElytra')}
|
||||||
onClick={toggleRun}
|
onClick={toggleBackEquippment}
|
||||||
></ActionButton>
|
></ActionButton>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
className="fas fa-redo-alt"
|
className={`fas fa-person-running`}
|
||||||
data-toggle="tooltip"
|
data-toggle="tooltip"
|
||||||
data-placement="bottom"
|
data-placement="bottom"
|
||||||
title={t('general.rotation')}
|
title={t('general.switchAnimation')}
|
||||||
onClick={toggleRotate}
|
onClick={toggleAnimation}
|
||||||
></ActionButton>
|
></ActionButton>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
className={`fas fa-${paused ? 'play' : 'pause'}`}
|
className={`fas fa-${paused ? 'play' : 'pause'}`}
|
||||||
data-toggle="tooltip"
|
data-toggle="tooltip"
|
||||||
data-placement="bottom"
|
data-placement="bottom"
|
||||||
title={t('general.pause')}
|
title={
|
||||||
|
paused
|
||||||
|
? t('general.playAnimation')
|
||||||
|
: t('general.pauseAnimation')
|
||||||
|
}
|
||||||
onClick={togglePause}
|
onClick={togglePause}
|
||||||
></ActionButton>
|
></ActionButton>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
className="fas fa-stop"
|
className="fas fa-rotate-right"
|
||||||
data-toggle="tooltip"
|
data-toggle="tooltip"
|
||||||
data-placement="bottom"
|
data-placement="bottom"
|
||||||
title={t('general.reset')}
|
title={t('general.rotation')}
|
||||||
onClick={handleReset}
|
onClick={toggleRotate}
|
||||||
></ActionButton>
|
></ActionButton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="card-body p-0">
|
<div ref={containerWrapperRef} css={cssViewer} className="p-0">
|
||||||
<canvas ref={containerRef} css={cssViewer}></canvas>
|
<canvas ref={containerRef}></canvas>
|
||||||
</div>
|
</div>
|
||||||
<div className="card-footer">
|
<div className="card-footer">
|
||||||
<div className="mt-2 mb-3 d-flex">
|
<div className="mt-2 mb-3 d-flex">
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,11 @@ import routes from './scripts/route'
|
||||||
|
|
||||||
Object.assign(window, { React, ReactDOM, $ })
|
Object.assign(window, { React, ReactDOM, $ })
|
||||||
|
|
||||||
if (blessing.route.startsWith('admin')) {
|
const entry = document.querySelector('[href="#launch-cli"]')
|
||||||
const entry = document.querySelector<HTMLAnchorElement>('#launch-cli')
|
entry?.addEventListener('click', async () => {
|
||||||
entry?.addEventListener('click', async () => {
|
const { launch } = await import('./scripts/cli')
|
||||||
const { launch } = await import('./scripts/cli')
|
launch()
|
||||||
launch()
|
})
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const route = routes.find((route) =>
|
const route = routes.find((route) =>
|
||||||
new RegExp(`^${route.path}$`, 'i').test(blessing.route),
|
new RegExp(`^${route.path}$`, 'i').test(blessing.route),
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
const blessingElement = document.querySelector('#blessing-globals')!
|
|
||||||
// @ts-ignore
|
|
||||||
window.blessing = JSON.parse(blessingElement.textContent!)
|
|
||||||
|
|
||||||
window.addEventListener('load', () => {
|
|
||||||
navigator.serviceWorker.register('/sw.js?v6')
|
|
||||||
})
|
|
||||||
|
|
||||||
export {}
|
|
||||||
|
|
@ -1,123 +0,0 @@
|
||||||
import { registerRoute } from 'workbox-routing'
|
|
||||||
import {
|
|
||||||
CacheFirst,
|
|
||||||
StaleWhileRevalidate,
|
|
||||||
NetworkOnly,
|
|
||||||
} from 'workbox-strategies'
|
|
||||||
import { ExpirationPlugin } from 'workbox-expiration'
|
|
||||||
|
|
||||||
const oneWeek = 7 * 24 * 3600
|
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'development') {
|
|
||||||
registerRoute(/\.js/, new NetworkOnly())
|
|
||||||
registerRoute(/\.css/, new NetworkOnly())
|
|
||||||
}
|
|
||||||
|
|
||||||
//#region Pictures
|
|
||||||
registerRoute(
|
|
||||||
/\/preview\/\d+/,
|
|
||||||
new CacheFirst({
|
|
||||||
cacheName: 'texture-preview-v2',
|
|
||||||
fetchOptions: {
|
|
||||||
credentials: 'omit',
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
new ExpirationPlugin({ maxAgeSeconds: oneWeek, purgeOnQuotaError: true }),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
registerRoute(
|
|
||||||
/\/app\/.*\.webp/,
|
|
||||||
new StaleWhileRevalidate({
|
|
||||||
cacheName: 'webp-resource-v1',
|
|
||||||
fetchOptions: {
|
|
||||||
credentials: 'omit',
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
registerRoute(
|
|
||||||
/\/avatar\/\d+/,
|
|
||||||
new CacheFirst({
|
|
||||||
cacheName: 'avatar-v2',
|
|
||||||
fetchOptions: {
|
|
||||||
credentials: 'omit',
|
|
||||||
},
|
|
||||||
plugins: [new ExpirationPlugin({ maxAgeSeconds: oneWeek })],
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region JavaScript files
|
|
||||||
registerRoute(
|
|
||||||
/.+\/app\/\w{2,3}\.\w{7}\.js$/,
|
|
||||||
new CacheFirst({
|
|
||||||
cacheName: 'javascript-v1',
|
|
||||||
fetchOptions: {
|
|
||||||
credentials: 'omit',
|
|
||||||
mode: 'cors',
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
new ExpirationPlugin({ maxAgeSeconds: oneWeek, purgeOnQuotaError: true }),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
registerRoute(
|
|
||||||
/.+\/plugins\/.+\.js$/,
|
|
||||||
new StaleWhileRevalidate({
|
|
||||||
cacheName: 'javascript-v1',
|
|
||||||
fetchOptions: {
|
|
||||||
credentials: 'omit',
|
|
||||||
mode: 'cors',
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
new ExpirationPlugin({ maxAgeSeconds: oneWeek, purgeOnQuotaError: true }),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region CSS files
|
|
||||||
registerRoute(
|
|
||||||
/.+\/app\/.*\.css$/,
|
|
||||||
new CacheFirst({
|
|
||||||
cacheName: 'stylesheet-v1',
|
|
||||||
fetchOptions: {
|
|
||||||
credentials: 'omit',
|
|
||||||
mode: 'cors',
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
new ExpirationPlugin({ maxAgeSeconds: oneWeek, purgeOnQuotaError: true }),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
registerRoute(
|
|
||||||
/.+\/plugins\/.+\.css$/,
|
|
||||||
new StaleWhileRevalidate({
|
|
||||||
cacheName: 'stylesheet-v1',
|
|
||||||
fetchOptions: {
|
|
||||||
credentials: 'omit',
|
|
||||||
mode: 'cors',
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
new ExpirationPlugin({ maxAgeSeconds: oneWeek, purgeOnQuotaError: true }),
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region Fonts
|
|
||||||
registerRoute(
|
|
||||||
({ request }) => request.destination === 'font',
|
|
||||||
new StaleWhileRevalidate({
|
|
||||||
cacheName: 'font-v1',
|
|
||||||
fetchOptions: {
|
|
||||||
credentials: 'omit',
|
|
||||||
mode: 'cors',
|
|
||||||
},
|
|
||||||
plugins: [new ExpirationPlugin({ maxEntries: 12 })],
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
//#endregion
|
|
||||||
|
|
@ -75,7 +75,7 @@ body {
|
||||||
|
|
||||||
.main-button {
|
.main-button {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
padding: 0.8em 2.5em;
|
padding: 0.8em 2em;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
background: transparent;
|
background: transparent;
|
||||||
border: 1px solid #fff;
|
border: 1px solid #fff;
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,9 @@ function createLineChart(
|
||||||
chart.setOption({
|
chart.setOption({
|
||||||
title: {
|
title: {
|
||||||
text: data.label,
|
text: data.label,
|
||||||
|
textStyle: {
|
||||||
|
color: textColor,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
textStyle: {
|
textStyle: {
|
||||||
color: textColor,
|
color: textColor,
|
||||||
|
|
|
||||||
|
|
@ -257,7 +257,9 @@ const Show: React.FC = () => {
|
||||||
})()
|
})()
|
||||||
|
|
||||||
const canEdit = currentUid === texture.uploader || isAdmin
|
const canEdit = currentUid === texture.uploader || isAdmin
|
||||||
const textureUrl = `${blessing.base_url}/textures/${texture.hash}`
|
const textureUrl = texture.hash
|
||||||
|
? `${blessing.base_url}/textures/${texture.hash}`
|
||||||
|
: ''
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ const EmailVerification: React.FC = () => {
|
||||||
{t('user.verification.sending')}
|
{t('user.verification.sending')}
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<a href="#" onClick={send}>
|
<a className="link-info" href="#" onClick={send}>
|
||||||
{t('user.verification.resend')}
|
{t('user.verification.resend')}
|
||||||
</a>
|
</a>
|
||||||
)}
|
)}
|
||||||
|
|
|
||||||
|
|
@ -1,71 +1,55 @@
|
||||||
/* eslint-disable max-params */
|
/* eslint-disable max-params */
|
||||||
/* eslint-disable max-classes-per-file */
|
/* eslint-disable max-classes-per-file */
|
||||||
import type { PlayerObject, SkinObject, CapeObject } from 'skinview3d'
|
import type {
|
||||||
|
PlayerObject,
|
||||||
|
SkinObject,
|
||||||
|
CapeObject,
|
||||||
|
EarsObject,
|
||||||
|
} from 'skinview3d'
|
||||||
|
|
||||||
export class FXAASkinViewer {
|
export class SkinViewer {
|
||||||
disposed = false
|
disposed = false
|
||||||
background = ''
|
background = null
|
||||||
animations = new RootAnimation()
|
animation = null
|
||||||
animationPaused = false
|
autoRotate = false
|
||||||
|
autoRotateSpeed = 1.0
|
||||||
|
|
||||||
playerObject: PlayerObject
|
playerObject: PlayerObject
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.animationPaused = false
|
|
||||||
this.playerObject = {
|
this.playerObject = {
|
||||||
skin: {} as SkinObject,
|
skin: {} as SkinObject,
|
||||||
cape: {} as CapeObject,
|
cape: {} as CapeObject,
|
||||||
|
ears: {} as EarsObject,
|
||||||
|
backEquipment: 'cape',
|
||||||
} as PlayerObject
|
} as PlayerObject
|
||||||
}
|
}
|
||||||
|
|
||||||
loadSkin() {}
|
loadSkin() {}
|
||||||
|
resetSkin() {}
|
||||||
loadCape() {}
|
loadCape() {}
|
||||||
resetCape() {}
|
resetCape() {}
|
||||||
loadBackground() {}
|
loadBackground() {}
|
||||||
|
setSize() {}
|
||||||
|
|
||||||
dispose() {
|
dispose() {
|
||||||
this.disposed = true
|
this.disposed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RootAnimation {
|
export class PlayerAnimation {
|
||||||
|
speed = 1.0
|
||||||
paused = false
|
paused = false
|
||||||
|
progress = 0
|
||||||
add(animation: unknown) {
|
|
||||||
return animation
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createOrbitControls() {
|
export class IdleAnimation extends PlayerAnimation {}
|
||||||
return {
|
|
||||||
dispose() {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const WalkingAnimation = new Proxy(
|
export class WalkingAnimation extends PlayerAnimation {}
|
||||||
{},
|
|
||||||
{
|
export class RunningAnimation extends PlayerAnimation {}
|
||||||
get() {
|
|
||||||
return jest.fn()
|
export class FlyingAnimation extends PlayerAnimation {}
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
export const RunningAnimation = new Proxy(
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
get() {
|
|
||||||
return jest.fn()
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
export const RotatingAnimation = new Proxy(
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
get() {
|
|
||||||
return jest.fn()
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
export function isSlimSkin() {
|
export function isSlimSkin() {
|
||||||
return false
|
return false
|
||||||
|
|
|
||||||
|
|
@ -49,33 +49,27 @@ describe('indicator', () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('actions', () => {
|
describe('actions', () => {
|
||||||
it('toggle run', () => {
|
it('toggle animation', () => {
|
||||||
const { getByTitle } = render(<Viewer isAlex={false} />)
|
const component = <Viewer isAlex={false} />
|
||||||
fireEvent.click(getByTitle(`${t('general.walk')} / ${t('general.run')}`))
|
const { getByTitle } = render(component)
|
||||||
|
fireEvent.click(getByTitle(`${t('general.switchAnimation')}`)) // should start running
|
||||||
|
fireEvent.click(getByTitle(`${t('general.switchAnimation')}`)) // should start flying
|
||||||
|
fireEvent.click(getByTitle(`${t('general.switchAnimation')}`)) // should be idle
|
||||||
|
fireEvent.click(getByTitle(`${t('general.switchAnimation')}`)) // should start walking
|
||||||
})
|
})
|
||||||
|
|
||||||
it('toggle rotation', () => {
|
it('toggle rotation', () => {
|
||||||
const { getByTitle } = render(<Viewer isAlex={false} />)
|
const { getByTitle } = render(<Viewer isAlex={false} />)
|
||||||
fireEvent.click(getByTitle(t('general.rotation')))
|
fireEvent.click(getByTitle(t('general.rotation'))) // should stop rotation
|
||||||
|
fireEvent.click(getByTitle(t('general.rotation'))) // should start rotation
|
||||||
})
|
})
|
||||||
|
|
||||||
it('toggle pause', () => {
|
it('toggle pause', () => {
|
||||||
const { getByTitle } = render(<Viewer isAlex={false} />)
|
const { getByTitle } = render(<Viewer isAlex={false} />)
|
||||||
const icon = getByTitle(t('general.pause'))
|
const icon = getByTitle(t('general.pauseAnimation'))
|
||||||
fireEvent.click(icon)
|
fireEvent.click(icon)
|
||||||
expect(icon).toHaveClass('fa-play')
|
expect(icon).toHaveClass('fa-play')
|
||||||
})
|
})
|
||||||
|
|
||||||
it('reset', () => {
|
|
||||||
const { getByTitle } = render(<Viewer isAlex={false} />)
|
|
||||||
fireEvent.click(getByTitle(t('general.reset')))
|
|
||||||
})
|
|
||||||
|
|
||||||
it('reset when running', () => {
|
|
||||||
const { getByTitle } = render(<Viewer isAlex={false} />)
|
|
||||||
fireEvent.click(getByTitle(`${t('general.walk')} / ${t('general.run')}`))
|
|
||||||
fireEvent.click(getByTitle(t('general.reset')))
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('background', () => {
|
describe('background', () => {
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ score-intro:
|
||||||
rates:
|
rates:
|
||||||
storage: ':score scores = 1 KB storage'
|
storage: ':score scores = 1 KB storage'
|
||||||
player: ':score scores = 1 player'
|
player: ':score scores = 1 player'
|
||||||
closet: ':score socres = 1 closet item'
|
closet: ':score scores = 1 closet item'
|
||||||
closet:
|
closet:
|
||||||
add:
|
add:
|
||||||
success: Added :name to closet successfully.
|
success: Added :name to closet successfully.
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user