Compare commits
2 Commits
0.7.0
...
analysis-a
| Author | SHA1 | Date | |
|---|---|---|---|
| 773ec570d9 | |||
| 53c23f3698 |
0
.editorconfig
Executable file → Normal file
0
.editorconfig
Executable file → Normal file
12
.env.example
Executable file → Normal file
12
.env.example
Executable file → Normal file
@@ -7,15 +7,7 @@ APP_LOGO="https://www.raspberrypi.org/app/uploads/2020/05/Raspberry-Pi-OS-downlo
|
|||||||
APP_SITEHOMEPAGE=""
|
APP_SITEHOMEPAGE=""
|
||||||
# This can be your main homepage, other than this site itself
|
# This can be your main homepage, other than this site itself
|
||||||
|
|
||||||
# Forces ssl connections even if the environment is set to "local".
|
LOG_CHANNEL=stack
|
||||||
# Void if env is production.
|
|
||||||
NONPROD_FORCE_SECURE=false
|
|
||||||
|
|
||||||
# Disables certain features for security purposes while running an open authentication system
|
|
||||||
# Enable only for demonostration purposes
|
|
||||||
DEMO_MODE=false
|
|
||||||
|
|
||||||
LOG_CHANNEL=daily
|
|
||||||
|
|
||||||
DB_CONNECTION=mysql
|
DB_CONNECTION=mysql
|
||||||
DB_HOST=127.0.0.1
|
DB_HOST=127.0.0.1
|
||||||
@@ -37,7 +29,7 @@ IPGEO_API_URL="https://api.ipgeolocation.io/ipgeo"
|
|||||||
|
|
||||||
ARCANEDEV_LOGVIEWER_MIDDLEWARE=web,auth,can:admin.maintenance.logs.view
|
ARCANEDEV_LOGVIEWER_MIDDLEWARE=web,auth,can:admin.maintenance.logs.view
|
||||||
|
|
||||||
RELEASE=0.6.2
|
RELEASE=staffmanagement@0.6.1
|
||||||
|
|
||||||
SLACK_INTEGRATION_WEBHOOK=
|
SLACK_INTEGRATION_WEBHOOK=
|
||||||
|
|
||||||
|
|||||||
0
.gitattributes
vendored
Executable file → Normal file
0
.gitattributes
vendored
Executable file → Normal file
0
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Executable file → Normal file
0
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Executable file → Normal file
0
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Executable file → Normal file
0
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Executable file → Normal file
0
.gitignore
vendored
Executable file → Normal file
0
.gitignore
vendored
Executable file → Normal file
139
.idea/hrm-mcserver.iml
generated
Normal file
139
.idea/hrm-mcserver.iml
generated
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="WEB_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager">
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="Tests\" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/app" isTestSource="false" packagePrefix="App\" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/almasaeed2010/adminlte" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/asm89/stack-cors" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/barryvdh/laravel-debugbar" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/brick/math" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/clue/stream-filter" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/dnoegel/php-xdg-base-dir" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/cache" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/dbal" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/event-manager" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/inflector" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/instantiator" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/lexer" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/dragonmantank/cron-expression" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/egulias/email-validator" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/flare-client-php" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/ignition" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/ignition-contracts" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/fideloper/proxy" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/filp/whoops" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/fruitcake/laravel-cors" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/fzaninotto/faker" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/guzzle" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/promises" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/psr7" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/hamcrest/hamcrest-php" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/http-interop/http-factory-guzzle" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/jean85/pretty-package-versions" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/jeroennoten/laravel-adminlte" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/framework" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/tinker" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/ui" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/league/commonmark" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/league/flysystem" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/league/mime-type-detection" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/maximebf/debugbar" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/mcamara/laravel-localization" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/mockery/mockery" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/monolog/monolog" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/deep-copy" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/nesbot/carbon" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/nikic/php-parser" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/nunomaduro/collision" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/opis/closure" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/paragonie/random_compat" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/manifest" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/version" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/php-http/client-common" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/php-http/discovery" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/php-http/guzzle6-adapter" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/php-http/httplug" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/php-http/message" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/php-http/message-factory" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/php-http/promise" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-common" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-docblock" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/type-resolver" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpoption/phpoption" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpspec/prophecy" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-code-coverage" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-file-iterator" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-text-template" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-timer" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-token-stream" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/phpunit" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/container" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/event-dispatcher" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-client" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-factory" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-message" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/log" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/simple-cache" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/psy/psysh" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/ralouphie/getallheaders" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/ramsey/collection" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/ramsey/uuid" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/scrivo/highlight.php" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/comparator" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/diff" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/environment" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/exporter" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/global-state" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-enumerator" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-reflector" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/recursion-context" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/resource-operations" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/type" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/version" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sentry/sentry" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/sentry/sentry-laravel" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/spatie/laravel-permission" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/swiftmailer/swiftmailer" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/console" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/css-selector" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/debug" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/deprecation-contracts" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/error-handler" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher-contracts" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/finder" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-foundation" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-kernel" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/mime" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/options-resolver" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-ctype" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-iconv" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-grapheme" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-idn" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-normalizer" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-mbstring" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php72" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php73" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php80" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-uuid" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/process" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/routing" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/service-contracts" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/string" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation-contracts" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/var-dumper" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/theseer/tokenizer" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/tijsverkoyen/css-to-inline-styles" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/vlucas/phpdotenv" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/voku/portable-ascii" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/vendor/webmozart/assert" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
0
.idea/laravel-plugin.xml
generated
Executable file → Normal file
0
.idea/laravel-plugin.xml
generated
Executable file → Normal file
0
.idea/misc.xml
generated
Executable file → Normal file
0
.idea/misc.xml
generated
Executable file → Normal file
2
.idea/modules.xml
generated
Executable file → Normal file
2
.idea/modules.xml
generated
Executable file → Normal file
@@ -2,7 +2,7 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectModuleManager">
|
<component name="ProjectModuleManager">
|
||||||
<modules>
|
<modules>
|
||||||
<module fileurl="file://$PROJECT_DIR$/../rbrecruiter/.idea/rbrecruiter.iml" filepath="$PROJECT_DIR$/../rbrecruiter/.idea/rbrecruiter.iml" />
|
<module fileurl="file://$PROJECT_DIR$/.idea/hrm-mcserver.iml" filepath="$PROJECT_DIR$/.idea/hrm-mcserver.iml" />
|
||||||
</modules>
|
</modules>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
15
.idea/php.xml
generated
Executable file → Normal file
15
.idea/php.xml
generated
Executable file → Normal file
@@ -141,22 +141,9 @@
|
|||||||
<path value="$PROJECT_DIR$/vendor/graham-campbell/markdown" />
|
<path value="$PROJECT_DIR$/vendor/graham-campbell/markdown" />
|
||||||
<path value="$PROJECT_DIR$/vendor/league/mime-type-detection" />
|
<path value="$PROJECT_DIR$/vendor/league/mime-type-detection" />
|
||||||
<path value="$PROJECT_DIR$/vendor/mcamara/laravel-localization" />
|
<path value="$PROJECT_DIR$/vendor/mcamara/laravel-localization" />
|
||||||
<path value="$PROJECT_DIR$/vendor/mpociot/teamwork" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/sebastian/cli-parser" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/sebastian/complexity" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/sebastian/lines-of-code" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/graham-campbell/result-type" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/symfony/http-client" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/symfony/http-client-contracts" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-invoker" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/awssat/discord-notification-channel" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/berkayk/onesignal-laravel" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/symfony/psr-http-message-bridge" />
|
|
||||||
<path value="$PROJECT_DIR$/vendor/laravel/sanctum" />
|
|
||||||
</include_path>
|
</include_path>
|
||||||
</component>
|
</component>
|
||||||
<component name="PhpProjectSharedConfiguration" php_language_level="7.3" />
|
<component name="PhpProjectSharedConfiguration" php_language_level="7.2" />
|
||||||
<component name="PhpUnit">
|
<component name="PhpUnit">
|
||||||
<phpunit_settings>
|
<phpunit_settings>
|
||||||
<PhpUnitSettings configuration_file_path="$PROJECT_DIR$/phpunit.xml" custom_loader_path="$PROJECT_DIR$/vendor/autoload.php" use_configuration_file="true" />
|
<PhpUnitSettings configuration_file_path="$PROJECT_DIR$/phpunit.xml" custom_loader_path="$PROJECT_DIR$/vendor/autoload.php" use_configuration_file="true" />
|
||||||
|
|||||||
0
.idea/phpunit.xml
generated
Executable file → Normal file
0
.idea/phpunit.xml
generated
Executable file → Normal file
0
.idea/vcs.xml
generated
Executable file → Normal file
0
.idea/vcs.xml
generated
Executable file → Normal file
0
.phive/phars.xml
Executable file → Normal file
0
.phive/phars.xml
Executable file → Normal file
24
.styleci.yml
Executable file → Normal file
24
.styleci.yml
Executable file → Normal file
@@ -1,13 +1,13 @@
|
|||||||
risky: false
|
php:
|
||||||
version: 7
|
preset: laravel
|
||||||
preset: recommended
|
disabled:
|
||||||
finder:
|
- unused_use
|
||||||
exclude:
|
finder:
|
||||||
- "modules"
|
|
||||||
- "node_modules"
|
|
||||||
- "storage"
|
|
||||||
- "vendor"
|
|
||||||
name: "*.php"
|
|
||||||
not-name:
|
not-name:
|
||||||
- "*.blade.php"
|
- index.php
|
||||||
- "_ide_helper.php"
|
- server.php
|
||||||
|
js:
|
||||||
|
finder:
|
||||||
|
not-name:
|
||||||
|
- webpack.mix.js
|
||||||
|
css: true
|
||||||
|
|||||||
6
.vscode/launch.json
vendored
Executable file → Normal file
6
.vscode/launch.json
vendored
Executable file → Normal file
@@ -4,15 +4,11 @@
|
|||||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "Listen for XDebug",
|
"name": "Listen for XDebug",
|
||||||
"type": "php",
|
"type": "php",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"port": 9000,
|
"port": 9000
|
||||||
"ignore": [
|
|
||||||
"**/vendor/**/*.php"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Launch currently open script",
|
"name": "Launch currently open script",
|
||||||
|
|||||||
0
CODE_OF_CONDUCT.md
Executable file → Normal file
0
CODE_OF_CONDUCT.md
Executable file → Normal file
0
CONTRIBUTING.md
Executable file → Normal file
0
CONTRIBUTING.md
Executable file → Normal file
66
README.md
Executable file → Normal file
66
README.md
Executable file → Normal file
@@ -1,13 +1,11 @@
|
|||||||
# THIS IS A DEVELOPMENT BUILD. USE OF THIS BRANCH IS NOT SUPPORTED.
|
|
||||||
|
|
||||||
## RB Recruiter - The Simple Staff Application Manager v 0.6.2 [](https://crowdin.com/project/raspberry-staff-manager)
|
# RB Recruiter v 0.6.2 [](https://crowdin.com/project/raspberry-staff-manager)
|
||||||
|
## The quick and pain-free form management solution for communities
|
||||||
|
|
||||||
## The quick and pain-free staff application manager
|
Have you ever gotten tired of managing your Minecraft server/network's applications through Discord (or anything else) and having to scroll through hundreds of new messages just to find that one applicant's username?
|
||||||
|
|
||||||
Have you ever gotten tired of managing your community's applications through Discord (or anything else) and having to scroll through hundreds of new messages just to find that one applicant's username?
|
|
||||||
|
|
||||||
|
|
||||||
Wish you had a better application managemet strategy? Well, then RB Recruiter is for you!
|
Wish you had a better application managemet strategy? Well, then Raspberry Teams is for you! It was originally designed and developed for internal use for a gameserver network, but sharing is caring!
|
||||||
|
|
||||||
|
|
||||||
# Features (not exhaustive)
|
# Features (not exhaustive)
|
||||||
@@ -33,60 +31,54 @@ Wish you had a better application managemet strategy? Well, then RB Recruiter is
|
|||||||
# Roadmap
|
# Roadmap
|
||||||
|
|
||||||
Many other features are currently planned for this app, such as:
|
Many other features are currently planned for this app, such as:
|
||||||
- Customisable front page
|
- Discord role management (approved applicants)
|
||||||
- REST API (underway)
|
- Luckperms/PEX integration - For now, you'll have to promote users manually in-game
|
||||||
- Support more game servers and communities
|
- Flexibility - This app is built on a flexible concept! It will be able to be used for other purposes other than MC staff members.
|
||||||
- Editable homepage
|
- Customisable front page (**priority**)
|
||||||
- CKEditor 5 for all text fields
|
- Auto provisioning - Sign up on a website and get your instance of Raspberry Teams up and running in no time
|
||||||
- More form field types
|
- Suggestions accepted!
|
||||||
- Check out this [pull request](https://code.spacejewel-hosting.com/spacejewelhosting/staffmanager/pulls/1) for more planned features.
|
|
||||||
- ~~Web installer~~
|
|
||||||
|
|
||||||
Next release: v0.7.0, which brings a number of fixes and a REST API to the table.
|
|
||||||
|
|
||||||
# Technical overview
|
# Technical overview
|
||||||
|
|
||||||
Tech stack:
|
Tech stack:
|
||||||
- [Laravel 8](https://laravel.com/)
|
- [Laravel 7](https://laravel.com/)
|
||||||
- [Eloquent ORM](https://laravel.com/docs/5.0/eloquent)
|
- Eloquent ORM
|
||||||
- [AdminLTE](https://adminlte.io/) / [Bootstrap 4](https://getbootstrap.com/docs/4.0/getting-started/introduction/)
|
- AdminLTE / Bootstrap 4
|
||||||
- [jQuery](https://jquery.com/)
|
- jQuery / Plain Javascript
|
||||||
- [Bootstrap 4](https://getbootstrap.com/)
|
- vueJS (in the future)
|
||||||
- [Icons by FontAwesome](https://fontawesome.com/)
|
|
||||||
|
|
||||||
# Stability
|
# Stability
|
||||||
|
|
||||||
Currently, the ``master`` branch is unusable. It's currently broken and bug-ridden, and it's also protected to prevent more broken commits. The development branch is currently the stable enough branch to be used, however, please note that it's still actively updated, albeit with less frequency. Rest assured that no broken commits will be uploaded to develop without testing first.
|
Currently, the ``master`` branch is highly unstable, since it's under active development. Expect it to break with each commit. Even though I make an effort to make sure each commit is good to go before pushing, things might still break unexpectedly, and you may find a lot of bugs (which you should report).
|
||||||
|
|
||||||
After 1.0.0, master will be used as the main branch, receiving new, tested features from develop as pull requests. The master branch will only be usable and fixed after it's merged with develop.
|
Every released version is currently pre-release. If you really want to run this before version ``1.0.0`` comes out, always stay on the latest version, as those will always be tested before release, ensuring less chaos.
|
||||||
|
|
||||||
*Note: This application is NOT production ready! It won't be until the first stable release comes out, which might take a bit longer, due to me having other responsabilities outside this project.
|
*Note: This application is NOT production ready! It won't be until the first stable release comes out, which might take a bit longer.
|
||||||
|
|
||||||
# Operating System Requirements
|
# Operating System Requirements
|
||||||
|
|
||||||
Currently, this application is only supported on Linux (any distro). No support will be provided for Windows installs. Sorry!
|
Currently, this application is only supported on Linux environments (Ubuntu 20.04 or derivatives are recommended).
|
||||||
|
|
||||||
|
# Software Requirements
|
||||||
# Currently broken features
|
- ``composer`` (min version: 1.8.4)
|
||||||
- User deletion is not working at the moment.
|
- ``npm`` (tested w/ v 5.8.0)
|
||||||
- Notifications are semi-broken; Sometimes they work, sometimes they don't. Scheduled to be fixed on next release.
|
- ``php`` (required PHP 7 or newer - lower versions unsupported!)
|
||||||
|
|
||||||
# PHP Extension Requirements
|
# PHP Extension Requirements
|
||||||
|
|
||||||
- ImageMagick (imagick) for 2FA support
|
- JSON
|
||||||
|
- Curl (highly recommended)
|
||||||
Most of these extensions are already enabled by default so you don't need to worry.
|
- Image Magick (imagick) for 2FA support
|
||||||
|
|
||||||
# Installation
|
# Installation
|
||||||
|
|
||||||
The automatic installer may not work, but it's still worth to give it a try. If after the installation you find errors, clear the config cache. This is something the installer doesn't do correctly yet.
|
Make sure all prerequisites are installed. Afterwards, clone this repository, make ``install.sh``executable and run it.
|
||||||
|
|
||||||
If errors presist, please install the app the traditional Laravel way. Execute the install script to start.
|
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
Configuration is currently done via the installer. Alternatively, you may also edit the ``.env`` file directly.
|
Configuration is currently done via the installer. Alternatively, you may also edit the ``.env`` file directly.
|
||||||
~~This process will be moved to the browser later.~~
|
This process will be moved to the browser later.
|
||||||
|
|
||||||
# Bug reports
|
# Bug reports
|
||||||
|
|
||||||
Please report any bugs you find to the issues section. Since this project is being tracked on JIRA Software, the issue tracker will be moved to JIRA Service Desk. Atlassian has a great suite of products for software developers and RB Recruiter could benefit from this workflow, especially when more developers are added down the line.
|
Please report any bugs you find to the issues section here! It'd be immensely helpful. PRs are also accepted.
|
||||||
|
|||||||
0
SECURITY.md
Executable file → Normal file
0
SECURITY.md
Executable file → Normal file
@@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App;
|
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
|
|
||||||
class ApiKey extends Model
|
|
||||||
{
|
|
||||||
use HasFactory;
|
|
||||||
|
|
||||||
protected $fillable = [
|
|
||||||
'name',
|
|
||||||
'status',
|
|
||||||
'discriminator',
|
|
||||||
'last_used',
|
|
||||||
'secret',
|
|
||||||
'owner_user_id'
|
|
||||||
];
|
|
||||||
|
|
||||||
public function user()
|
|
||||||
{
|
|
||||||
return $this->belongsTo('App\User', 'owner_user_id', 'id');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
13
app/Application.php
Executable file → Normal file
13
app/Application.php
Executable file → Normal file
@@ -33,11 +33,6 @@ class Application extends Model
|
|||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
public function oneoffApplicant()
|
|
||||||
{
|
|
||||||
return $this->hasOne('App\OneoffApplicant', 'application_id', 'id');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function user()
|
public function user()
|
||||||
{
|
{
|
||||||
return $this->belongsTo('App\User', 'applicantUserID', 'id');
|
return $this->belongsTo('App\User', 'applicantUserID', 'id');
|
||||||
@@ -69,12 +64,4 @@ class Application extends Model
|
|||||||
'applicationStatus' => $status,
|
'applicationStatus' => $status,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function isOneoff()
|
|
||||||
{
|
|
||||||
return $this->user->id == 1; // ID 1 is always the ghost
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
0
app/Appointment.php
Executable file → Normal file
0
app/Appointment.php
Executable file → Normal file
4
app/Ban.php
Executable file → Normal file
4
app/Ban.php
Executable file → Normal file
@@ -30,13 +30,13 @@ class Ban extends Model
|
|||||||
'userID',
|
'userID',
|
||||||
'reason',
|
'reason',
|
||||||
'bannedUntil',
|
'bannedUntil',
|
||||||
'isPermanent',
|
'userAgent',
|
||||||
'authorUserID',
|
'authorUserID',
|
||||||
|
|
||||||
];
|
];
|
||||||
|
|
||||||
public $dates = [
|
public $dates = [
|
||||||
'suspendedUntil',
|
'bannedUntil',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function user()
|
public function user()
|
||||||
|
|||||||
0
app/Comment.php
Executable file → Normal file
0
app/Comment.php
Executable file → Normal file
0
app/Console/Commands/CountVotes.php
Executable file → Normal file
0
app/Console/Commands/CountVotes.php
Executable file → Normal file
@@ -1,140 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright © 2020 Miguel Nogueira
|
|
||||||
*
|
|
||||||
* This file is part of Raspberry Staff Manager.
|
|
||||||
*
|
|
||||||
* Raspberry Staff Manager is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Raspberry Staff Manager is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with Raspberry Staff Manager. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Console\Commands;
|
|
||||||
|
|
||||||
use App\Facades\UUID;
|
|
||||||
use App\Profile;
|
|
||||||
use App\User;
|
|
||||||
use Illuminate\Console\Command;
|
|
||||||
use Illuminate\Support\Facades\Hash;
|
|
||||||
|
|
||||||
class CreateUser extends Command
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The name and signature of the console command.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $signature = 'users:create';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The console command description.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $description = 'Creates an application user. Seeding the database is for testing environments, so use this command in production for your first admin user.';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new command instance.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute the console command.
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function handle()
|
|
||||||
{
|
|
||||||
do {
|
|
||||||
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
|
|
||||||
system('cls');
|
|
||||||
} else {
|
|
||||||
system('clear');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->info('Welcome to the user account creation wizard. If you just installed the application, we recommend you create your first admin user here. If you don\'t, you won\'t gain admin privileges after creating an account in the web interface.');
|
|
||||||
$this->info('We\'ll ask some questions to get you started.');
|
|
||||||
|
|
||||||
$username = $this->ask('Username');
|
|
||||||
do {
|
|
||||||
$password = $this->secret('Password');
|
|
||||||
$password_confirm = $this->secret('Confirm Password');
|
|
||||||
|
|
||||||
if ($password === $password_confirm) {
|
|
||||||
$password = Hash::make($password);
|
|
||||||
$matches = true;
|
|
||||||
} else {
|
|
||||||
$this->error('Password doesn\'t match. Please try again.');
|
|
||||||
$matches = false;
|
|
||||||
}
|
|
||||||
} while (! $matches);
|
|
||||||
|
|
||||||
$email = $this->ask('E-mail address');
|
|
||||||
$name = $this->ask('First/Last Name');
|
|
||||||
|
|
||||||
do {
|
|
||||||
try {
|
|
||||||
$uuid = UUID::toUUID($this->ask('Minecraft username (Must be a valid Premium account)'));
|
|
||||||
} catch (\InvalidArgumentException $e) {
|
|
||||||
$this->error($e->getMessage());
|
|
||||||
$hasError = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($hasError)) {
|
|
||||||
$continue = true;
|
|
||||||
} else {
|
|
||||||
$continue = false;
|
|
||||||
}
|
|
||||||
unset($hasError);
|
|
||||||
} while ($continue);
|
|
||||||
|
|
||||||
$this->info('Please check if these details are correct: ');
|
|
||||||
$this->info('Username: '.$username);
|
|
||||||
$this->info('Email: '.$email);
|
|
||||||
$this->info('Name: '.$name);
|
|
||||||
} while (! $this->confirm('Create user now? You can go back to correct any details.'));
|
|
||||||
|
|
||||||
$user = User::create([
|
|
||||||
'uuid' => $uuid,
|
|
||||||
'name' => $name,
|
|
||||||
'email' => $email,
|
|
||||||
'username' => $username,
|
|
||||||
'originalIP' => '127.0.0.1',
|
|
||||||
'password' => $password,
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($user) {
|
|
||||||
$user->assignRole('admin', 'reviewer', 'user', 'hiringManager');
|
|
||||||
Profile::create([
|
|
||||||
'profileShortBio' => 'Random data '.rand(0, 1000),
|
|
||||||
'profileAboutMe' => 'Random data '.rand(0, 1000),
|
|
||||||
'socialLinks' => '[]',
|
|
||||||
'avatarPreference' => 'gravatar',
|
|
||||||
'userID' => $user->id,
|
|
||||||
]);
|
|
||||||
|
|
||||||
$this->info('Account created! You may now login at '.route('login').'. Enjoy the app!');
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
$this->error('There was an unknown problem creating the user. There might have been errors above. Please try again.');
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
4
app/Console/Commands/Install.php
Executable file → Normal file
4
app/Console/Commands/Install.php
Executable file → Normal file
@@ -61,7 +61,9 @@ class Install extends Command
|
|||||||
if (Storage::disk('local')->missing('INSTALLED')) {
|
if (Storage::disk('local')->missing('INSTALLED')) {
|
||||||
$this->info('[!! Welcome to Rasberry Teams !!]');
|
$this->info('[!! Welcome to Rasberry Teams !!]');
|
||||||
$this->info('>> Installing...');
|
$this->info('>> Installing...');
|
||||||
$this->call('down');
|
$this->call('down', [
|
||||||
|
'--message' => 'Down for maintenance. We\'ll be right back!',
|
||||||
|
]);
|
||||||
|
|
||||||
copy($basePath.'/.env.example', $basePath.'/.env');
|
copy($basePath.'/.env.example', $basePath.'/.env');
|
||||||
$this->call('key:generate');
|
$this->call('key:generate');
|
||||||
|
|||||||
@@ -1,82 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright © 2020 Miguel Nogueira
|
|
||||||
*
|
|
||||||
* This file is part of Raspberry Staff Manager.
|
|
||||||
*
|
|
||||||
* Raspberry Staff Manager is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Raspberry Staff Manager is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with Raspberry Staff Manager. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Console\Commands;
|
|
||||||
|
|
||||||
use Faker\Factory;
|
|
||||||
use Faker\Generator;
|
|
||||||
use Illuminate\Console\Command;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
|
|
||||||
class MakeFile extends Command
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The name and signature of the console command.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $signature = 'files:make {count : How many test files to generate}';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The console command description.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $description = 'Generates test files for the TeamFile model. Use in conjunction with it\'s factory.';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The faker instance used to obtain dummy text.
|
|
||||||
*
|
|
||||||
* @var Generator
|
|
||||||
*/
|
|
||||||
private $faker;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new command instance.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
$this->faker = Factory::create();
|
|
||||||
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute the console command.
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function handle()
|
|
||||||
{
|
|
||||||
$count = $this->argument('count');
|
|
||||||
$this->info('Creating '.$this->argument('count').' files!');
|
|
||||||
|
|
||||||
for ($max = 1; $max < $count; $max++) {
|
|
||||||
Storage::disk('local')->put('factory_files/testfile_'.rand(0, 5000).'.txt', $this->faker->paragraphs(40, true));
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->info('Finished creating files! They will be randomly picked by the factory.');
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
0
app/Console/Commands/SetEnv.php
Executable file → Normal file
0
app/Console/Commands/SetEnv.php
Executable file → Normal file
4
app/Console/Kernel.php
Executable file → Normal file
4
app/Console/Kernel.php
Executable file → Normal file
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
namespace App\Console;
|
namespace App\Console;
|
||||||
|
|
||||||
use App\Jobs\ProcessDueSuspensions;
|
use App\Jobs\CleanBans;
|
||||||
use Illuminate\Console\Scheduling\Schedule;
|
use Illuminate\Console\Scheduling\Schedule;
|
||||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ class Kernel extends ConsoleKernel
|
|||||||
->daily();
|
->daily();
|
||||||
// Production value: Every day
|
// Production value: Every day
|
||||||
|
|
||||||
$schedule->job(new ProcessDueSuspensions)
|
$schedule->job(new CleanBans)
|
||||||
->daily();
|
->daily();
|
||||||
// Production value: Every day
|
// Production value: Every day
|
||||||
}
|
}
|
||||||
|
|||||||
7
app/CustomFacades/IP.php
Executable file → Normal file
7
app/CustomFacades/IP.php
Executable file → Normal file
@@ -38,8 +38,8 @@ class IP
|
|||||||
'ip' => $IP,
|
'ip' => $IP,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// TODO: Maybe unwrap this? Methods are chained here
|
||||||
|
|
||||||
if (!config('demo.is_enabled')) {
|
|
||||||
return json_decode(Cache::remember($IP, 3600, function () use ($IP) {
|
return json_decode(Cache::remember($IP, 3600, function () use ($IP) {
|
||||||
return Http::get(config('general.urls.ipapi.ipcheck'), [
|
return Http::get(config('general.urls.ipapi.ipcheck'), [
|
||||||
'apiKey' => config('general.keys.ipapi.apikey'),
|
'apiKey' => config('general.keys.ipapi.apikey'),
|
||||||
@@ -47,9 +47,4 @@ class IP
|
|||||||
])->body();
|
])->body();
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new class {
|
|
||||||
public $message = "This feature is disabled.";
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
0
app/Events/ApplicationApprovedEvent.php
Executable file → Normal file
0
app/Events/ApplicationApprovedEvent.php
Executable file → Normal file
0
app/Events/ApplicationDeniedEvent.php
Executable file → Normal file
0
app/Events/ApplicationDeniedEvent.php
Executable file → Normal file
0
app/Events/NewApplicationEvent.php
Executable file → Normal file
0
app/Events/NewApplicationEvent.php
Executable file → Normal file
0
app/Events/UserBannedEvent.php
Executable file → Normal file
0
app/Events/UserBannedEvent.php
Executable file → Normal file
@@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|
||||||
|
|
||||||
class ApplicationNotFoundException extends ModelNotFoundException
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class EmptyFormException extends Exception
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class EmptyOptionsException extends Exception
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class FailedCaptchaException extends Exception
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class FileUploadException extends Exception
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class FormHasConstraintsException extends Exception
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
0
app/Exceptions/Handler.php
Executable file → Normal file
0
app/Exceptions/Handler.php
Executable file → Normal file
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class IncompleteApplicationException extends Exception
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class InvalidAppointmentException extends Exception
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class InvalidAppointmentStatusException extends Exception
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class InvalidGamePreferenceException extends Exception
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class InvalidInviteException extends Exception
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class OptionCategoryNotFoundException extends Exception
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class OptionNotFoundException extends Exception
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class ProfileNotFoundException extends Exception
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class PublicTeamInviteException extends Exception
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class UnavailableApplicationException extends Exception
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
class UserAlreadyInvitedException extends Exception
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Exceptions;
|
|
||||||
|
|
||||||
use Exception;
|
|
||||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
|
||||||
|
|
||||||
class VacancyNotFoundException extends ModelNotFoundException
|
|
||||||
{
|
|
||||||
//
|
|
||||||
}
|
|
||||||
0
app/Facades/ContextAwareValidation.php
Executable file → Normal file
0
app/Facades/ContextAwareValidation.php
Executable file → Normal file
@@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
namespace App\Facades;
|
|
||||||
|
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Facade;
|
|
||||||
|
|
||||||
class DigitalStorageHelper extends Facade
|
|
||||||
{
|
|
||||||
|
|
||||||
protected static function getFacadeAccessor()
|
|
||||||
{
|
|
||||||
return 'digitalStorageHelperFacadeRoot';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
0
app/Facades/IP.php
Executable file → Normal file
0
app/Facades/IP.php
Executable file → Normal file
@@ -1,17 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
namespace App\Facades;
|
|
||||||
|
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Facade;
|
|
||||||
|
|
||||||
class JSON extends Facade
|
|
||||||
{
|
|
||||||
|
|
||||||
protected static function getFacadeAccessor()
|
|
||||||
{
|
|
||||||
return 'json';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
0
app/Facades/Options.php
Executable file → Normal file
0
app/Facades/Options.php
Executable file → Normal file
0
app/Facades/UUID.php
Executable file → Normal file
0
app/Facades/UUID.php
Executable file → Normal file
0
app/Form.php
Executable file → Normal file
0
app/Form.php
Executable file → Normal file
2
app/Helpers/ContextAwareValidator.php
Executable file → Normal file
2
app/Helpers/ContextAwareValidator.php
Executable file → Normal file
@@ -71,7 +71,7 @@ class ContextAwareValidator
|
|||||||
$validator = [];
|
$validator = [];
|
||||||
|
|
||||||
if ($includeFormName) {
|
if ($includeFormName) {
|
||||||
$validator['formName'] = 'required|string';
|
$validator['formName'] = 'required|string|max:100';
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($fields as $fieldName => $field) {
|
foreach ($fields as $fieldName => $field) {
|
||||||
|
|||||||
@@ -1,107 +0,0 @@
|
|||||||
<?php declare(strict_types=1);
|
|
||||||
|
|
||||||
|
|
||||||
namespace App\Helpers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class DigitalStorageHelper
|
|
||||||
*
|
|
||||||
* The digital storage helper class helps you convert bytes into several other units.
|
|
||||||
* It should be used whenever you need to display a file's size in a human readable way.
|
|
||||||
*
|
|
||||||
* It's framework agnostic, meaning you can take it out of context and it'll still work; However, you'll have to instantiate it first.
|
|
||||||
* @package App\Helpers
|
|
||||||
*/
|
|
||||||
class DigitalStorageHelper
|
|
||||||
{
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The digital storage value to be manipulated.
|
|
||||||
* @var $value
|
|
||||||
*/
|
|
||||||
protected $value;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the digital storage value for manipulation.
|
|
||||||
*
|
|
||||||
* @param int $value The digital storage value in bytes
|
|
||||||
* @return $this The current instance
|
|
||||||
*/
|
|
||||||
public function setValue(int $value): DigitalStorageHelper
|
|
||||||
{
|
|
||||||
$this->value = $value;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts the digital storage value to kilobytes.
|
|
||||||
*
|
|
||||||
* @return float|int
|
|
||||||
*/
|
|
||||||
public function toKilobytes(): float
|
|
||||||
{
|
|
||||||
return $this->value / 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts the digital storage value to megabytes.
|
|
||||||
*
|
|
||||||
* @return float|int
|
|
||||||
*/
|
|
||||||
public function toMegabytes(): float
|
|
||||||
{
|
|
||||||
return $this->value / (1 * pow(10, 6)); // 1 times 10 to the power of 6
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert the digital storage value to gigabytes. Might be an approximation
|
|
||||||
*
|
|
||||||
* @return float
|
|
||||||
*/
|
|
||||||
public function toGigabytes(): float
|
|
||||||
{
|
|
||||||
return $this->value / (1 * pow(10, 9));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert the digital storage value to terabytes.
|
|
||||||
*
|
|
||||||
* @return float
|
|
||||||
*/
|
|
||||||
public function toTerabytes(): float
|
|
||||||
{
|
|
||||||
return $this->value / (1 * pow(10, 12));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Format the digital storage value to one of the units: b, kb, mb, gb and tb.
|
|
||||||
* The method has been adapted to use both MiB and MB values.
|
|
||||||
*
|
|
||||||
* @param int $precision The rounding precision
|
|
||||||
* @param bool $si Use international system units. Defaults to false
|
|
||||||
* @return string The human readable digital storage value, in either, for instance, MB or MiB
|
|
||||||
* @see https://stackoverflow.com/a/2510459/11540218 StackOverflow question regarding unit conversion
|
|
||||||
* @since 7.3.23
|
|
||||||
*/
|
|
||||||
public function formatBytes($precision = 2, $si = false): string
|
|
||||||
{
|
|
||||||
$units = ['B', 'KiB', 'MiB', 'GiB', 'TiB'];
|
|
||||||
if ($si)
|
|
||||||
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
||||||
|
|
||||||
$bytes = max($this->value, 0);
|
|
||||||
$pow = floor(($bytes ? log($bytes) : 0) / log(($si) ? 1000 : 1024));
|
|
||||||
$pow = min($pow, count($units) - 1);
|
|
||||||
|
|
||||||
$bytes /= pow(($si) ? 1000 : 1024, $pow);
|
|
||||||
|
|
||||||
return round($bytes, $precision) . ' ' . $units[$pow];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
|
|
||||||
namespace App\Helpers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class JSON - Used for JSON responses.
|
|
||||||
* @package App\Helpers
|
|
||||||
*/
|
|
||||||
class JSON
|
|
||||||
{
|
|
||||||
|
|
||||||
protected $type, $status, $message, $code, $data, $additional;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mixed $type
|
|
||||||
*/
|
|
||||||
public function setResponseType($type): JSON
|
|
||||||
{
|
|
||||||
$this->type = $type;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mixed $additional
|
|
||||||
*/
|
|
||||||
public function setAdditional($additional)
|
|
||||||
{
|
|
||||||
$this->additional = $additional;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function getAdditional()
|
|
||||||
{
|
|
||||||
return $this->additional;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function getType()
|
|
||||||
{
|
|
||||||
return $this->type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function getStatus()
|
|
||||||
{
|
|
||||||
return $this->status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mixed $status
|
|
||||||
* @return JSON
|
|
||||||
*/
|
|
||||||
public function setStatus($status)
|
|
||||||
{
|
|
||||||
$this->status = $status;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function getMessage()
|
|
||||||
{
|
|
||||||
return $this->message;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mixed $message
|
|
||||||
* @return JSON
|
|
||||||
*/
|
|
||||||
public function setMessage($message)
|
|
||||||
{
|
|
||||||
$this->message = $message;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function getCode()
|
|
||||||
{
|
|
||||||
return $this->code;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mixed $code
|
|
||||||
* @return JSON
|
|
||||||
*/
|
|
||||||
public function setCode($code)
|
|
||||||
{
|
|
||||||
$this->code = $code;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function getData()
|
|
||||||
{
|
|
||||||
return $this->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param mixed $data
|
|
||||||
* @return JSON
|
|
||||||
*/
|
|
||||||
public function setData($data)
|
|
||||||
{
|
|
||||||
$this->data = $data;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function build($headers = [])
|
|
||||||
{
|
|
||||||
// Uses the same structure as model resources, for consistency when they aren't used.
|
|
||||||
$response = [
|
|
||||||
'data' => $this->getData(),
|
|
||||||
'meta' => [
|
|
||||||
'status' => $this->getStatus(),
|
|
||||||
'message' => $this->getMessage(),
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
if (!empty($this->additional))
|
|
||||||
{
|
|
||||||
foreach($this->additional as $additionalKeyName => $key)
|
|
||||||
{
|
|
||||||
$response[$additionalKeyName] = $key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return response($response, $this->getCode(), $headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
39
app/Helpers/Options.php
Executable file → Normal file
39
app/Helpers/Options.php
Executable file → Normal file
@@ -21,64 +21,35 @@
|
|||||||
|
|
||||||
namespace App\Helpers;
|
namespace App\Helpers;
|
||||||
|
|
||||||
use App\Exceptions\EmptyOptionsException;
|
|
||||||
use App\Exceptions\OptionNotFoundException;
|
|
||||||
use App\Options as Option;
|
use App\Options as Option;
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
use Illuminate\Support\Facades\Cache;
|
use Illuminate\Support\Facades\Cache;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
/**
|
|
||||||
* The options class. A simple wrapper around the model. Could be a repository, but we're not using that design pattern just yet
|
|
||||||
*/
|
|
||||||
class Options
|
class Options
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an assortment of settings found in the mentioned category
|
|
||||||
*
|
|
||||||
* @param $category The category
|
|
||||||
* @return Collection The settings in this category
|
|
||||||
*/
|
|
||||||
public function getCategory(string $category): Collection
|
|
||||||
{
|
|
||||||
$options = Option::where('option_category', $category)->get();
|
|
||||||
if ($options->isEmpty())
|
|
||||||
{
|
|
||||||
throw new EmptyOptionsException('There are no options in category ' . $category);
|
|
||||||
}
|
|
||||||
return $options;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function getOption(string $option): string
|
public function getOption(string $option): string
|
||||||
{
|
{
|
||||||
$value = Cache::get($option);
|
$value = Cache::get($option);
|
||||||
|
|
||||||
|
|
||||||
if (is_null($value)) {
|
if (is_null($value)) {
|
||||||
Log::debug('Option '.$option.'not found in cache, refreshing from database');
|
Log::debug('Option '.$option.'not found in cache, refreshing from database');
|
||||||
$value = Option::where('option_name', $option)->first();
|
$value = Option::where('option_name', $option)->first();
|
||||||
if (is_null($value)) {
|
if (is_null($value)) {
|
||||||
throw new OptionNotFoundException('This option does not exist.');
|
throw new \Exception('This option does not exist.');
|
||||||
}
|
}
|
||||||
Cache::put($option, $value->option_value);
|
Cache::put($option, $value);
|
||||||
Cache::put($option.'_desc', 'Undefined description');
|
Cache::put($option.'_desc', 'Undefined description');
|
||||||
|
}
|
||||||
|
|
||||||
return $value->option_value;
|
return $value->option_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $value;
|
public function setOption(string $option, string $value, string $description)
|
||||||
}
|
|
||||||
|
|
||||||
// Null categories are settings without categories and will appear ungrouped
|
|
||||||
public function setOption(string $option, string $value, string $description, string $category = null)
|
|
||||||
{
|
{
|
||||||
Option::create([
|
Option::create([
|
||||||
'option_name' => $option,
|
'option_name' => $option,
|
||||||
'option_value' => $value,
|
'option_value' => $value,
|
||||||
'friendly_name' => $description,
|
'friendly_name' => $description,
|
||||||
'option_category' => $category
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
Cache::put($option, $value, now()->addDay());
|
Cache::put($option, $value, now()->addDay());
|
||||||
@@ -120,7 +91,7 @@ class Options
|
|||||||
|
|
||||||
Cache::put('option_name', $newValue, now()->addDay());
|
Cache::put('option_name', $newValue, now()->addDay());
|
||||||
} else {
|
} else {
|
||||||
throw new OptionNotFoundException('This option does not exist.');
|
throw new \Exception('This option does not exist.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,95 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use App\ApiKey;
|
|
||||||
use App\Http\Requests\CreateApiKeyRequest;
|
|
||||||
use App\User;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
use Illuminate\Support\Facades\Hash;
|
|
||||||
|
|
||||||
class ApiKeyController extends Controller
|
|
||||||
{
|
|
||||||
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
$this->authorize('viewAny', ApiKey::class);
|
|
||||||
|
|
||||||
return view('dashboard.administration.keys')
|
|
||||||
->with('keys', ApiKey::all());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store a newly created resource in storage.
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
*/
|
|
||||||
public function store(CreateApiKeyRequest $request)
|
|
||||||
{
|
|
||||||
$this->authorize('create', ApiKey::class);
|
|
||||||
|
|
||||||
$discriminator = "#" . bin2hex(random_bytes(7));
|
|
||||||
$secret = bin2hex(random_bytes(32));
|
|
||||||
|
|
||||||
$key = ApiKey::create([
|
|
||||||
'name' => $request->keyName,
|
|
||||||
'discriminator' => $discriminator,
|
|
||||||
'secret' => Hash::make($secret),
|
|
||||||
'status' => 'active',
|
|
||||||
'owner_user_id' => Auth::user()->id
|
|
||||||
]);
|
|
||||||
|
|
||||||
if ($key)
|
|
||||||
{
|
|
||||||
$request->session()->flash('success', __('Key successfully registered!'));
|
|
||||||
$request->session()->flash('finalKey', $discriminator . '.' . $secret);
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', __('An error occurred whilst trying to create an API key.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function revokeKey(Request $request, ApiKey $key)
|
|
||||||
{
|
|
||||||
$this->authorize('update', $key);
|
|
||||||
|
|
||||||
if ($key->status == 'active')
|
|
||||||
{
|
|
||||||
$key->status = 'disabled';
|
|
||||||
$key->save();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', __('Key already revoked.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('success', __('Key revoked. Apps using this key will stop working.'));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the specified resource from storage.
|
|
||||||
*/
|
|
||||||
public function destroy($id)
|
|
||||||
{
|
|
||||||
$key = ApiKey::findOrFail($id);
|
|
||||||
$this->authorize('delete', $key);
|
|
||||||
|
|
||||||
$key->delete();
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('success', __('Key deleted successfully. Apps using this key will stop working.'));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
205
app/Http/Controllers/ApplicationController.php
Executable file → Normal file
205
app/Http/Controllers/ApplicationController.php
Executable file → Normal file
@@ -22,24 +22,31 @@
|
|||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Application;
|
use App\Application;
|
||||||
use App\Exceptions\ApplicationNotFoundException;
|
use App\Events\ApplicationDeniedEvent;
|
||||||
use App\Exceptions\IncompleteApplicationException;
|
use App\Notifications\ApplicationMoved;
|
||||||
use App\Exceptions\UnavailableApplicationException;
|
use App\Notifications\NewApplicant;
|
||||||
use App\Exceptions\VacancyNotFoundException;
|
use App\Response;
|
||||||
use App\Services\ApplicationService;
|
use App\User;
|
||||||
|
use App\Vacancy;
|
||||||
|
use ContextAwareValidator;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class ApplicationController extends Controller
|
class ApplicationController extends Controller
|
||||||
{
|
{
|
||||||
|
private function canVote($votes)
|
||||||
|
{
|
||||||
|
$allvotes = collect([]);
|
||||||
|
|
||||||
private $applicationService;
|
foreach ($votes as $vote) {
|
||||||
|
if ($vote->userID == Auth::user()->id) {
|
||||||
public function __construct(ApplicationService $applicationService) {
|
$allvotes->push($vote);
|
||||||
|
}
|
||||||
$this->applicationService = $applicationService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ($allvotes->count() == 1) ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
public function showUserApps()
|
public function showUserApps()
|
||||||
{
|
{
|
||||||
@@ -51,7 +58,7 @@ class ApplicationController extends Controller
|
|||||||
{
|
{
|
||||||
$this->authorize('view', $application);
|
$this->authorize('view', $application);
|
||||||
|
|
||||||
if (!is_null($application)) {
|
if (! is_null($application)) {
|
||||||
return view('dashboard.user.viewapp')
|
return view('dashboard.user.viewapp')
|
||||||
->with(
|
->with(
|
||||||
[
|
[
|
||||||
@@ -60,88 +67,178 @@ class ApplicationController extends Controller
|
|||||||
'structuredResponses' => json_decode($application->response->responseData, true),
|
'structuredResponses' => json_decode($application->response->responseData, true),
|
||||||
'formStructure' => $application->response->form,
|
'formStructure' => $application->response->form,
|
||||||
'vacancy' => $application->response->vacancy,
|
'vacancy' => $application->response->vacancy,
|
||||||
'canVote' => $this->applicationService->canVote($application->votes),
|
'canVote' => $this->canVote($application->votes),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
$request->session()->flash('error', __('The application you requested could not be found.'));
|
$request->session()->flash('error', 'The application you requested could not be found.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function showAllApps(Request $request)
|
public function showAllApps()
|
||||||
{
|
{
|
||||||
$this->authorize('viewAny', Application::class);
|
$this->authorize('viewAny', Application::class);
|
||||||
|
|
||||||
return view('dashboard.appmanagement.all')
|
return view('dashboard.appmanagement.all')
|
||||||
->with('applications', Application::all());
|
->with('applications', Application::paginate(6));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function showAllPendingApps()
|
||||||
public function renderApplicationForm($vacancySlug)
|
|
||||||
{
|
{
|
||||||
try {
|
$this->authorize('viewAny', Application::class);
|
||||||
return $this->applicationService->renderForm($vacancySlug);
|
|
||||||
|
return view('dashboard.appmanagement.outstandingapps')
|
||||||
|
->with('applications', Application::where('applicationStatus', 'STAGE_SUBMITTED')->get());
|
||||||
}
|
}
|
||||||
catch (ApplicationNotFoundException $ex) {
|
|
||||||
return redirect()
|
public function showPendingInterview()
|
||||||
->back()
|
{
|
||||||
->with('error', $ex->getMessage());
|
$this->authorize('viewAny', Application::class);
|
||||||
|
$applications = Application::with('appointment', 'user')->get();
|
||||||
|
$count = 0;
|
||||||
|
|
||||||
|
$pendingInterviews = collect([]);
|
||||||
|
$upcomingInterviews = collect([]);
|
||||||
|
|
||||||
|
foreach ($applications as $application) {
|
||||||
|
if (! is_null($application->appointment) && $application->appointment->appointmentStatus == 'CONCLUDED') {
|
||||||
|
$count = +1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($application->applicationStatus) {
|
||||||
|
case 'STAGE_INTERVIEW':
|
||||||
|
$upcomingInterviews->push($application);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'STAGE_INTERVIEW_SCHEDULED':
|
||||||
|
$pendingInterviews->push($application);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return view('dashboard.appmanagement.interview')
|
||||||
|
->with([
|
||||||
|
'finishedCount' => $count,
|
||||||
|
'applications' => $pendingInterviews,
|
||||||
|
'upcomingApplications' => $upcomingInterviews,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function showPeerReview()
|
||||||
|
{
|
||||||
|
$this->authorize('viewAny', Application::class);
|
||||||
|
|
||||||
|
return view('dashboard.appmanagement.peerreview')
|
||||||
|
->with('applications', Application::where('applicationStatus', 'STAGE_PEERAPPROVAL')->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function renderApplicationForm(Request $request, $vacancySlug)
|
||||||
|
{
|
||||||
|
// FIXME: Get rid of references to first(), this is a wonky query
|
||||||
|
$vacancyWithForm = Vacancy::with('forms')->where('vacancySlug', $vacancySlug)->get();
|
||||||
|
|
||||||
|
$firstVacancy = $vacancyWithForm->first();
|
||||||
|
|
||||||
|
if (! $vacancyWithForm->isEmpty() && $firstVacancy->vacancyCount !== 0 && $firstVacancy->vacancyStatus == 'OPEN') {
|
||||||
|
return view('dashboard.application-rendering.apply')
|
||||||
|
->with([
|
||||||
|
|
||||||
|
'vacancy' => $vacancyWithForm->first(),
|
||||||
|
'preprocessedForm' => json_decode($vacancyWithForm->first()->forms->formStructure, true),
|
||||||
|
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
abort(404, 'The application you\'re looking for could not be found or it is currently unavailable.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function saveApplicationAnswers(Request $request, $vacancySlug)
|
public function saveApplicationAnswers(Request $request, $vacancySlug)
|
||||||
{
|
{
|
||||||
try {
|
$vacancy = Vacancy::with('forms')->where('vacancySlug', $vacancySlug)->get();
|
||||||
|
|
||||||
$this->applicationService->fillForm(Auth::user(), $request->all(), $vacancySlug);
|
if ($vacancy->first()->vacancyCount == 0 || $vacancy->first()->vacancyStatus !== 'OPEN') {
|
||||||
|
$request->session()->flash('error', 'This application is unavailable.');
|
||||||
|
|
||||||
} catch (VacancyNotFoundException | IncompleteApplicationException | UnavailableApplicationException $e) {
|
return redirect()->back();
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', $e->getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()
|
Log::info('Processing new application!');
|
||||||
->to(route('showUserApps'))
|
|
||||||
->with('success', __('Thank you! Your application has been processed and our team will get to it shortly.'));
|
$formStructure = json_decode($vacancy->first()->forms->formStructure, true);
|
||||||
|
$responseValidation = ContextAwareValidator::getResponseValidator($request->all(), $formStructure);
|
||||||
|
|
||||||
|
Log::info('Built response & validator structure!');
|
||||||
|
|
||||||
|
if (! $responseValidation->get('validator')->fails()) {
|
||||||
|
$response = Response::create([
|
||||||
|
'responseFormID' => $vacancy->first()->forms->id,
|
||||||
|
'associatedVacancyID' => $vacancy->first()->id, // Since a form can be used by multiple vacancies, we can only know which specific vacancy this response ties to by using a vacancy ID
|
||||||
|
'responseData' => $responseValidation->get('responseStructure'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
Log::info('Registered form response for user '.Auth::user()->name.' for vacancy '.$vacancy->first()->vacancyName);
|
||||||
|
|
||||||
|
$application = Application::create([
|
||||||
|
'applicantUserID' => Auth::user()->id,
|
||||||
|
'applicantFormResponseID' => $response->id,
|
||||||
|
'applicationStatus' => 'STAGE_SUBMITTED',
|
||||||
|
]);
|
||||||
|
|
||||||
|
Log::info('Submitted application for user '.Auth::user()->name.' with response ID'.$response->id);
|
||||||
|
|
||||||
|
foreach (User::all() as $user) {
|
||||||
|
if ($user->hasRole('admin')) {
|
||||||
|
$user->notify((new NewApplicant($application, $vacancy->first()))->delay(now()->addSeconds(10)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$request->session()->flash('success', 'Thank you for your application! It will be reviewed as soon as possible.');
|
||||||
|
|
||||||
|
return redirect()->to(route('showUserApps'));
|
||||||
|
} else {
|
||||||
|
Log::warning('Application form for '.Auth::user()->name.' contained errors, resetting!');
|
||||||
|
$request->session()->flash('error', 'There are one or more errors in your application. Please make sure none of your fields are empty, since they are all required.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updateApplicationStatus(Request $request, Application $application, $newStatus)
|
public function updateApplicationStatus(Request $request, Application $application, $newStatus)
|
||||||
{
|
{
|
||||||
$messageIsError = false;
|
|
||||||
$this->authorize('update', Application::class);
|
$this->authorize('update', Application::class);
|
||||||
|
|
||||||
try {
|
switch ($newStatus) {
|
||||||
$status = $this->applicationService->updateStatus($application, $newStatus);
|
case 'deny':
|
||||||
} catch (\LogicException $ex)
|
|
||||||
{
|
event(new ApplicationDeniedEvent($application));
|
||||||
return redirect()
|
break;
|
||||||
->back()
|
|
||||||
->with('error', $ex->getMessage());
|
case 'interview':
|
||||||
|
Log::info('User '.Auth::user()->name.' has moved application ID '.$application->id.'to interview stage');
|
||||||
|
$request->session()->flash('success', 'Application moved to interview stage! (:');
|
||||||
|
$application->setStatus('STAGE_INTERVIEW');
|
||||||
|
|
||||||
|
$application->user->notify(new ApplicationMoved());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
$request->session()->flash('error', 'There are no suitable statuses to update to. Do not mess with the URL.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()
|
return redirect()->back();
|
||||||
->back()
|
|
||||||
->with('success', $status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function delete(Request $request, Application $application)
|
public function delete(Request $request, Application $application)
|
||||||
{
|
{
|
||||||
$this->authorize('delete', $application);
|
$this->authorize('delete', $application);
|
||||||
$this->applicationService->delete($application);
|
$application->delete(); // observers will run, cleaning it up
|
||||||
|
|
||||||
return redirect()
|
$request->session()->flash('success', 'Application deleted. Comments, appointments and responses have also been deleted.');
|
||||||
->back()
|
|
||||||
->with('success', __('Application deleted. Comments, appointments and responses have also been deleted.'));
|
|
||||||
|
|
||||||
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
100
app/Http/Controllers/AppointmentController.php
Executable file → Normal file
100
app/Http/Controllers/AppointmentController.php
Executable file → Normal file
@@ -23,79 +23,85 @@ namespace App\Http\Controllers;
|
|||||||
|
|
||||||
use App\Application;
|
use App\Application;
|
||||||
use App\Appointment;
|
use App\Appointment;
|
||||||
use App\Exceptions\InvalidAppointmentException;
|
|
||||||
use App\Exceptions\InvalidAppointmentStatusException;
|
|
||||||
use App\Http\Requests\SaveNotesRequest;
|
use App\Http\Requests\SaveNotesRequest;
|
||||||
use App\Services\AppointmentService;
|
use App\Notifications\ApplicationMoved;
|
||||||
use App\Services\MeetingNoteService;
|
use App\Notifications\AppointmentScheduled;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Auth\Access\AuthorizationException;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class AppointmentController extends Controller
|
class AppointmentController extends Controller
|
||||||
{
|
{
|
||||||
|
private $allowedPlatforms = [
|
||||||
|
|
||||||
private $appointmentService;
|
'ZOOM',
|
||||||
private $meetingNoteService;
|
'DISCORD',
|
||||||
|
'SKYPE',
|
||||||
|
'MEET',
|
||||||
|
'TEAMSPEAK',
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
public function __construct(AppointmentService $appointmentService, MeetingNoteService $meetingNoteService) {
|
public function saveAppointment(Request $request, Application $application)
|
||||||
|
|
||||||
$this->appointmentService = $appointmentService;
|
|
||||||
$this->meetingNoteService = $meetingNoteService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function saveAppointment(Request $request, Application $application): RedirectResponse
|
|
||||||
{
|
{
|
||||||
$this->authorize('create', Appointment::class);
|
$this->authorize('create', Appointment::class);
|
||||||
|
|
||||||
$appointmentDate = Carbon::parse($request->appointmentDateTime);
|
$appointmentDate = Carbon::parse($request->appointmentDateTime);
|
||||||
$this->appointmentService->createAppointment($application, $appointmentDate, $request->appointmentDescription, $request->appointmentLocation);
|
|
||||||
|
|
||||||
return redirect()
|
$appointment = Appointment::create([
|
||||||
->back()
|
'appointmentDescription' => $request->appointmentDescription,
|
||||||
->with('success',__('Appointment successfully scheduled @ :appointmentTime', ['appointmentTime', $appointmentDate->toDateTimeString()]));
|
'appointmentDate' => $appointmentDate->toDateTimeString(),
|
||||||
|
'applicationID' => $application->id,
|
||||||
|
'appointmentLocation' => (in_array($request->appointmentLocation, $this->allowedPlatforms)) ? $request->appointmentLocation : 'DISCORD',
|
||||||
|
]);
|
||||||
|
$application->setStatus('STAGE_INTERVIEW_SCHEDULED');
|
||||||
|
|
||||||
|
Log::info('User '.Auth::user()->name.' has scheduled an appointment with '.$application->user->name.' for application ID'.$application->id, [
|
||||||
|
'datetime' => $appointmentDate->toDateTimeString(),
|
||||||
|
'scheduled' => now(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
$application->user->notify(new AppointmentScheduled($appointment));
|
||||||
|
$request->session()->flash('success', 'Appointment successfully scheduled @ '.$appointmentDate->toDateTimeString());
|
||||||
|
|
||||||
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function updateAppointment(Request $request, Application $application, $status)
|
||||||
* @throws AuthorizationException
|
|
||||||
*/
|
|
||||||
public function updateAppointment(Application $application, $status): RedirectResponse
|
|
||||||
{
|
{
|
||||||
$this->authorize('update', $application->appointment);
|
$this->authorize('update', $application->appointment);
|
||||||
|
|
||||||
try {
|
$validStatuses = [
|
||||||
$this->appointmentService->updateAppointment($application, $status);
|
'SCHEDULED',
|
||||||
|
'CONCLUDED',
|
||||||
return redirect()
|
];
|
||||||
->back()
|
|
||||||
->with('success', __("Interview finished! Staff members can now vote on it."));
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (InvalidAppointmentStatusException $ex) {
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', $ex->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// NOTE: This is a little confusing, refactor
|
||||||
|
$application->appointment->appointmentStatus = (in_array($status, $validStatuses)) ? strtoupper($status) : 'SCHEDULED';
|
||||||
|
$application->appointment->save();
|
||||||
|
|
||||||
|
$application->setStatus('STAGE_PEERAPPROVAL');
|
||||||
|
$application->user->notify(new ApplicationMoved());
|
||||||
|
|
||||||
|
$request->session()->flash('success', 'Interview finished! Staff members can now vote on it.');
|
||||||
|
|
||||||
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// also updates
|
||||||
public function saveNotes(SaveNotesRequest $request, Application $application)
|
public function saveNotes(SaveNotesRequest $request, Application $application)
|
||||||
{
|
{
|
||||||
try {
|
if (! is_null($application)) {
|
||||||
|
$application->load('appointment');
|
||||||
|
|
||||||
$this->meetingNoteService->addToApplication($application, $request->noteText);
|
$application->appointment->meetingNotes = $request->noteText;
|
||||||
|
$application->appointment->save();
|
||||||
|
|
||||||
return redirect()
|
$request->session()->flash('success', 'Meeting notes have been saved.');
|
||||||
->back()
|
} else {
|
||||||
->with('success', 'Saved notes.');
|
$request->session()->flash('error', 'There\'s no appointment to save notes to!');
|
||||||
|
|
||||||
} catch (InvalidAppointmentException $ex) {
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', $ex->getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
0
app/Http/Controllers/Auth/ConfirmPasswordController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/ConfirmPasswordController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/ForgotPasswordController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/ForgotPasswordController.php
Executable file → Normal file
14
app/Http/Controllers/Auth/LoginController.php
Executable file → Normal file
14
app/Http/Controllers/Auth/LoginController.php
Executable file → Normal file
@@ -25,7 +25,6 @@ use App\Http\Controllers\Controller;
|
|||||||
use App\User;
|
use App\User;
|
||||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
|
|
||||||
class LoginController extends Controller
|
class LoginController extends Controller
|
||||||
{
|
{
|
||||||
@@ -78,17 +77,4 @@ class LoginController extends Controller
|
|||||||
|
|
||||||
return $this->originalAttemptLogin($request);
|
return $this->originalAttemptLogin($request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function authenticated(Request $request, User $user)
|
|
||||||
{
|
|
||||||
if ($user->originalIP !== $request->ip())
|
|
||||||
{
|
|
||||||
Log::alert('User IP address changed from last login. Updating.', [
|
|
||||||
'prev' => $user->originalIP,
|
|
||||||
'new' => $request->ip()
|
|
||||||
]);
|
|
||||||
$user->originalIP = $request->ip();
|
|
||||||
$user->save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
28
app/Http/Controllers/Auth/RegisterController.php
Executable file → Normal file
28
app/Http/Controllers/Auth/RegisterController.php
Executable file → Normal file
@@ -24,7 +24,6 @@ namespace App\Http\Controllers\Auth;
|
|||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Profile;
|
use App\Profile;
|
||||||
use App\User;
|
use App\User;
|
||||||
use App\Facades\Options;
|
|
||||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
@@ -82,30 +81,11 @@ class RegisterController extends Controller
|
|||||||
*/
|
*/
|
||||||
protected function validator(array $data)
|
protected function validator(array $data)
|
||||||
{
|
{
|
||||||
$password = ['required', 'string', 'confirmed'];
|
|
||||||
|
|
||||||
switch (Options::getOption('pw_security_policy'))
|
|
||||||
{ // this could be better structured, switch doesn't feel right
|
|
||||||
case 'off':
|
|
||||||
$password = ['required', 'string', 'confirmed'];
|
|
||||||
break;
|
|
||||||
case 'low':
|
|
||||||
$password = ['required', 'string', 'min:10', 'confirmed'];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'medium':
|
|
||||||
$password = ['required', 'string', 'confirmed', 'regex:/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[#?!@$%^&*-]).{12,}$/'];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'high':
|
|
||||||
$password = ['required', 'string', 'confirmed', 'regex:/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{20,}$/'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return Validator::make($data, [
|
return Validator::make($data, [
|
||||||
'uuid' => (Options::getOption('requireGameLicense') && Options::getOption('currentGame') == 'MINECRAFT') ? ['required', 'string', 'unique:users', 'min:32', 'max:32'] : ['nullable', 'string'],
|
'uuid' => ['required', 'string', 'unique:users', 'min:32', 'max:32'],
|
||||||
'name' => ['required', 'string', 'max:255'],
|
'name' => ['required', 'string', 'max:255'],
|
||||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
||||||
'password' => $password,
|
'password' => ['required', 'string', 'min:10', 'confirmed', 'regex:/^.*(?=.{3,})(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[\d\x])(?=.*[!$#%]).*$/'],
|
||||||
], [
|
], [
|
||||||
'uuid.required' => 'Please enter a valid (and Premium) Minecraft username! We do not support cracked users.',
|
'uuid.required' => 'Please enter a valid (and Premium) Minecraft username! We do not support cracked users.',
|
||||||
]);
|
]);
|
||||||
@@ -124,11 +104,11 @@ class RegisterController extends Controller
|
|||||||
'name' => $data['name'],
|
'name' => $data['name'],
|
||||||
'email' => $data['email'],
|
'email' => $data['email'],
|
||||||
'password' => Hash::make($data['password']),
|
'password' => Hash::make($data['password']),
|
||||||
'originalIP' => config('demo.is_enabled') ? '0.0.0.0' : request()->ip(),
|
'originalIP' => request()->ip(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// It's not the registration controller's concern to create a profile for the user,
|
// It's not the registration controller's concern to create a profile for the user,
|
||||||
// so this code has been moved to its respective observer, following the separation of concerns pattern.
|
// so this code has been moved to it's respective observer, following the separation of concerns pattern.
|
||||||
|
|
||||||
$user->assignRole('user');
|
$user->assignRole('user');
|
||||||
|
|
||||||
|
|||||||
0
app/Http/Controllers/Auth/ResetPasswordController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/ResetPasswordController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/TwofaController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/TwofaController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/VerificationController.php
Executable file → Normal file
0
app/Http/Controllers/Auth/VerificationController.php
Executable file → Normal file
73
app/Http/Controllers/BanController.php
Executable file → Normal file
73
app/Http/Controllers/BanController.php
Executable file → Normal file
@@ -24,41 +24,58 @@ namespace App\Http\Controllers;
|
|||||||
use App\Ban;
|
use App\Ban;
|
||||||
use App\Events\UserBannedEvent;
|
use App\Events\UserBannedEvent;
|
||||||
use App\Http\Requests\BanUserRequest;
|
use App\Http\Requests\BanUserRequest;
|
||||||
use App\Services\AccountSuspensionService;
|
|
||||||
use App\User;
|
use App\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class BanController extends Controller
|
class BanController extends Controller
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $suspensionService;
|
|
||||||
|
|
||||||
public function __construct(AccountSuspensionService $suspensionService)
|
|
||||||
{
|
|
||||||
// Inject the service via DI
|
|
||||||
$this->suspensionService = $suspensionService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function insert(BanUserRequest $request, User $user)
|
public function insert(BanUserRequest $request, User $user)
|
||||||
{
|
{
|
||||||
if (config('demo.is_enabled')) {
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', 'This feature is disabled');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->authorize('create', [Ban::class, $user]);
|
$this->authorize('create', [Ban::class, $user]);
|
||||||
|
|
||||||
|
if (is_null($user->bans)) {
|
||||||
|
$reason = $request->reason;
|
||||||
|
$duration = strtolower($request->durationOperator);
|
||||||
|
$durationOperand = $request->durationOperand;
|
||||||
|
|
||||||
if (!$this->suspensionService->isSuspended($user)) {
|
$expiryDate = now();
|
||||||
|
|
||||||
$this->suspensionService->suspend($request->reason, $request->duration, $user, $request->suspensionType);
|
if (! empty($duration)) {
|
||||||
$request->session()->flash('success', __('Account suspended.'));
|
switch ($duration) {
|
||||||
|
case 'days':
|
||||||
|
$expiryDate->addDays($durationOperand);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'weeks':
|
||||||
|
$expiryDate->addWeeks($durationOperand);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'months':
|
||||||
|
$expiryDate->addMonths($durationOperand);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'years':
|
||||||
|
$expiryDate->addYears($durationOperand);
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// Essentially permanent
|
||||||
|
$expiryDate->addYears(5);
|
||||||
|
}
|
||||||
|
|
||||||
$request->session()->flash('error', __('Account already suspended!'));
|
$ban = Ban::create([
|
||||||
|
'userID' => $user->id,
|
||||||
|
'reason' => $reason,
|
||||||
|
'bannedUntil' => $expiryDate->format('Y-m-d H:i:s'),
|
||||||
|
'userAgent' => 'Unknown',
|
||||||
|
'authorUserID' => Auth::user()->id,
|
||||||
|
]);
|
||||||
|
|
||||||
|
event(new UserBannedEvent($user, $ban));
|
||||||
|
$request->session()->flash('success', 'User banned successfully! Ban ID: #'.$ban->id);
|
||||||
|
} else {
|
||||||
|
$request->session()->flash('error', 'User already banned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
@@ -66,21 +83,13 @@ class BanController extends Controller
|
|||||||
|
|
||||||
public function delete(Request $request, User $user)
|
public function delete(Request $request, User $user)
|
||||||
{
|
{
|
||||||
if (config('demo.is_enabled')) {
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', 'This feature is disabled');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->authorize('delete', $user->bans);
|
$this->authorize('delete', $user->bans);
|
||||||
|
|
||||||
if ($this->suspensionService->isSuspended($user)) {
|
if (! is_null($user->bans)) {
|
||||||
|
$user->bans->delete();
|
||||||
$this->suspensionService->unsuspend($user);
|
$request->session()->flash('success', 'User unbanned successfully!');
|
||||||
$request->session()->flash('success', __('Account unsuspended successfully!'));
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$request->session()->flash('error', __('This account isn\'t suspended!'));
|
$request->session()->flash('error', 'This user isn\'t banned!');
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
|
|||||||
27
app/Http/Controllers/CommentController.php
Executable file → Normal file
27
app/Http/Controllers/CommentController.php
Executable file → Normal file
@@ -24,27 +24,30 @@ namespace App\Http\Controllers;
|
|||||||
use App\Application;
|
use App\Application;
|
||||||
use App\Comment;
|
use App\Comment;
|
||||||
use App\Http\Requests\NewCommentRequest;
|
use App\Http\Requests\NewCommentRequest;
|
||||||
use App\Services\CommentService;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
class CommentController extends Controller
|
class CommentController extends Controller
|
||||||
{
|
{
|
||||||
private $commentService;
|
public function index()
|
||||||
|
{
|
||||||
public function __construct(CommentService $commentService) {
|
//
|
||||||
$this->commentService = $commentService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function insert(NewCommentRequest $request, Application $application)
|
public function insert(NewCommentRequest $request, Application $application)
|
||||||
{
|
{
|
||||||
$this->authorize('create', Comment::class);
|
$this->authorize('create', Comment::class);
|
||||||
$comment = $this->commentService->addComment($application, $request->comment);
|
|
||||||
|
$comment = Comment::create([
|
||||||
|
'authorID' => Auth::user()->id,
|
||||||
|
'applicationID' => $application->id,
|
||||||
|
'text' => $request->comment,
|
||||||
|
]);
|
||||||
|
|
||||||
if ($comment) {
|
if ($comment) {
|
||||||
$request->session()->flash('success', __('Comment posted!'));
|
$request->session()->flash('success', 'Comment posted! (:');
|
||||||
} else {
|
} else {
|
||||||
$request->session()->flash('error', __('Something went wrong while posting your comment!'));
|
$request->session()->flash('error', 'Something went wrong while posting your comment!');
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
@@ -53,10 +56,10 @@ class CommentController extends Controller
|
|||||||
public function delete(Request $request, Comment $comment)
|
public function delete(Request $request, Comment $comment)
|
||||||
{
|
{
|
||||||
$this->authorize('delete', $comment);
|
$this->authorize('delete', $comment);
|
||||||
$this->commentService->deleteComment($comment);
|
|
||||||
|
|
||||||
return redirect()
|
$comment->delete();
|
||||||
->back()
|
$request->session()->flash('success', 'Comment deleted!');
|
||||||
->with('success', __('Comment deleted!'));
|
|
||||||
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
45
app/Http/Controllers/ContactController.php
Executable file → Normal file
45
app/Http/Controllers/ContactController.php
Executable file → Normal file
@@ -21,9 +21,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Exceptions\FailedCaptchaException;
|
|
||||||
use App\Notifications\NewContact;
|
use App\Notifications\NewContact;
|
||||||
use App\Services\ContactService;
|
|
||||||
use App\User;
|
use App\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Http;
|
use Illuminate\Support\Facades\Http;
|
||||||
@@ -32,32 +30,47 @@ class ContactController extends Controller
|
|||||||
{
|
{
|
||||||
protected $users;
|
protected $users;
|
||||||
|
|
||||||
private $contactService;
|
public function __construct(User $users)
|
||||||
|
|
||||||
public function __construct(User $users, ContactService $contactService)
|
|
||||||
{
|
{
|
||||||
$this->contactService = $contactService;
|
|
||||||
$this->users = $users;
|
$this->users = $users;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function create(Request $request)
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
try {
|
$name = $request->name;
|
||||||
|
|
||||||
$email = $request->email;
|
$email = $request->email;
|
||||||
|
$subject = $request->subject;
|
||||||
$msg = $request->msg;
|
$msg = $request->msg;
|
||||||
|
|
||||||
$challenge = $request->input('captcha');
|
$challenge = $request->input('captcha');
|
||||||
|
|
||||||
$this->contactService->sendMessage($request->ip(), $msg, $email, $challenge);
|
// TODO: now: add middleware for this verification, move to invisible captcha
|
||||||
|
$verifyrequest = Http::asForm()->post(config('recaptcha.verify.apiurl'), [
|
||||||
|
'secret' => config('recaptcha.keys.secret'),
|
||||||
|
'response' => $challenge,
|
||||||
|
'remoteip' => $request->ip(),
|
||||||
|
]);
|
||||||
|
|
||||||
return redirect()
|
$response = json_decode($verifyrequest->getBody(), true);
|
||||||
->back()
|
|
||||||
->with('success',__('Message sent successfully! We usually respond within 48 hours.'));
|
|
||||||
|
|
||||||
} catch (FailedCaptchaException $ex) {
|
if (! $response['success']) {
|
||||||
return redirect()
|
$request->session()->flash('error', 'Beep beep boop... Robot? Submission failed.');
|
||||||
->back()
|
|
||||||
->with('error', $ex->getMessage());
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (User::all() as $user) {
|
||||||
|
if ($user->hasRole('admin')) {
|
||||||
|
$user->notify(new NewContact(collect([
|
||||||
|
'message' => $msg,
|
||||||
|
'ip' => $request->ip(),
|
||||||
|
'email' => $email,
|
||||||
|
])));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$request->session()->flash('success', 'Message sent successfully! We usually respond within 48 hours.');
|
||||||
|
|
||||||
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
0
app/Http/Controllers/Controller.php
Executable file → Normal file
0
app/Http/Controllers/Controller.php
Executable file → Normal file
18
app/Http/Controllers/DashboardController.php
Executable file → Normal file
18
app/Http/Controllers/DashboardController.php
Executable file → Normal file
@@ -24,38 +24,22 @@ namespace App\Http\Controllers;
|
|||||||
use App\Application;
|
use App\Application;
|
||||||
use App\User;
|
use App\User;
|
||||||
use App\Vacancy;
|
use App\Vacancy;
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
|
|
||||||
class DashboardController extends Controller
|
class DashboardController extends Controller
|
||||||
{
|
{
|
||||||
// Note: The dashboard doesn't need a service because it doesn't contain any significant business logic
|
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$totalPeerReview = Application::where('applicationStatus', 'STAGE_PEERAPPROVAL')->get()->count();
|
$totalPeerReview = Application::where('applicationStatus', 'STAGE_PEERAPPROVAL')->get()->count();
|
||||||
$totalNewApplications = Application::where('applicationStatus', 'STAGE_SUBMITTED')->get()->count();
|
$totalNewApplications = Application::where('applicationStatus', 'STAGE_SUBMITTED')->get()->count();
|
||||||
$totalDenied = Application::where('applicationStatus', 'DENIED')->get()->count();
|
$totalDenied = Application::where('applicationStatus', 'DENIED')->get()->count();
|
||||||
$vacancies = Vacancy::where('vacancyStatus', '<>', 'CLOSED')->get();
|
|
||||||
|
|
||||||
$totalDeniedSingle = Application::where([
|
|
||||||
['applicationStatus', '=', 'DENIED'],
|
|
||||||
['applicantUserID', '=', Auth::user()->id]
|
|
||||||
])->get();
|
|
||||||
|
|
||||||
$totalNewSingle = Application::where([
|
|
||||||
['applicationStatus', '=', 'STAGE_SUBMITTED'],
|
|
||||||
['applicantUserID', '=', Auth::user()->id]
|
|
||||||
])->get();
|
|
||||||
|
|
||||||
return view('dashboard.dashboard')
|
return view('dashboard.dashboard')
|
||||||
->with([
|
->with([
|
||||||
'vacancies' => $vacancies,
|
'vacancies' => Vacancy::all(),
|
||||||
'totalUserCount' => User::all()->count(),
|
'totalUserCount' => User::all()->count(),
|
||||||
'totalDenied' => $totalDenied,
|
'totalDenied' => $totalDenied,
|
||||||
'totalPeerReview' => $totalPeerReview,
|
'totalPeerReview' => $totalPeerReview,
|
||||||
'totalNewApplications' => $totalNewApplications,
|
'totalNewApplications' => $totalNewApplications,
|
||||||
'totalNewSingle' => $totalNewSingle->count(),
|
|
||||||
'totalDeniedSingle' => $totalDeniedSingle->count()
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
6
app/Http/Controllers/DevToolsController.php
Executable file → Normal file
6
app/Http/Controllers/DevToolsController.php
Executable file → Normal file
@@ -32,7 +32,7 @@ class DevToolsController extends Controller
|
|||||||
protected function isolatedAuthorise()
|
protected function isolatedAuthorise()
|
||||||
{
|
{
|
||||||
if (! Auth::user()->can('admin.developertools.use')) {
|
if (! Auth::user()->can('admin.developertools.use')) {
|
||||||
abort(403, __('You\'re not authorized to access this page.'));
|
abort(403, 'You\'re not authorized to access this page.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,9 +52,9 @@ class DevToolsController extends Controller
|
|||||||
if (! is_null($application)) {
|
if (! is_null($application)) {
|
||||||
event(new ApplicationApprovedEvent($application));
|
event(new ApplicationApprovedEvent($application));
|
||||||
|
|
||||||
$request->session()->flash('success', __('Event dispatched! Please check the debug logs for more info'));
|
$request->session()->flash('success', 'Event dispatched! Please check the debug logs for more info');
|
||||||
} else {
|
} else {
|
||||||
$request->session()->flash('error', __('Application doesn\'t exist!'));
|
$request->session()->flash('error', 'Application doesn\'t exist!');
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
|
|||||||
94
app/Http/Controllers/FormController.php
Executable file → Normal file
94
app/Http/Controllers/FormController.php
Executable file → Normal file
@@ -21,21 +21,12 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Exceptions\EmptyFormException;
|
|
||||||
use App\Exceptions\FormHasConstraintsException;
|
|
||||||
use App\Form;
|
use App\Form;
|
||||||
use App\Services\FormManagementService;
|
|
||||||
use ContextAwareValidator;
|
use ContextAwareValidator;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
class FormController extends Controller
|
class FormController extends Controller
|
||||||
{
|
{
|
||||||
private $formService;
|
|
||||||
|
|
||||||
public function __construct(FormManagementService $formService) {
|
|
||||||
$this->formService = $formService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$forms = Form::all();
|
$forms = Form::all();
|
||||||
@@ -54,46 +45,50 @@ class FormController extends Controller
|
|||||||
|
|
||||||
public function saveForm(Request $request)
|
public function saveForm(Request $request)
|
||||||
{
|
{
|
||||||
try {
|
$this->authorize('create', Form::class);
|
||||||
$form = $this->formService->addForm($request->all());
|
$fields = $request->all();
|
||||||
}
|
|
||||||
catch (EmptyFormException $ex)
|
$contextValidation = ContextAwareValidator::getValidator($fields, true, true);
|
||||||
{
|
|
||||||
return redirect()
|
if (! $contextValidation->get('validator')->fails()) {
|
||||||
->back()
|
$storableFormStructure = $contextValidation->get('structure');
|
||||||
->with('exception', $ex->getMessage());
|
|
||||||
|
Form::create(
|
||||||
|
[
|
||||||
|
'formName' => $fields['formName'],
|
||||||
|
'formStructure' => $storableFormStructure,
|
||||||
|
'formStatus' => 'ACTIVE',
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
$request->session()->flash('success', 'Form created! You can now link this form to a vacancy.');
|
||||||
|
|
||||||
|
return redirect()->to(route('showForms'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Form is boolean or array
|
$request->session()->flash('errors', $contextValidation->get('validator')->errors()->getMessages());
|
||||||
if ($form)
|
|
||||||
{
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('success', __('Form created!'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()
|
return redirect()->back();
|
||||||
->back()
|
|
||||||
->with('errors', $form);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function destroy(Request $request, Form $form)
|
public function destroy(Request $request, Form $form)
|
||||||
{
|
{
|
||||||
$this->authorize('delete', $form);
|
$this->authorize('delete', $form);
|
||||||
try {
|
$deletable = true;
|
||||||
|
|
||||||
$this->formService->deleteForm($form);
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('success', __('Form deleted successfuly'));
|
|
||||||
|
|
||||||
} catch (FormHasConstraintsException $ex) {
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', $ex->getMessage());
|
|
||||||
|
|
||||||
|
if (! is_null($form) && ! is_null($form->vacancies) && $form->vacancies->count() !== 0 || ! is_null($form->responses)) {
|
||||||
|
$deletable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($deletable) {
|
||||||
|
$form->delete();
|
||||||
|
|
||||||
|
$request->session()->flash('success', 'Form deleted successfully.');
|
||||||
|
} else {
|
||||||
|
$request->session()->flash('error', 'You cannot delete this form because it\'s tied to one or more applications and ranks, or because it doesn\'t exist.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function preview(Request $request, Form $form)
|
public function preview(Request $request, Form $form)
|
||||||
@@ -119,15 +114,22 @@ class FormController extends Controller
|
|||||||
public function update(Request $request, Form $form)
|
public function update(Request $request, Form $form)
|
||||||
{
|
{
|
||||||
$this->authorize('update', $form);
|
$this->authorize('update', $form);
|
||||||
$updatedForm = $this->formService->updateForm($form, $request->all());
|
|
||||||
|
|
||||||
if ($updatedForm instanceof Form) {
|
$contextValidation = ContextAwareValidator::getValidator($request->all(), true);
|
||||||
return redirect()->to(route('previewForm', ['form' => $updatedForm->id]));
|
$this->authorize('update', $form);
|
||||||
|
|
||||||
|
if (! $contextValidation->get('validator')->fails()) {
|
||||||
|
// Add the new structure into the form. New, subsquent fields will be identified by the "new" prefix
|
||||||
|
// This prefix doesn't actually change the app's behavior when it receives applications.
|
||||||
|
// Additionally, old applications won't of course display new and updated fields, because we can't travel into the past and get data for them
|
||||||
|
$form->formStructure = $contextValidation->get('structure');
|
||||||
|
$form->save();
|
||||||
|
|
||||||
|
$request->session()->flash('success', 'Hooray! Your form was updated. New applications for it\'s vacancy will use it.');
|
||||||
|
} else {
|
||||||
|
$request->session()->flash('errors', $contextValidation->get('validator')->errors()->getMessages());
|
||||||
}
|
}
|
||||||
|
|
||||||
// array of errors
|
return redirect()->to(route('previewForm', ['form' => $form->id]));
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('errors', $updatedForm);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
app/Http/Controllers/HomeController.php
Executable file → Normal file
2
app/Http/Controllers/HomeController.php
Executable file → Normal file
@@ -25,8 +25,6 @@ use App\Vacancy;
|
|||||||
|
|
||||||
class HomeController extends Controller
|
class HomeController extends Controller
|
||||||
{
|
{
|
||||||
// doesn't need a service, because it doesn't contain major logic.
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the application dashboard.
|
* Show the application dashboard.
|
||||||
*
|
*
|
||||||
|
|||||||
96
app/Http/Controllers/OptionsController.php
Executable file → Normal file
96
app/Http/Controllers/OptionsController.php
Executable file → Normal file
@@ -21,25 +21,14 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Exceptions\InvalidGamePreferenceException;
|
|
||||||
use App\Exceptions\OptionNotFoundException;
|
|
||||||
use App\Facades\Options;
|
use App\Facades\Options;
|
||||||
use App\Options as Option;
|
use App\Options as Option;
|
||||||
use App\Services\ConfigurationService;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Auth;
|
use Illuminate\Support\Facades\Auth;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
|
|
||||||
class OptionsController extends Controller
|
class OptionsController extends Controller
|
||||||
{
|
{
|
||||||
private $configurationService;
|
|
||||||
|
|
||||||
public function __construct(ConfigurationService $configurationService) {
|
|
||||||
|
|
||||||
$this->configurationService = $configurationService;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display a listing of the resource.
|
* Display a listing of the resource.
|
||||||
*
|
*
|
||||||
@@ -47,59 +36,50 @@ class OptionsController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
// TODO: Replace with settings package
|
// TODO: Obtain this from the facade
|
||||||
|
$options = Option::all();
|
||||||
|
|
||||||
return view('dashboard.administration.settings')
|
return view('dashboard.administration.settings')
|
||||||
->with([
|
->with('options', $options);
|
||||||
'options' => Options::getCategory('notifications'),
|
|
||||||
'security' => [ // We could use the method above, but we need to set these names here for greater control in the template. This would nto be feasible for many options, we'd need to use a loop and the category method.
|
|
||||||
'secPolicy' => Options::getOption('pw_security_policy'),
|
|
||||||
'graceperiod' => Options::getOption('graceperiod'),
|
|
||||||
'pwExpiry' => Options::getOption('password_expiry'),
|
|
||||||
'requiresPMC' => Options::getOption('requireGameLicense'),
|
|
||||||
'enforce2fa' => Options::getOption('force2fa')
|
|
||||||
],
|
|
||||||
'currentGame' => Options::getOption('currentGame')
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function saveSettings(Request $request): \Illuminate\Http\RedirectResponse
|
public function saveSettings(Request $request)
|
||||||
{
|
{
|
||||||
try {
|
|
||||||
|
|
||||||
if (Auth::user()->can('admin.settings.edit')) {
|
if (Auth::user()->can('admin.settings.edit')) {
|
||||||
$this->configurationService->saveConfiguration($request->all());
|
Log::debug('Updating application options', [
|
||||||
|
'ip' => $request->ip(),
|
||||||
return redirect()
|
'ua' => $request->userAgent(),
|
||||||
->back()
|
'username' => Auth::user()->username,
|
||||||
->with('success', __('Options updated successfully!'));
|
]);
|
||||||
}
|
foreach ($request->all() as $optionName => $option) {
|
||||||
|
|
||||||
} catch (OptionNotFoundException | \Exception $ex) {
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', $ex->getMessage());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', __('You do not have permission to update this resource.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
public function saveGameIntegration(Request $request)
|
|
||||||
{
|
|
||||||
try {
|
try {
|
||||||
|
Log::debug('Going through option '.$optionName);
|
||||||
$this->configurationService->saveGameIntegration($request->gamePref);
|
if (Options::optionExists($optionName)) {
|
||||||
return redirect()
|
Log::debug('Option exists, updating to new values', [
|
||||||
->back()
|
'opt' => $optionName,
|
||||||
->with('success', __('Game preference updated.'));
|
'new_value' => $option,
|
||||||
|
]);
|
||||||
} catch (InvalidGamePreferenceException $ex) {
|
Options::changeOption($optionName, $option);
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', $ex->getMessage());
|
|
||||||
}
|
}
|
||||||
|
} catch (\Exception $ex) {
|
||||||
|
Log::error('Unable to update options!', [
|
||||||
|
'msg' => $ex->getMessage(),
|
||||||
|
'trace' => $ex->getTraceAsString(),
|
||||||
|
]);
|
||||||
|
report($ex);
|
||||||
|
|
||||||
|
$errorCond = true;
|
||||||
|
$request->session()->flash('error', 'An error occurred while trying to save settings: '.$ex->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! isset($errorCond)) {
|
||||||
|
$request->session()->flash('success', 'Settings saved successfully!');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$request->session()->flash('error', 'You do not have permission to update this resource.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
60
app/Http/Controllers/ProfileController.php
Executable file → Normal file
60
app/Http/Controllers/ProfileController.php
Executable file → Normal file
@@ -23,7 +23,6 @@ namespace App\Http\Controllers;
|
|||||||
|
|
||||||
use App\Facades\IP;
|
use App\Facades\IP;
|
||||||
use App\Http\Requests\ProfileSave;
|
use App\Http\Requests\ProfileSave;
|
||||||
use App\Services\ProfileService;
|
|
||||||
use App\User;
|
use App\User;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -32,12 +31,6 @@ use Spatie\Permission\Models\Role;
|
|||||||
|
|
||||||
class ProfileController extends Controller
|
class ProfileController extends Controller
|
||||||
{
|
{
|
||||||
private $profileService;
|
|
||||||
|
|
||||||
public function __construct(ProfileService $profileService) {
|
|
||||||
$this->profileService = $profileService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
return view('dashboard.user.directory')
|
return view('dashboard.user.directory')
|
||||||
@@ -46,7 +39,6 @@ class ProfileController extends Controller
|
|||||||
|
|
||||||
public function showProfile()
|
public function showProfile()
|
||||||
{
|
{
|
||||||
// TODO: Come up with cleaner social media solution, e.g. social media object
|
|
||||||
$socialLinks = Auth::user()->profile->socialLinks ?? '[]';
|
$socialLinks = Auth::user()->profile->socialLinks ?? '[]';
|
||||||
$socialMediaProfiles = json_decode($socialLinks, true);
|
$socialMediaProfiles = json_decode($socialLinks, true);
|
||||||
|
|
||||||
@@ -60,7 +52,8 @@ class ProfileController extends Controller
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function showSingleProfile(User $user)
|
// Route model binding
|
||||||
|
public function showSingleProfile(Request $request, User $user)
|
||||||
{
|
{
|
||||||
$socialMediaProfiles = json_decode($user->profile->socialLinks, true);
|
$socialMediaProfiles = json_decode($user->profile->socialLinks, true);
|
||||||
$createdDate = Carbon::parse($user->created_at);
|
$createdDate = Carbon::parse($user->created_at);
|
||||||
@@ -78,17 +71,6 @@ class ProfileController extends Controller
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$suspensionInfo = null;
|
|
||||||
if ($user->isBanned())
|
|
||||||
{
|
|
||||||
$suspensionInfo = [
|
|
||||||
|
|
||||||
'isPermanent' => $user->bans->isPermanent,
|
|
||||||
'reason' => $user->bans->reason,
|
|
||||||
'bannedUntil' => $user->bans->bannedUntil
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Auth::user()->is($user) || Auth::user()->can('profiles.view.others')) {
|
if (Auth::user()->is($user) || Auth::user()->can('profiles.view.others')) {
|
||||||
return view('dashboard.user.profile.displayprofile')
|
return view('dashboard.user.profile.displayprofile')
|
||||||
->with([
|
->with([
|
||||||
@@ -100,18 +82,44 @@ class ProfileController extends Controller
|
|||||||
'since' => $createdDate->englishMonth.' '.$createdDate->year,
|
'since' => $createdDate->englishMonth.' '.$createdDate->year,
|
||||||
'ipInfo' => IP::lookup($user->originalIP),
|
'ipInfo' => IP::lookup($user->originalIP),
|
||||||
'roles' => $roleList,
|
'roles' => $roleList,
|
||||||
'suspensionInfo' => $suspensionInfo
|
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
abort(403, __('You cannot view someone else\'s profile.'));
|
abort(403, 'You cannot view someone else\'s profile.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function saveProfile(ProfileSave $request)
|
public function saveProfile(ProfileSave $request)
|
||||||
{
|
{
|
||||||
$this->profileService->updateProfile(Auth::user()->id, $request);
|
$profile = User::find(Auth::user()->id)->profile;
|
||||||
return redirect()
|
$social = [];
|
||||||
->back()
|
|
||||||
->with('success', __('Profile updated.'));
|
if (! is_null($profile)) {
|
||||||
|
switch ($request->avatarPref) {
|
||||||
|
case 'MOJANG':
|
||||||
|
$avatarPref = 'crafatar';
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'GRAVATAR':
|
||||||
|
$avatarPref = strtolower($request->avatarPref);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
$social['links']['github'] = $request->socialGithub;
|
||||||
|
$social['links']['twitter'] = $request->socialTwitter;
|
||||||
|
$social['links']['insta'] = $request->socialInsta;
|
||||||
|
$social['links']['discord'] = $request->socialDiscord;
|
||||||
|
|
||||||
|
$profile->profileShortBio = $request->shortBio;
|
||||||
|
$profile->profileAboutMe = $request->aboutMe;
|
||||||
|
$profile->avatarPreference = $avatarPref;
|
||||||
|
$profile->socialLinks = json_encode($social);
|
||||||
|
|
||||||
|
$newProfile = $profile->save();
|
||||||
|
|
||||||
|
$request->session()->flash('success', 'Profile settings saved successfully.');
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
25
app/Team.php → app/Http/Controllers/ResponseController.php
Executable file → Normal file
25
app/Team.php → app/Http/Controllers/ResponseController.php
Executable file → Normal file
@@ -19,28 +19,9 @@
|
|||||||
* along with Raspberry Staff Manager. If not, see <https://www.gnu.org/licenses/>.
|
* along with Raspberry Staff Manager. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace App;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use Mpociot\Teamwork\TeamworkTeam;
|
class ResponseController extends Controller
|
||||||
|
|
||||||
class Team extends TeamworkTeam
|
|
||||||
{
|
{
|
||||||
public $fillable = [
|
//
|
||||||
'owner_id',
|
|
||||||
'name',
|
|
||||||
'description',
|
|
||||||
'openJoin',
|
|
||||||
];
|
|
||||||
|
|
||||||
public function vacancies()
|
|
||||||
{
|
|
||||||
return $this->belongsToMany('App\Vacancy', 'team_has_vacancy');
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public function files()
|
|
||||||
{
|
|
||||||
return $this->hasMany('App\TeamFile', 'team_id');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use App\Facades\Options;
|
|
||||||
use App\Http\Requests\SaveSecuritySettings;
|
|
||||||
use App\Services\SecuritySettingsService;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
|
|
||||||
use function PHPSTORM_META\map;
|
|
||||||
|
|
||||||
class SecuritySettingsController extends Controller
|
|
||||||
{
|
|
||||||
private $securityService;
|
|
||||||
|
|
||||||
public function __construct(SecuritySettingsService $securityService) {
|
|
||||||
$this->securityService = $securityService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function save(SaveSecuritySettings $request)
|
|
||||||
{
|
|
||||||
$this->securityService->save($request->secPolicy, [
|
|
||||||
'graceperiod' => $request->graceperiod,
|
|
||||||
'pwExpiry' => $request->pwExpiry,
|
|
||||||
'enforce2fa' => $request->enforce2fa,
|
|
||||||
'requirePMC' => $request->requirePMC
|
|
||||||
]);
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('success', __('Settings saved.'));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
28
app/Http/Requests/SendInviteRequest.php → app/Http/Controllers/StaffProfileController.php
Executable file → Normal file
28
app/Http/Requests/SendInviteRequest.php → app/Http/Controllers/StaffProfileController.php
Executable file → Normal file
@@ -19,31 +19,9 @@
|
|||||||
* along with Raspberry Staff Manager. If not, see <https://www.gnu.org/licenses/>.
|
* along with Raspberry Staff Manager. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace App\Http\Requests;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use Illuminate\Foundation\Http\FormRequest;
|
class StaffProfileController extends Controller
|
||||||
|
|
||||||
class SendInviteRequest extends FormRequest
|
|
||||||
{
|
{
|
||||||
/**
|
//
|
||||||
* Determine if the user is authorized to make this request.
|
|
||||||
*
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function authorize()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the validation rules that apply to the request.
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function rules()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'user' => 'required|integer',
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,199 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Copyright © 2020 Miguel Nogueira
|
|
||||||
*
|
|
||||||
* This file is part of Raspberry Staff Manager.
|
|
||||||
*
|
|
||||||
* Raspberry Staff Manager is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* Raspberry Staff Manager is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with Raspberry Staff Manager. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
use App\Exceptions\InvalidInviteException;
|
|
||||||
use App\Exceptions\PublicTeamInviteException;
|
|
||||||
use App\Exceptions\UserAlreadyInvitedException;
|
|
||||||
use App\Http\Requests\EditTeamRequest;
|
|
||||||
use App\Http\Requests\NewTeamRequest;
|
|
||||||
use App\Http\Requests\SendInviteRequest;
|
|
||||||
use App\Mail\InviteToTeam;
|
|
||||||
use App\Services\TeamService;
|
|
||||||
use App\Team;
|
|
||||||
use App\User;
|
|
||||||
use App\Vacancy;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
use Illuminate\Support\Facades\Mail;
|
|
||||||
use Mpociot\Teamwork\Exceptions\UserNotInTeamException;
|
|
||||||
use Mpociot\Teamwork\Facades\Teamwork;
|
|
||||||
use Mpociot\Teamwork\TeamInvite;
|
|
||||||
|
|
||||||
class TeamController extends Controller
|
|
||||||
{
|
|
||||||
private $teamService;
|
|
||||||
|
|
||||||
public function __construct(TeamService $teamService) {
|
|
||||||
$this->teamService = $teamService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display a listing of the resource.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public function index()
|
|
||||||
{
|
|
||||||
$this->authorize('index', Team::class);
|
|
||||||
|
|
||||||
$teams = Team::with('users.roles')->get();
|
|
||||||
|
|
||||||
return view('dashboard.teams.teams')
|
|
||||||
->with('teams', $teams);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store a newly created resource in storage.
|
|
||||||
*
|
|
||||||
* @param NewTeamRequest $request
|
|
||||||
* @return RedirectResponse
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
*/
|
|
||||||
public function store(NewTeamRequest $request)
|
|
||||||
{
|
|
||||||
$this->authorize('create', Team::class);
|
|
||||||
$this->teamService->createTeam($request->teamName, Auth::user()->id);
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('success', __('Team successfully created.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Show the form for editing the specified resource.
|
|
||||||
*
|
|
||||||
* @param Team $team
|
|
||||||
* @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Http\Response
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
*/
|
|
||||||
public function edit(Team $team)
|
|
||||||
{
|
|
||||||
$this->authorize('update', $team);
|
|
||||||
return view('dashboard.teams.edit-team')
|
|
||||||
->with([
|
|
||||||
'team' => $team,
|
|
||||||
'users' => User::all(),
|
|
||||||
'vacancies' => Vacancy::with('teams')->get()->all()
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the specified resource in storage.
|
|
||||||
*
|
|
||||||
* @param EditTeamRequest $request
|
|
||||||
* @param Team $team
|
|
||||||
* @return RedirectResponse
|
|
||||||
* @throws \Illuminate\Auth\Access\AuthorizationException
|
|
||||||
*/
|
|
||||||
public function update(EditTeamRequest $request, Team $team): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->authorize('update', $team);
|
|
||||||
$team = $this->teamService->updateTeam($team, $request->teamDescription, $team->joinType);
|
|
||||||
|
|
||||||
|
|
||||||
if ($team) {
|
|
||||||
return redirect()
|
|
||||||
->to(route('teams.index'))
|
|
||||||
->with('success', __('Team updated.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', __('An error ocurred while trying to update this team.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the specified resource from storage.
|
|
||||||
*
|
|
||||||
* @param int $id
|
|
||||||
* @return \Illuminate\Http\Response
|
|
||||||
*/
|
|
||||||
public function destroy($id)
|
|
||||||
{
|
|
||||||
// wip
|
|
||||||
}
|
|
||||||
|
|
||||||
public function invite(SendInviteRequest $request, Team $team): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->authorize('invite', $team);
|
|
||||||
|
|
||||||
try {
|
|
||||||
|
|
||||||
$this->teamService->inviteUser($team, $request->user);
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('success', __('User invited successfully!'));
|
|
||||||
|
|
||||||
} catch (UserAlreadyInvitedException | PublicTeamInviteException $ex) {
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', $ex->getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processInviteAction(Request $request, $action, $token): RedirectResponse
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
|
|
||||||
$this->teamService->processInvite(Auth::user(), $action, $token);
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->to(route('teams.index'))
|
|
||||||
->with('success', __('Invite processed successfully!'));
|
|
||||||
|
|
||||||
} catch (InvalidInviteException $e) {
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', $e->getMessage());
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function switchTeam(Request $request, Team $team): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->authorize('switchTeam', $team);
|
|
||||||
|
|
||||||
try {
|
|
||||||
Auth::user()->switchTeam($team);
|
|
||||||
|
|
||||||
$request->session()->flash('success', __('Switched teams! Your team dashboard will now use this context.'));
|
|
||||||
} catch (UserNotInTeamException $ex) {
|
|
||||||
$request->session()->flash('error', __('You can\'t switch to a team you don\'t belong to.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Since it's a separate form, we shouldn't use the same update method
|
|
||||||
public function assignVacancies(Request $request, Team $team): RedirectResponse
|
|
||||||
{
|
|
||||||
$this->authorize('update', $team);
|
|
||||||
$message = $this->teamService->updateVacancies($team, $request->assocVacancies);
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('success', $message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,141 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Controllers;
|
|
||||||
|
|
||||||
// Most of these namespaces have no effect on the code, however, they're used by IDEs so they can resolve return types and for PHPDocumentor as well
|
|
||||||
|
|
||||||
|
|
||||||
use App\Exceptions\FileUploadException;
|
|
||||||
use App\Services\TeamFileService;
|
|
||||||
use App\TeamFile;
|
|
||||||
use App\Http\Requests\UploadFileRequest;
|
|
||||||
|
|
||||||
|
|
||||||
use Illuminate\Support\Facades\Auth;
|
|
||||||
use Illuminate\Support\Facades\Storage;
|
|
||||||
use League\Flysystem\FileNotFoundException;
|
|
||||||
// Documentation-purpose namespaces
|
|
||||||
use Illuminate\Contracts\Foundation\Application;
|
|
||||||
use Illuminate\Contts\View\Factory;
|
|
||||||
use Illuminate\Contracts\View\View;
|
|
||||||
use Illuminate\Http\RedirectResponse;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Http\Response;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class TeamFileController extends Controller
|
|
||||||
{
|
|
||||||
private $fileService;
|
|
||||||
|
|
||||||
public function __construct(TeamFileService $fileService) {
|
|
||||||
$this->fileService = $fileService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display a listing of the resource.
|
|
||||||
*
|
|
||||||
* @param Request $request
|
|
||||||
*/
|
|
||||||
public function index(Request $request)
|
|
||||||
{
|
|
||||||
$this->authorize('index', TeamFile::class);
|
|
||||||
|
|
||||||
if (is_null(Auth::user()->currentTeam))
|
|
||||||
{
|
|
||||||
$request->session()->flash('error', 'Please choose a team before viewing it\'s files.');
|
|
||||||
return redirect()->to(route('teams.index'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return view('dashboard.teams.team-files')
|
|
||||||
->with('files', TeamFile::with('team', 'uploader')->paginate(6));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Store a newly created resource in storage.
|
|
||||||
*
|
|
||||||
* @param UploadFileRequest $request
|
|
||||||
* @return RedirectResponse
|
|
||||||
*/
|
|
||||||
public function store(UploadFileRequest $request)
|
|
||||||
{
|
|
||||||
$this->authorize('store', TeamFile::class);
|
|
||||||
|
|
||||||
if (config('demo.is_enabled'))
|
|
||||||
{
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', 'This feature is disabled');
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$caption = $request->caption;
|
|
||||||
$description = $request->description;
|
|
||||||
|
|
||||||
$this->fileService->addFile($request->file('file'), Auth::user()->id, Auth::user()->currentTeam->id, $caption, $description);
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('success', __('File uploaded successfully.'));
|
|
||||||
|
|
||||||
} catch (FileUploadException $uploadException) {
|
|
||||||
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', $uploadException->getMessage());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function download(Request $request, TeamFile $teamFile)
|
|
||||||
{
|
|
||||||
$this->authorize('download', TeamFile::class);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return Storage::download($teamFile->fs_location, $teamFile->name);
|
|
||||||
}
|
|
||||||
catch (FileNotFoundException $ex)
|
|
||||||
{
|
|
||||||
$request->session()->flash('error', 'Sorry, but the requested file could not be found in storage. Sometimes, files may be physically deleted by admins, but not from the app\'s database.');
|
|
||||||
return redirect()->back();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the specified resource from storage.
|
|
||||||
*
|
|
||||||
* @param Request $request
|
|
||||||
* @param \App\TeamFile $teamFile
|
|
||||||
* @return RedirectResponse
|
|
||||||
*/
|
|
||||||
public function destroy(Request $request, TeamFile $teamFile)
|
|
||||||
{
|
|
||||||
$this->authorize('delete', $teamFile);
|
|
||||||
|
|
||||||
if (config('demo.is_enabled'))
|
|
||||||
{
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', 'This feature is disabled');
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Storage::delete($teamFile->fs_location);
|
|
||||||
$teamFile->delete();
|
|
||||||
|
|
||||||
$request->session()->flash('success', __('File deleted successfully.'));
|
|
||||||
}
|
|
||||||
catch (\Exception $ex)
|
|
||||||
{
|
|
||||||
$request->session()->flash('error', __('There was an error deleting the file: :msg', ['msg' => $ex->getMessage()]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return redirect()->back();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
67
app/Http/Controllers/UserController.php
Executable file → Normal file
67
app/Http/Controllers/UserController.php
Executable file → Normal file
@@ -32,8 +32,6 @@ use App\Http\Requests\SearchPlayerRequest;
|
|||||||
use App\Http\Requests\UpdateUserRequest;
|
use App\Http\Requests\UpdateUserRequest;
|
||||||
use App\Notifications\ChangedPassword;
|
use App\Notifications\ChangedPassword;
|
||||||
use App\Notifications\EmailChanged;
|
use App\Notifications\EmailChanged;
|
||||||
use App\Traits\DisablesFeatures;
|
|
||||||
use App\Traits\ReceivesAccountTokens;
|
|
||||||
use App\User;
|
use App\User;
|
||||||
use Google2FA;
|
use Google2FA;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -44,8 +42,6 @@ use Spatie\Permission\Models\Role;
|
|||||||
|
|
||||||
class UserController extends Controller
|
class UserController extends Controller
|
||||||
{
|
{
|
||||||
use ReceivesAccountTokens;
|
|
||||||
|
|
||||||
public function showStaffMembers()
|
public function showStaffMembers()
|
||||||
{
|
{
|
||||||
$this->authorize('viewStaff', User::class);
|
$this->authorize('viewStaff', User::class);
|
||||||
@@ -111,7 +107,7 @@ class UserController extends Controller
|
|||||||
->get();
|
->get();
|
||||||
|
|
||||||
if (! $matchingUsers->isEmpty()) {
|
if (! $matchingUsers->isEmpty()) {
|
||||||
$request->session()->flash('success', __('There were :usersCount user(s) matching your search.', ['usersCount' => $matchingUsers->count()]));
|
$request->session()->flash('success', 'There were '.$matchingUsers->count().' user(s) matching your search.');
|
||||||
|
|
||||||
return view('dashboard.administration.players')
|
return view('dashboard.administration.players')
|
||||||
->with([
|
->with([
|
||||||
@@ -119,7 +115,7 @@ class UserController extends Controller
|
|||||||
'bannedUserCount' => Ban::all()->count(),
|
'bannedUserCount' => Ban::all()->count(),
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
$request->session()->flash('error', __('Your search term did not return any results.'));
|
$request->session()->flash('error', 'Your search term did not return any results.');
|
||||||
|
|
||||||
return redirect(route('registeredPlayerList'));
|
return redirect(route('registeredPlayerList'));
|
||||||
}
|
}
|
||||||
@@ -162,24 +158,17 @@ class UserController extends Controller
|
|||||||
'timestamp' => now(),
|
'timestamp' => now(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$request->session()->flash('success', __('Successfully logged out other devices. Remember to change your password if you think you\'ve been compromised.'));
|
$request->session()->flash('success', 'Successfully logged out other devices. Remember to change your password if you think you\'ve been compromised.');
|
||||||
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function changePassword(ChangePasswordRequest $request)
|
public function changePassword(ChangePasswordRequest $request)
|
||||||
{
|
{
|
||||||
if (config('demo.is_enabled')) {
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', 'This feature is disabled');
|
|
||||||
}
|
|
||||||
$user = User::find(Auth::user()->id);
|
$user = User::find(Auth::user()->id);
|
||||||
|
|
||||||
if (! is_null($user)) {
|
if (! is_null($user)) {
|
||||||
$user->password = Hash::make($request->newPassword);
|
$user->password = Hash::make($request->newPassword);
|
||||||
$user->password_last_updated = now();
|
|
||||||
|
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
||||||
Log::info('User '.$user->name.' has changed their password', [
|
Log::info('User '.$user->name.' has changed their password', [
|
||||||
@@ -197,12 +186,6 @@ class UserController extends Controller
|
|||||||
|
|
||||||
public function changeEmail(ChangeEmailRequest $request)
|
public function changeEmail(ChangeEmailRequest $request)
|
||||||
{
|
{
|
||||||
if (config('demo.is_enabled')) {
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', 'This feature is disabled');
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = User::find(Auth::user()->id);
|
$user = User::find(Auth::user()->id);
|
||||||
|
|
||||||
if (! is_null($user)) {
|
if (! is_null($user)) {
|
||||||
@@ -216,9 +199,9 @@ class UserController extends Controller
|
|||||||
]);
|
]);
|
||||||
$user->notify(new EmailChanged());
|
$user->notify(new EmailChanged());
|
||||||
|
|
||||||
$request->session()->flash('success', __('Your email address has been changed!'));
|
$request->session()->flash('success', 'Your email address has been changed!');
|
||||||
} else {
|
} else {
|
||||||
$request->session()->flash('error', __('There has been an error whilst trying to update your account. Please contact administrators.'));
|
$request->session()->flash('error', 'There has been an error whilst trying to update your account. Please contact administrators.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
@@ -226,19 +209,13 @@ class UserController extends Controller
|
|||||||
|
|
||||||
public function delete(DeleteUserRequest $request, User $user)
|
public function delete(DeleteUserRequest $request, User $user)
|
||||||
{
|
{
|
||||||
if (config('demo.is_enabled')) {
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', 'This feature is disabled');
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->authorize('delete', $user);
|
$this->authorize('delete', $user);
|
||||||
|
|
||||||
if ($request->confirmPrompt == 'DELETE ACCOUNT') {
|
if ($request->confirmPrompt == 'DELETE ACCOUNT') {
|
||||||
$user->forceDelete();
|
$user->delete();
|
||||||
$request->session()->flash('success', __('User deleted successfully.'));
|
$request->session()->flash('success', 'User deleted successfully. PII has been erased.');
|
||||||
} else {
|
} else {
|
||||||
$request->session()->flash('error', __('Wrong confirmation text! Try again.'));
|
$request->session()->flash('error', 'Wrong confirmation text! Try again.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()->route('registeredPlayerList');
|
return redirect()->route('registeredPlayerList');
|
||||||
@@ -246,11 +223,6 @@ class UserController extends Controller
|
|||||||
|
|
||||||
public function update(UpdateUserRequest $request, User $user)
|
public function update(UpdateUserRequest $request, User $user)
|
||||||
{
|
{
|
||||||
if (config('demo.is_enabled')) {
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', 'This feature is disabled');
|
|
||||||
}
|
|
||||||
$this->authorize('adminEdit', $user);
|
$this->authorize('adminEdit', $user);
|
||||||
|
|
||||||
// Mass update would not be possible here without extra code, making route model binding useless
|
// Mass update would not be possible here without extra code, making route model binding useless
|
||||||
@@ -278,19 +250,13 @@ class UserController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
$user->save();
|
$user->save();
|
||||||
$request->session()->flash('success', __('User updated successfully!'));
|
$request->session()->flash('success', 'User updated successfully!');
|
||||||
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function add2FASecret(Add2FASecretRequest $request)
|
public function add2FASecret(Add2FASecretRequest $request)
|
||||||
{
|
{
|
||||||
if (config('demo.is_enabled')) {
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', 'This feature is disabled');
|
|
||||||
}
|
|
||||||
|
|
||||||
$currentSecret = $request->session()->get('current2FA');
|
$currentSecret = $request->session()->get('current2FA');
|
||||||
$isValid = Google2FA::verifyKey($currentSecret, $request->otp);
|
$isValid = Google2FA::verifyKey($currentSecret, $request->otp);
|
||||||
|
|
||||||
@@ -316,9 +282,9 @@ class UserController extends Controller
|
|||||||
$request->session()->forget('twofaAttemptFailed');
|
$request->session()->forget('twofaAttemptFailed');
|
||||||
}
|
}
|
||||||
|
|
||||||
$request->session()->flash('success', __('2FA succesfully enabled! You\'ll now be prompted for an OTP each time you log in.'));
|
$request->session()->flash('success', '2FA succesfully enabled! You\'ll now be prompted for an OTP each time you log in.');
|
||||||
} else {
|
} else {
|
||||||
$request->session()->flash('error', __('Incorrect code. Please reopen the 2FA settings panel and try again.'));
|
$request->session()->flash('error', 'Incorrect code. Please reopen the 2FA settings panel and try again.');
|
||||||
$request->session()->put('twofaAttemptFailed', true);
|
$request->session()->put('twofaAttemptFailed', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,7 +301,7 @@ class UserController extends Controller
|
|||||||
$request->user()->twofa_secret = null;
|
$request->user()->twofa_secret = null;
|
||||||
$request->user()->save();
|
$request->user()->save();
|
||||||
|
|
||||||
$request->session()->flash('success', __('Two-factor authentication disabled.'));
|
$request->session()->flash('success', 'Two-factor authentication disabled.');
|
||||||
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
@@ -343,15 +309,10 @@ class UserController extends Controller
|
|||||||
public function terminate(Request $request, User $user)
|
public function terminate(Request $request, User $user)
|
||||||
{
|
{
|
||||||
$this->authorize('terminate', User::class);
|
$this->authorize('terminate', User::class);
|
||||||
if (config('demo.is_enabled')) {
|
|
||||||
return redirect()
|
|
||||||
->back()
|
|
||||||
->with('error', 'This feature is disabled');
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: move logic to policy
|
// TODO: move logic to policy
|
||||||
if (! $user->isStaffMember() || $user->is(Auth::user())) {
|
if (! $user->isStaffMember() || $user->is(Auth::user())) {
|
||||||
$request->session()->flash('error', __('You cannot terminate this user.'));
|
$request->session()->flash('error', 'You cannot terminate this user.');
|
||||||
|
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
@@ -365,7 +326,7 @@ class UserController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
Log::info('User '.$user->name.' has just been demoted.');
|
Log::info('User '.$user->name.' has just been demoted.');
|
||||||
$request->session()->flash('success', __('User terminated successfully.'));
|
$request->session()->flash('success', 'User terminated successfully.');
|
||||||
|
|
||||||
//TODO: Dispatch event
|
//TODO: Dispatch event
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
|
|||||||
34
app/Http/Controllers/VacancyController.php
Executable file → Normal file
34
app/Http/Controllers/VacancyController.php
Executable file → Normal file
@@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Facades\JSON;
|
|
||||||
use App\Form;
|
use App\Form;
|
||||||
use App\Http\Requests\VacancyEditRequest;
|
use App\Http\Requests\VacancyEditRequest;
|
||||||
use App\Http\Requests\VacancyRequest;
|
use App\Http\Requests\VacancyRequest;
|
||||||
@@ -46,11 +45,7 @@ class VacancyController extends Controller
|
|||||||
|
|
||||||
public function store(VacancyRequest $request)
|
public function store(VacancyRequest $request)
|
||||||
{
|
{
|
||||||
$messageIsError = false;
|
|
||||||
$this->authorize('create', Vacancy::class);
|
$this->authorize('create', Vacancy::class);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$form = Form::find($request->vacancyFormID);
|
$form = Form::find($request->vacancyFormID);
|
||||||
|
|
||||||
if (! is_null($form)) {
|
if (! is_null($form)) {
|
||||||
@@ -72,16 +67,12 @@ class VacancyController extends Controller
|
|||||||
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$message = __('Vacancy successfully opened. It will now show in the home page.');
|
$request->session()->flash('success', 'Vacancy successfully opened. It will now show in the home page.');
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
$message = __('You cannot create a vacancy without a valid form.');
|
$request->session()->flash('error', 'You cannot create a vacancy without a valid form.');
|
||||||
$messageIsError = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()
|
return redirect()->back();
|
||||||
->back()
|
|
||||||
->with(($messageIsError) ? 'error' : 'success', $message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function updatePositionAvailability(Request $request, $status, Vacancy $vacancy)
|
public function updatePositionAvailability(Request $request, $status, Vacancy $vacancy)
|
||||||
@@ -94,13 +85,13 @@ class VacancyController extends Controller
|
|||||||
switch ($status) {
|
switch ($status) {
|
||||||
case 'open':
|
case 'open':
|
||||||
$vacancy->open();
|
$vacancy->open();
|
||||||
$message = __('Position successfully opened!');
|
$message = 'Position successfully opened!';
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'close':
|
case 'close':
|
||||||
$vacancy->close();
|
$vacancy->close();
|
||||||
$message = __('Position successfully closed!');
|
$message = 'Position successfully closed!';
|
||||||
|
|
||||||
foreach (User::all() as $user) {
|
foreach (User::all() as $user) {
|
||||||
if ($user->isStaffMember()) {
|
if ($user->isStaffMember()) {
|
||||||
@@ -110,19 +101,18 @@ class VacancyController extends Controller
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$message = __("Please do not tamper with the URLs. To report a bug, please contact an administrator.");
|
$message = "Please do not tamper with the button's URLs. To report a bug, please contact an administrator.";
|
||||||
$type = 'error';
|
$type = 'error';
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$message = __("The position you're trying to update doesn't exist!");
|
$message = "The position you're trying to update doesn't exist!";
|
||||||
$type = 'error';
|
$type = 'error';
|
||||||
}
|
}
|
||||||
|
|
||||||
return redirect()
|
$request->session()->flash($type, $message);
|
||||||
->back()
|
|
||||||
->with($type, $message);
|
|
||||||
|
|
||||||
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function edit(Request $request, Vacancy $vacancy)
|
public function edit(Request $request, Vacancy $vacancy)
|
||||||
@@ -143,8 +133,8 @@ class VacancyController extends Controller
|
|||||||
|
|
||||||
$vacancy->save();
|
$vacancy->save();
|
||||||
|
|
||||||
return redirect()
|
$request->session()->flash('success', 'Vacancy successfully updated.');
|
||||||
->back()
|
|
||||||
->with('success', __('Vacancy successfully updated.'));
|
return redirect()->back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
app/Http/Controllers/VoteController.php
Executable file → Normal file
2
app/Http/Controllers/VoteController.php
Executable file → Normal file
@@ -42,7 +42,7 @@ class VoteController extends Controller
|
|||||||
Log::info('User '.Auth::user()->name.' has voted in applicant '.$application->user->name.'\'s application', [
|
Log::info('User '.Auth::user()->name.' has voted in applicant '.$application->user->name.'\'s application', [
|
||||||
'voteType' => $voteRequest->voteType,
|
'voteType' => $voteRequest->voteType,
|
||||||
]);
|
]);
|
||||||
$voteRequest->session()->flash('success', __('Your vote has been counted!'));
|
$voteRequest->session()->flash('success', 'Your vote has been registered!');
|
||||||
|
|
||||||
// Cron job will run command that processes votes
|
// Cron job will run command that processes votes
|
||||||
return redirect()->back();
|
return redirect()->back();
|
||||||
|
|||||||
4
app/Http/Kernel.php
Executable file → Normal file
4
app/Http/Kernel.php
Executable file → Normal file
@@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
namespace App\Http;
|
namespace App\Http;
|
||||||
|
|
||||||
use App\Http\Middleware\APIAuthenticationMiddleware;
|
|
||||||
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||||
|
|
||||||
class Kernel extends HttpKernel
|
class Kernel extends HttpKernel
|
||||||
@@ -61,7 +60,6 @@ class Kernel extends HttpKernel
|
|||||||
'api' => [
|
'api' => [
|
||||||
'throttle:60,1',
|
'throttle:60,1',
|
||||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||||
APIAuthenticationMiddleware::class
|
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -87,8 +85,6 @@ class Kernel extends HttpKernel
|
|||||||
'usernameUUID' => \App\Http\Middleware\UsernameUUID::class,
|
'usernameUUID' => \App\Http\Middleware\UsernameUUID::class,
|
||||||
'forcelogout' => \App\Http\Middleware\ForceLogoutMiddleware::class,
|
'forcelogout' => \App\Http\Middleware\ForceLogoutMiddleware::class,
|
||||||
'2fa' => \PragmaRX\Google2FALaravel\Middleware::class,
|
'2fa' => \PragmaRX\Google2FALaravel\Middleware::class,
|
||||||
'passwordexpiration' => \App\Http\Middleware\PasswordExpirationMiddleware::class,
|
|
||||||
'passwordredirect' => \App\Http\Middleware\PasswordExpirationRedirectMiddleware::class,
|
|
||||||
'localize' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class,
|
'localize' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRoutes::class,
|
||||||
'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class,
|
'localizationRedirect' => \Mcamara\LaravelLocalization\Middleware\LaravelLocalizationRedirectFilter::class,
|
||||||
'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class,
|
'localeSessionRedirect' => \Mcamara\LaravelLocalization\Middleware\LocaleSessionRedirect::class,
|
||||||
|
|||||||
@@ -1,65 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace App\Http\Middleware;
|
|
||||||
|
|
||||||
use App\ApiKey;
|
|
||||||
use App\Facades\JSON;
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use Closure;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Hash;
|
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Illuminate\Support\Facades\Route;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
|
|
||||||
class APIAuthenticationMiddleware
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Handle an incoming request.
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Http\Request $request
|
|
||||||
* @param \Closure $next
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function handle(Request $request, Closure $next)
|
|
||||||
{
|
|
||||||
$key = $request->bearerToken();
|
|
||||||
|
|
||||||
if (!is_null($key))
|
|
||||||
{
|
|
||||||
// we have a valid discriminator
|
|
||||||
$discriminator = Str::before($key, '.');
|
|
||||||
$loneKey = Str::after($key, '.');
|
|
||||||
|
|
||||||
$keyRecord = ApiKey::where('discriminator', $discriminator)->first();
|
|
||||||
|
|
||||||
if ($keyRecord && Hash::check($loneKey, $keyRecord->secret) && $keyRecord->status == 'active')
|
|
||||||
{
|
|
||||||
$keyRecord->last_used = Carbon::now();
|
|
||||||
$keyRecord->save();
|
|
||||||
|
|
||||||
Log::info('Recording API call, see context', [
|
|
||||||
'uri' => $request->url(),
|
|
||||||
'name' => Route::currentRouteName(),
|
|
||||||
'discriminator' => $discriminator,
|
|
||||||
'ip' => $request->ip()
|
|
||||||
]);
|
|
||||||
|
|
||||||
return $next($request);
|
|
||||||
}
|
|
||||||
|
|
||||||
return JSON::setResponseType('error')
|
|
||||||
->setStatus('authfail')
|
|
||||||
->setMessage('Invalid / Revoked API key.')
|
|
||||||
->setCode(401)
|
|
||||||
->build();
|
|
||||||
}
|
|
||||||
|
|
||||||
return JSON::setResponseType('error')
|
|
||||||
->setStatus('malformed_key')
|
|
||||||
->setMessage('Missing or malformed API key.')
|
|
||||||
->setCode(400)
|
|
||||||
->build();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
0
app/Http/Middleware/ApplicationEligibility.php
Executable file → Normal file
0
app/Http/Middleware/ApplicationEligibility.php
Executable file → Normal file
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user