Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F2518361
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
29 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/src/.env.example b/src/.env.example
index 2811f18d..6c2b584b 100644
--- a/src/.env.example
+++ b/src/.env.example
@@ -1,98 +1,101 @@
APP_NAME=Kolab
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://127.0.0.1:8000
APP_PUBLIC_URL=
APP_DOMAIN=kolabnow.com
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_DATABASE=kolabdev
DB_HOST=127.0.0.1
DB_PASSWORD=kolab
DB_PORT=3306
DB_USERNAME=kolabdev
BROADCAST_DRIVER=log
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
SESSION_DRIVER=file
SESSION_LIFETIME=120
2FA_DSN=mysql://roundcube:Welcome2KolabSystems@127.0.0.1/roundcube
2FA_TOTP_DIGITS=6
2FA_TOTP_INTERVAL=30
2FA_TOTP_DIGEST=sha1
IMAP_URI=ssl://127.0.0.1:993
IMAP_ADMIN_LOGIN=cyrus-admin
IMAP_ADMIN_PASSWORD=Welcome2KolabSystems
IMAP_VERIFY_HOST=false
IMAP_VERIFY_PEER=false
LDAP_BASE_DN="dc=mgmt,dc=com"
LDAP_DOMAIN_BASE_DN="ou=Domains,dc=mgmt,dc=com"
LDAP_HOSTS=127.0.0.1
LDAP_PORT=389
LDAP_SERVICE_BIND_DN="uid=kolab-service,ou=Special Users,dc=mgmt,dc=com"
LDAP_SERVICE_BIND_PW="Welcome2KolabSystems"
LDAP_USE_SSL=false
LDAP_USE_TLS=false
# Administrative
LDAP_ADMIN_BIND_DN="cn=Directory Manager"
LDAP_ADMIN_BIND_PW="Welcome2KolabSystems"
LDAP_ADMIN_ROOT_DN="dc=mgmt,dc=com"
# Hosted (public registration)
LDAP_HOSTED_BIND_DN="uid=hosted-kolab-service,ou=Special Users,dc=mgmt,dc=com"
LDAP_HOSTED_BIND_PW="Welcome2KolabSystems"
LDAP_HOSTED_ROOT_DN="dc=hosted,dc=com"
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
SWOOLE_HTTP_HOST=127.0.0.1
SWOOLE_HTTP_PORT=8000
PAYMENT_PROVIDER=
MOLLIE_KEY=
STRIPE_KEY=
STRIPE_PUBLIC_KEY=
STRIPE_WEBHOOK_SECRET=
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS="noreply@example.com"
MAIL_FROM_NAME="Example.com"
MAIL_REPLYTO_ADDRESS=null
MAIL_REPLYTO_NAME=null
DNS_TTL=3600
DNS_SPF="v=spf1 mx -all"
DNS_STATIC="%s. MX 10 ext-mx01.mykolab.com."
DNS_COPY_FROM=null
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
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}"
JWT_SECRET=
+
+KB_ACCOUNT_DELETE=
+KB_ACCOUNT_SUSPENDED=
diff --git a/src/app/Console/Development/TemplateRender.php b/src/app/Console/Development/TemplateRender.php
new file mode 100644
index 00000000..50893431
--- /dev/null
+++ b/src/app/Console/Development/TemplateRender.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace App\Console\Development;
+
+use Illuminate\Console\Command;
+
+class TemplateRender extends Command
+{
+ /**
+ * The name and signature of the console command.
+ *
+ * @var string
+ */
+ protected $signature = 'template:render {template}';
+
+ /**
+ * The console command description.
+ *
+ * @var string
+ */
+ protected $description = "Render a email template.";
+
+ /**
+ * Execute the console command.
+ *
+ * @return mixed
+ */
+ public function handle()
+ {
+ $template = $this->argument('template');
+ $template = str_replace('/', '\\', $template);
+
+ $class = '\\App\\' . $template;
+
+ echo $class::fakeRender();
+ }
+}
diff --git a/src/app/Mail/NegativeBalance.php b/src/app/Mail/NegativeBalance.php
new file mode 100644
index 00000000..54ff3371
--- /dev/null
+++ b/src/app/Mail/NegativeBalance.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace App\Mail;
+
+use App\User;
+use App\Utils;
+use Illuminate\Bus\Queueable;
+use Illuminate\Mail\Mailable;
+use Illuminate\Queue\SerializesModels;
+
+class NegativeBalance extends Mailable
+{
+ use Queueable;
+ use SerializesModels;
+
+ /** @var \App\User A user (account) that is behind with payments */
+ protected $account;
+
+
+ /**
+ * Create a new message instance.
+ *
+ * @param \App\User $account A user (account)
+ *
+ * @return void
+ */
+ public function __construct(User $account)
+ {
+ $this->account = $account;
+ }
+
+ /**
+ * Build the message.
+ *
+ * @return $this
+ */
+ public function build()
+ {
+ $user = $this->account;
+
+ $subject = \trans('mail.negativebalance-subject', ['site' => \config('app.name')]);
+
+ $this->view('emails.negative_balance')
+ ->subject($subject)
+ ->with([
+ 'site' => \config('app.name'),
+ 'subject' => $subject,
+ 'username' => $user->name(true),
+ 'supportUrl' => \config('app.support_url'),
+ 'walletUrl' => Utils::serviceUrl('/wallet'),
+ ]);
+
+ return $this;
+ }
+
+ /**
+ * Render the mail template with fake data
+ *
+ * @return string HTML output
+ */
+ public static function fakeRender(): string
+ {
+ $user = new User();
+
+ $mail = new self($user);
+
+ return $mail->build()->render();
+ }
+}
diff --git a/src/app/Mail/PasswordReset.php b/src/app/Mail/PasswordReset.php
index 7f65d741..1cdd2a96 100644
--- a/src/app/Mail/PasswordReset.php
+++ b/src/app/Mail/PasswordReset.php
@@ -1,57 +1,80 @@
<?php
namespace App\Mail;
+use App\User;
use App\VerificationCode;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
+use Illuminate\Support\Str;
class PasswordReset extends Mailable
{
use Queueable;
use SerializesModels;
/** @var \App\VerificationCode A verification code object */
protected $code;
/**
* Create a new message instance.
*
* @param \App\VerificationCode $code A verification code object
*
* @return void
*/
public function __construct(VerificationCode $code)
{
$this->code = $code;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
$href = sprintf(
'%s/login/reset/%s-%s',
\config('app.url'),
$this->code->short_code,
$this->code->code
);
$this->view('emails.password_reset')
->subject(__('mail.passwordreset-subject', ['site' => \config('app.name')]))
->with([
'site' => \config('app.name'),
'code' => $this->code->code,
'short_code' => $this->code->short_code,
'link' => sprintf('<a href="%s">%s</a>', $href, $href),
'username' => $this->code->user->name(true)
]);
return $this;
}
+
+ /**
+ * Render the mail template with fake data
+ *
+ * @return string HTML output
+ */
+ public static function fakeRender(): string
+ {
+ $code = new VerificationCode([
+ 'code' => Str::random(VerificationCode::CODE_LENGTH),
+ 'short_code' => VerificationCode::generateShortCode(),
+ ]);
+
+ $code->user = new User([
+ 'email' => 'test@' . \config('app.domain'),
+ ]);
+
+ $mail = new self($code);
+
+ return $mail->build()->render();
+ }
}
diff --git a/src/app/Mail/SignupVerification.php b/src/app/Mail/SignupVerification.php
index 9036420f..99c98672 100644
--- a/src/app/Mail/SignupVerification.php
+++ b/src/app/Mail/SignupVerification.php
@@ -1,63 +1,87 @@
<?php
namespace App\Mail;
use App\SignupCode;
use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
+use Illuminate\Support\Str;
class SignupVerification extends Mailable
{
use Queueable;
use SerializesModels;
/** @var SignupCode A signup verification code object */
protected $code;
/**
* Create a new message instance.
*
* @param SignupCode $code A signup verification code object
*
* @return void
*/
public function __construct(SignupCode $code)
{
$this->code = $code;
}
/**
* Build the message.
*
* @return $this
*/
public function build()
{
$href = sprintf(
'%s/signup/%s-%s',
\config('app.url'),
$this->code->short_code,
$this->code->code
);
$username = $this->code->data['first_name'] ?? '';
if (!empty($this->code->data['last_name'])) {
$username .= ' ' . $this->code->data['last_name'];
}
$username = trim($username);
$this->view('emails.signup_code')
->subject(__('mail.signupcode-subject', ['site' => \config('app.name')]))
->with([
'site' => \config('app.name'),
'username' => $username ?: 'User',
'code' => $this->code->code,
'short_code' => $this->code->short_code,
'link' => sprintf('<a href="%s">%s</a>', $href, $href),
]);
return $this;
}
+
+ /**
+ * Render the mail template with fake data
+ *
+ * @return string HTML output
+ */
+ public static function fakeRender(): string
+ {
+ $code = new SignupCode([
+ 'code' => Str::random(SignupCode::CODE_LENGTH),
+ 'short_code' => SignupCode::generateShortCode(),
+ 'data' => [
+ 'email' => 'test@' . \config('app.domain'),
+ 'first_name' => 'Firstname',
+ 'last_name' => 'Lastname',
+ ],
+ ]);
+
+
+ $mail = new self($code);
+
+ return $mail->build()->render();
+ }
}
diff --git a/src/app/Mail/SuspendedDebtor.php b/src/app/Mail/SuspendedDebtor.php
new file mode 100644
index 00000000..e3509f91
--- /dev/null
+++ b/src/app/Mail/SuspendedDebtor.php
@@ -0,0 +1,77 @@
+<?php
+
+namespace App\Mail;
+
+use App\User;
+use App\Utils;
+use Illuminate\Bus\Queueable;
+use Illuminate\Mail\Mailable;
+use Illuminate\Queue\SerializesModels;
+
+class SuspendedDebtor extends Mailable
+{
+ use Queueable;
+ use SerializesModels;
+
+ /** @var \App\User A suspended user (account) */
+ protected $account;
+
+
+ /**
+ * Create a new message instance.
+ *
+ * @param \App\User $account A suspended user (account)
+ *
+ * @return void
+ */
+ public function __construct(User $account)
+ {
+ $this->account = $account;
+ }
+
+ /**
+ * Build the message.
+ *
+ * @return $this
+ */
+ public function build()
+ {
+ $user = $this->account;
+
+ $subject = \trans('mail.suspendeddebtor-subject', ['site' => \config('app.name')]);
+
+ $moreInfo = null;
+ if ($moreInfoUrl = \config('app.kb.account_suspended')) {
+ $moreInfo = \trans('mail.more-info-html', ['href' => $moreInfoUrl]);
+ }
+
+ $this->view('emails.suspended_debtor')
+ ->subject($subject)
+ ->with([
+ 'site' => \config('app.name'),
+ 'subject' => $subject,
+ 'username' => $user->name(true),
+ 'cancelUrl' => \config('app.kb.account_delete'),
+ 'supportUrl' => \config('app.support_url'),
+ 'walletUrl' => Utils::serviceUrl('/wallet'),
+ 'moreInfo' => $moreInfo,
+ 'days' => 14 // TODO: Configurable
+ ]);
+
+ return $this;
+ }
+
+ /**
+ * Render the mail template with fake data
+ *
+ * @return string HTML output
+ */
+ public static function fakeRender(): string
+ {
+ $user = new User();
+
+ $mail = new self($user);
+
+ return $mail->build()->render();
+ }
+}
diff --git a/src/config/app.php b/src/config/app.php
index 9dd7ddac..8dce8ef0 100644
--- a/src/config/app.php
+++ b/src/config/app.php
@@ -1,239 +1,247 @@
<?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'),
'public_url' => env('APP_PUBLIC_URL', env('APP_URL', 'http://localhost')),
'asset_url' => env('ASSET_URL', null),
/*
|--------------------------------------------------------------------------
| Application Domain
|--------------------------------------------------------------------------
|
| System domain used for user signup (kolab identity)
*/
'domain' => env('APP_DOMAIN', 'domain.tld'),
/*
|--------------------------------------------------------------------------
| 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,
],
/*
|--------------------------------------------------------------------------
| 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,
'Arr' => Illuminate\Support\Arr::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,
'Str' => Illuminate\Support\Str::class,
'URL' => Illuminate\Support\Facades\URL::class,
'Validator' => Illuminate\Support\Facades\Validator::class,
'View' => Illuminate\Support\Facades\View::class,
],
+
+ // Locations of knowledge base articles
+ 'kb' => [
+ // An article about suspended accounts
+ 'account_suspended' => env('KB_ACCOUNT_SUSPENDED'),
+ // An article about a way to delete an owned account
+ 'account_delete' => env('KB_ACCOUNT_DELETE'),
+ ],
];
diff --git a/src/resources/lang/en/mail.php b/src/resources/lang/en/mail.php
index 5b5b3f97..732dc4ac 100644
--- a/src/resources/lang/en/mail.php
+++ b/src/resources/lang/en/mail.php
@@ -1,25 +1,42 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Mail Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used in mail/sms messages sent by the app.
*/
'header' => "Dear :name,",
'footer' => "Best regards,\nYour :site Team",
+ 'negativebalance-subject' => ":site Payment Reminder",
+ 'negativebalance-body' => "It has probably skipped your attention that you are behind on paying for your :site account. "
+ . "Consider setting up auto-payment to avoid messages like this in the future.\n\n"
+ . "Settle up to keep your account running.",
+
'passwordreset-subject' => ":site Password Reset",
'passwordreset-body' => "Someone recently asked to change your :site password.\n"
. "If this was you, use this verification code to complete the process: :code.\n"
. "You can also click the link below.\n"
. "If you did not make such a request, you can either ignore this message or get in touch with us about this incident.",
'signupcode-subject' => ":site Registration",
'signupcode-body' => "This is your verification code for the :site registration process: :code.\n"
. "You can also click the link below to continue the registration process:",
+
+ 'suspendeddebtor-subject' => ":site Account Suspended",
+ 'suspendeddebtor-body' => "You have been behind on paying for your :site account "
+ ."for over :days days. Your account has been suspended.",
+ 'suspendeddebtor-middle' => "Settle up now to reactivate your account.",
+ 'suspendeddebtor-cancel' => "Don't want to be our customer anymore? "
+ . "Here is how you can cancel your account:",
+
+ 'support' => "Special circumstances? Something wrong with a charge?\n"
+ . " :site Support is here to help:",
+
+ 'more-info-html' => "See <a href=\":href\">here</a> for more information.",
];
diff --git a/src/resources/views/emails/negative_balance.blade.php b/src/resources/views/emails/negative_balance.blade.php
new file mode 100644
index 00000000..1294aa9e
--- /dev/null
+++ b/src/resources/views/emails/negative_balance.blade.php
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
+ <head>
+ <meta charset="utf-8">
+ </head>
+ <body>
+ <p>{{ __('mail.header', ['name' => $username]) }}</p>
+
+ <p>{{ __('mail.negativebalance-body', ['site' => $site]) }}</p>
+ <p><a href="{{ $walletUrl }}">{{ $walletUrl }}</a></p>
+
+@if ($supportUrl)
+ <p>{{ __('mail.support', ['site' => $site]) }}</p>
+ <p><a href="{{ $supportUrl }}">{{ $supportUrl }}</a></p>
+@endif
+
+ <p>{{ __('mail.footer', ['site' => $site, 'appurl' => config('app.url')]) }}</p>
+ </body>
+</html>
diff --git a/src/resources/views/emails/suspended_debtor.blade.php b/src/resources/views/emails/suspended_debtor.blade.php
new file mode 100644
index 00000000..ead7fc12
--- /dev/null
+++ b/src/resources/views/emails/suspended_debtor.blade.php
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
+ <head>
+ <meta charset="utf-8">
+ </head>
+ <body>
+ <p>{{ __('mail.header', ['name' => $username]) }}</p>
+
+ <p>{{ __('mail.suspendeddebtor-body', ['site' => $site, 'days' => $days]) }} {!! $moreInfo !!}</p>
+ <p>{{ __('mail.suspendeddebtor-middle') }}</p>
+ <p><a href="{{ $walletUrl }}">{{ $walletUrl }}</a></p>
+
+@if ($supportUrl)
+ <p>{{ __('mail.support', ['site' => $site]) }}</p>
+ <p><a href="{{ $supportUrl }}">{{ $supportUrl }}</a></p>
+@endif
+@if ($cancelUrl)
+ <p>{{ __('mail.suspendeddebtor-cancel') }}</p>
+ <p><a href="{{ $cancelUrl }}">{{ $cancelUrl }}</a></p>
+@endif
+
+ <p>{{ __('mail.footer', ['site' => $site, 'appurl' => config('app.url')]) }}</p>
+ </body>
+</html>
diff --git a/src/tests/Unit/Mail/NegativeBalanceTest.php b/src/tests/Unit/Mail/NegativeBalanceTest.php
new file mode 100644
index 00000000..1e173a29
--- /dev/null
+++ b/src/tests/Unit/Mail/NegativeBalanceTest.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Tests\Unit\Mail;
+
+use App\Mail\NegativeBalance;
+use App\User;
+use Tests\TestCase;
+
+class NegativeBalanceTest extends TestCase
+{
+ /**
+ * Test email content
+ *
+ * @return void
+ */
+ public function testBuild()
+ {
+ $user = new User();
+
+ \config([
+ 'app.support_url' => 'https://kolab.org/support',
+ ]);
+
+ $mail = new NegativeBalance($user);
+ $html = $mail->build()->render();
+
+ $walletUrl = \App\Utils::serviceUrl('/wallet');
+ $walletLink = sprintf('<a href="%s">%s</a>', $walletUrl, $walletUrl);
+ $supportUrl = \config('app.support_url');
+ $supportLink = sprintf('<a href="%s">%s</a>', $supportUrl, $supportUrl);
+
+ $appName = \config('app.name');
+
+ $this->assertSame("$appName Payment Reminder", $mail->subject);
+ $this->assertStringStartsWith('<!DOCTYPE html>', $html);
+ $this->assertTrue(strpos($html, $user->name(true)) > 0);
+ $this->assertTrue(strpos($html, $walletLink) > 0);
+ $this->assertTrue(strpos($html, $supportLink) > 0);
+ $this->assertTrue(strpos($html, "behind on paying for your $appName account") > 0);
+ $this->assertTrue(strpos($html, "$appName Support") > 0);
+ $this->assertTrue(strpos($html, "$appName Team") > 0);
+ }
+}
diff --git a/src/tests/Unit/Mail/SuspendedDebtorTest.php b/src/tests/Unit/Mail/SuspendedDebtorTest.php
new file mode 100644
index 00000000..a823bd71
--- /dev/null
+++ b/src/tests/Unit/Mail/SuspendedDebtorTest.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace Tests\Unit\Mail;
+
+use App\Mail\SuspendedDebtor;
+use App\User;
+use Tests\TestCase;
+
+class SuspendedDebtorTest extends TestCase
+{
+ /**
+ * Test email content
+ *
+ * @return void
+ */
+ public function testBuild()
+ {
+ $user = new User();
+
+ \config([
+ 'app.support_url' => 'https://kolab.org/support',
+ 'app.kb.account_suspended' => 'https://kb.kolab.org/account-suspended',
+ 'app.kb.account_delete' => 'https://kb.kolab.org/account-delete',
+ ]);
+
+ $mail = new SuspendedDebtor($user);
+ $html = $mail->build()->render();
+
+ $walletUrl = \App\Utils::serviceUrl('/wallet');
+ $walletLink = sprintf('<a href="%s">%s</a>', $walletUrl, $walletUrl);
+ $supportUrl = \config('app.support_url');
+ $supportLink = sprintf('<a href="%s">%s</a>', $supportUrl, $supportUrl);
+ $deleteUrl = \config('app.kb.account_delete');
+ $deleteLink = sprintf('<a href="%s">%s</a>', $deleteUrl, $deleteUrl);
+ $moreUrl = \config('app.kb.account_suspended');
+ $moreLink = sprintf('<a href="%s">here</a>', $moreUrl);
+
+ $appName = \config('app.name');
+
+ $this->assertSame("$appName Account Suspended", $mail->subject);
+ $this->assertStringStartsWith('<!DOCTYPE html>', $html);
+ $this->assertTrue(strpos($html, $user->name(true)) > 0);
+ $this->assertTrue(strpos($html, $walletLink) > 0);
+ $this->assertTrue(strpos($html, $supportLink) > 0);
+ $this->assertTrue(strpos($html, $deleteLink) > 0);
+ $this->assertTrue(strpos($html, "You have been behind on paying for your $appName account") > 0);
+ $this->assertTrue(strpos($html, "over 14 days") > 0);
+ $this->assertTrue(strpos($html, "See $moreLink for more information") > 0);
+ $this->assertTrue(strpos($html, "$appName Support") > 0);
+ $this->assertTrue(strpos($html, "$appName Team") > 0);
+ }
+}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Dec 18, 1:30 PM (1 d, 15 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
418857
Default Alt Text
(29 KB)
Attached To
Mode
R2 kolab
Attached
Detach File
Event Timeline
Log In to Comment