diff --git a/README.md b/README.md
index e95ec69..85adc71 100644
--- a/README.md
+++ b/README.md
@@ -19,17 +19,14 @@ I made the code open-source to show everyone what was going on behind the scenes
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/save 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 *@example.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:
@@ -46,7 +43,6 @@ Here are a few reasons I can think of:
* Ability to add additional usernames to compartmentalise aliases
* New features added regularly
-
#### **How do I add my own GPG/OpenPGP key for encryption?**
On the recipients page you simply need to click "Add public key" and paste in your **public** key data. Now all emails forwarded to you will be encrypted with your key. You should also replace the subject line of forwarded messages in your account settings as this cannot be encrypted.
@@ -63,7 +59,6 @@ You can add this key to your own keyring so that you can verify emails have come
The fingerprint of the mailer@anonaddy.me key is "26A987650243B28802524E2F809FD0D502E2F695" you can find the key on [https://keys.openpgp.org](https://keys.openpgp.org/search?q=26A987650243B28802524E2F809FD0D502E2F695).
-
#### **What if I don't want anyone to link ownership of my aliases together?**
If you're concerned that your aliases are all linked by your username e.g. @johndoe.anonaddy.com, then you have a couple of options:
@@ -71,22 +66,18 @@ If you're concerned that your aliases are all linked by your username e.g. @john
1. You can generate UUID aliases instead, these are all under the root domain and cannot be linked to a user.
2. You can add additional usernames and separate your aliases under your these. e.g. you could have one username for personal stuff, another for work, another for hobbies etc.
-
#### **Where is the server located?**
The server is located in Amsterdam, Netherlands with [Greenhost.net](https://greenhost.net/). Greenhost focuses greatly on privacy and security and their servers run entirely on Dutch wind energy.
-
#### **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. You'll need to know about server administration and PHP. 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:
@@ -100,7 +91,6 @@ When you delete your account the following happens:
The reason aliases with a custom domain are soft deleted (a deleted_at column is 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.
@@ -110,16 +100,28 @@ Yes this will work with any provider, althought I can't guarantee it won't land
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 count towards your bandwidth.
-
#### **What is the max email size limit?**
The max email size is currently set to 10MB (including attachments).
+#### **What happens if I have a subscription but then cancel it?**
+
+If you cancel your subscription it will remain active until the end of your current billing cycle, you will still be able to use Pro features until the billing cycle ends.
+
+A few days before your billing cycle ends you will receive an email letting you know the steps you need to take to prevent the loss of any emails. Shortly after ending the following will happen:
+
+* Any custom domains will be **deactivated**
+* Any additional usernames will be **deactivated**
+* If you have any more than **2 recipients** they will be **deleted**
+* Pro account settings will be reverted to default values
+* Any aliases using Pro only domains will be **deactivated**
+* If you have any more than 20 UUID aliases they will be **deactivated**
+
+You will not be able to activate any of the above again until you resubscribe.
#### **How do you prevent spammers?**
@@ -137,7 +139,6 @@ The following is in place to help prevent spam:
The server is running a local DNS caching server to improve the speed of queries. DNS.WATCH resolvers are 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.
@@ -154,27 +155,22 @@ I don't use rolling 30 day total as the only way to do this would be to log the
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 be keeping it running indefinitely.
-
#### **Is the application tested?**
Yes it has over 100 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. You can find more information here [https://github.com/anonaddy/anonaddy#self-hosting](https://github.com/anonaddy/anonaddy#self-hosting).
@@ -183,7 +179,6 @@ You will need to set up your own server with Postfix so that you can pipe the re
My name is Will Browning, I'm a web developer from the UK and an advocate for online privacy and open-source software. You can find me on [Twitter](https://twitter.com/willbrowningme) although I don't tweet that much!
-
#### **I couldn't find an answer to my question, how can I contact you?**
For any other questions just send an email to - [contact@anonaddy.com](mailto:contact@anonaddy.com)
diff --git a/app/Alias.php b/app/Alias.php
index 15e063d..daa8ee1 100644
--- a/app/Alias.php
+++ b/app/Alias.php
@@ -66,9 +66,9 @@ class Alias extends Model
/**
* Get the custom domain for the email alias.
*/
- public function domain()
+ public function customDomain()
{
- return $this->belongsTo(Domain::class);
+ return $this->belongsTo(Domain::class, 'domain_id');
}
/**
@@ -76,7 +76,7 @@ class Alias extends Model
*/
public function recipients()
{
- return $this->BelongsToMany(Recipient::class, 'alias_recipients')->withPivot('id')->using(AliasRecipient::class);
+ return $this->belongsToMany(Recipient::class, 'alias_recipients')->withPivot('id')->using(AliasRecipient::class);
}
/**
@@ -93,6 +93,11 @@ class Alias extends Model
public function verifiedRecipientsOrDefault()
{
if ($this->verifiedRecipients()->count() === 0) {
+ // If the alias is for a custom domain that has a default recipient set.
+ if (isset($this->customDomain->defaultRecipient)) {
+ return $this->customDomain->defaultRecipient();
+ }
+
return $this->user->defaultRecipient();
}
diff --git a/app/Domain.php b/app/Domain.php
index 0a6491e..baac6aa 100644
--- a/app/Domain.php
+++ b/app/Domain.php
@@ -33,7 +33,8 @@ class Domain extends Model
protected $casts = [
'id' => 'string',
'user_id' => 'string',
- 'active' => 'boolean'
+ 'active' => 'boolean',
+ 'default_recipient_id' => 'string',
];
/**
@@ -60,6 +61,23 @@ class Domain extends Model
return $this->hasMany(Alias::class);
}
+ /**
+ * Get the domains's default recipient.
+ */
+ public function defaultRecipient()
+ {
+ return $this->hasOne(Recipient::class, 'id', 'default_recipient_id');
+ }
+
+ /**
+ * Set the domains's default recipient.
+ */
+ public function setDefaultRecipientAttribute($recipient)
+ {
+ $this->attributes['default_recipient_id'] = $recipient->id;
+ $this->setRelation('defaultRecipient', $recipient);
+ }
+
/**
* Deactivate the domain.
*/
diff --git a/app/Http/Controllers/DomainController.php b/app/Http/Controllers/DomainController.php
index bcd5c64..0a2f70f 100644
--- a/app/Http/Controllers/DomainController.php
+++ b/app/Http/Controllers/DomainController.php
@@ -11,7 +11,7 @@ class DomainController extends Controller
public function index()
{
return view('domains.index', [
- 'domains' => user()->domains()->with('aliases')->latest()->get()
+ 'domains' => user()->domains()->with(['aliases', 'defaultRecipient'])->latest()->get()
]);
}
diff --git a/app/Http/Controllers/DomainDefaultRecipientController.php b/app/Http/Controllers/DomainDefaultRecipientController.php
new file mode 100644
index 0000000..cb816d4
--- /dev/null
+++ b/app/Http/Controllers/DomainDefaultRecipientController.php
@@ -0,0 +1,24 @@
+domains()->findOrFail($id);
+ if (empty($request->default_recipient)) {
+ $domain->default_recipient_id = null;
+ } else {
+ $recipient = user()->verifiedRecipients()->findOrFail($request->default_recipient);
+ $domain->default_recipient = $recipient;
+ }
+
+ $domain->save();
+
+ return new DomainResource($domain);
+ }
+}
diff --git a/app/Http/Requests/UpdateDomainDefaultRecipientRequest.php b/app/Http/Requests/UpdateDomainDefaultRecipientRequest.php
new file mode 100644
index 0000000..ecf8d63
--- /dev/null
+++ b/app/Http/Requests/UpdateDomainDefaultRecipientRequest.php
@@ -0,0 +1,30 @@
+ 'nullable|string'
+ ];
+ }
+}
diff --git a/app/User.php b/app/User.php
index b01462a..dbdfbac 100644
--- a/app/User.php
+++ b/app/User.php
@@ -165,6 +165,14 @@ class User extends Authenticatable implements MustVerifyEmail
return $this->recipients()->whereNotNull('email_verified_at');
}
+ /**
+ * Get all of the user's verified domains.
+ */
+ public function verifiedDomains()
+ {
+ return $this->domains()->whereNotNull('domain_verified_at');
+ }
+
/**
* Get all of the alias recipient pivot rows for the user.
*/
diff --git a/database/migrations/2019_09_24_153605_add_default_recipient_id_column_to_domains_table.php b/database/migrations/2019_09_24_153605_add_default_recipient_id_column_to_domains_table.php
new file mode 100644
index 0000000..6a53288
--- /dev/null
+++ b/database/migrations/2019_09_24_153605_add_default_recipient_id_column_to_domains_table.php
@@ -0,0 +1,32 @@
+uuid('default_recipient_id')->nullable()->after('user_id');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('domains', function (Blueprint $table) {
+ $table->dropColumn('default_recipient_id');
+ });
+ }
+}
diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png
index 61b117e..8ef8f9e 100644
Binary files a/public/android-chrome-192x192.png and b/public/android-chrome-192x192.png differ
diff --git a/public/android-chrome-256x256.png b/public/android-chrome-256x256.png
index 82afccb..2895f11 100644
Binary files a/public/android-chrome-256x256.png and b/public/android-chrome-256x256.png differ
diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png
index 20817c1..40ac823 100644
Binary files a/public/apple-touch-icon.png and b/public/apple-touch-icon.png differ
diff --git a/public/browserconfig.xml b/public/browserconfig.xml
index b3930d0..fae43da 100644
--- a/public/browserconfig.xml
+++ b/public/browserconfig.xml
@@ -3,7 +3,7 @@
- #da532c
+ #19216c
diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png
index 4675530..bd73fd0 100644
Binary files a/public/favicon-16x16.png and b/public/favicon-16x16.png differ
diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png
index 62f1255..664e14d 100644
Binary files a/public/favicon-32x32.png and b/public/favicon-32x32.png differ
diff --git a/public/favicon.ico b/public/favicon.ico
index a7b3965..cae439b 100644
Binary files a/public/favicon.ico and b/public/favicon.ico differ
diff --git a/public/mstile-150x150.png b/public/mstile-150x150.png
index c0c32ba..5e1a954 100644
Binary files a/public/mstile-150x150.png and b/public/mstile-150x150.png differ
diff --git a/public/safari-pinned-tab.svg b/public/safari-pinned-tab.svg
index cd1ff9e..7a9d4c6 100644
--- a/public/safari-pinned-tab.svg
+++ b/public/safari-pinned-tab.svg
@@ -10,19 +10,22 @@ Created by potrace 1.11, written by Peter Selinger 2001-2013
-
-
+-1300z m2200 655 c63 -32 60 -7 60 -596 l0 -536 -31 -61 c-17 -36 -46 -74 -69
+-92 -78 -62 -57 -60 -799 -60 -513 0 -680 3 -689 12 -16 16 -16 70 0 86 9 9
+170 12 662 12 417 0 664 4 688 10 46 13 92 50 107 87 8 20 11 162 9 497 l-3
+468 -305 -238 c-394 -307 -376 -294 -420 -294 -46 0 -71 17 -551 387 -102 78
+-191 154 -197 168 -26 57 -2 127 51 150 50 22 1445 22 1487 0z m-1496 -381
+c17 -16 21 -51 8 -70 -4 -7 -47 -44 -97 -83 -94 -74 -129 -86 -159 -55 -9 8
+-16 26 -16 40 0 26 15 41 125 128 74 58 111 69 139 40z m226 -144 c39 -39 18
+-84 -62 -135 -50 -31 -108 5 -94 59 7 27 91 96 118 96 10 0 27 -9 38 -20z
+m-536 -96 c50 -50 -31 -146 -90 -106 -18 12 -35 52 -28 65 31 54 86 74 118 41z
+m742 -67 c42 -36 28 -65 -64 -136 -42 -33 -115 -89 -162 -125 -90 -71 -124
+-81 -154 -47 -35 38 -18 60 144 189 140 111 181 139 202 141 4 1 19 -9 34 -22z
+m-408 -20 c12 -24 11 -31 -2 -52 -24 -37 -387 -315 -411 -315 -31 0 -57 33
+-53 66 2 23 38 55 198 181 164 129 200 153 225 151 21 -2 34 -11 43 -31z m-26
+-324 c34 -30 18 -82 -32 -108 -24 -13 -35 -13 -53 -4 -46 24 -50 68 -11 104
+31 29 70 32 96 8z"/>
+
diff --git a/public/site.webmanifest b/public/site.webmanifest
index de65106..c2c7e3f 100644
--- a/public/site.webmanifest
+++ b/public/site.webmanifest
@@ -1,6 +1,6 @@
{
- "name": "",
- "short_name": "",
+ "name": "AnonAddy",
+ "short_name": "AnonAddy",
"icons": [
{
"src": "/android-chrome-192x192.png",
diff --git a/public/svg/icon-logo.svg b/public/svg/icon-logo.svg
new file mode 100644
index 0000000..6a2e6a8
--- /dev/null
+++ b/public/svg/icon-logo.svg
@@ -0,0 +1,19 @@
+
+
+
diff --git a/public/svg/logo-dark.svg b/public/svg/logo-dark.svg
index 22da622..4df3414 100644
--- a/public/svg/logo-dark.svg
+++ b/public/svg/logo-dark.svg
@@ -1,23 +1,41 @@
-
-