Initial commit
This commit is contained in:
commit
a4c0188a09
235 changed files with 36790 additions and 0 deletions
15
.editorconfig
Normal file
15
.editorconfig
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
|
[*.yml]
|
||||||
|
indent_size = 2
|
47
.env.example
Normal file
47
.env.example
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
APP_NAME=Laravel
|
||||||
|
APP_ENV=local
|
||||||
|
APP_KEY=
|
||||||
|
APP_DEBUG=true
|
||||||
|
APP_URL=http://localhost
|
||||||
|
|
||||||
|
LOG_CHANNEL=stack
|
||||||
|
|
||||||
|
DB_CONNECTION=mysql
|
||||||
|
DB_HOST=127.0.0.1
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=homestead
|
||||||
|
DB_USERNAME=homestead
|
||||||
|
DB_PASSWORD=secret
|
||||||
|
|
||||||
|
BROADCAST_DRIVER=log
|
||||||
|
CACHE_DRIVER=file
|
||||||
|
QUEUE_CONNECTION=sync
|
||||||
|
SESSION_DRIVER=file
|
||||||
|
SESSION_LIFETIME=120
|
||||||
|
|
||||||
|
REDIS_HOST=127.0.0.1
|
||||||
|
REDIS_PASSWORD=null
|
||||||
|
REDIS_PORT=6379
|
||||||
|
|
||||||
|
MAIL_DRIVER=smtp
|
||||||
|
MAIL_HOST=smtp.mailtrap.io
|
||||||
|
MAIL_PORT=2525
|
||||||
|
MAIL_USERNAME=null
|
||||||
|
MAIL_PASSWORD=null
|
||||||
|
MAIL_ENCRYPTION=null
|
||||||
|
|
||||||
|
PUSHER_APP_ID=
|
||||||
|
PUSHER_APP_KEY=
|
||||||
|
PUSHER_APP_SECRET=
|
||||||
|
PUSHER_APP_CLUSTER=mt1
|
||||||
|
|
||||||
|
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
|
||||||
|
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||||
|
|
||||||
|
ENVOY_USER_AND_SERVER=username@server
|
||||||
|
ENVOY_BASE_DIR=/path/to/app/directory
|
||||||
|
ENVOY_RUN_TESTS="ssh -tt -p22 vagrant@192.168.10.10 '/path/to/homestead/app/vendor/bin/phpunit --configuration /path/to/homestead/app/phpunit.xml'"
|
||||||
|
|
||||||
|
ANONADDY_ADMIN_USERNAME=johndoe
|
||||||
|
ANONADDY_DOMAIN=anonaddy.me
|
||||||
|
ANONADDY_SECRET=long-random-string
|
5
.gitattributes
vendored
Normal file
5
.gitattributes
vendored
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
* text=auto
|
||||||
|
*.css linguist-vendored
|
||||||
|
*.scss linguist-vendored
|
||||||
|
*.js linguist-vendored
|
||||||
|
CHANGELOG.md export-ignore
|
19
.gitignore
vendored
Normal file
19
.gitignore
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/node_modules
|
||||||
|
/public/hot
|
||||||
|
/public/storage
|
||||||
|
/public/build
|
||||||
|
/public/css
|
||||||
|
/public/js
|
||||||
|
/public/mix-manifest.json
|
||||||
|
/storage/*.key
|
||||||
|
/vendor
|
||||||
|
/.idea
|
||||||
|
/.vscode
|
||||||
|
/.vagrant
|
||||||
|
Homestead.json
|
||||||
|
Homestead.yaml
|
||||||
|
npm-debug.log
|
||||||
|
yarn-error.log
|
||||||
|
.env
|
||||||
|
.php_cs.cache
|
||||||
|
.phpunit.result.cache
|
20
.php_cs
Normal file
20
.php_cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$finder = Symfony\Component\Finder\Finder::create()
|
||||||
|
->notPath('vendor')
|
||||||
|
->notPath('bootstrap')
|
||||||
|
->notPath('storage')
|
||||||
|
->in(__DIR__)
|
||||||
|
->name('*.php')
|
||||||
|
->notName('*.blade.php')
|
||||||
|
->ignoreDotFiles(true)
|
||||||
|
->ignoreVCS(true);
|
||||||
|
|
||||||
|
return PhpCsFixer\Config::create()
|
||||||
|
->setRules([
|
||||||
|
'@PSR2' => true,
|
||||||
|
'array_syntax' => ['syntax' => 'short'],
|
||||||
|
'ordered_imports' => ['sortAlgorithm' => 'alpha'],
|
||||||
|
'no_unused_imports' => true,
|
||||||
|
])
|
||||||
|
->setFinder($finder);
|
2
.prettierignore
Normal file
2
.prettierignore
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
public/
|
||||||
|
vendor/
|
7
.prettierrc
Normal file
7
.prettierrc
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"printWidth": 100,
|
||||||
|
"singleQuote": true,
|
||||||
|
"tabWidth": 2,
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"semi": false
|
||||||
|
}
|
175
Envoy.blade.php
Normal file
175
Envoy.blade.php
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
@setup
|
||||||
|
require __DIR__."/vendor/autoload.php";
|
||||||
|
$dotenv = Dotenv\Dotenv::create(__DIR__, ".env");
|
||||||
|
$dotenv->load();
|
||||||
|
|
||||||
|
$userAndServer = getenv("ENVOY_USER_AND_SERVER");
|
||||||
|
$repository = "willbrowningme/anonaddy";
|
||||||
|
$baseDir = getenv("ENVOY_BASE_DIR");
|
||||||
|
$releasesDir = "{$baseDir}/releases";
|
||||||
|
$persistentDir = "{$baseDir}/persistent";
|
||||||
|
$currentDir = "{$baseDir}/current";
|
||||||
|
$newReleaseName = date("Ymd-His");
|
||||||
|
$newReleaseDir = "{$releasesDir}/{$newReleaseName}";
|
||||||
|
|
||||||
|
function logMessage($message) {
|
||||||
|
return "echo '\033[32m" .$message. "\033[0m';\n";
|
||||||
|
}
|
||||||
|
@endsetup
|
||||||
|
|
||||||
|
@servers(["local" => "127.0.0.1", "remote" => $userAndServer])
|
||||||
|
|
||||||
|
@story("deploy")
|
||||||
|
startDeployment
|
||||||
|
runTests
|
||||||
|
cloneRepository
|
||||||
|
runComposer
|
||||||
|
runNpm
|
||||||
|
generateAssets
|
||||||
|
updateSymlinks
|
||||||
|
optimizeInstallation
|
||||||
|
migrateDatabase
|
||||||
|
blessNewRelease
|
||||||
|
cleanOldReleases
|
||||||
|
finishDeploy
|
||||||
|
@endstory
|
||||||
|
|
||||||
|
@story("deploy-code")
|
||||||
|
runTests
|
||||||
|
deployOnlyCode
|
||||||
|
@endstory
|
||||||
|
|
||||||
|
@story("deploy-rollback")
|
||||||
|
deploymentRollback
|
||||||
|
@endstory
|
||||||
|
|
||||||
|
@task("startDeployment", ["on" => "local"])
|
||||||
|
{{ logMessage("🏃 Starting deployment...") }}
|
||||||
|
@endtask
|
||||||
|
|
||||||
|
@task("runTests", ["on" => "local"])
|
||||||
|
{{ logMessage("💻 Running Unit Tests...") }}
|
||||||
|
env -i bash -c "{{ getenv('ENVOY_RUN_TESTS') }}" || exit 1
|
||||||
|
@endtask
|
||||||
|
|
||||||
|
@task("cloneRepository", ["on" => "remote"])
|
||||||
|
{{ logMessage("🌀 Cloning repository...") }}
|
||||||
|
[ -d {{ $releasesDir }} ] || mkdir {{ $releasesDir }}
|
||||||
|
[ -d {{ $persistentDir }} ] || mkdir {{ $persistentDir }}
|
||||||
|
[ -d {{ $persistentDir }}/storage ] || mkdir {{ $persistentDir }}/storage
|
||||||
|
cd {{ $releasesDir }}
|
||||||
|
|
||||||
|
# Create the release dir
|
||||||
|
mkdir {{ $newReleaseDir }}
|
||||||
|
|
||||||
|
# Clone the repo
|
||||||
|
git clone --depth 1 git@github.com:{{ $repository }} {{ $newReleaseName }}
|
||||||
|
|
||||||
|
# Configure sparse checkout
|
||||||
|
cd {{ $newReleaseDir }}
|
||||||
|
git config core.sparsecheckout true
|
||||||
|
echo "*" > .git/info/sparse-checkout
|
||||||
|
echo "!storage" >> .git/info/sparse-checkout
|
||||||
|
echo "!public/build" >> .git/info/sparse-checkout
|
||||||
|
git read-tree -mu HEAD
|
||||||
|
|
||||||
|
# Mark release
|
||||||
|
cd {{ $newReleaseDir }}
|
||||||
|
echo "{{ $newReleaseName }}" > public/release-name.txt
|
||||||
|
@endtask
|
||||||
|
|
||||||
|
@task("runComposer", ["on" => "remote"])
|
||||||
|
{{ logMessage("🚚 Running Composer...") }}
|
||||||
|
cd {{ $newReleaseDir }}
|
||||||
|
composer install --prefer-dist --no-scripts --no-dev -q -o
|
||||||
|
@endtask
|
||||||
|
|
||||||
|
@task("runNpm", ["on" => "remote"])
|
||||||
|
{{ logMessage("📦 Running Npm...") }}
|
||||||
|
cd {{ $newReleaseDir }}
|
||||||
|
npm install --no-progress &> /dev/null
|
||||||
|
@endtask
|
||||||
|
|
||||||
|
@task("generateAssets", ["on" => "remote"])
|
||||||
|
{{ logMessage("🌅 Generating assets...") }}
|
||||||
|
cd {{ $newReleaseDir }}
|
||||||
|
npm run production --no-progress &> /dev/null
|
||||||
|
@endtask
|
||||||
|
|
||||||
|
@task("updateSymlinks", ["on" => "remote"])
|
||||||
|
{{ logMessage("🔗 Updating symlinks to persistent data...") }}
|
||||||
|
# Remove the storage directory and replace with persistent data
|
||||||
|
rm -rf {{ $newReleaseDir }}/storage
|
||||||
|
cd {{ $newReleaseDir }}
|
||||||
|
ln -nfs {{ $baseDir }}/persistent/storage storage
|
||||||
|
|
||||||
|
# Import the environment config
|
||||||
|
cd {{ $newReleaseDir }}
|
||||||
|
ln -nfs {{ $baseDir }}/.env .env
|
||||||
|
@endtask
|
||||||
|
|
||||||
|
@task("optimizeInstallation", ["on" => "remote"])
|
||||||
|
{{ logMessage("✨ Optimizing installation...") }}
|
||||||
|
cd {{ $newReleaseDir }}
|
||||||
|
php artisan clear-compiled
|
||||||
|
@endtask
|
||||||
|
|
||||||
|
@task("migrateDatabase", ["on" => "remote"])
|
||||||
|
{{ logMessage("🙈 Migrating database...") }}
|
||||||
|
cd {{ $newReleaseDir }}
|
||||||
|
php artisan migrate --force
|
||||||
|
@endtask
|
||||||
|
|
||||||
|
@task("blessNewRelease", ["on" => "remote"])
|
||||||
|
{{ logMessage("🙏 Blessing new release...") }}
|
||||||
|
ln -nfs {{ $newReleaseDir }} {{ $currentDir }}
|
||||||
|
cd {{ $newReleaseDir }}
|
||||||
|
|
||||||
|
php artisan storage:link
|
||||||
|
|
||||||
|
php artisan config:clear
|
||||||
|
php artisan view:clear
|
||||||
|
php artisan cache:clear
|
||||||
|
|
||||||
|
php artisan config:cache
|
||||||
|
php artisan view:cache
|
||||||
|
php artisan route:cache
|
||||||
|
|
||||||
|
php artisan queue:restart
|
||||||
|
@endtask
|
||||||
|
|
||||||
|
@task("cleanOldReleases", ["on" => "remote"])
|
||||||
|
{{ logMessage("🚾 Cleaning up old releases...") }}
|
||||||
|
# Delete all but the 5 most recent.
|
||||||
|
cd {{ $releasesDir }}
|
||||||
|
ls -dt {{ $releasesDir }}/* | tail -n +6 | xargs -d "\n" chown -R deployer .
|
||||||
|
ls -dt {{ $releasesDir }}/* | tail -n +6 | xargs -d "\n" rm -rf
|
||||||
|
@endtask
|
||||||
|
|
||||||
|
@task("finishDeploy", ["on" => "local"])
|
||||||
|
{{ logMessage("🚀 Application deployed!") }}
|
||||||
|
@endtask
|
||||||
|
|
||||||
|
@task("deployOnlyCode",["on" => "remote"])
|
||||||
|
{{ logMessage("💻 Deploying code changes...") }}
|
||||||
|
cd {{ $currentDir }}
|
||||||
|
git pull origin master
|
||||||
|
|
||||||
|
php artisan storage:link
|
||||||
|
|
||||||
|
php artisan config:clear
|
||||||
|
php artisan view:clear
|
||||||
|
php artisan cache:clear
|
||||||
|
|
||||||
|
php artisan config:cache
|
||||||
|
php artisan view:cache
|
||||||
|
php artisan route:cache
|
||||||
|
|
||||||
|
php artisan queue:restart
|
||||||
|
@endtask
|
||||||
|
|
||||||
|
@task("deploymentRollback")
|
||||||
|
cd {{ $releasesDir }}
|
||||||
|
ln -nfs {{ $releasesDir }}/$(find . -maxdepth 1 -name "20*" | sort | tail -n 2 | head -n1) {{ $baseDir }}/current
|
||||||
|
echo "Rolled back to $(find . -maxdepth 1 -name "20*" | sort | tail -n 2 | head -n1)"
|
||||||
|
@endtask
|
22
LICENSE.md
Normal file
22
LICENSE.md
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 anonaddy
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
143
README.md
Normal file
143
README.md
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
# Anonymous Email Forwarding
|
||||||
|
|
||||||
|
This is the source code for [app.anonaddy.com](https://app.anonaddy.com).
|
||||||
|
|
||||||
|
## FAQ
|
||||||
|
|
||||||
|
#### Why did you make this site?
|
||||||
|
|
||||||
|
I made this service after trying a few other options that do a similar thing. I was really interested in how they worked and loved the thought of protecting my real email addresses from spam.
|
||||||
|
|
||||||
|
I decided to make the code open-source to show everyone what was going on behind the scenes and to allow others to help improve the application.
|
||||||
|
|
||||||
|
I use this service myself for the vast majority of sites I'm signed up to.
|
||||||
|
|
||||||
|
|
||||||
|
#### Do you store emails?
|
||||||
|
|
||||||
|
No I definitely do not store/record any emails that pass through the server.
|
||||||
|
|
||||||
|
|
||||||
|
#### Can I use my own domain?
|
||||||
|
|
||||||
|
Yes you can use your own domain name so you can also have *@yourdomain.com as your aliases. To do so you simply need to add an MX record to your domain so that our server can handle incoming emails.
|
||||||
|
|
||||||
|
|
||||||
|
#### Why should I use this instead of a similar service?
|
||||||
|
|
||||||
|
Here are a few reasons I can think of:
|
||||||
|
|
||||||
|
* No adverts
|
||||||
|
* No analytics or trackers (just server access logs)
|
||||||
|
* Open-source application code
|
||||||
|
* No limitation on the number of aliases that can be created
|
||||||
|
* Generous monthly bandwidth
|
||||||
|
|
||||||
|
|
||||||
|
#### What if I don't trust you?
|
||||||
|
|
||||||
|
It's good to keep your guard up when online so you should never trust anyone 100%. I'll try my best to be as honest and transparent as I can but if you still aren't convinced you can always just fire up your own server and self-host this application. I'll be adding more details on how to do this soon.
|
||||||
|
|
||||||
|
|
||||||
|
#### What is the maximum number of recipients I can add to an alias?
|
||||||
|
|
||||||
|
The limit is currently set to 10 which should suffice in the vast majority of situations.
|
||||||
|
|
||||||
|
|
||||||
|
#### What happens when I delete my account?
|
||||||
|
|
||||||
|
When you delete your account the following happens:
|
||||||
|
|
||||||
|
* All of your recipients are deleted from the database
|
||||||
|
* All of your other aliases are deleted from the database (aliases with a custom domain are soft deleted - see why below)
|
||||||
|
* All of your custom domains are deleted from the database
|
||||||
|
* Your user details are deleted from the database
|
||||||
|
* Your username is encrypted and added to a table in the database. This is to prevent anybody signing up with the same username in the future.
|
||||||
|
|
||||||
|
The reason aliases with a custom domain are soft deleted (a deleted_at column if filled in the database) is to ensure that nobody else can register your same domain in the future and then sign up to our site and receive emails for aliases you have previously used.
|
||||||
|
|
||||||
|
|
||||||
|
#### Does this work with any email provider?
|
||||||
|
|
||||||
|
Yes this will work with any provider, althought I can't guarantee it won't land in spam initially.
|
||||||
|
|
||||||
|
|
||||||
|
#### Will people see my real email if I reply to a forwarded one?
|
||||||
|
|
||||||
|
No, your real email will not be shown, the email will look as if it has come from us instead. Just make sure not to include anything that might identify you when composing the reply, i.e. your full name.
|
||||||
|
|
||||||
|
|
||||||
|
#### Can emails have attachments?
|
||||||
|
|
||||||
|
Yes you can add attachments to emails forwarded and replies. Attachments do count towards your bandwidth.
|
||||||
|
|
||||||
|
|
||||||
|
#### What is the max email size limit?
|
||||||
|
|
||||||
|
The max email size is currently set to 10MB.
|
||||||
|
|
||||||
|
|
||||||
|
#### How do you prevent spammers?
|
||||||
|
|
||||||
|
The following is in place to help prevent spam:
|
||||||
|
|
||||||
|
* SpamAssassin - score threshold of 5.0
|
||||||
|
* DNS blacklist checks - spamhaus.org
|
||||||
|
* SPF, DKIM - to check the SPF record on the sender's domain
|
||||||
|
* Disposable Email Addresses are blocked - [disposable-email-domains](https://github.com/ivolo/disposable-email-domains)
|
||||||
|
* DMARC - to check for email spoofing and reject emails that fail
|
||||||
|
* FQDN - the sender must be using a valid fully qualified domain name
|
||||||
|
* PTR record check - if the sender has no valid PTR record it is rejected
|
||||||
|
|
||||||
|
#### What do you use to do DNS lookups on domain names?
|
||||||
|
|
||||||
|
The server is running a local DNS caching server to improve the speed of queries. Cloudflare's (1.1.1.1) is used as a fallback.
|
||||||
|
|
||||||
|
|
||||||
|
#### Is there a limit to how many emails I can forward?
|
||||||
|
|
||||||
|
Not unless you are really going to town. Each user is throttled to 200 emails per hour through the server.
|
||||||
|
|
||||||
|
|
||||||
|
#### How is my bandwidth calculated?
|
||||||
|
|
||||||
|
Each time a new email is received Postfix calculates its size in bytes, a column in our database is then simply incremented by the size if the email is forwarded or replied. At the start of each month your bandwidth is reset to 0.
|
||||||
|
|
||||||
|
I don't use rolling 30 day total as the only way to do this would be to log the date and size of every single email received.
|
||||||
|
|
||||||
|
Blocked emails do not count towards your bandwidth (e.g. an alias is inactive or deleted).
|
||||||
|
|
||||||
|
|
||||||
|
#### What happens if I go over my bandwidth limit in a given month?
|
||||||
|
|
||||||
|
If you get close to your limit you'll be sent an email letting you know. If you continue and go over your limit the server will start discarding emails until your bandwidth resets the next month.
|
||||||
|
|
||||||
|
|
||||||
|
#### I'm not receiving any emails, what's wrong?
|
||||||
|
|
||||||
|
Please make sure to add mailer@anonaddy.me to your address book and check your spam folder. Make sure to mark emails from us as safe if they turn up in spam. If you still aren't receiving emails contact me.
|
||||||
|
|
||||||
|
|
||||||
|
#### How do I know this site won't disappear next month?
|
||||||
|
|
||||||
|
I am very passionite about this project. I use it myself everyday and will definitely be keeping it running.
|
||||||
|
|
||||||
|
|
||||||
|
#### Is the application tested?
|
||||||
|
|
||||||
|
Yes it has automated PHPUnit tests written.
|
||||||
|
|
||||||
|
|
||||||
|
#### How do I host this myself?
|
||||||
|
|
||||||
|
You will need to set up your own server with Postfix so that you can pipe the received mail to the application. I'll add more details and instructions here soon.
|
||||||
|
|
||||||
|
|
||||||
|
#### I couldn't find an answer to my question, how can I contact you?
|
||||||
|
|
||||||
|
For any others questions just send an email to - [contact@anonaddy.com](mailto:contact@anonaddy.com)
|
||||||
|
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.
|
110
app/Alias.php
Normal file
110
app/Alias.php
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
use App\Traits\HasEncryptedAttributes;
|
||||||
|
use App\Traits\HasUuid;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||||
|
|
||||||
|
class Alias extends Model
|
||||||
|
{
|
||||||
|
use SoftDeletes, HasUuid, HasEncryptedAttributes;
|
||||||
|
|
||||||
|
public $incrementing = false;
|
||||||
|
|
||||||
|
protected $encrypted = [
|
||||||
|
'description'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'active',
|
||||||
|
'description',
|
||||||
|
'email',
|
||||||
|
'local_part',
|
||||||
|
'domain',
|
||||||
|
'domain_id'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $dates = [
|
||||||
|
'created_at',
|
||||||
|
'updated_at',
|
||||||
|
'deleted_at'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'id' => 'string',
|
||||||
|
'user_id' => 'string',
|
||||||
|
'domain_id' => 'string',
|
||||||
|
'active' => 'boolean'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function setLocalPartAttribute($value)
|
||||||
|
{
|
||||||
|
$this->attributes['local_part'] = strtolower($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setDomainAttribute($value)
|
||||||
|
{
|
||||||
|
$this->attributes['domain'] = strtolower($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setEmailAttribute($value)
|
||||||
|
{
|
||||||
|
$this->attributes['email'] = strtolower($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the user for the email alias.
|
||||||
|
*/
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the custom domain for the email alias.
|
||||||
|
*/
|
||||||
|
public function domain()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Domain::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the recipients for the email alias.
|
||||||
|
*/
|
||||||
|
public function recipients()
|
||||||
|
{
|
||||||
|
return $this->BelongsToMany(Recipient::class, 'alias_recipients')->withPivot('id')->using(AliasRecipient::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the verified recipients for the email alias.
|
||||||
|
*/
|
||||||
|
public function verifiedRecipients()
|
||||||
|
{
|
||||||
|
return $this->recipients()->whereNotNull('email_verified_at');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the verified emails of recipients for the email alias.
|
||||||
|
*/
|
||||||
|
public function recipientEmails()
|
||||||
|
{
|
||||||
|
return $this->verifiedRecipients()->count() ? $this->verifiedRecipients()
|
||||||
|
->get()
|
||||||
|
->map(function ($recipient) {
|
||||||
|
return $recipient->email;
|
||||||
|
})->toArray() : $this->user->email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deactivate()
|
||||||
|
{
|
||||||
|
$this->update(['active' => false]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function activate()
|
||||||
|
{
|
||||||
|
$this->update(['active' => true]);
|
||||||
|
}
|
||||||
|
}
|
51
app/AliasRecipient.php
Normal file
51
app/AliasRecipient.php
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
use App\Traits\HasUuid;
|
||||||
|
use Illuminate\Database\Eloquent\Relations\Pivot;
|
||||||
|
|
||||||
|
class AliasRecipient extends Pivot
|
||||||
|
{
|
||||||
|
use HasUuid;
|
||||||
|
|
||||||
|
public $incrementing = false;
|
||||||
|
|
||||||
|
public $timestamps = false;
|
||||||
|
|
||||||
|
protected $table = 'alias_recipients';
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'id' => 'string',
|
||||||
|
'alias_id' => 'string',
|
||||||
|
'recipient_id' => 'string'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function setAliasAttribute($alias)
|
||||||
|
{
|
||||||
|
$this->attributes['alias_id'] = $alias->getKey();
|
||||||
|
$this->setRelation('alias', $alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setRecipientAttribute($recipient)
|
||||||
|
{
|
||||||
|
$this->attributes['recipient_id'] = $recipient->getKey();
|
||||||
|
$this->setRelation('recipient', $recipient);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the alias for this pivot row.
|
||||||
|
*/
|
||||||
|
public function alias()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Alias::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the recipient for this pivot row.
|
||||||
|
*/
|
||||||
|
public function recipient()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Recipient::class);
|
||||||
|
}
|
||||||
|
}
|
236
app/Console/Commands/ReceiveEmail.php
Normal file
236
app/Console/Commands/ReceiveEmail.php
Normal file
|
@ -0,0 +1,236 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\Alias;
|
||||||
|
use App\Domain;
|
||||||
|
use App\EmailData;
|
||||||
|
use App\Mail\ForwardEmail;
|
||||||
|
use App\Mail\ReplyToEmail;
|
||||||
|
use App\Notifications\NearBandwidthLimit;
|
||||||
|
use App\User;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Illuminate\Support\Facades\Mail;
|
||||||
|
use Illuminate\Support\Facades\Redis;
|
||||||
|
use PhpMimeMailParser\Parser;
|
||||||
|
|
||||||
|
class ReceiveEmail extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'anonaddy:receive-email
|
||||||
|
{file=stream : The file of the email}
|
||||||
|
{--sender= : The sender of the email}
|
||||||
|
{--recipient=* : The recipient of the email}
|
||||||
|
{--local_part=* : The local part of the recipient}
|
||||||
|
{--extension=* : The extension of the local part of the recipient}
|
||||||
|
{--domain=* : The domain of the recipient}
|
||||||
|
{--size= : The size of the email in bytes}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Receive email from postfix pipe';
|
||||||
|
protected $parser;
|
||||||
|
protected $size;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new command instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$file = $this->argument('file');
|
||||||
|
|
||||||
|
$this->parser = $this->getParser($file);
|
||||||
|
|
||||||
|
$recipients = collect($this->option('recipient'))->map(function ($item, $key) {
|
||||||
|
return [
|
||||||
|
'email' => $item,
|
||||||
|
'local_part' => $this->option('local_part')[$key],
|
||||||
|
'extension' => $this->option('extension')[$key],
|
||||||
|
'domain' => $this->option('domain')[$key]
|
||||||
|
];
|
||||||
|
});
|
||||||
|
|
||||||
|
// Divide the size of the email by the number of recipients to prevent it being added multiple times
|
||||||
|
$this->size = $this->option('size') / count($recipients);
|
||||||
|
|
||||||
|
foreach ($recipients as $key => $recipient) {
|
||||||
|
$subdomain = substr($recipient['domain'], 0, strrpos($recipient['domain'], '.'.config('anonaddy.domain'))); // e.g. johndoe
|
||||||
|
|
||||||
|
$displayTo = $this->parser->getAddresses('to')[$key]['display'];
|
||||||
|
|
||||||
|
if ($subdomain === 'unsubscribe') {
|
||||||
|
$this->handleUnsubscribe($recipient);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = User::where('username', $subdomain)->first();
|
||||||
|
|
||||||
|
// If no user is found for the subdomain check if it is a custom or root domain instead
|
||||||
|
if (is_null($user)) {
|
||||||
|
// check if this is a custom domain
|
||||||
|
if ($customDomain = Domain::where('domain', $recipient['domain'])->first()) {
|
||||||
|
$user = $customDomain->user;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this is the root domain e.g. anonaddy.me
|
||||||
|
if ($recipient['domain'] === config('anonaddy.domain') && !empty(config('anonaddy.admin_username'))) {
|
||||||
|
$user = User::where('username', config('anonaddy.admin_username'))->first();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there is still no user or the user has no verified default recipient then continue
|
||||||
|
if (is_null($user) || !$user->hasVerifiedDefaultRecipient()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->checkRateLimit($user);
|
||||||
|
|
||||||
|
// check whether this email is a reply or a new email to be forwarded
|
||||||
|
if ($recipient['extension'] === sha1(config('anonaddy.secret').$displayTo)) {
|
||||||
|
$this->handleReply($user, $recipient, $displayTo);
|
||||||
|
} else {
|
||||||
|
$this->handleForward($user, $recipient, $customDomain->id ?? null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
Log::error($e->getMessage() . PHP_EOL . $e->getTraceAsString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleUnsubscribe($recipient)
|
||||||
|
{
|
||||||
|
$alias = Alias::find($recipient['local_part']);
|
||||||
|
|
||||||
|
if ($alias) {
|
||||||
|
// Make sure the sender is one of the user's recipients
|
||||||
|
$userRecipients = $alias->user
|
||||||
|
->verifiedRecipients()
|
||||||
|
->get()
|
||||||
|
->map(function ($recipient) {
|
||||||
|
return $recipient->email;
|
||||||
|
})
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
if (in_array($this->parser->getAddresses('from')[0]['address'], $userRecipients)) {
|
||||||
|
$alias->deactivate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleReply($user, $recipient, $displayTo)
|
||||||
|
{
|
||||||
|
$alias = $user->aliases()->where('email', $recipient['local_part'] . '@' . $recipient['domain'])->first();
|
||||||
|
|
||||||
|
if (!is_null($alias) && filter_var($displayTo, FILTER_VALIDATE_EMAIL)) {
|
||||||
|
// This is simply a class that allows us to base64_encode all attachment data before serialization
|
||||||
|
$emailData = new EmailData($this->parser);
|
||||||
|
|
||||||
|
$message = (new ReplyToEmail($user, $alias, $emailData))->onQueue('default');
|
||||||
|
|
||||||
|
Mail::to($displayTo)->queue($message);
|
||||||
|
|
||||||
|
if (!Mail::failures()) {
|
||||||
|
$alias->emails_replied += 1;
|
||||||
|
$alias->save();
|
||||||
|
|
||||||
|
$user->bandwidth += $this->size;
|
||||||
|
$user->save();
|
||||||
|
|
||||||
|
if ($user->nearBandwidthLimit()) {
|
||||||
|
$user->notify(new NearBandwidthLimit());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function handleForward($user, $recipient, $customDomainId)
|
||||||
|
{
|
||||||
|
if ($recipient['extension'] !== '') {
|
||||||
|
// TODO override default recipient for alias?
|
||||||
|
// or pass number and if forwarded equals that no. then block?
|
||||||
|
}
|
||||||
|
|
||||||
|
$alias = $user->aliases()->firstOrCreate([
|
||||||
|
'email' => $recipient['local_part'] . '@' . $recipient['domain'],
|
||||||
|
'local_part' => $recipient['local_part'],
|
||||||
|
'domain' => $recipient['domain'],
|
||||||
|
'domain_id' => $customDomainId
|
||||||
|
])->refresh();
|
||||||
|
|
||||||
|
// This is simply a class that allows us to base64_encode all attachment data before serialization
|
||||||
|
$emailData = new EmailData($this->parser);
|
||||||
|
|
||||||
|
$message = (new ForwardEmail($alias, $emailData))->onQueue('default');
|
||||||
|
|
||||||
|
Mail::to($alias->recipientEmails())->queue($message);
|
||||||
|
|
||||||
|
if (!Mail::failures()) {
|
||||||
|
$alias->emails_forwarded += 1;
|
||||||
|
$alias->save();
|
||||||
|
|
||||||
|
$user->bandwidth += $this->size;
|
||||||
|
$user->save();
|
||||||
|
|
||||||
|
if ($user->nearBandwidthLimit()) {
|
||||||
|
$user->notify(new NearBandwidthLimit());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function checkRateLimit($user)
|
||||||
|
{
|
||||||
|
Redis::throttle("user:{$user->username}:limit:emails")
|
||||||
|
->allow(config('anonaddy.limit'))
|
||||||
|
->every(3600)
|
||||||
|
->then(
|
||||||
|
function () {
|
||||||
|
},
|
||||||
|
function () use ($user) {
|
||||||
|
|
||||||
|
// Rate limit reached, return error message
|
||||||
|
$this->error('5.7.1 Rate limit exceeded for user ' . $user->username . '. Please try again later.');
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getParser($file)
|
||||||
|
{
|
||||||
|
$parser = new Parser;
|
||||||
|
|
||||||
|
if ($file == 'stream') {
|
||||||
|
$fd = fopen('php://stdin', 'r');
|
||||||
|
$this->rawEmail = '';
|
||||||
|
while (!feof($fd)) {
|
||||||
|
$this->rawEmail .= fread($fd, 1024);
|
||||||
|
}
|
||||||
|
fclose($fd);
|
||||||
|
$parser->setText($this->rawEmail);
|
||||||
|
} else {
|
||||||
|
$parser->setPath($file);
|
||||||
|
}
|
||||||
|
return $parser;
|
||||||
|
}
|
||||||
|
}
|
43
app/Console/Commands/ResetBandwidth.php
Normal file
43
app/Console/Commands/ResetBandwidth.php
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
|
use App\User;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
|
||||||
|
class ResetBandwidth extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The name and signature of the console command.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'anonaddy:reset-bandwidth';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The console command description.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Reset bandwidth for all users at the start of each month';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new command instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the console command.
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
User::where('bandwidth', '>', 0)->update(['bandwidth' => 0]);
|
||||||
|
}
|
||||||
|
}
|
41
app/Console/Kernel.php
Normal file
41
app/Console/Kernel.php
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Console;
|
||||||
|
|
||||||
|
use Illuminate\Console\Scheduling\Schedule;
|
||||||
|
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||||
|
|
||||||
|
class Kernel extends ConsoleKernel
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The Artisan commands provided by your application.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $commands = [
|
||||||
|
'App\Console\Commands\ResetBandwidth'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the application's command schedule.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function schedule(Schedule $schedule)
|
||||||
|
{
|
||||||
|
$schedule->command('anonaddy:reset-bandwidth')->monthlyOn(1, '00:00');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the commands for the application.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function commands()
|
||||||
|
{
|
||||||
|
$this->load(__DIR__.'/Commands');
|
||||||
|
|
||||||
|
require base_path('routes/console.php');
|
||||||
|
}
|
||||||
|
}
|
23
app/DeletedUsername.php
Normal file
23
app/DeletedUsername.php
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
use App\Traits\HasEncryptedAttributes;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class DeletedUsername extends Model
|
||||||
|
{
|
||||||
|
use HasEncryptedAttributes;
|
||||||
|
|
||||||
|
public $incrementing = false;
|
||||||
|
|
||||||
|
public $timestamps = false;
|
||||||
|
|
||||||
|
protected $encrypted = [
|
||||||
|
'username'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'username'
|
||||||
|
];
|
||||||
|
}
|
75
app/Domain.php
Normal file
75
app/Domain.php
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
use App\Traits\HasEncryptedAttributes;
|
||||||
|
use App\Traits\HasUuid;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Domain extends Model
|
||||||
|
{
|
||||||
|
use HasUuid, HasEncryptedAttributes;
|
||||||
|
|
||||||
|
public $incrementing = false;
|
||||||
|
|
||||||
|
protected $encrypted = [
|
||||||
|
'description'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'domain',
|
||||||
|
'description',
|
||||||
|
'active'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $dates = [
|
||||||
|
'created_at',
|
||||||
|
'updated_at'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'id' => 'string',
|
||||||
|
'user_id' => 'string',
|
||||||
|
'active' => 'boolean'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the domain's name.
|
||||||
|
*/
|
||||||
|
public function setDomainAttribute($value)
|
||||||
|
{
|
||||||
|
$this->attributes['domain'] = strtolower($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the user for the custom domain.
|
||||||
|
*/
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the domains's aliases.
|
||||||
|
*/
|
||||||
|
public function aliases()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Alias::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deactivate the alias.
|
||||||
|
*/
|
||||||
|
public function deactivate()
|
||||||
|
{
|
||||||
|
$this->update(['active' => false]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activate the alias.
|
||||||
|
*/
|
||||||
|
public function activate()
|
||||||
|
{
|
||||||
|
$this->update(['active' => true]);
|
||||||
|
}
|
||||||
|
}
|
25
app/EmailData.php
Normal file
25
app/EmailData.php
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
use PhpMimeMailParser\Parser;
|
||||||
|
|
||||||
|
class EmailData
|
||||||
|
{
|
||||||
|
public function __construct(Parser $parser)
|
||||||
|
{
|
||||||
|
$this->sender = $parser->getAddresses('from')[0]['address'];
|
||||||
|
$this->subject = $parser->getHeader('subject');
|
||||||
|
$this->text = $parser->getMessageBody('text');
|
||||||
|
$this->html = $parser->getMessageBody('html');
|
||||||
|
$this->attachments = [];
|
||||||
|
|
||||||
|
foreach ($parser->getAttachments() as $attachment) {
|
||||||
|
$this->attachments[] = [
|
||||||
|
'stream' => base64_encode(stream_get_contents($attachment->getStream())),
|
||||||
|
'file_name' => $attachment->getFileName(),
|
||||||
|
'mime' => $attachment->getContentType()
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
51
app/Exceptions/Handler.php
Normal file
51
app/Exceptions/Handler.php
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Exceptions;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||||
|
|
||||||
|
class Handler extends ExceptionHandler
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A list of the exception types that are not reported.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $dontReport = [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of the inputs that are never flashed for validation exceptions.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $dontFlash = [
|
||||||
|
'password',
|
||||||
|
'password_confirmation',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report or log an exception.
|
||||||
|
*
|
||||||
|
* @param \Exception $exception
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function report(Exception $exception)
|
||||||
|
{
|
||||||
|
parent::report($exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render an exception into an HTTP response.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \Exception $exception
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
*/
|
||||||
|
public function render($request, Exception $exception)
|
||||||
|
{
|
||||||
|
return parent::render($request, $exception);
|
||||||
|
}
|
||||||
|
}
|
13
app/Helpers/Helper.php
Normal file
13
app/Helpers/Helper.php
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
|
||||||
|
function user()
|
||||||
|
{
|
||||||
|
return auth()->user();
|
||||||
|
}
|
||||||
|
|
||||||
|
function carbon(...$args)
|
||||||
|
{
|
||||||
|
return new Carbon(...$args);
|
||||||
|
}
|
27
app/Http/Controllers/ActiveAliasController.php
Normal file
27
app/Http/Controllers/ActiveAliasController.php
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Resources\AliasResource;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ActiveAliasController extends Controller
|
||||||
|
{
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
$alias = user()->aliases()->findOrFail($request->id);
|
||||||
|
|
||||||
|
$alias->activate();
|
||||||
|
|
||||||
|
return new AliasResource($alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
$alias = user()->aliases()->findOrFail($id);
|
||||||
|
|
||||||
|
$alias->deactivate();
|
||||||
|
|
||||||
|
return new AliasResource($alias);
|
||||||
|
}
|
||||||
|
}
|
27
app/Http/Controllers/ActiveDomainController.php
Normal file
27
app/Http/Controllers/ActiveDomainController.php
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Resources\DomainResource;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ActiveDomainController extends Controller
|
||||||
|
{
|
||||||
|
public function store(Request $request)
|
||||||
|
{
|
||||||
|
$domain = user()->domains()->findOrFail($request->id);
|
||||||
|
|
||||||
|
$domain->activate();
|
||||||
|
|
||||||
|
return new DomainResource($domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
$domain = user()->domains()->findOrFail($id);
|
||||||
|
|
||||||
|
$domain->deactivate();
|
||||||
|
|
||||||
|
return new DomainResource($domain);
|
||||||
|
}
|
||||||
|
}
|
43
app/Http/Controllers/AliasController.php
Normal file
43
app/Http/Controllers/AliasController.php
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\UpdateAliasRequest;
|
||||||
|
use App\Http\Resources\AliasResource;
|
||||||
|
|
||||||
|
class AliasController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('aliases.index', [
|
||||||
|
'defaultRecipient' => user()->defaultRecipient,
|
||||||
|
'aliases' => user()->aliases()->with('recipients')->latest()->get(),
|
||||||
|
'recipients' => user()->verifiedRecipients,
|
||||||
|
'totalForwarded' => user()->totalEmailsForwarded(),
|
||||||
|
'totalBlocked' => user()->totalEmailsBlocked(),
|
||||||
|
'totalReplies' => user()->totalEmailsReplied(),
|
||||||
|
'domain' => user()->username.'.'.config('anonaddy.domain'),
|
||||||
|
'bandwidthMb' => user()->bandwidth_mb
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(UpdateAliasRequest $request, $id)
|
||||||
|
{
|
||||||
|
$alias = user()->aliases()->findOrFail($id);
|
||||||
|
|
||||||
|
$alias->update(['description' => $request->description]);
|
||||||
|
|
||||||
|
return new AliasResource($alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
$alias = user()->aliases()->findOrFail($id);
|
||||||
|
|
||||||
|
$alias->recipients()->detach();
|
||||||
|
|
||||||
|
$alias->delete();
|
||||||
|
|
||||||
|
return response('', 204);
|
||||||
|
}
|
||||||
|
}
|
27
app/Http/Controllers/AliasRecipientController.php
Normal file
27
app/Http/Controllers/AliasRecipientController.php
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\StoreAliasRecipientRequest;
|
||||||
|
use App\Http\Resources\AliasResource;
|
||||||
|
|
||||||
|
class AliasRecipientController extends Controller
|
||||||
|
{
|
||||||
|
public function store(StoreAliasRecipientRequest $request)
|
||||||
|
{
|
||||||
|
$alias = user()->aliases()->findOrFail($request->alias_id);
|
||||||
|
|
||||||
|
$alias->recipients()->sync($request->recipient_ids);
|
||||||
|
|
||||||
|
return new AliasResource($alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
$aliasRecipient = user()->aliasRecipients()->findOrFail($id);
|
||||||
|
|
||||||
|
$aliasRecipient->delete();
|
||||||
|
|
||||||
|
return response('', 204);
|
||||||
|
}
|
||||||
|
}
|
82
app/Http/Controllers/Auth/ForgotPasswordController.php
Normal file
82
app/Http/Controllers/Auth/ForgotPasswordController.php
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\User;
|
||||||
|
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Password;
|
||||||
|
|
||||||
|
class ForgotPasswordController extends Controller
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Password Reset Controller
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This controller is responsible for handling password reset emails and
|
||||||
|
| includes a trait which assists in sending these notifications from
|
||||||
|
| your application to your users. Feel free to explore this trait.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
use SendsPasswordResetEmails;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new controller instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->middleware('guest');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a reset link to the given user.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
public function sendResetLinkEmail(Request $request)
|
||||||
|
{
|
||||||
|
$this->validateUsername($request);
|
||||||
|
|
||||||
|
// We will send the password reset link to this user. Once we have attempted
|
||||||
|
// to send the link, we will examine the response then see the message we
|
||||||
|
// need to show to the user. Finally, we'll send out a proper response.
|
||||||
|
$response = $this->broker()->sendResetLink(
|
||||||
|
$request->only('username')
|
||||||
|
);
|
||||||
|
|
||||||
|
return $response == Password::RESET_LINK_SENT
|
||||||
|
? $this->sendResetLinkResponse($request, $response)
|
||||||
|
: $this->sendResetLinkFailedResponse($request, $response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate the email for the given request.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function validateUsername(Request $request)
|
||||||
|
{
|
||||||
|
$request->validate(['username' => 'required|alpha_num|max:20']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the response for a failed password reset link.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param string $response
|
||||||
|
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
protected function sendResetLinkFailedResponse(Request $request, $response)
|
||||||
|
{
|
||||||
|
return back()
|
||||||
|
->withInput($request->only('username'))
|
||||||
|
->withErrors(['username' => trans($response)]);
|
||||||
|
}
|
||||||
|
}
|
44
app/Http/Controllers/Auth/LoginController.php
Normal file
44
app/Http/Controllers/Auth/LoginController.php
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||||
|
|
||||||
|
class LoginController extends Controller
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Login Controller
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This controller handles authenticating users for the application and
|
||||||
|
| redirecting them to your home screen. The controller uses a trait
|
||||||
|
| to conveniently provide its functionality to your applications.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
use AuthenticatesUsers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Where to redirect users after login.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $redirectTo = '/';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new controller instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->middleware('guest')->except('logout');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function username()
|
||||||
|
{
|
||||||
|
return 'username';
|
||||||
|
}
|
||||||
|
}
|
95
app/Http/Controllers/Auth/RegisterController.php
Normal file
95
app/Http/Controllers/Auth/RegisterController.php
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Recipient;
|
||||||
|
use App\Rules\NotBlacklisted;
|
||||||
|
use App\Rules\NotDeletedUsername;
|
||||||
|
use App\User;
|
||||||
|
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use Illuminate\Support\Facades\Validator;
|
||||||
|
use Ramsey\Uuid\Uuid;
|
||||||
|
|
||||||
|
class RegisterController extends Controller
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Register Controller
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This controller handles the registration of new users as well as their
|
||||||
|
| validation and creation. By default this controller uses a trait to
|
||||||
|
| provide this functionality without requiring any additional code.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
use RegistersUsers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Where to redirect users after registration.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $redirectTo = '/';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new controller instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->middleware('guest');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a validator for an incoming registration request.
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return \Illuminate\Contracts\Validation\Validator
|
||||||
|
*/
|
||||||
|
protected function validator(array $data)
|
||||||
|
{
|
||||||
|
return Validator::make($data, [
|
||||||
|
'username' => [
|
||||||
|
'required',
|
||||||
|
'alpha_num',
|
||||||
|
'max:20',
|
||||||
|
'unique:users',
|
||||||
|
new NotBlacklisted,
|
||||||
|
new NotDeletedUsername
|
||||||
|
],
|
||||||
|
'email' => ['required', 'email', 'max:254', 'confirmed'],
|
||||||
|
'password' => ['required', 'min:8'],
|
||||||
|
'terms' => ['required', 'accepted']
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new user instance after a valid registration.
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return \App\User
|
||||||
|
*/
|
||||||
|
protected function create(array $data)
|
||||||
|
{
|
||||||
|
$userId = Uuid::uuid4();
|
||||||
|
|
||||||
|
$recipient = Recipient::create([
|
||||||
|
'email' => $data['email'],
|
||||||
|
'user_id' => $userId
|
||||||
|
]);
|
||||||
|
|
||||||
|
$twoFactor = app('pragmarx.google2fa');
|
||||||
|
|
||||||
|
return User::create([
|
||||||
|
'id' => $userId,
|
||||||
|
'username' => $data['username'],
|
||||||
|
'default_recipient_id' => $recipient->id,
|
||||||
|
'password' => Hash::make($data['password']),
|
||||||
|
'two_factor_secret' => $twoFactor->generateSecretKey()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
100
app/Http/Controllers/Auth/ResetPasswordController.php
Normal file
100
app/Http/Controllers/Auth/ResetPasswordController.php
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class ResetPasswordController extends Controller
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Password Reset Controller
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This controller is responsible for handling password reset requests
|
||||||
|
| and uses a simple trait to include this behavior. You're free to
|
||||||
|
| explore this trait and override any methods you wish to tweak.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
use ResetsPasswords;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Where to redirect users after resetting their password.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $redirectTo = '/';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new controller instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->middleware('guest');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the password reset view for the given token.
|
||||||
|
*
|
||||||
|
* If no token is present, display the link request form.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param string|null $token
|
||||||
|
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||||
|
*/
|
||||||
|
public function showResetForm(Request $request, $token = null)
|
||||||
|
{
|
||||||
|
return view('auth.passwords.reset')->with(
|
||||||
|
['token' => $token, 'username' => $request->username]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the password reset validation rules.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'token' => 'required',
|
||||||
|
'username' => 'required|alpha_num|max:20',
|
||||||
|
'password' => 'required|confirmed|min:8',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the password reset credentials from the request.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function credentials(Request $request)
|
||||||
|
{
|
||||||
|
return $request->only(
|
||||||
|
'username',
|
||||||
|
'password',
|
||||||
|
'password_confirmation',
|
||||||
|
'token'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the response for a failed password reset.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param string $response
|
||||||
|
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
|
||||||
|
*/
|
||||||
|
protected function sendResetFailedResponse(Request $request, $response)
|
||||||
|
{
|
||||||
|
return back()
|
||||||
|
->withInput($request->only('username'))
|
||||||
|
->withErrors(['username' => trans($response)]);
|
||||||
|
}
|
||||||
|
}
|
78
app/Http/Controllers/Auth/VerificationController.php
Normal file
78
app/Http/Controllers/Auth/VerificationController.php
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use Illuminate\Auth\Access\AuthorizationException;
|
||||||
|
use Illuminate\Auth\Events\Verified;
|
||||||
|
use Illuminate\Foundation\Auth\VerifiesEmails;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class VerificationController extends Controller
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Email Verification Controller
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This controller is responsible for handling email verification for any
|
||||||
|
| user that recently registered with the application. Emails may also
|
||||||
|
| be re-sent if the user didn't receive the original email message.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
use VerifiesEmails;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Where to redirect users after verification.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $redirectTo = '/';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new controller instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->middleware('auth');
|
||||||
|
$this->middleware('signed')->only('verify');
|
||||||
|
$this->middleware('throttle:6,1')->only('verify', 'resend');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the authenticated user's email address as verified.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return \Illuminate\Http\Response
|
||||||
|
* @throws \Illuminate\Auth\Access\AuthorizationException
|
||||||
|
*/
|
||||||
|
public function verify(Request $request)
|
||||||
|
{
|
||||||
|
if ($recipient = $request->user()->recipients()->find($request->route('id'))) {
|
||||||
|
if ($recipient->hasVerifiedEmail()) {
|
||||||
|
return redirect($this->redirectPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
$recipient->markEmailAsVerified();
|
||||||
|
|
||||||
|
return redirect(route('recipients.index'))->with('verified', true);
|
||||||
|
} else {
|
||||||
|
if ($request->route('id') != $request->user()->getKey()) {
|
||||||
|
throw new AuthorizationException;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->user()->hasVerifiedEmail()) {
|
||||||
|
return redirect($this->redirectPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($request->user()->markEmailAsVerified()) {
|
||||||
|
event(new Verified($request->user()));
|
||||||
|
}
|
||||||
|
|
||||||
|
return redirect($this->redirectPath())->with('verified', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
app/Http/Controllers/BannerLocationController.php
Normal file
15
app/Http/Controllers/BannerLocationController.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\UpdateBannerLocationRequest;
|
||||||
|
|
||||||
|
class BannerLocationController extends Controller
|
||||||
|
{
|
||||||
|
public function update(UpdateBannerLocationRequest $request)
|
||||||
|
{
|
||||||
|
user()->update(['banner_location' => $request->banner_location]);
|
||||||
|
|
||||||
|
return back()->with(['status' => 'Location Updated Successfully']);
|
||||||
|
}
|
||||||
|
}
|
13
app/Http/Controllers/Controller.php
Normal file
13
app/Http/Controllers/Controller.php
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
|
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||||
|
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||||
|
use Illuminate\Routing\Controller as BaseController;
|
||||||
|
|
||||||
|
class Controller extends BaseController
|
||||||
|
{
|
||||||
|
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||||
|
}
|
26
app/Http/Controllers/DeactivateAliasController.php
Normal file
26
app/Http/Controllers/DeactivateAliasController.php
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
class DeactivateAliasController extends Controller
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new controller instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->middleware('signed');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deactivate($id)
|
||||||
|
{
|
||||||
|
$alias = user()->aliases()->findOrFail($id);
|
||||||
|
|
||||||
|
$alias->deactivate();
|
||||||
|
|
||||||
|
return redirect()->route('aliases.index')
|
||||||
|
->with(['status' => 'Alias ' . $alias->email . ' deactivated successfully!']);
|
||||||
|
}
|
||||||
|
}
|
18
app/Http/Controllers/DefaultRecipientController.php
Normal file
18
app/Http/Controllers/DefaultRecipientController.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\UpdateDefaultRecipientRequest;
|
||||||
|
|
||||||
|
class DefaultRecipientController extends Controller
|
||||||
|
{
|
||||||
|
public function update(UpdateDefaultRecipientRequest $request)
|
||||||
|
{
|
||||||
|
$recipient = user()->verifiedRecipients()->findOrFail($request->default_recipient);
|
||||||
|
|
||||||
|
user()->default_recipient = $recipient;
|
||||||
|
user()->save();
|
||||||
|
|
||||||
|
return back()->with(['status' => 'Default Recipient Updated Successfully']);
|
||||||
|
}
|
||||||
|
}
|
42
app/Http/Controllers/DomainController.php
Normal file
42
app/Http/Controllers/DomainController.php
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\StoreDomainRequest;
|
||||||
|
use App\Http\Requests\UpdateDomainRequest;
|
||||||
|
use App\Http\Resources\DomainResource;
|
||||||
|
|
||||||
|
class DomainController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
return view('domains.index', [
|
||||||
|
'domains' => user()->domains()->with('aliases')->latest()->get()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(StoreDomainRequest $request)
|
||||||
|
{
|
||||||
|
$domain = user()->domains()->create(['domain' => $request->domain]);
|
||||||
|
|
||||||
|
return new DomainResource($domain->fresh());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(UpdateDomainRequest $request, $id)
|
||||||
|
{
|
||||||
|
$domain = user()->domains()->findOrFail($id);
|
||||||
|
|
||||||
|
$domain->update(['description' => $request->description]);
|
||||||
|
|
||||||
|
return new DomainResource($domain);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
$domain = user()->domains()->findOrFail($id);
|
||||||
|
|
||||||
|
$domain->delete();
|
||||||
|
|
||||||
|
return response('', 204);
|
||||||
|
}
|
||||||
|
}
|
15
app/Http/Controllers/FromNameController.php
Normal file
15
app/Http/Controllers/FromNameController.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\UpdateFromNameRequest;
|
||||||
|
|
||||||
|
class FromNameController extends Controller
|
||||||
|
{
|
||||||
|
public function update(UpdateFromNameRequest $request)
|
||||||
|
{
|
||||||
|
user()->update(['from_name' => $request->from_name]);
|
||||||
|
|
||||||
|
return back()->with(['status' => 'From Name Updated Successfully']);
|
||||||
|
}
|
||||||
|
}
|
21
app/Http/Controllers/PasswordController.php
Normal file
21
app/Http/Controllers/PasswordController.php
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\UpdatePasswordRequest;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
|
||||||
|
class PasswordController extends Controller
|
||||||
|
{
|
||||||
|
public function update(UpdatePasswordRequest $request)
|
||||||
|
{
|
||||||
|
if (!Hash::check($request->current, user()->password)) {
|
||||||
|
return back()->withErrors(['current' => 'Current password incorrect']);
|
||||||
|
}
|
||||||
|
|
||||||
|
user()->password = Hash::make($request->password);
|
||||||
|
user()->save();
|
||||||
|
|
||||||
|
return back()->with(['status' => 'Password Updated Successfully']);
|
||||||
|
}
|
||||||
|
}
|
43
app/Http/Controllers/RecipientController.php
Normal file
43
app/Http/Controllers/RecipientController.php
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\StoreRecipientRequest;
|
||||||
|
use App\Http\Resources\RecipientResource;
|
||||||
|
|
||||||
|
class RecipientController extends Controller
|
||||||
|
{
|
||||||
|
public function index()
|
||||||
|
{
|
||||||
|
$recipients = user()->recipients()->with('aliases')->latest()->get();
|
||||||
|
|
||||||
|
return view('recipients.index', [
|
||||||
|
'recipients' => $recipients,
|
||||||
|
'aliasesUsingDefault' => user()->aliasesUsingDefault
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(StoreRecipientRequest $request)
|
||||||
|
{
|
||||||
|
$recipient = user()->recipients()->create(['email' => $request->email]);
|
||||||
|
|
||||||
|
$recipient->sendEmailVerificationNotification();
|
||||||
|
|
||||||
|
return new RecipientResource($recipient->fresh());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy($id)
|
||||||
|
{
|
||||||
|
if ($id === user()->default_recipient_id) {
|
||||||
|
return response('', 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
$recipient = user()->recipients()->findOrFail($id);
|
||||||
|
|
||||||
|
$recipient->aliases()->detach();
|
||||||
|
|
||||||
|
$recipient->delete();
|
||||||
|
|
||||||
|
return response('', 204);
|
||||||
|
}
|
||||||
|
}
|
19
app/Http/Controllers/RecipientVerificationController.php
Normal file
19
app/Http/Controllers/RecipientVerificationController.php
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
class RecipientVerificationController extends Controller
|
||||||
|
{
|
||||||
|
public function resend($id)
|
||||||
|
{
|
||||||
|
$recipient = user()->recipients()->findOrFail($id);
|
||||||
|
|
||||||
|
if ($recipient->hasVerifiedEmail()) {
|
||||||
|
return response('Email already verified', 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
$recipient->sendEmailVerificationNotification();
|
||||||
|
|
||||||
|
return response('', 200);
|
||||||
|
}
|
||||||
|
}
|
40
app/Http/Controllers/SettingController.php
Normal file
40
app/Http/Controllers/SettingController.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\DestroyAccountRequest;
|
||||||
|
use App\Jobs\DeleteAccount;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
|
||||||
|
class SettingController extends Controller
|
||||||
|
{
|
||||||
|
public function show()
|
||||||
|
{
|
||||||
|
$twoFactor = app('pragmarx.google2fa');
|
||||||
|
|
||||||
|
$qrCode = $twoFactor->getQRCodeInline(
|
||||||
|
config('app.name'),
|
||||||
|
user()->email,
|
||||||
|
user()->two_factor_secret
|
||||||
|
);
|
||||||
|
|
||||||
|
return view('settings.show', [
|
||||||
|
'user' => user(),
|
||||||
|
'recipientOptions' => user()->verifiedRecipients,
|
||||||
|
'authSecret' => user()->two_factor_secret,
|
||||||
|
'qrCode' => $qrCode
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy(DestroyAccountRequest $request)
|
||||||
|
{
|
||||||
|
if (!Hash::check($request->current_password_delete, user()->password)) {
|
||||||
|
return back()->withErrors(['current_password_delete' => 'Incorrect password entered']);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteAccount::dispatch(user());
|
||||||
|
|
||||||
|
return redirect()->route('login')
|
||||||
|
->with(['status' => 'Account deleted successfully!']);
|
||||||
|
}
|
||||||
|
}
|
66
app/Http/Controllers/TwoFactorAuthController.php
Normal file
66
app/Http/Controllers/TwoFactorAuthController.php
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Http\Requests\EnableTwoFactorAuthRequest;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
use PragmaRX\Google2FALaravel\Support\Authenticator;
|
||||||
|
|
||||||
|
class TwoFactorAuthController extends Controller
|
||||||
|
{
|
||||||
|
protected $twoFactor;
|
||||||
|
protected $authenticator;
|
||||||
|
|
||||||
|
public function __construct(Request $request)
|
||||||
|
{
|
||||||
|
$this->twoFactor = app('pragmarx.google2fa');
|
||||||
|
$this->authenticator = app(Authenticator::class)->boot($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function store(EnableTwoFactorAuthRequest $request)
|
||||||
|
{
|
||||||
|
if (!$this->twoFactor->verifyKey(user()->two_factor_secret, $request->two_factor_token)) {
|
||||||
|
return back()->withErrors(['two_factor_token' => 'The token you entered was incorrect']);
|
||||||
|
}
|
||||||
|
|
||||||
|
user()->update(['two_factor_enabled' => true]);
|
||||||
|
|
||||||
|
$this->authenticator->login();
|
||||||
|
|
||||||
|
return back()->with(['status' => '2FA Enabled Successfully']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update()
|
||||||
|
{
|
||||||
|
if (user()->two_factor_enabled) {
|
||||||
|
return back()->withErrors(['regenerate_2fa' => 'You must disable 2FA before you can regenerate your secret key']);
|
||||||
|
}
|
||||||
|
|
||||||
|
user()->update(['two_factor_secret' => $this->twoFactor->generateSecretKey()]);
|
||||||
|
|
||||||
|
return back()->with(['status' => '2FA Secret Successfully Regenerated']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function destroy(Request $request)
|
||||||
|
{
|
||||||
|
if (!Hash::check($request->current_password_2fa, user()->password)) {
|
||||||
|
return back()->withErrors(['current_password_2fa' => 'Current password incorrect']);
|
||||||
|
}
|
||||||
|
|
||||||
|
user()->update(['two_factor_enabled' => false]);
|
||||||
|
|
||||||
|
$this->authenticator->logout();
|
||||||
|
|
||||||
|
return back()->with(['status' => '2FA Disabled Successfully']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function authenticateTwoFactor(Request $request)
|
||||||
|
{
|
||||||
|
if ($request->session()->has('intended_path')) {
|
||||||
|
return redirect($request->session()->pull('intended_path'));
|
||||||
|
}
|
||||||
|
|
||||||
|
redirect()->intended($request->redirectPath);
|
||||||
|
}
|
||||||
|
}
|
81
app/Http/Kernel.php
Normal file
81
app/Http/Kernel.php
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\Kernel as HttpKernel;
|
||||||
|
|
||||||
|
class Kernel extends HttpKernel
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The application's global HTTP middleware stack.
|
||||||
|
*
|
||||||
|
* These middleware are run during every request to your application.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $middleware = [
|
||||||
|
\App\Http\Middleware\CheckForMaintenanceMode::class,
|
||||||
|
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||||
|
\App\Http\Middleware\TrimStrings::class,
|
||||||
|
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
|
||||||
|
\App\Http\Middleware\TrustProxies::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The application's route middleware groups.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $middlewareGroups = [
|
||||||
|
'web' => [
|
||||||
|
\App\Http\Middleware\EncryptCookies::class,
|
||||||
|
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||||
|
\Illuminate\Session\Middleware\StartSession::class,
|
||||||
|
// \Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||||
|
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||||
|
\App\Http\Middleware\VerifyCsrfToken::class,
|
||||||
|
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||||
|
],
|
||||||
|
|
||||||
|
'api' => [
|
||||||
|
'throttle:60,1',
|
||||||
|
'bindings',
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The application's route middleware.
|
||||||
|
*
|
||||||
|
* These middleware may be assigned to groups or used individually.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $routeMiddleware = [
|
||||||
|
'auth' => \App\Http\Middleware\Authenticate::class,
|
||||||
|
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||||
|
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||||
|
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||||
|
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||||
|
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||||
|
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
|
||||||
|
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
|
||||||
|
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
|
||||||
|
'2fa' => \App\Http\Middleware\VerifyTwoFactorAuth::class,
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The priority-sorted list of middleware.
|
||||||
|
*
|
||||||
|
* This forces non-global middleware to always be in the given order.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $middlewarePriority = [
|
||||||
|
\Illuminate\Session\Middleware\StartSession::class,
|
||||||
|
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||||
|
\App\Http\Middleware\Authenticate::class,
|
||||||
|
\Illuminate\Session\Middleware\AuthenticateSession::class,
|
||||||
|
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||||
|
\Illuminate\Auth\Middleware\Authorize::class,
|
||||||
|
];
|
||||||
|
}
|
21
app/Http/Middleware/Authenticate.php
Normal file
21
app/Http/Middleware/Authenticate.php
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Illuminate\Auth\Middleware\Authenticate as Middleware;
|
||||||
|
|
||||||
|
class Authenticate extends Middleware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the path the user should be redirected to when they are not authenticated.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function redirectTo($request)
|
||||||
|
{
|
||||||
|
if (! $request->expectsJson()) {
|
||||||
|
return route('login');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
17
app/Http/Middleware/CheckForMaintenanceMode.php
Normal file
17
app/Http/Middleware/CheckForMaintenanceMode.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
|
||||||
|
|
||||||
|
class CheckForMaintenanceMode extends Middleware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The URIs that should be reachable while maintenance mode is enabled.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $except = [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
17
app/Http/Middleware/EncryptCookies.php
Normal file
17
app/Http/Middleware/EncryptCookies.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Illuminate\Cookie\Middleware\EncryptCookies as Middleware;
|
||||||
|
|
||||||
|
class EncryptCookies extends Middleware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The names of the cookies that should not be encrypted.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $except = [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
26
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
26
app/Http/Middleware/RedirectIfAuthenticated.php
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
|
||||||
|
class RedirectIfAuthenticated
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \Closure $next
|
||||||
|
* @param string|null $guard
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle($request, Closure $next, $guard = null)
|
||||||
|
{
|
||||||
|
if (Auth::guard($guard)->check()) {
|
||||||
|
return redirect('/');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
}
|
18
app/Http/Middleware/TrimStrings.php
Normal file
18
app/Http/Middleware/TrimStrings.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\Middleware\TrimStrings as Middleware;
|
||||||
|
|
||||||
|
class TrimStrings extends Middleware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The names of the attributes that should not be trimmed.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $except = [
|
||||||
|
'password',
|
||||||
|
'password_confirmation',
|
||||||
|
];
|
||||||
|
}
|
23
app/Http/Middleware/TrustProxies.php
Normal file
23
app/Http/Middleware/TrustProxies.php
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Fideloper\Proxy\TrustProxies as Middleware;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class TrustProxies extends Middleware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The trusted proxies for this application.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $proxies;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The headers that should be used to detect proxies.
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $headers = Request::HEADER_X_FORWARDED_ALL;
|
||||||
|
}
|
24
app/Http/Middleware/VerifyCsrfToken.php
Normal file
24
app/Http/Middleware/VerifyCsrfToken.php
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
|
||||||
|
|
||||||
|
class VerifyCsrfToken extends Middleware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Indicates whether the XSRF-TOKEN cookie should be set on the response.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
protected $addHttpCookie = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URIs that should be excluded from CSRF verification.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $except = [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
35
app/Http/Middleware/VerifyTwoFactorAuth.php
Normal file
35
app/Http/Middleware/VerifyTwoFactorAuth.php
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
use PragmaRX\Google2FALaravel\Middleware;
|
||||||
|
use PragmaRX\Google2FALaravel\Support\Authenticator;
|
||||||
|
|
||||||
|
class VerifyTwoFactorAuth extends Middleware
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Http\Request $request
|
||||||
|
* @param \Closure $next
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function handle($request, Closure $next)
|
||||||
|
{
|
||||||
|
$authenticator = app(Authenticator::class)->boot($request);
|
||||||
|
|
||||||
|
if ($authenticator->isAuthenticated() || ! $request->user()->two_factor_enabled) {
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! Str::endsWith($request->url(), '/login/2fa')) {
|
||||||
|
$request->session()->put([
|
||||||
|
'intended_path' => $request->url()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $authenticator->makeRequestOneTimePasswordResponse();
|
||||||
|
}
|
||||||
|
}
|
30
app/Http/Requests/DestroyAccountRequest.php
Normal file
30
app/Http/Requests/DestroyAccountRequest.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class DestroyAccountRequest 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 [
|
||||||
|
'current_password_delete' => 'required|string'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
30
app/Http/Requests/DisableTwoFactorAuthRequest.php
Normal file
30
app/Http/Requests/DisableTwoFactorAuthRequest.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class DisableTwoFactorAuthRequest 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 [
|
||||||
|
'current_password_2fa' => 'required|string'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
30
app/Http/Requests/EnableTwoFactorAuthRequest.php
Normal file
30
app/Http/Requests/EnableTwoFactorAuthRequest.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class EnableTwoFactorAuthRequest 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 [
|
||||||
|
'two_factor_token' => 'required|min:6'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
35
app/Http/Requests/StoreAliasRecipientRequest.php
Normal file
35
app/Http/Requests/StoreAliasRecipientRequest.php
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use App\Rules\VerifiedRecipientId;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class StoreAliasRecipientRequest 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 [
|
||||||
|
'recipient_ids' => [
|
||||||
|
'array',
|
||||||
|
'max:10',
|
||||||
|
new VerifiedRecipientId
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
37
app/Http/Requests/StoreDomainRequest.php
Normal file
37
app/Http/Requests/StoreDomainRequest.php
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use App\Rules\ValidDomain;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class StoreDomainRequest 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 [
|
||||||
|
'domain' => [
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
'max:50',
|
||||||
|
'unique:domains',
|
||||||
|
new ValidDomain
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
37
app/Http/Requests/StoreRecipientRequest.php
Normal file
37
app/Http/Requests/StoreRecipientRequest.php
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use App\Rules\UniqueUserRecipient;
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class StoreRecipientRequest 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 [
|
||||||
|
'email' => [
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
'max:254',
|
||||||
|
'email',
|
||||||
|
new UniqueUserRecipient
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
30
app/Http/Requests/UpdateAliasRequest.php
Normal file
30
app/Http/Requests/UpdateAliasRequest.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class UpdateAliasRequest 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 [
|
||||||
|
'description' => 'nullable|max:100'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
30
app/Http/Requests/UpdateBannerLocationRequest.php
Normal file
30
app/Http/Requests/UpdateBannerLocationRequest.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class UpdateBannerLocationRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize()
|
||||||
|
{
|
||||||
|
return true; // Pro plan
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'banner_location' => 'required|string|in:top,bottom,off'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
30
app/Http/Requests/UpdateDefaultRecipientRequest.php
Normal file
30
app/Http/Requests/UpdateDefaultRecipientRequest.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class UpdateDefaultRecipientRequest 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 [
|
||||||
|
'default_recipient' => 'required|string'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
30
app/Http/Requests/UpdateDomainRequest.php
Normal file
30
app/Http/Requests/UpdateDomainRequest.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class UpdateDomainRequest 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 [
|
||||||
|
'description' => 'nullable|max:100'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
30
app/Http/Requests/UpdateFromNameRequest.php
Normal file
30
app/Http/Requests/UpdateFromNameRequest.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class UpdateFromNameRequest extends FormRequest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Determine if the user is authorized to make this request.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function authorize()
|
||||||
|
{
|
||||||
|
return true; // Pro plan
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation rules that apply to the request.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function rules()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'from_name' => 'nullable|string|max:50'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
31
app/Http/Requests/UpdatePasswordRequest.php
Normal file
31
app/Http/Requests/UpdatePasswordRequest.php
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Requests;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Http\FormRequest;
|
||||||
|
|
||||||
|
class UpdatePasswordRequest 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 [
|
||||||
|
'current' => 'required|string',
|
||||||
|
'password' => 'required|string|confirmed'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
24
app/Http/Resources/AliasResource.php
Normal file
24
app/Http/Resources/AliasResource.php
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class AliasResource extends JsonResource
|
||||||
|
{
|
||||||
|
public function toArray($request)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'user_id' => $this->user_id,
|
||||||
|
'email' => $this->email,
|
||||||
|
'active' => $this->active,
|
||||||
|
'description' => $this->description,
|
||||||
|
'emails_forwarded' => $this->emails_forwarded,
|
||||||
|
'emails_blocked' => $this->emails_blocked,
|
||||||
|
'recipients' => $this->recipients,
|
||||||
|
'created_at' => $this->created_at->toDateTimeString(),
|
||||||
|
'updated_at' => $this->updated_at->toDateTimeString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
22
app/Http/Resources/DomainResource.php
Normal file
22
app/Http/Resources/DomainResource.php
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class DomainResource extends JsonResource
|
||||||
|
{
|
||||||
|
public function toArray($request)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'user_id' => $this->user_id,
|
||||||
|
'domain' => $this->domain,
|
||||||
|
'description' => $this->description,
|
||||||
|
'aliases' => $this->aliases,
|
||||||
|
'active' => $this->active,
|
||||||
|
'created_at' => $this->created_at->toDateTimeString(),
|
||||||
|
'updated_at' => $this->updated_at->toDateTimeString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
21
app/Http/Resources/RecipientResource.php
Normal file
21
app/Http/Resources/RecipientResource.php
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Resources;
|
||||||
|
|
||||||
|
use Illuminate\Http\Resources\Json\JsonResource;
|
||||||
|
|
||||||
|
class RecipientResource extends JsonResource
|
||||||
|
{
|
||||||
|
public function toArray($request)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'id' => $this->id,
|
||||||
|
'user_id' => $this->user_id,
|
||||||
|
'alias_id' => $this->alias_id,
|
||||||
|
'email' => $this->email,
|
||||||
|
'aliases' => $this->aliases,
|
||||||
|
'created_at' => $this->created_at->toDateTimeString(),
|
||||||
|
'updated_at' => $this->updated_at->toDateTimeString(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
45
app/Jobs/DeleteAccount.php
Normal file
45
app/Jobs/DeleteAccount.php
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Jobs;
|
||||||
|
|
||||||
|
use App\DeletedUsername;
|
||||||
|
use App\User;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Foundation\Bus\Dispatchable;
|
||||||
|
use Illuminate\Queue\InteractsWithQueue;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class DeleteAccount implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||||
|
|
||||||
|
protected $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new job instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(User $user)
|
||||||
|
{
|
||||||
|
$this->user = $user;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the job.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
DeletedUsername::create(['username' => $this->user->username]);
|
||||||
|
|
||||||
|
$this->user->aliasRecipients()->delete();
|
||||||
|
$this->user->aliases()->whereNull('domain_id')->forceDelete();
|
||||||
|
$this->user->aliases()->delete();
|
||||||
|
$this->user->recipients()->delete();
|
||||||
|
$this->user->domains()->delete();
|
||||||
|
$this->user->delete();
|
||||||
|
}
|
||||||
|
}
|
91
app/Mail/ForwardEmail.php
Normal file
91
app/Mail/ForwardEmail.php
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Mail;
|
||||||
|
|
||||||
|
use App\Alias;
|
||||||
|
use App\EmailData;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Mail\Mailable;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
use Illuminate\Support\Facades\URL;
|
||||||
|
|
||||||
|
class ForwardEmail extends Mailable implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Queueable, SerializesModels;
|
||||||
|
|
||||||
|
protected $user;
|
||||||
|
protected $alias;
|
||||||
|
protected $sender;
|
||||||
|
protected $emailSubject;
|
||||||
|
protected $emailText;
|
||||||
|
protected $emailHtml;
|
||||||
|
protected $emailAttachments;
|
||||||
|
protected $deactivateUrl;
|
||||||
|
protected $bannerLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new message instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(Alias $alias, EmailData $emailData)
|
||||||
|
{
|
||||||
|
$this->alias = $alias;
|
||||||
|
$this->sender = $emailData->sender;
|
||||||
|
$this->emailSubject = $emailData->subject;
|
||||||
|
$this->emailText = $emailData->text;
|
||||||
|
$this->emailHtml = $emailData->html;
|
||||||
|
$this->emailAttachments = $emailData->attachments;
|
||||||
|
|
||||||
|
$this->deactivateUrl = URL::signedRoute('deactivate', ['alias' => $alias->id]);
|
||||||
|
$this->bannerLocation = $this->alias->user->banner_location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the message.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
$replyToEmail = $this->alias->local_part.'+'.sha1(config('anonaddy.secret').$this->sender).'@'.$this->alias->domain;
|
||||||
|
|
||||||
|
$email = $this
|
||||||
|
->from(config('mail.from.address'), $this->sender.' via '.config('app.name'))
|
||||||
|
->replyTo($replyToEmail, $this->sender)
|
||||||
|
->subject($this->emailSubject)
|
||||||
|
->text('emails.forward.text')->with([
|
||||||
|
'text' => $this->emailText
|
||||||
|
])
|
||||||
|
->with([
|
||||||
|
'location' => $this->bannerLocation,
|
||||||
|
'deactivateUrl' => $this->deactivateUrl,
|
||||||
|
'aliasEmail' => $this->alias->email,
|
||||||
|
'fromEmail' => $this->sender
|
||||||
|
])
|
||||||
|
->withSwiftMessage(function ($message) {
|
||||||
|
$message->getHeaders()
|
||||||
|
->addTextHeader('List-Unsubscribe', '<mailto:' . $this->alias->id . '@unsubscribe.' . config('anonaddy.domain') . '>, <' . $this->deactivateUrl . '>');
|
||||||
|
|
||||||
|
$message->getHeaders()
|
||||||
|
->addTextHeader('Return-Path', config('mail.from.address'));
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($this->emailHtml) {
|
||||||
|
$email->view('emails.forward.html')->with([
|
||||||
|
'html' => $this->emailHtml
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->emailAttachments as $attachment) {
|
||||||
|
$email->attachData(
|
||||||
|
base64_decode($attachment['stream']),
|
||||||
|
$attachment['file_name'],
|
||||||
|
['mime' => $attachment['mime']]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $email;
|
||||||
|
}
|
||||||
|
}
|
76
app/Mail/ReplyToEmail.php
Normal file
76
app/Mail/ReplyToEmail.php
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Mail;
|
||||||
|
|
||||||
|
use App\Alias;
|
||||||
|
use App\EmailData;
|
||||||
|
use App\User;
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Mail\Mailable;
|
||||||
|
use Illuminate\Queue\SerializesModels;
|
||||||
|
|
||||||
|
class ReplyToEmail extends Mailable implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Queueable, SerializesModels;
|
||||||
|
|
||||||
|
protected $user;
|
||||||
|
protected $alias;
|
||||||
|
protected $emailSubject;
|
||||||
|
protected $emailText;
|
||||||
|
protected $emailHtml;
|
||||||
|
protected $emailAttachments;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new message instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct(User $user, Alias $alias, EmailData $emailData)
|
||||||
|
{
|
||||||
|
$this->user = $user;
|
||||||
|
$this->alias = $alias;
|
||||||
|
$this->emailSubject = $emailData->subject;
|
||||||
|
$this->emailText = $emailData->text;
|
||||||
|
$this->emailHtml = $emailData->html;
|
||||||
|
$this->emailAttachments = $emailData->attachments;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the message.
|
||||||
|
*
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function build()
|
||||||
|
{
|
||||||
|
$fromName = $this->user->from_name ? $this->user->from_name : $this->alias->email.' via '.config('app.name');
|
||||||
|
|
||||||
|
$email = $this
|
||||||
|
->from(config('mail.from.address'), $fromName)
|
||||||
|
->replyTo($this->alias->email, $fromName)
|
||||||
|
->subject($this->emailSubject)
|
||||||
|
->text('emails.reply.text')->with([
|
||||||
|
'text' => $this->emailText
|
||||||
|
])
|
||||||
|
->withSwiftMessage(function ($message) {
|
||||||
|
$message->getHeaders()
|
||||||
|
->addTextHeader('Return-Path', config('mail.from.address'));
|
||||||
|
});
|
||||||
|
|
||||||
|
if ($this->emailHtml) {
|
||||||
|
$email->view('emails.reply.html')->with([
|
||||||
|
'html' => $this->emailHtml
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($this->emailAttachments as $attachment) {
|
||||||
|
$email->attachData(
|
||||||
|
base64_decode($attachment['stream']),
|
||||||
|
$attachment['file_name'],
|
||||||
|
['mime' => $attachment['mime']]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $email;
|
||||||
|
}
|
||||||
|
}
|
69
app/Notifications/NearBandwidthLimit.php
Normal file
69
app/Notifications/NearBandwidthLimit.php
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Notifications;
|
||||||
|
|
||||||
|
use Illuminate\Bus\Queueable;
|
||||||
|
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||||
|
use Illuminate\Notifications\Messages\MailMessage;
|
||||||
|
use Illuminate\Notifications\Notification;
|
||||||
|
|
||||||
|
class NearBandwidthLimit extends Notification implements ShouldQueue
|
||||||
|
{
|
||||||
|
use Queueable;
|
||||||
|
|
||||||
|
protected $month;
|
||||||
|
protected $reset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new notification instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->month = now()->format('F');
|
||||||
|
$this->reset = now()->addMonthsNoOverflow(1)->startOfMonth()->format('jS F');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the notification's delivery channels.
|
||||||
|
*
|
||||||
|
* @param mixed $notifiable
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function via($notifiable)
|
||||||
|
{
|
||||||
|
return ['mail'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the mail representation of the notification.
|
||||||
|
*
|
||||||
|
* @param mixed $notifiable
|
||||||
|
* @return \Illuminate\Notifications\Messages\MailMessage
|
||||||
|
*/
|
||||||
|
public function toMail($notifiable)
|
||||||
|
{
|
||||||
|
return (new MailMessage)
|
||||||
|
->subject("You're close to your bandwidth limit for ".$this->month)
|
||||||
|
->markdown('mail.near_bandwidth_limit', [
|
||||||
|
'bandwidthUsage' => $notifiable->bandwidth_mb,
|
||||||
|
'bandwidthLimit' => $notifiable->getBandwidthLimitMb(),
|
||||||
|
'month' => $this->month,
|
||||||
|
'reset' => $this->reset
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the array representation of the notification.
|
||||||
|
*
|
||||||
|
* @param mixed $notifiable
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function toArray($notifiable)
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
//
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
28
app/Providers/AppServiceProvider.php
Normal file
28
app/Providers/AppServiceProvider.php
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
|
class AppServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Register any application services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function register()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bootstrap any application services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function boot()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
29
app/Providers/AuthServiceProvider.php
Normal file
29
app/Providers/AuthServiceProvider.php
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||||
|
|
||||||
|
class AuthServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The policy mappings for the application.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $policies = [
|
||||||
|
'App\Model' => 'App\Policies\ModelPolicy',
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register any authentication / authorization services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function boot()
|
||||||
|
{
|
||||||
|
$this->registerPolicies();
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
21
app/Providers/BroadcastServiceProvider.php
Normal file
21
app/Providers/BroadcastServiceProvider.php
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Broadcast;
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
|
class BroadcastServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Bootstrap any application services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function boot()
|
||||||
|
{
|
||||||
|
Broadcast::routes();
|
||||||
|
|
||||||
|
require base_path('routes/channels.php');
|
||||||
|
}
|
||||||
|
}
|
34
app/Providers/EventServiceProvider.php
Normal file
34
app/Providers/EventServiceProvider.php
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Auth\Events\Registered;
|
||||||
|
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
|
||||||
|
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
|
||||||
|
use Illuminate\Support\Facades\Event;
|
||||||
|
|
||||||
|
class EventServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The event listener mappings for the application.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $listen = [
|
||||||
|
Registered::class => [
|
||||||
|
SendEmailVerificationNotification::class,
|
||||||
|
],
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register any events for your application.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function boot()
|
||||||
|
{
|
||||||
|
parent::boot();
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
28
app/Providers/HelperServiceProvider.php
Normal file
28
app/Providers/HelperServiceProvider.php
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Support\ServiceProvider;
|
||||||
|
|
||||||
|
class HelperServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Register services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function register()
|
||||||
|
{
|
||||||
|
require_once(app_path().'/Helpers/Helper.php');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bootstrap services.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function boot()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
}
|
73
app/Providers/RouteServiceProvider.php
Normal file
73
app/Providers/RouteServiceProvider.php
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Providers;
|
||||||
|
|
||||||
|
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||||
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
|
class RouteServiceProvider extends ServiceProvider
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* This namespace is applied to your controller routes.
|
||||||
|
*
|
||||||
|
* In addition, it is set as the URL generator's root namespace.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $namespace = 'App\Http\Controllers';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define your route model bindings, pattern filters, etc.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function boot()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
|
||||||
|
parent::boot();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the routes for the application.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function map()
|
||||||
|
{
|
||||||
|
$this->mapApiRoutes();
|
||||||
|
|
||||||
|
$this->mapWebRoutes();
|
||||||
|
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the "web" routes for the application.
|
||||||
|
*
|
||||||
|
* These routes all receive session state, CSRF protection, etc.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function mapWebRoutes()
|
||||||
|
{
|
||||||
|
Route::middleware('web')
|
||||||
|
->namespace($this->namespace)
|
||||||
|
->group(base_path('routes/web.php'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the "api" routes for the application.
|
||||||
|
*
|
||||||
|
* These routes are typically stateless.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function mapApiRoutes()
|
||||||
|
{
|
||||||
|
Route::prefix('api')
|
||||||
|
->middleware('api')
|
||||||
|
->namespace($this->namespace)
|
||||||
|
->group(base_path('routes/api.php'));
|
||||||
|
}
|
||||||
|
}
|
86
app/Recipient.php
Normal file
86
app/Recipient.php
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
use App\Traits\HasEncryptedAttributes;
|
||||||
|
use App\Traits\HasUuid;
|
||||||
|
use Illuminate\Auth\Notifications\VerifyEmail;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
|
||||||
|
class Recipient extends Model
|
||||||
|
{
|
||||||
|
use Notifiable, HasUuid, HasEncryptedAttributes;
|
||||||
|
|
||||||
|
public $incrementing = false;
|
||||||
|
|
||||||
|
protected $encrypted = [
|
||||||
|
'email'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'email',
|
||||||
|
'user_id',
|
||||||
|
'email_verified_at'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $dates = [
|
||||||
|
'created_at',
|
||||||
|
'updated_at',
|
||||||
|
'email_verified_at'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $casts = [
|
||||||
|
'id' => 'string',
|
||||||
|
'user_id' => 'string'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the user the recipient belongs to.
|
||||||
|
*/
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the aliases that have this recipient attached.
|
||||||
|
*/
|
||||||
|
public function aliases()
|
||||||
|
{
|
||||||
|
return $this->belongsToMany(Alias::class, 'alias_recipients')->using(AliasRecipient::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the recipient has a verified email address.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasVerifiedEmail()
|
||||||
|
{
|
||||||
|
return ! is_null($this->email_verified_at);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark this recipient's email as verified.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function markEmailAsVerified()
|
||||||
|
{
|
||||||
|
return $this->forceFill([
|
||||||
|
'email_verified_at' => $this->freshTimestamp(),
|
||||||
|
])->save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send the email verification notification.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function sendEmailVerificationNotification()
|
||||||
|
{
|
||||||
|
$this->notify(new VerifyEmail);
|
||||||
|
}
|
||||||
|
}
|
40
app/Rules/NotBlacklisted.php
Normal file
40
app/Rules/NotBlacklisted.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Rules;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Validation\Rule;
|
||||||
|
|
||||||
|
class NotBlacklisted implements Rule
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new rule instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the validation rule passes.
|
||||||
|
*
|
||||||
|
* @param string $attribute
|
||||||
|
* @param mixed $value
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function passes($attribute, $value)
|
||||||
|
{
|
||||||
|
return !in_array($value, config('anonaddy.blacklist'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation error message.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function message()
|
||||||
|
{
|
||||||
|
return 'The :attribute has already been taken.';
|
||||||
|
}
|
||||||
|
}
|
47
app/Rules/NotDeletedUsername.php
Normal file
47
app/Rules/NotDeletedUsername.php
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Rules;
|
||||||
|
|
||||||
|
use App\DeletedUsername;
|
||||||
|
use Illuminate\Contracts\Validation\Rule;
|
||||||
|
|
||||||
|
class NotDeletedUsername implements Rule
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new rule instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the validation rule passes.
|
||||||
|
*
|
||||||
|
* @param string $attribute
|
||||||
|
* @param mixed $value
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function passes($attribute, $value)
|
||||||
|
{
|
||||||
|
$deletedUsernames = DeletedUsername::all()
|
||||||
|
->map(function ($item) {
|
||||||
|
return $item->username;
|
||||||
|
})
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
return !in_array($value, $deletedUsernames);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation error message.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function message()
|
||||||
|
{
|
||||||
|
return 'The :attribute has already been taken.';
|
||||||
|
}
|
||||||
|
}
|
50
app/Rules/UniqueUserRecipient.php
Normal file
50
app/Rules/UniqueUserRecipient.php
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Rules;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Validation\Rule;
|
||||||
|
|
||||||
|
class UniqueUserRecipient implements Rule
|
||||||
|
{
|
||||||
|
protected $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new rule instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->user = user();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the validation rule passes.
|
||||||
|
*
|
||||||
|
* @param string $attribute
|
||||||
|
* @param mixed $value
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function passes($attribute, $value)
|
||||||
|
{
|
||||||
|
$userRecipients = $this->user
|
||||||
|
->recipients()
|
||||||
|
->get()
|
||||||
|
->map(function ($recipient) {
|
||||||
|
return $recipient->email;
|
||||||
|
})
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
return !in_array($value, $userRecipients);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation error message.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function message()
|
||||||
|
{
|
||||||
|
return 'A recipient with that email already exists.';
|
||||||
|
}
|
||||||
|
}
|
40
app/Rules/ValidDomain.php
Normal file
40
app/Rules/ValidDomain.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Rules;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Validation\Rule;
|
||||||
|
|
||||||
|
class ValidDomain implements Rule
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new rule instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the validation rule passes.
|
||||||
|
*
|
||||||
|
* @param string $attribute
|
||||||
|
* @param mixed $value
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function passes($attribute, $value)
|
||||||
|
{
|
||||||
|
return preg_match('/(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{0,62}[a-zA-Z0-9]\.)+[a-zA-Z]{2,63}$)/', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation error message.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function message()
|
||||||
|
{
|
||||||
|
return 'Invalid domain name.';
|
||||||
|
}
|
||||||
|
}
|
56
app/Rules/VerifiedRecipientId.php
Normal file
56
app/Rules/VerifiedRecipientId.php
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Rules;
|
||||||
|
|
||||||
|
use Illuminate\Contracts\Validation\Rule;
|
||||||
|
|
||||||
|
class VerifiedRecipientId implements Rule
|
||||||
|
{
|
||||||
|
protected $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new rule instance.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->user = user();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the validation rule passes.
|
||||||
|
*
|
||||||
|
* @param string $attribute
|
||||||
|
* @param mixed $ids
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function passes($attribute, $ids)
|
||||||
|
{
|
||||||
|
$verifiedRecipientIds = $this->user
|
||||||
|
->verifiedRecipients()
|
||||||
|
->get()
|
||||||
|
->map(function ($recipient) {
|
||||||
|
return $recipient->id;
|
||||||
|
})
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
foreach ($ids as $id) {
|
||||||
|
if (!in_array($id, $verifiedRecipientIds)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the validation error message.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function message()
|
||||||
|
{
|
||||||
|
return 'Invalid Recipient.';
|
||||||
|
}
|
||||||
|
}
|
40
app/Traits/HasEncryptedAttributes.php
Normal file
40
app/Traits/HasEncryptedAttributes.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Traits;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Crypt;
|
||||||
|
|
||||||
|
trait HasEncryptedAttributes
|
||||||
|
{
|
||||||
|
public function getAttribute($key)
|
||||||
|
{
|
||||||
|
$value = parent::getAttribute($key);
|
||||||
|
|
||||||
|
if (!is_null($value) && in_array($key, $this->encrypted)) {
|
||||||
|
$value = Crypt::decrypt($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setAttribute($key, $value)
|
||||||
|
{
|
||||||
|
if (!is_null($value) && in_array($key, $this->encrypted)) {
|
||||||
|
$value = Crypt::encrypt($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent::setAttribute($key, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function attributesToArray()
|
||||||
|
{
|
||||||
|
$attributes = parent::attributesToArray();
|
||||||
|
|
||||||
|
foreach ($this->encrypted as $key) {
|
||||||
|
if (isset($attributes[$key])) {
|
||||||
|
$attributes[$key] = Crypt::decrypt($attributes[$key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $attributes;
|
||||||
|
}
|
||||||
|
}
|
17
app/Traits/HasUuid.php
Normal file
17
app/Traits/HasUuid.php
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Traits;
|
||||||
|
|
||||||
|
use Ramsey\Uuid\Uuid;
|
||||||
|
|
||||||
|
trait HasUuid
|
||||||
|
{
|
||||||
|
protected static function bootHasUuid()
|
||||||
|
{
|
||||||
|
static::creating(function ($model) {
|
||||||
|
if (!$model->id) {
|
||||||
|
$model->{$model->getKeyName()} = Uuid::uuid4();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
208
app/User.php
Normal file
208
app/User.php
Normal file
|
@ -0,0 +1,208 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App;
|
||||||
|
|
||||||
|
use App\Traits\HasEncryptedAttributes;
|
||||||
|
use App\Traits\HasUuid;
|
||||||
|
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||||
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
|
use Illuminate\Notifications\Notifiable;
|
||||||
|
|
||||||
|
class User extends Authenticatable implements MustVerifyEmail
|
||||||
|
{
|
||||||
|
use Notifiable, HasUuid, HasEncryptedAttributes;
|
||||||
|
|
||||||
|
public $incrementing = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that are mass assignable.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $fillable = [
|
||||||
|
'id',
|
||||||
|
'username',
|
||||||
|
'from_name',
|
||||||
|
'banner_location',
|
||||||
|
'bandwidth',
|
||||||
|
'default_recipient_id',
|
||||||
|
'password',
|
||||||
|
'two_factor_enabled',
|
||||||
|
'two_factor_secret'
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $encrypted = [
|
||||||
|
'from_name',
|
||||||
|
'two_factor_secret'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be hidden for arrays.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $hidden = [
|
||||||
|
'password',
|
||||||
|
'remember_token',
|
||||||
|
'two_factor_secret'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The attributes that should be cast to native types.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $casts = [
|
||||||
|
'id' => 'string',
|
||||||
|
'default_recipient_id' => 'string',
|
||||||
|
'two_factor_enabled' => 'boolean',
|
||||||
|
];
|
||||||
|
|
||||||
|
protected $dates = [
|
||||||
|
'created_at',
|
||||||
|
'updated_at',
|
||||||
|
'email_verified_at'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the user's username.
|
||||||
|
*/
|
||||||
|
public function setUsernameAttribute($value)
|
||||||
|
{
|
||||||
|
$this->attributes['username'] = strtolower($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the user's default email.
|
||||||
|
*/
|
||||||
|
public function getEmailAttribute()
|
||||||
|
{
|
||||||
|
return $this->defaultRecipient->email;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the user's default email verified_at.
|
||||||
|
*/
|
||||||
|
public function getEmailVerifiedAtAttribute()
|
||||||
|
{
|
||||||
|
return $this->defaultRecipient->email_verified_at;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the user's default email verified_at.
|
||||||
|
*/
|
||||||
|
public function setEmailVerifiedAtAttribute($value)
|
||||||
|
{
|
||||||
|
$this->defaultRecipient->update(['email_verified_at' => $value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the user's default email.
|
||||||
|
*/
|
||||||
|
public function setDefaultRecipientAttribute($recipient)
|
||||||
|
{
|
||||||
|
$this->attributes['default_recipient_id'] = $recipient->id;
|
||||||
|
$this->setRelation('defaultRecipient', $recipient);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the user's bandwidth in MB.
|
||||||
|
*/
|
||||||
|
public function getBandwidthMbAttribute()
|
||||||
|
{
|
||||||
|
return round($this->bandwidth / 1024 / 1024, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the user's default recipient.
|
||||||
|
*/
|
||||||
|
public function defaultRecipient()
|
||||||
|
{
|
||||||
|
return $this->hasOne(Recipient::class, 'id', 'default_recipient_id');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the user's email aliases.
|
||||||
|
*/
|
||||||
|
public function aliases()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Alias::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the user's recipients.
|
||||||
|
*/
|
||||||
|
public function recipients()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Recipient::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the user's custom domains.
|
||||||
|
*/
|
||||||
|
public function domains()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Domain::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the user's verified recipients.
|
||||||
|
*/
|
||||||
|
public function verifiedRecipients()
|
||||||
|
{
|
||||||
|
return $this->recipients()->whereNotNull('email_verified_at');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the alias recipient pivot rows for the user.
|
||||||
|
*/
|
||||||
|
public function aliasRecipients()
|
||||||
|
{
|
||||||
|
return $this->hasManyThrough(AliasRecipient::class, Alias::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the user's aliases that are using the default recipient
|
||||||
|
*/
|
||||||
|
public function aliasesUsingDefault()
|
||||||
|
{
|
||||||
|
return $this->aliases()->whereDoesntHave('recipients');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hasVerifiedDefaultRecipient()
|
||||||
|
{
|
||||||
|
return ! is_null($this->defaultRecipient->email_verified_at);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function totalEmailsForwarded()
|
||||||
|
{
|
||||||
|
return $this->aliases()->sum('emails_forwarded');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function totalEmailsBlocked()
|
||||||
|
{
|
||||||
|
return $this->aliases()->sum('emails_blocked');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function totalEmailsReplied()
|
||||||
|
{
|
||||||
|
return $this->aliases()->sum('emails_replied');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBandwidthLimit()
|
||||||
|
{
|
||||||
|
// TODO check user's limit and return
|
||||||
|
return 104857600;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getBandwidthLimitMb()
|
||||||
|
{
|
||||||
|
return round($this->getBandwidthLimit() / 1024 / 1024, 2);
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function nearBandwidthLimit()
|
||||||
|
{
|
||||||
|
return ($this->bandwidth / $this->getBandwidthLimit()) > 0.9;
|
||||||
|
}
|
||||||
|
}
|
53
artisan
Normal file
53
artisan
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#!/usr/bin/env php
|
||||||
|
<?php
|
||||||
|
|
||||||
|
define('LARAVEL_START', microtime(true));
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Register The Auto Loader
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Composer provides a convenient, automatically generated class loader
|
||||||
|
| for our application. We just need to utilize it! We'll require it
|
||||||
|
| into the script here so that we do not have to worry about the
|
||||||
|
| loading of any our classes "manually". Feels great to relax.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
require __DIR__.'/vendor/autoload.php';
|
||||||
|
|
||||||
|
$app = require_once __DIR__.'/bootstrap/app.php';
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Run The Artisan Application
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| When we run the console application, the current CLI command will be
|
||||||
|
| executed in this console and the response sent back to a terminal
|
||||||
|
| or another output device for the developers. Here goes nothing!
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
$kernel = $app->make(Illuminate\Contracts\Console\Kernel::class);
|
||||||
|
|
||||||
|
$status = $kernel->handle(
|
||||||
|
$input = new Symfony\Component\Console\Input\ArgvInput,
|
||||||
|
new Symfony\Component\Console\Output\ConsoleOutput
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Shutdown The Application
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Once Artisan has finished running, we will fire off the shutdown events
|
||||||
|
| so that any final work may be done by the application before we shut
|
||||||
|
| down the process. This is the last thing to happen to the request.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
$kernel->terminate($input, $status);
|
||||||
|
|
||||||
|
exit($status);
|
55
bootstrap/app.php
Normal file
55
bootstrap/app.php
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Create The Application
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The first thing we will do is create a new Laravel application instance
|
||||||
|
| which serves as the "glue" for all the components of Laravel, and is
|
||||||
|
| the IoC container for the system binding all of the various parts.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
$app = new Illuminate\Foundation\Application(
|
||||||
|
$_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Bind Important Interfaces
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Next, we need to bind some important interfaces into the container so
|
||||||
|
| we will be able to resolve them when needed. The kernels serve the
|
||||||
|
| incoming requests to this application from both the web and CLI.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
$app->singleton(
|
||||||
|
Illuminate\Contracts\Http\Kernel::class,
|
||||||
|
App\Http\Kernel::class
|
||||||
|
);
|
||||||
|
|
||||||
|
$app->singleton(
|
||||||
|
Illuminate\Contracts\Console\Kernel::class,
|
||||||
|
App\Console\Kernel::class
|
||||||
|
);
|
||||||
|
|
||||||
|
$app->singleton(
|
||||||
|
Illuminate\Contracts\Debug\ExceptionHandler::class,
|
||||||
|
App\Exceptions\Handler::class
|
||||||
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Return The Application
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This script returns the application instance. The instance is given to
|
||||||
|
| the calling script so we can separate the building of the instances
|
||||||
|
| from the actual running of the application and sending responses.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
return $app;
|
2
bootstrap/cache/.gitignore
vendored
Executable file
2
bootstrap/cache/.gitignore
vendored
Executable file
|
@ -0,0 +1,2 @@
|
||||||
|
*
|
||||||
|
!.gitignore
|
72
composer.json
Normal file
72
composer.json
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
{
|
||||||
|
"name": "laravel/laravel",
|
||||||
|
"type": "project",
|
||||||
|
"description": "The Laravel Framework.",
|
||||||
|
"keywords": [
|
||||||
|
"framework",
|
||||||
|
"laravel"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"require": {
|
||||||
|
"php": "^7.1.3",
|
||||||
|
"bacon/bacon-qr-code": "^2.0",
|
||||||
|
"doctrine/dbal": "^2.9",
|
||||||
|
"fideloper/proxy": "^4.0",
|
||||||
|
"laravel/framework": "5.8.*",
|
||||||
|
"laravel/tinker": "^1.0",
|
||||||
|
"php-mime-mail-parser/php-mime-mail-parser": "^5.0",
|
||||||
|
"pragmarx/google2fa-laravel": "^1.0",
|
||||||
|
"predis/predis": "^1.1",
|
||||||
|
"ramsey/uuid": "^3.8"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"beyondcode/laravel-dump-server": "^1.0",
|
||||||
|
"filp/whoops": "^2.0",
|
||||||
|
"friendsofphp/php-cs-fixer": "^2.14",
|
||||||
|
"fzaninotto/faker": "^1.4",
|
||||||
|
"mockery/mockery": "^1.0",
|
||||||
|
"nunomaduro/collision": "^3.0",
|
||||||
|
"phpunit/phpunit": "^8.0"
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"optimize-autoloader": true,
|
||||||
|
"preferred-install": "dist",
|
||||||
|
"sort-packages": true
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"dont-discover": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"App\\": "app/"
|
||||||
|
},
|
||||||
|
"classmap": [
|
||||||
|
"database/seeds",
|
||||||
|
"database/factories"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"autoload-dev": {
|
||||||
|
"psr-4": {
|
||||||
|
"Tests\\": "tests/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimum-stability": "dev",
|
||||||
|
"prefer-stable": true,
|
||||||
|
"scripts": {
|
||||||
|
"post-autoload-dump": [
|
||||||
|
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||||
|
"@php artisan package:discover --ansi"
|
||||||
|
],
|
||||||
|
"post-root-package-install": [
|
||||||
|
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
||||||
|
],
|
||||||
|
"post-create-project-cmd": [
|
||||||
|
"@php artisan key:generate --ansi"
|
||||||
|
],
|
||||||
|
"format": [
|
||||||
|
"./vendor/bin/php-cs-fixer fix --config .php_cs"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
6036
composer.lock
generated
Normal file
6036
composer.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
603
config/anonaddy.php
Normal file
603
config/anonaddy.php
Normal file
|
@ -0,0 +1,603 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Admin Username
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| If set this value will be used and allow you to receive forwarded emails
|
||||||
|
| at the root domain, e.g. @anonaddy.me aswell as @username.anonaddy.me
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'admin_username' => env('ANONADDY_ADMIN_USERNAME'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Domain
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| If set and you are self hosting AnonAddy then a check will be done so that you can
|
||||||
|
| receive email at the root domain, e.g. @yourdomain.com aswell as @username.yourdomain.com
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'domain' => env('ANONADDY_DOMAIN'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Secret
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Simply a long random string used when hashing data for the anonymous
|
||||||
|
| replies, make sure that you set something suitably long and random in your .env
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'secret' => env('ANONADDY_SECRET'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Limit
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This value is an integer that determines the number of emails a user can forward
|
||||||
|
| and reply per hour, e.g. 200 would mean the user is rate limited to 200 emails per hour
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'limit' => env('ANONADDY_LIMIT'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Username Blacklist
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| List of blacklisted usernames with some additions from - https://github.com/marteinn/The-Big-Username-Blacklist
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'blacklist' =>[
|
||||||
|
'.htaccess',
|
||||||
|
'.htpasswd',
|
||||||
|
'.well-known',
|
||||||
|
'400',
|
||||||
|
'401',
|
||||||
|
'403',
|
||||||
|
'404',
|
||||||
|
'405',
|
||||||
|
'406',
|
||||||
|
'407',
|
||||||
|
'408',
|
||||||
|
'409',
|
||||||
|
'410',
|
||||||
|
'411',
|
||||||
|
'412',
|
||||||
|
'413',
|
||||||
|
'414',
|
||||||
|
'415',
|
||||||
|
'416',
|
||||||
|
'417',
|
||||||
|
'421',
|
||||||
|
'422',
|
||||||
|
'423',
|
||||||
|
'424',
|
||||||
|
'426',
|
||||||
|
'428',
|
||||||
|
'429',
|
||||||
|
'431',
|
||||||
|
'500',
|
||||||
|
'501',
|
||||||
|
'502',
|
||||||
|
'503',
|
||||||
|
'504',
|
||||||
|
'505',
|
||||||
|
'506',
|
||||||
|
'507',
|
||||||
|
'508',
|
||||||
|
'509',
|
||||||
|
'510',
|
||||||
|
'511',
|
||||||
|
'about',
|
||||||
|
'about-us',
|
||||||
|
'abuse',
|
||||||
|
'access',
|
||||||
|
'account',
|
||||||
|
'accounts',
|
||||||
|
'activate',
|
||||||
|
'active',
|
||||||
|
'ad',
|
||||||
|
'add',
|
||||||
|
'addy',
|
||||||
|
'admin',
|
||||||
|
'administration',
|
||||||
|
'administrator',
|
||||||
|
'ads',
|
||||||
|
'advertise',
|
||||||
|
'advertising',
|
||||||
|
'aes128-ctr',
|
||||||
|
'aes128-gcm',
|
||||||
|
'aes192-ctr',
|
||||||
|
'aes256-ctr',
|
||||||
|
'aes256-gcm',
|
||||||
|
'affiliate',
|
||||||
|
'affiliates',
|
||||||
|
'ajax',
|
||||||
|
'alert',
|
||||||
|
'alerts',
|
||||||
|
'alias',
|
||||||
|
'alpha',
|
||||||
|
'amp',
|
||||||
|
'analytics',
|
||||||
|
'anonaddy',
|
||||||
|
'api',
|
||||||
|
'app',
|
||||||
|
'apps',
|
||||||
|
'asc',
|
||||||
|
'assets',
|
||||||
|
'atom',
|
||||||
|
'auth',
|
||||||
|
'authentication',
|
||||||
|
'authorize',
|
||||||
|
'autoconfig',
|
||||||
|
'autodiscover',
|
||||||
|
'avatar',
|
||||||
|
'backup',
|
||||||
|
'banner',
|
||||||
|
'banners',
|
||||||
|
'beta',
|
||||||
|
'billing',
|
||||||
|
'billings',
|
||||||
|
'blog',
|
||||||
|
'blogs',
|
||||||
|
'board',
|
||||||
|
'bookmark',
|
||||||
|
'bookmarks',
|
||||||
|
'bounce',
|
||||||
|
'bounces',
|
||||||
|
'broadcasthost',
|
||||||
|
'business',
|
||||||
|
'buy',
|
||||||
|
'cache',
|
||||||
|
'calendar',
|
||||||
|
'campaign',
|
||||||
|
'captcha',
|
||||||
|
'careers',
|
||||||
|
'cart',
|
||||||
|
'cas',
|
||||||
|
'categories',
|
||||||
|
'category',
|
||||||
|
'cdn',
|
||||||
|
'cgi',
|
||||||
|
'cgi-bin',
|
||||||
|
'chacha20-poly1305',
|
||||||
|
'change',
|
||||||
|
'channel',
|
||||||
|
'channels',
|
||||||
|
'chart',
|
||||||
|
'chat',
|
||||||
|
'checkout',
|
||||||
|
'clear',
|
||||||
|
'client',
|
||||||
|
'close',
|
||||||
|
'cms',
|
||||||
|
'com',
|
||||||
|
'comment',
|
||||||
|
'comments',
|
||||||
|
'community',
|
||||||
|
'compare',
|
||||||
|
'compose',
|
||||||
|
'config',
|
||||||
|
'connect',
|
||||||
|
'contact',
|
||||||
|
'contest',
|
||||||
|
'cookies',
|
||||||
|
'copy',
|
||||||
|
'copyright',
|
||||||
|
'count',
|
||||||
|
'create',
|
||||||
|
'crossdomain.xml',
|
||||||
|
'css',
|
||||||
|
'curve25519-sha256',
|
||||||
|
'customer',
|
||||||
|
'customers',
|
||||||
|
'customize',
|
||||||
|
'dashboard',
|
||||||
|
'db',
|
||||||
|
'deactivate',
|
||||||
|
'deals',
|
||||||
|
'debug',
|
||||||
|
'delete',
|
||||||
|
'desc',
|
||||||
|
'destroy',
|
||||||
|
'dev',
|
||||||
|
'developer',
|
||||||
|
'developers',
|
||||||
|
'diffie-hellman-group-exchange-sha256',
|
||||||
|
'diffie-hellman-group14-sha1',
|
||||||
|
'disconnect',
|
||||||
|
'discuss',
|
||||||
|
'dns',
|
||||||
|
'dns0',
|
||||||
|
'dns1',
|
||||||
|
'dns2',
|
||||||
|
'dns3',
|
||||||
|
'dns4',
|
||||||
|
'docs',
|
||||||
|
'documentation',
|
||||||
|
'domain',
|
||||||
|
'download',
|
||||||
|
'downloads',
|
||||||
|
'downvote',
|
||||||
|
'draft',
|
||||||
|
'drop',
|
||||||
|
'ecdh-sha2-nistp256',
|
||||||
|
'ecdh-sha2-nistp384',
|
||||||
|
'ecdh-sha2-nistp521',
|
||||||
|
'edit',
|
||||||
|
'editor',
|
||||||
|
'email',
|
||||||
|
'enterprise',
|
||||||
|
'error',
|
||||||
|
'errors',
|
||||||
|
'event',
|
||||||
|
'events',
|
||||||
|
'example',
|
||||||
|
'exception',
|
||||||
|
'exit',
|
||||||
|
'explore',
|
||||||
|
'export',
|
||||||
|
'extensions',
|
||||||
|
'false',
|
||||||
|
'family',
|
||||||
|
'faq',
|
||||||
|
'faqs',
|
||||||
|
'favicon.ico',
|
||||||
|
'features',
|
||||||
|
'feed',
|
||||||
|
'feedback',
|
||||||
|
'feeds',
|
||||||
|
'file',
|
||||||
|
'files',
|
||||||
|
'filter',
|
||||||
|
'follow',
|
||||||
|
'follower',
|
||||||
|
'followers',
|
||||||
|
'following',
|
||||||
|
'fonts',
|
||||||
|
'forgot',
|
||||||
|
'forgot-password',
|
||||||
|
'forgotpassword',
|
||||||
|
'form',
|
||||||
|
'forms',
|
||||||
|
'forum',
|
||||||
|
'forums',
|
||||||
|
'forward',
|
||||||
|
'forwarder',
|
||||||
|
'friend',
|
||||||
|
'friends',
|
||||||
|
'ftp',
|
||||||
|
'get',
|
||||||
|
'git',
|
||||||
|
'go',
|
||||||
|
'group',
|
||||||
|
'groups',
|
||||||
|
'guest',
|
||||||
|
'guidelines',
|
||||||
|
'guides',
|
||||||
|
'head',
|
||||||
|
'header',
|
||||||
|
'help',
|
||||||
|
'hide',
|
||||||
|
'hmac-sha',
|
||||||
|
'hmac-sha1',
|
||||||
|
'hmac-sha1-etm',
|
||||||
|
'hmac-sha2-256',
|
||||||
|
'hmac-sha2-256-etm',
|
||||||
|
'hmac-sha2-512',
|
||||||
|
'hmac-sha2-512-etm',
|
||||||
|
'home',
|
||||||
|
'host',
|
||||||
|
'hosting',
|
||||||
|
'hostmaster',
|
||||||
|
'htpasswd',
|
||||||
|
'http',
|
||||||
|
'httpd',
|
||||||
|
'https',
|
||||||
|
'humans.txt',
|
||||||
|
'icons',
|
||||||
|
'images',
|
||||||
|
'imap',
|
||||||
|
'img',
|
||||||
|
'import',
|
||||||
|
'index',
|
||||||
|
'info',
|
||||||
|
'insert',
|
||||||
|
'investors',
|
||||||
|
'invitations',
|
||||||
|
'invite',
|
||||||
|
'invites',
|
||||||
|
'invoice',
|
||||||
|
'is',
|
||||||
|
'isatap',
|
||||||
|
'issues',
|
||||||
|
'it',
|
||||||
|
'jobs',
|
||||||
|
'join',
|
||||||
|
'js',
|
||||||
|
'json',
|
||||||
|
'keybase.txt',
|
||||||
|
'learn',
|
||||||
|
'legal',
|
||||||
|
'license',
|
||||||
|
'licensing',
|
||||||
|
'like',
|
||||||
|
'limit',
|
||||||
|
'live',
|
||||||
|
'load',
|
||||||
|
'local',
|
||||||
|
'localdomain',
|
||||||
|
'localhost',
|
||||||
|
'lock',
|
||||||
|
'login',
|
||||||
|
'logout',
|
||||||
|
'lost-password',
|
||||||
|
'mail',
|
||||||
|
'mail0',
|
||||||
|
'mail1',
|
||||||
|
'mail2',
|
||||||
|
'mail3',
|
||||||
|
'mail4',
|
||||||
|
'mail5',
|
||||||
|
'mail6',
|
||||||
|
'mail7',
|
||||||
|
'mail8',
|
||||||
|
'mail9',
|
||||||
|
'mailer',
|
||||||
|
'mailer-daemon',
|
||||||
|
'mailerdaemon',
|
||||||
|
'map',
|
||||||
|
'marketing',
|
||||||
|
'marketplace',
|
||||||
|
'master',
|
||||||
|
'me',
|
||||||
|
'media',
|
||||||
|
'member',
|
||||||
|
'members',
|
||||||
|
'message',
|
||||||
|
'messages',
|
||||||
|
'metrics',
|
||||||
|
'mis',
|
||||||
|
'mobile',
|
||||||
|
'moderator',
|
||||||
|
'modify',
|
||||||
|
'more',
|
||||||
|
'mx',
|
||||||
|
'my',
|
||||||
|
'net',
|
||||||
|
'network',
|
||||||
|
'new',
|
||||||
|
'news',
|
||||||
|
'newsletter',
|
||||||
|
'newsletters',
|
||||||
|
'next',
|
||||||
|
'nil',
|
||||||
|
'no-reply',
|
||||||
|
'nobody',
|
||||||
|
'noc',
|
||||||
|
'none',
|
||||||
|
'noreply',
|
||||||
|
'notification',
|
||||||
|
'notifications',
|
||||||
|
'ns',
|
||||||
|
'ns0',
|
||||||
|
'ns1',
|
||||||
|
'ns2',
|
||||||
|
'ns3',
|
||||||
|
'ns4',
|
||||||
|
'ns5',
|
||||||
|
'ns6',
|
||||||
|
'ns7',
|
||||||
|
'ns8',
|
||||||
|
'ns9',
|
||||||
|
'null',
|
||||||
|
'oauth',
|
||||||
|
'oauth2',
|
||||||
|
'offer',
|
||||||
|
'offers',
|
||||||
|
'online',
|
||||||
|
'openid',
|
||||||
|
'order',
|
||||||
|
'orders',
|
||||||
|
'overview',
|
||||||
|
'owner',
|
||||||
|
'page',
|
||||||
|
'pages',
|
||||||
|
'partners',
|
||||||
|
'passwd',
|
||||||
|
'password',
|
||||||
|
'pay',
|
||||||
|
'payment',
|
||||||
|
'payments',
|
||||||
|
'photo',
|
||||||
|
'photos',
|
||||||
|
'pixel',
|
||||||
|
'plans',
|
||||||
|
'plugins',
|
||||||
|
'policies',
|
||||||
|
'policy',
|
||||||
|
'pop',
|
||||||
|
'pop3',
|
||||||
|
'popular',
|
||||||
|
'portfolio',
|
||||||
|
'post',
|
||||||
|
'postfix',
|
||||||
|
'postmaster',
|
||||||
|
'poweruser',
|
||||||
|
'preferences',
|
||||||
|
'premium',
|
||||||
|
'press',
|
||||||
|
'previous',
|
||||||
|
'pricing',
|
||||||
|
'print',
|
||||||
|
'privacy',
|
||||||
|
'privacy-policy',
|
||||||
|
'private',
|
||||||
|
'prod',
|
||||||
|
'product',
|
||||||
|
'production',
|
||||||
|
'profile',
|
||||||
|
'profiles',
|
||||||
|
'project',
|
||||||
|
'projects',
|
||||||
|
'public',
|
||||||
|
'purchase',
|
||||||
|
'put',
|
||||||
|
'quota',
|
||||||
|
'recipient',
|
||||||
|
'redirect',
|
||||||
|
'reduce',
|
||||||
|
'refund',
|
||||||
|
'refunds',
|
||||||
|
'register',
|
||||||
|
'registration',
|
||||||
|
'remove',
|
||||||
|
'replies',
|
||||||
|
'reply',
|
||||||
|
'report',
|
||||||
|
'request',
|
||||||
|
'request-password',
|
||||||
|
'reset',
|
||||||
|
'reset-password',
|
||||||
|
'response',
|
||||||
|
'return',
|
||||||
|
'returns',
|
||||||
|
'review',
|
||||||
|
'reviews',
|
||||||
|
'robots.txt',
|
||||||
|
'root',
|
||||||
|
'rootuser',
|
||||||
|
'rsa-sha2-2',
|
||||||
|
'rsa-sha2-512',
|
||||||
|
'rss',
|
||||||
|
'rules',
|
||||||
|
'sales',
|
||||||
|
'save',
|
||||||
|
'script',
|
||||||
|
'sdk',
|
||||||
|
'search',
|
||||||
|
'secure',
|
||||||
|
'security',
|
||||||
|
'select',
|
||||||
|
'services',
|
||||||
|
'session',
|
||||||
|
'sessions',
|
||||||
|
'settings',
|
||||||
|
'setup',
|
||||||
|
'share',
|
||||||
|
'shift',
|
||||||
|
'shop',
|
||||||
|
'signin',
|
||||||
|
'signup',
|
||||||
|
'site',
|
||||||
|
'sitemap',
|
||||||
|
'sites',
|
||||||
|
'smtp',
|
||||||
|
'sort',
|
||||||
|
'source',
|
||||||
|
'sql',
|
||||||
|
'ssh',
|
||||||
|
'ssh-rsa',
|
||||||
|
'ssl',
|
||||||
|
'ssladmin',
|
||||||
|
'ssladministrator',
|
||||||
|
'sslwebmaster',
|
||||||
|
'stage',
|
||||||
|
'staging',
|
||||||
|
'stat',
|
||||||
|
'static',
|
||||||
|
'statistics',
|
||||||
|
'stats',
|
||||||
|
'status',
|
||||||
|
'store',
|
||||||
|
'style',
|
||||||
|
'styles',
|
||||||
|
'stylesheet',
|
||||||
|
'stylesheets',
|
||||||
|
'subdomain',
|
||||||
|
'subscribe',
|
||||||
|
'sudo',
|
||||||
|
'super',
|
||||||
|
'superuser',
|
||||||
|
'support',
|
||||||
|
'survey',
|
||||||
|
'sync',
|
||||||
|
'sysadmin',
|
||||||
|
'system',
|
||||||
|
'tablet',
|
||||||
|
'tag',
|
||||||
|
'tags',
|
||||||
|
'team',
|
||||||
|
'telnet',
|
||||||
|
'terms',
|
||||||
|
'terms-of-use',
|
||||||
|
'test',
|
||||||
|
'testimonials',
|
||||||
|
'theme',
|
||||||
|
'themes',
|
||||||
|
'today',
|
||||||
|
'tools',
|
||||||
|
'topic',
|
||||||
|
'topics',
|
||||||
|
'tour',
|
||||||
|
'training',
|
||||||
|
'translate',
|
||||||
|
'translations',
|
||||||
|
'trending',
|
||||||
|
'trial',
|
||||||
|
'true',
|
||||||
|
'umac-128',
|
||||||
|
'umac-128-etm',
|
||||||
|
'umac-64',
|
||||||
|
'umac-64-etm',
|
||||||
|
'undefined',
|
||||||
|
'unfollow',
|
||||||
|
'unlike',
|
||||||
|
'unsub',
|
||||||
|
'unsubscribe',
|
||||||
|
'update',
|
||||||
|
'upgrade',
|
||||||
|
'usenet',
|
||||||
|
'user',
|
||||||
|
'username',
|
||||||
|
'users',
|
||||||
|
'uucp',
|
||||||
|
'var',
|
||||||
|
'verify',
|
||||||
|
'video',
|
||||||
|
'view',
|
||||||
|
'void',
|
||||||
|
'vote',
|
||||||
|
'webmail',
|
||||||
|
'webmaster',
|
||||||
|
'website',
|
||||||
|
'widget',
|
||||||
|
'widgets',
|
||||||
|
'wiki',
|
||||||
|
'wpad',
|
||||||
|
'write',
|
||||||
|
'www',
|
||||||
|
'www-data',
|
||||||
|
'www1',
|
||||||
|
'www2',
|
||||||
|
'www3',
|
||||||
|
'www4',
|
||||||
|
'you',
|
||||||
|
'yourname',
|
||||||
|
'yourusername',
|
||||||
|
'zlib'
|
||||||
|
]
|
||||||
|
|
||||||
|
];
|
230
config/app.php
Normal file
230
config/app.php
Normal file
|
@ -0,0 +1,230 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Application Name
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This value is the name of your application. This value is used when the
|
||||||
|
| framework needs to place the application's name in a notification or
|
||||||
|
| any other location as required by the application or its packages.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'name' => env('APP_NAME', 'Laravel'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Application Environment
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This value determines the "environment" your application is currently
|
||||||
|
| running in. This may determine how you prefer to configure various
|
||||||
|
| services the application utilizes. Set this in your ".env" file.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'env' => env('APP_ENV', 'production'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Application Debug Mode
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| When your application is in debug mode, detailed error messages with
|
||||||
|
| stack traces will be shown on every error that occurs within your
|
||||||
|
| application. If disabled, a simple generic error page is shown.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'debug' => env('APP_DEBUG', false),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Application URL
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This URL is used by the console to properly generate URLs when using
|
||||||
|
| the Artisan command line tool. You should set this to the root of
|
||||||
|
| your application so that it is used when running Artisan tasks.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'url' => env('APP_URL', 'http://localhost'),
|
||||||
|
|
||||||
|
'asset_url' => env('ASSET_URL', null),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Application Timezone
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify the default timezone for your application, which
|
||||||
|
| will be used by the PHP date and date-time functions. We have gone
|
||||||
|
| ahead and set this to a sensible default for you out of the box.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'timezone' => 'UTC',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Application Locale Configuration
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The application locale determines the default locale that will be used
|
||||||
|
| by the translation service provider. You are free to set this value
|
||||||
|
| to any of the locales which will be supported by the application.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'locale' => 'en',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Application Fallback Locale
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The fallback locale determines the locale to use when the current one
|
||||||
|
| is not available. You may change the value to correspond to any of
|
||||||
|
| the language folders that are provided through your application.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'fallback_locale' => 'en',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Faker Locale
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This locale will be used by the Faker PHP library when generating fake
|
||||||
|
| data for your database seeds. For example, this will be used to get
|
||||||
|
| localized telephone numbers, street address information and more.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'faker_locale' => 'en_US',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Encryption Key
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This key is used by the Illuminate encrypter service and should be set
|
||||||
|
| to a random, 32 character string, otherwise these encrypted strings
|
||||||
|
| will not be safe. Please do this before deploying an application!
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'key' => env('APP_KEY'),
|
||||||
|
|
||||||
|
'cipher' => 'AES-256-CBC',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Autoloaded Service Providers
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| The service providers listed here will be automatically loaded on the
|
||||||
|
| request to your application. Feel free to add your own services to
|
||||||
|
| this array to grant expanded functionality to your applications.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'providers' => [
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Laravel Framework Service Providers...
|
||||||
|
*/
|
||||||
|
Illuminate\Auth\AuthServiceProvider::class,
|
||||||
|
Illuminate\Broadcasting\BroadcastServiceProvider::class,
|
||||||
|
Illuminate\Bus\BusServiceProvider::class,
|
||||||
|
Illuminate\Cache\CacheServiceProvider::class,
|
||||||
|
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
|
||||||
|
Illuminate\Cookie\CookieServiceProvider::class,
|
||||||
|
Illuminate\Database\DatabaseServiceProvider::class,
|
||||||
|
Illuminate\Encryption\EncryptionServiceProvider::class,
|
||||||
|
Illuminate\Filesystem\FilesystemServiceProvider::class,
|
||||||
|
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
|
||||||
|
Illuminate\Hashing\HashServiceProvider::class,
|
||||||
|
Illuminate\Mail\MailServiceProvider::class,
|
||||||
|
Illuminate\Notifications\NotificationServiceProvider::class,
|
||||||
|
Illuminate\Pagination\PaginationServiceProvider::class,
|
||||||
|
Illuminate\Pipeline\PipelineServiceProvider::class,
|
||||||
|
Illuminate\Queue\QueueServiceProvider::class,
|
||||||
|
Illuminate\Redis\RedisServiceProvider::class,
|
||||||
|
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
|
||||||
|
Illuminate\Session\SessionServiceProvider::class,
|
||||||
|
Illuminate\Translation\TranslationServiceProvider::class,
|
||||||
|
Illuminate\Validation\ValidationServiceProvider::class,
|
||||||
|
Illuminate\View\ViewServiceProvider::class,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Package Service Providers...
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Application Service Providers...
|
||||||
|
*/
|
||||||
|
App\Providers\AppServiceProvider::class,
|
||||||
|
App\Providers\AuthServiceProvider::class,
|
||||||
|
// App\Providers\BroadcastServiceProvider::class,
|
||||||
|
App\Providers\EventServiceProvider::class,
|
||||||
|
App\Providers\RouteServiceProvider::class,
|
||||||
|
App\Providers\HelperServiceProvider::class,
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Class Aliases
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This array of class aliases will be registered when this application
|
||||||
|
| is started. However, feel free to register as many as you wish as
|
||||||
|
| the aliases are "lazy" loaded so they don't hinder performance.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'aliases' => [
|
||||||
|
|
||||||
|
'App' => Illuminate\Support\Facades\App::class,
|
||||||
|
'Artisan' => Illuminate\Support\Facades\Artisan::class,
|
||||||
|
'Auth' => Illuminate\Support\Facades\Auth::class,
|
||||||
|
'Blade' => Illuminate\Support\Facades\Blade::class,
|
||||||
|
'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
|
||||||
|
'Bus' => Illuminate\Support\Facades\Bus::class,
|
||||||
|
'Cache' => Illuminate\Support\Facades\Cache::class,
|
||||||
|
'Config' => Illuminate\Support\Facades\Config::class,
|
||||||
|
'Cookie' => Illuminate\Support\Facades\Cookie::class,
|
||||||
|
'Crypt' => Illuminate\Support\Facades\Crypt::class,
|
||||||
|
'DB' => Illuminate\Support\Facades\DB::class,
|
||||||
|
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
|
||||||
|
'Event' => Illuminate\Support\Facades\Event::class,
|
||||||
|
'File' => Illuminate\Support\Facades\File::class,
|
||||||
|
'Gate' => Illuminate\Support\Facades\Gate::class,
|
||||||
|
'Hash' => Illuminate\Support\Facades\Hash::class,
|
||||||
|
'Lang' => Illuminate\Support\Facades\Lang::class,
|
||||||
|
'Log' => Illuminate\Support\Facades\Log::class,
|
||||||
|
'Mail' => Illuminate\Support\Facades\Mail::class,
|
||||||
|
'Notification' => Illuminate\Support\Facades\Notification::class,
|
||||||
|
'Password' => Illuminate\Support\Facades\Password::class,
|
||||||
|
'Queue' => Illuminate\Support\Facades\Queue::class,
|
||||||
|
'Redirect' => Illuminate\Support\Facades\Redirect::class,
|
||||||
|
'Redis' => Illuminate\Support\Facades\Redis::class,
|
||||||
|
'Request' => Illuminate\Support\Facades\Request::class,
|
||||||
|
'Response' => Illuminate\Support\Facades\Response::class,
|
||||||
|
'Route' => Illuminate\Support\Facades\Route::class,
|
||||||
|
'Schema' => Illuminate\Support\Facades\Schema::class,
|
||||||
|
'Session' => Illuminate\Support\Facades\Session::class,
|
||||||
|
'Storage' => Illuminate\Support\Facades\Storage::class,
|
||||||
|
'URL' => Illuminate\Support\Facades\URL::class,
|
||||||
|
'Validator' => Illuminate\Support\Facades\Validator::class,
|
||||||
|
'View' => Illuminate\Support\Facades\View::class,
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
102
config/auth.php
Normal file
102
config/auth.php
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Authentication Defaults
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option controls the default authentication "guard" and password
|
||||||
|
| reset options for your application. You may change these defaults
|
||||||
|
| as required, but they're a perfect start for most applications.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'defaults' => [
|
||||||
|
'guard' => 'web',
|
||||||
|
'passwords' => 'users',
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Authentication Guards
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Next, you may define every authentication guard for your application.
|
||||||
|
| Of course, a great default configuration has been defined for you
|
||||||
|
| here which uses session storage and the Eloquent user provider.
|
||||||
|
|
|
||||||
|
| All authentication drivers have a user provider. This defines how the
|
||||||
|
| users are actually retrieved out of your database or other storage
|
||||||
|
| mechanisms used by this application to persist your user's data.
|
||||||
|
|
|
||||||
|
| Supported: "session", "token"
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'guards' => [
|
||||||
|
'web' => [
|
||||||
|
'driver' => 'session',
|
||||||
|
'provider' => 'users',
|
||||||
|
],
|
||||||
|
|
||||||
|
'api' => [
|
||||||
|
'driver' => 'token',
|
||||||
|
'provider' => 'users',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| User Providers
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| All authentication drivers have a user provider. This defines how the
|
||||||
|
| users are actually retrieved out of your database or other storage
|
||||||
|
| mechanisms used by this application to persist your user's data.
|
||||||
|
|
|
||||||
|
| If you have multiple user tables or models you may configure multiple
|
||||||
|
| sources which represent each model / table. These sources may then
|
||||||
|
| be assigned to any extra authentication guards you have defined.
|
||||||
|
|
|
||||||
|
| Supported: "database", "eloquent"
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'providers' => [
|
||||||
|
'users' => [
|
||||||
|
'driver' => 'eloquent',
|
||||||
|
'model' => App\User::class,
|
||||||
|
],
|
||||||
|
|
||||||
|
// 'users' => [
|
||||||
|
// 'driver' => 'database',
|
||||||
|
// 'table' => 'users',
|
||||||
|
// ],
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Resetting Passwords
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| You may specify multiple password reset configurations if you have more
|
||||||
|
| than one user table or model in the application and you want to have
|
||||||
|
| separate password reset settings based on the specific user types.
|
||||||
|
|
|
||||||
|
| The expire time is the number of minutes that the reset token should be
|
||||||
|
| considered valid. This security feature keeps tokens short-lived so
|
||||||
|
| they have less time to be guessed. You may change this as needed.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'passwords' => [
|
||||||
|
'users' => [
|
||||||
|
'provider' => 'users',
|
||||||
|
'table' => 'password_resets',
|
||||||
|
'expire' => 60,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
59
config/broadcasting.php
Normal file
59
config/broadcasting.php
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default Broadcaster
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option controls the default broadcaster that will be used by the
|
||||||
|
| framework when an event needs to be broadcast. You may set this to
|
||||||
|
| any of the connections defined in the "connections" array below.
|
||||||
|
|
|
||||||
|
| Supported: "pusher", "redis", "log", "null"
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'default' => env('BROADCAST_DRIVER', 'null'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Broadcast Connections
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may define all of the broadcast connections that will be used
|
||||||
|
| to broadcast events to other systems or over websockets. Samples of
|
||||||
|
| each available type of connection are provided inside this array.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'connections' => [
|
||||||
|
|
||||||
|
'pusher' => [
|
||||||
|
'driver' => 'pusher',
|
||||||
|
'key' => env('PUSHER_APP_KEY'),
|
||||||
|
'secret' => env('PUSHER_APP_SECRET'),
|
||||||
|
'app_id' => env('PUSHER_APP_ID'),
|
||||||
|
'options' => [
|
||||||
|
'cluster' => env('PUSHER_APP_CLUSTER'),
|
||||||
|
'encrypted' => true,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
'redis' => [
|
||||||
|
'driver' => 'redis',
|
||||||
|
'connection' => 'default',
|
||||||
|
],
|
||||||
|
|
||||||
|
'log' => [
|
||||||
|
'driver' => 'log',
|
||||||
|
],
|
||||||
|
|
||||||
|
'null' => [
|
||||||
|
'driver' => 'null',
|
||||||
|
],
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
93
config/cache.php
Normal file
93
config/cache.php
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default Cache Store
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option controls the default cache connection that gets used while
|
||||||
|
| using this caching library. This connection is used when another is
|
||||||
|
| not explicitly specified when executing a given caching function.
|
||||||
|
|
|
||||||
|
| Supported: "apc", "array", "database", "file", "memcached", "redis"
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'default' => env('CACHE_DRIVER', 'file'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Cache Stores
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may define all of the cache "stores" for your application as
|
||||||
|
| well as their drivers. You may even define multiple stores for the
|
||||||
|
| same cache driver to group types of items stored in your caches.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'stores' => [
|
||||||
|
|
||||||
|
'apc' => [
|
||||||
|
'driver' => 'apc',
|
||||||
|
],
|
||||||
|
|
||||||
|
'array' => [
|
||||||
|
'driver' => 'array',
|
||||||
|
],
|
||||||
|
|
||||||
|
'database' => [
|
||||||
|
'driver' => 'database',
|
||||||
|
'table' => 'cache',
|
||||||
|
'connection' => null,
|
||||||
|
],
|
||||||
|
|
||||||
|
'file' => [
|
||||||
|
'driver' => 'file',
|
||||||
|
'path' => storage_path('framework/cache/data'),
|
||||||
|
],
|
||||||
|
|
||||||
|
'memcached' => [
|
||||||
|
'driver' => 'memcached',
|
||||||
|
'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
|
||||||
|
'sasl' => [
|
||||||
|
env('MEMCACHED_USERNAME'),
|
||||||
|
env('MEMCACHED_PASSWORD'),
|
||||||
|
],
|
||||||
|
'options' => [
|
||||||
|
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
|
||||||
|
],
|
||||||
|
'servers' => [
|
||||||
|
[
|
||||||
|
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
|
||||||
|
'port' => env('MEMCACHED_PORT', 11211),
|
||||||
|
'weight' => 100,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
'redis' => [
|
||||||
|
'driver' => 'redis',
|
||||||
|
'connection' => 'cache',
|
||||||
|
],
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Cache Key Prefix
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| When utilizing a RAM based store such as APC or Memcached, there might
|
||||||
|
| be other applications utilizing the same cache. So, we'll specify a
|
||||||
|
| value to get prefixed to all our keys so we can avoid collisions.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache'),
|
||||||
|
|
||||||
|
];
|
131
config/database.php
Normal file
131
config/database.php
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default Database Connection Name
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify which of the database connections below you wish
|
||||||
|
| to use as your default connection for all database work. Of course
|
||||||
|
| you may use many connections at once using the Database library.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'default' => env('DB_CONNECTION', 'mysql'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Database Connections
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here are each of the database connections setup for your application.
|
||||||
|
| Of course, examples of configuring each database platform that is
|
||||||
|
| supported by Laravel is shown below to make development simple.
|
||||||
|
|
|
||||||
|
|
|
||||||
|
| All database work in Laravel is done through the PHP PDO facilities
|
||||||
|
| so make sure you have the driver for your particular database of
|
||||||
|
| choice installed on your machine before you begin development.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'connections' => [
|
||||||
|
|
||||||
|
'sqlite' => [
|
||||||
|
'driver' => 'sqlite',
|
||||||
|
'database' => env('DB_DATABASE', database_path('database.sqlite')),
|
||||||
|
'prefix' => '',
|
||||||
|
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
|
||||||
|
],
|
||||||
|
|
||||||
|
'mysql' => [
|
||||||
|
'driver' => 'mysql',
|
||||||
|
'host' => env('DB_HOST', '127.0.0.1'),
|
||||||
|
'port' => env('DB_PORT', '3306'),
|
||||||
|
'database' => env('DB_DATABASE', 'forge'),
|
||||||
|
'username' => env('DB_USERNAME', 'forge'),
|
||||||
|
'password' => env('DB_PASSWORD', ''),
|
||||||
|
'unix_socket' => env('DB_SOCKET', ''),
|
||||||
|
'charset' => 'utf8mb4',
|
||||||
|
'collation' => 'utf8mb4_unicode_ci',
|
||||||
|
'prefix' => '',
|
||||||
|
'prefix_indexes' => true,
|
||||||
|
'strict' => true,
|
||||||
|
'engine' => null,
|
||||||
|
],
|
||||||
|
|
||||||
|
'pgsql' => [
|
||||||
|
'driver' => 'pgsql',
|
||||||
|
'host' => env('DB_HOST', '127.0.0.1'),
|
||||||
|
'port' => env('DB_PORT', '5432'),
|
||||||
|
'database' => env('DB_DATABASE', 'forge'),
|
||||||
|
'username' => env('DB_USERNAME', 'forge'),
|
||||||
|
'password' => env('DB_PASSWORD', ''),
|
||||||
|
'charset' => 'utf8',
|
||||||
|
'prefix' => '',
|
||||||
|
'prefix_indexes' => true,
|
||||||
|
'schema' => 'public',
|
||||||
|
'sslmode' => 'prefer',
|
||||||
|
],
|
||||||
|
|
||||||
|
'sqlsrv' => [
|
||||||
|
'driver' => 'sqlsrv',
|
||||||
|
'host' => env('DB_HOST', 'localhost'),
|
||||||
|
'port' => env('DB_PORT', '1433'),
|
||||||
|
'database' => env('DB_DATABASE', 'forge'),
|
||||||
|
'username' => env('DB_USERNAME', 'forge'),
|
||||||
|
'password' => env('DB_PASSWORD', ''),
|
||||||
|
'charset' => 'utf8',
|
||||||
|
'prefix' => '',
|
||||||
|
'prefix_indexes' => true,
|
||||||
|
],
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Migration Repository Table
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This table keeps track of all the migrations that have already run for
|
||||||
|
| your application. Using this information, we can determine which of
|
||||||
|
| the migrations on disk haven't actually been run in the database.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'migrations' => 'migrations',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Redis Databases
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Redis is an open source, fast, and advanced key-value store that also
|
||||||
|
| provides a richer body of commands than a typical key-value system
|
||||||
|
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'redis' => [
|
||||||
|
|
||||||
|
'client' => 'predis',
|
||||||
|
|
||||||
|
'default' => [
|
||||||
|
'host' => env('REDIS_HOST', '127.0.0.1'),
|
||||||
|
'password' => env('REDIS_PASSWORD', null),
|
||||||
|
'port' => env('REDIS_PORT', 6379),
|
||||||
|
'database' => env('REDIS_DB', 0),
|
||||||
|
],
|
||||||
|
|
||||||
|
'cache' => [
|
||||||
|
'host' => env('REDIS_HOST', '127.0.0.1'),
|
||||||
|
'password' => env('REDIS_PASSWORD', null),
|
||||||
|
'port' => env('REDIS_PORT', 6379),
|
||||||
|
'database' => env('REDIS_CACHE_DB', 1),
|
||||||
|
],
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
69
config/filesystems.php
Normal file
69
config/filesystems.php
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default Filesystem Disk
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify the default filesystem disk that should be used
|
||||||
|
| by the framework. The "local" disk, as well as a variety of cloud
|
||||||
|
| based disks are available to your application. Just store away!
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'default' => env('FILESYSTEM_DRIVER', 'local'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default Cloud Filesystem Disk
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Many applications store files both locally and in the cloud. For this
|
||||||
|
| reason, you may specify a default "cloud" driver here. This driver
|
||||||
|
| will be bound as the Cloud disk implementation in the container.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'cloud' => env('FILESYSTEM_CLOUD', 's3'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Filesystem Disks
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may configure as many filesystem "disks" as you wish, and you
|
||||||
|
| may even configure multiple disks of the same driver. Defaults have
|
||||||
|
| been setup for each driver as an example of the required options.
|
||||||
|
|
|
||||||
|
| Supported Drivers: "local", "ftp", "sftp", "s3", "rackspace"
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'disks' => [
|
||||||
|
|
||||||
|
'local' => [
|
||||||
|
'driver' => 'local',
|
||||||
|
'root' => storage_path('app'),
|
||||||
|
],
|
||||||
|
|
||||||
|
'public' => [
|
||||||
|
'driver' => 'local',
|
||||||
|
'root' => storage_path('app/public'),
|
||||||
|
'url' => env('APP_URL').'/storage',
|
||||||
|
'visibility' => 'public',
|
||||||
|
],
|
||||||
|
|
||||||
|
's3' => [
|
||||||
|
'driver' => 's3',
|
||||||
|
'key' => env('AWS_ACCESS_KEY_ID'),
|
||||||
|
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
||||||
|
'region' => env('AWS_DEFAULT_REGION'),
|
||||||
|
'bucket' => env('AWS_BUCKET'),
|
||||||
|
'url' => env('AWS_URL'),
|
||||||
|
],
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
73
config/google2fa.php
Normal file
73
config/google2fa.php
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Auth container binding
|
||||||
|
*/
|
||||||
|
|
||||||
|
'enabled' => true,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lifetime in minutes.
|
||||||
|
* In case you need your users to be asked for a new one time passwords from time to time.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'lifetime' => 0, // 0 = eternal
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Renew lifetime at every new request.
|
||||||
|
*/
|
||||||
|
|
||||||
|
'keep_alive' => true,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Auth container binding
|
||||||
|
*/
|
||||||
|
|
||||||
|
'auth' => 'auth',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 2FA verified session var
|
||||||
|
*/
|
||||||
|
|
||||||
|
'session_var' => 'two_factor_auth',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* One Time Password request input name
|
||||||
|
*/
|
||||||
|
'otp_input' => 'one_time_password',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* One Time Password Window
|
||||||
|
*/
|
||||||
|
'window' => 1,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Forbid user to reuse One Time Passwords.
|
||||||
|
*/
|
||||||
|
'forbid_old_passwords' => false,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* User's table column for google2fa secret
|
||||||
|
*/
|
||||||
|
'otp_secret_column' => 'two_factor_secret',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* One Time Password View
|
||||||
|
*/
|
||||||
|
'view' => 'auth.two_factor',
|
||||||
|
|
||||||
|
/*
|
||||||
|
* One Time Password error message
|
||||||
|
*/
|
||||||
|
'error_messages' => [
|
||||||
|
'wrong_otp' => "The 'One Time Password' typed was wrong.",
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Throw exceptions or just fire events?
|
||||||
|
*/
|
||||||
|
'throw_exceptions' => true,
|
||||||
|
|
||||||
|
];
|
52
config/hashing.php
Normal file
52
config/hashing.php
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default Hash Driver
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option controls the default hash driver that will be used to hash
|
||||||
|
| passwords for your application. By default, the bcrypt algorithm is
|
||||||
|
| used; however, you remain free to modify this option if you wish.
|
||||||
|
|
|
||||||
|
| Supported: "bcrypt", "argon", "argon2id"
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'driver' => 'bcrypt',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Bcrypt Options
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify the configuration options that should be used when
|
||||||
|
| passwords are hashed using the Bcrypt algorithm. This will allow you
|
||||||
|
| to control the amount of time it takes to hash the given password.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'bcrypt' => [
|
||||||
|
'rounds' => env('BCRYPT_ROUNDS', 10),
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Argon Options
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify the configuration options that should be used when
|
||||||
|
| passwords are hashed using the Argon algorithm. These will allow you
|
||||||
|
| to control the amount of time it takes to hash the given password.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'argon' => [
|
||||||
|
'memory' => 1024,
|
||||||
|
'threads' => 2,
|
||||||
|
'time' => 2,
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
94
config/logging.php
Normal file
94
config/logging.php
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Monolog\Handler\StreamHandler;
|
||||||
|
use Monolog\Handler\SyslogUdpHandler;
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default Log Channel
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This option defines the default log channel that gets used when writing
|
||||||
|
| messages to the logs. The name specified in this option should match
|
||||||
|
| one of the channels defined in the "channels" configuration array.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'default' => env('LOG_CHANNEL', 'stack'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Log Channels
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may configure the log channels for your application. Out of
|
||||||
|
| the box, Laravel uses the Monolog PHP logging library. This gives
|
||||||
|
| you a variety of powerful log handlers / formatters to utilize.
|
||||||
|
|
|
||||||
|
| Available Drivers: "single", "daily", "slack", "syslog",
|
||||||
|
| "errorlog", "monolog",
|
||||||
|
| "custom", "stack"
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'channels' => [
|
||||||
|
'stack' => [
|
||||||
|
'driver' => 'stack',
|
||||||
|
'channels' => ['daily'],
|
||||||
|
'ignore_exceptions' => false,
|
||||||
|
],
|
||||||
|
|
||||||
|
'single' => [
|
||||||
|
'driver' => 'single',
|
||||||
|
'path' => storage_path('logs/laravel.log'),
|
||||||
|
'level' => 'debug',
|
||||||
|
],
|
||||||
|
|
||||||
|
'daily' => [
|
||||||
|
'driver' => 'daily',
|
||||||
|
'path' => storage_path('logs/laravel.log'),
|
||||||
|
'level' => 'debug',
|
||||||
|
'days' => 14,
|
||||||
|
],
|
||||||
|
|
||||||
|
'slack' => [
|
||||||
|
'driver' => 'slack',
|
||||||
|
'url' => env('LOG_SLACK_WEBHOOK_URL'),
|
||||||
|
'username' => 'Laravel Log',
|
||||||
|
'emoji' => ':boom:',
|
||||||
|
'level' => 'critical',
|
||||||
|
],
|
||||||
|
|
||||||
|
'papertrail' => [
|
||||||
|
'driver' => 'monolog',
|
||||||
|
'level' => 'debug',
|
||||||
|
'handler' => SyslogUdpHandler::class,
|
||||||
|
'handler_with' => [
|
||||||
|
'host' => env('PAPERTRAIL_URL'),
|
||||||
|
'port' => env('PAPERTRAIL_PORT'),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
'stderr' => [
|
||||||
|
'driver' => 'monolog',
|
||||||
|
'handler' => StreamHandler::class,
|
||||||
|
'formatter' => env('LOG_STDERR_FORMATTER'),
|
||||||
|
'with' => [
|
||||||
|
'stream' => 'php://stderr',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
'syslog' => [
|
||||||
|
'driver' => 'syslog',
|
||||||
|
'level' => 'debug',
|
||||||
|
],
|
||||||
|
|
||||||
|
'errorlog' => [
|
||||||
|
'driver' => 'errorlog',
|
||||||
|
'level' => 'debug',
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
136
config/mail.php
Normal file
136
config/mail.php
Normal file
|
@ -0,0 +1,136 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Mail Driver
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Laravel supports both SMTP and PHP's "mail" function as drivers for the
|
||||||
|
| sending of e-mail. You may specify which one you're using throughout
|
||||||
|
| your application here. By default, Laravel is setup for SMTP mail.
|
||||||
|
|
|
||||||
|
| Supported: "smtp", "sendmail", "mailgun", "mandrill", "ses",
|
||||||
|
| "sparkpost", "log", "array"
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'driver' => env('MAIL_DRIVER', 'smtp'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| SMTP Host Address
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may provide the host address of the SMTP server used by your
|
||||||
|
| applications. A default option is provided that is compatible with
|
||||||
|
| the Mailgun mail service which will provide reliable deliveries.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| SMTP Host Port
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| This is the SMTP port used by your application to deliver e-mails to
|
||||||
|
| users of the application. Like the host we have set this value to
|
||||||
|
| stay compatible with the Mailgun e-mail application by default.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'port' => env('MAIL_PORT', 587),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Global "From" Address
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| You may wish for all e-mails sent by your application to be sent from
|
||||||
|
| the same address. Here, you may specify a name and address that is
|
||||||
|
| used globally for all e-mails that are sent by your application.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'from' => [
|
||||||
|
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
|
||||||
|
'name' => env('MAIL_FROM_NAME', 'Example'),
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| E-Mail Encryption Protocol
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may specify the encryption protocol that should be used when
|
||||||
|
| the application send e-mail messages. A sensible default using the
|
||||||
|
| transport layer security protocol should provide great security.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| SMTP Server Username
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| If your SMTP server requires a username for authentication, you should
|
||||||
|
| set it here. This will get used to authenticate with your server on
|
||||||
|
| connection. You may also set the "password" value below this one.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'username' => env('MAIL_USERNAME'),
|
||||||
|
|
||||||
|
'password' => env('MAIL_PASSWORD'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Sendmail System Path
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| When using the "sendmail" driver to send e-mails, we will need to know
|
||||||
|
| the path to where Sendmail lives on this server. A default path has
|
||||||
|
| been provided here, which will work well on most of your systems.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'sendmail' => '/usr/sbin/sendmail -bs',
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Markdown Mail Settings
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| If you are using Markdown based email rendering, you may configure your
|
||||||
|
| theme and component paths here, allowing you to customize the design
|
||||||
|
| of the emails. Or, you may simply stick with the Laravel defaults!
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'markdown' => [
|
||||||
|
'theme' => 'default',
|
||||||
|
|
||||||
|
'paths' => [
|
||||||
|
resource_path('views/vendor/mail'),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Log Channel
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| If you are using the "log" driver, you may specify the logging channel
|
||||||
|
| if you prefer to keep mail messages separate from other log entries
|
||||||
|
| for simpler reading. Otherwise, the default channel will be used.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'log_channel' => env('MAIL_LOG_CHANNEL'),
|
||||||
|
|
||||||
|
];
|
86
config/queue.php
Normal file
86
config/queue.php
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Default Queue Connection Name
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Laravel's queue API supports an assortment of back-ends via a single
|
||||||
|
| API, giving you convenient access to each back-end using the same
|
||||||
|
| syntax for every one. Here you may define a default connection.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'default' => env('QUEUE_CONNECTION', 'sync'),
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Queue Connections
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| Here you may configure the connection information for each server that
|
||||||
|
| is used by your application. A default configuration has been added
|
||||||
|
| for each back-end shipped with Laravel. You are free to add more.
|
||||||
|
|
|
||||||
|
| Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null"
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'connections' => [
|
||||||
|
|
||||||
|
'sync' => [
|
||||||
|
'driver' => 'sync',
|
||||||
|
],
|
||||||
|
|
||||||
|
'database' => [
|
||||||
|
'driver' => 'database',
|
||||||
|
'table' => 'jobs',
|
||||||
|
'queue' => 'default',
|
||||||
|
'retry_after' => 90,
|
||||||
|
],
|
||||||
|
|
||||||
|
'beanstalkd' => [
|
||||||
|
'driver' => 'beanstalkd',
|
||||||
|
'host' => 'localhost',
|
||||||
|
'queue' => 'default',
|
||||||
|
'retry_after' => 90,
|
||||||
|
],
|
||||||
|
|
||||||
|
'sqs' => [
|
||||||
|
'driver' => 'sqs',
|
||||||
|
'key' => env('SQS_KEY', 'your-public-key'),
|
||||||
|
'secret' => env('SQS_SECRET', 'your-secret-key'),
|
||||||
|
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'),
|
||||||
|
'queue' => env('SQS_QUEUE', 'your-queue-name'),
|
||||||
|
'region' => env('SQS_REGION', 'us-east-1'),
|
||||||
|
],
|
||||||
|
|
||||||
|
'redis' => [
|
||||||
|
'driver' => 'redis',
|
||||||
|
'connection' => 'default',
|
||||||
|
'queue' => env('REDIS_QUEUE', 'default'),
|
||||||
|
'retry_after' => 90,
|
||||||
|
'block_for' => 5,
|
||||||
|
],
|
||||||
|
|
||||||
|
],
|
||||||
|
|
||||||
|
/*
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
| Failed Queue Jobs
|
||||||
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
| These options configure the behavior of failed queue job logging so you
|
||||||
|
| can control which database and table are used to store the jobs that
|
||||||
|
| have failed. You may change them to any database / table you wish.
|
||||||
|
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
'failed' => [
|
||||||
|
'database' => env('DB_CONNECTION', 'mysql'),
|
||||||
|
'table' => 'failed_jobs',
|
||||||
|
],
|
||||||
|
|
||||||
|
];
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue