mirror of
https://gitlab.linphone.org/BC/public/flexisip-account-manager.git
synced 2026-01-17 10:08:05 +00:00
Fix FLEXIAPI-224 Add a console script to send Space Expiration emails
This commit is contained in:
parent
48961ea194
commit
b0b6ab2c51
13 changed files with 129 additions and 14 deletions
|
|
@ -35,6 +35,7 @@ v1.7
|
|||
- Fix FLEXIAPI-287 Refactor the emails templates
|
||||
- Fix FLEXIAPI-286 Send an account_recovery_token using a push notification and protect the account recovery using phone page with the account_recovery_token
|
||||
- Fix FLEXIAPI-293 Remove the (long) outdated general documentation
|
||||
- Fix FLEXIAPI-224 Add a console script to send Space Expiration emails
|
||||
|
||||
v1.6
|
||||
----
|
||||
|
|
|
|||
|
|
@ -61,9 +61,9 @@ php artisan spaces:create-update beta.sip beta.myhost.com "Beta Space"
|
|||
|
||||
5. Configure your Spaces.
|
||||
|
||||
6. Remove the instance based environnement variables (see **Changed** above) and configure them directly in the spaces using the API or Web Panel.
|
||||
6. (Optional) Import the old instance DotEnv environnement variables into a space.
|
||||
|
||||
7. (Optional) Import the old instance DotEnv environnement variables into a space.
|
||||
7. Remove the instance based environnement variables (see **Changed** above) and configure them directly in the spaces using the API or Web Panel.
|
||||
|
||||
⚠️ Be careful, during this import only the project DotEnv file variables will be imported, other environnement (eg. set in Apache, nginx or Docker) will be ignored.
|
||||
|
||||
|
|
|
|||
|
|
@ -5,3 +5,4 @@ sudo -su www-data && php artisan digest:clear-nonces 60
|
|||
sudo -su www-data && php artisan accounts:clear-api-keys 60
|
||||
sudo -su www-data && php artisan accounts:clear-accounts-tombstones 7 --apply
|
||||
sudo -su www-data && php artisan accounts:clear-unconfirmed 30 --apply
|
||||
sudo -su www-data && php artisan spaces:expiration-emails
|
||||
|
|
|
|||
|
|
@ -5,3 +5,4 @@ php artisan digest:clear-nonces 60
|
|||
php artisan accounts:clear-api-keys 60
|
||||
php artisan accounts:clear-accounts-tombstones 7 --apply
|
||||
php artisan accounts:clear-unconfirmed 30 --apply
|
||||
php artisan spaces:expiration-emails
|
||||
|
|
@ -80,7 +80,6 @@ class CreateAdminAccount extends Command
|
|||
$account = new Account;
|
||||
$account->username = $username;
|
||||
$account->domain = $domain;
|
||||
$account->email = 'admin_test@sip.example.org';
|
||||
$account->activated = true;
|
||||
$account->user_agent = 'Test';
|
||||
$account->ip_address = '0.0.0.0';
|
||||
|
|
|
|||
57
flexiapi/app/Console/Commands/Spaces/ExpirationEmails.php
Normal file
57
flexiapi/app/Console/Commands/Spaces/ExpirationEmails.php
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands\Spaces;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Facades\Mail;
|
||||
use Carbon\Carbon;
|
||||
|
||||
use App\Mail\ExpiringSpace;
|
||||
use App\Space;
|
||||
|
||||
class ExpirationEmails extends Command
|
||||
{
|
||||
protected $signature = 'spaces:expiration-emails {days?}';
|
||||
protected $description = 'Send an expiration email on the designated configured days before expiration. Days must be ordered descending and comma separated (eg. 7,3,1)';
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$days = ['7','3','1'];
|
||||
|
||||
if ($this->argument('days')) {
|
||||
preg_match_all('/\d++/', $this->argument('days'), $matches);
|
||||
|
||||
if (!empty($matches[0])) {
|
||||
$i = 0;
|
||||
|
||||
while ($i + 1 < count($matches[0]) && (int)$matches[0][$i] > (int)$matches[0][$i + 1]) {
|
||||
$i++;
|
||||
}
|
||||
|
||||
if ($i != count($matches[0]) - 1) {
|
||||
$this->error('The days must be integer, ordered descending and comma separated');
|
||||
|
||||
return Command::FAILURE;
|
||||
}
|
||||
|
||||
$days = $matches[0];
|
||||
}
|
||||
}
|
||||
|
||||
$expiringSpaces = Space::whereNotNull('expire_at')->whereDate('expire_at', '>=', Carbon::now())->get();
|
||||
|
||||
foreach ($expiringSpaces as $expiringSpace) {
|
||||
if (in_array($expiringSpace->daysLeft, $days)) {
|
||||
$this->info($expiringSpace->name . ' (' . $expiringSpace->host . ') is expiring in ' . $expiringSpace->daysLeft . ' days');
|
||||
|
||||
$admins = $expiringSpace->admins()->withoutGlobalScopes()->whereNotNull('email')->get();
|
||||
|
||||
$this->info('Sending an email to the admins ' . $admins->implode('email', ','));
|
||||
|
||||
foreach ($admins as $admin) {
|
||||
Mail::to($admin->email)->send(new ExpiringSpace($expiringSpace));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
36
flexiapi/app/Mail/ExpiringSpace.php
Normal file
36
flexiapi/app/Mail/ExpiringSpace.php
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
namespace App\Mail;
|
||||
|
||||
use App\Space;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Mail\Mailables\Content;
|
||||
use Illuminate\Mail\Mailables\Envelope;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class ExpiringSpace extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
public function __construct(
|
||||
public Space $space
|
||||
) {
|
||||
}
|
||||
|
||||
public function envelope(): Envelope
|
||||
{
|
||||
return new Envelope(
|
||||
subject: $this->space->name . ': '. __('Space is expiring in :days days', ['days' => $this->space->daysLeft]),
|
||||
);
|
||||
}
|
||||
|
||||
public function content(): Content
|
||||
{
|
||||
return new Content(
|
||||
markdown: 'mails.expiring_space',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -66,7 +66,7 @@ class Space extends Model
|
|||
];
|
||||
|
||||
public const HOST_REGEX = '[\w\-]+';
|
||||
public const DOMAIN_REGEX = '(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(?<!-)\.)+[a-zA-Z]{2,63}$)';
|
||||
public const DOMAIN_REGEX = '(?=^.{4,253}$)(^((?!-)[a-z0-9-]{1,63}(?<!-)\.)+[a-z]{2,63}$)';
|
||||
|
||||
public function accounts()
|
||||
{
|
||||
|
|
@ -129,7 +129,7 @@ class Space extends Model
|
|||
public function getDaysLeftAttribute(): ?int
|
||||
{
|
||||
if ($this->expire_at != null) {
|
||||
return (int)$this->expire_at->diffInDays(Carbon::now());
|
||||
return (int)$this->expire_at->diffInDays(Carbon::now()) + 1;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@
|
|||
"Sip Adress": "Adresse SIP",
|
||||
"SIP Domain": "Domaine SIP",
|
||||
"Space": "Espace",
|
||||
"Space is expiring in :days days": "Votre Espace expire dans %d jours",
|
||||
"Spaces": "Espaces",
|
||||
"Statistics": "Statistiques",
|
||||
"Subdomain": "Sous-domaine",
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@
|
|||
</div>
|
||||
@endif
|
||||
|
||||
@if ($account->accountRecoveryTokens)
|
||||
@if ($account->accountRecoveryTokens->isNotEmpty())
|
||||
<div class="card large">
|
||||
<h3>Account Recovery Tokens</h3>
|
||||
<table>
|
||||
|
|
|
|||
|
|
@ -40,6 +40,11 @@
|
|||
@else
|
||||
<i class="ph">infinity</i>
|
||||
@endif
|
||||
|
||||
@if ($space->expire_at)
|
||||
<br />
|
||||
<small>{{ $space->expire_at->format('d-m-Y') }}</small>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
|
|
|||
14
flexiapi/resources/views/mails/expiring_space.blade.php
Normal file
14
flexiapi/resources/views/mails/expiring_space.blade.php
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
@extends('mails.layout')
|
||||
|
||||
@section('content')
|
||||
# {{ $space->name }} is expiring in {{ $space->daysLeft }} days
|
||||
|
||||
You are one of the administrator of the {{ $space->name }} space configured on our service.
|
||||
|
||||
We inform you that this Space is officialy expiring on **{{ $space->expire_at->format('d-m-Y') }}**.
|
||||
|
||||
After that day you and your registered users will not be able to use the features provided by your subscription anymore.
|
||||
|
||||
Be sure to renew your subscription if you would like to continue to use our services.
|
||||
|
||||
@endsection
|
||||
|
|
@ -203,6 +203,12 @@ Route::middleware(['web_panel_enabled', 'space.check'])->group(function () {
|
|||
});
|
||||
|
||||
Route::name('account.')->prefix('accounts')->group(function () {
|
||||
Route::name('import.')->prefix('import')->controller(AccountImportController::class)->group(function () {
|
||||
Route::get('/', 'create')->name('create');
|
||||
Route::post('/', 'store')->name('store');
|
||||
Route::post('handle', 'handle')->name('handle');
|
||||
});
|
||||
|
||||
Route::middleware(['intercom_features'])->group(function () {
|
||||
Route::name('type.')->prefix('types')->controller(AccountTypeController::class)->group(function () {
|
||||
Route::get('/', 'index')->name('index');
|
||||
|
|
@ -260,12 +266,6 @@ Route::middleware(['web_panel_enabled', 'space.check'])->group(function () {
|
|||
Route::get('send', 'send')->name('send');
|
||||
});
|
||||
|
||||
Route::name('import.')->prefix('import')->controller(AccountImportController::class)->group(function () {
|
||||
Route::get('/', 'create')->name('create');
|
||||
Route::post('/', 'store')->name('store');
|
||||
Route::post('handle', 'handle')->name('handle');
|
||||
});
|
||||
|
||||
Route::name('contact.')->prefix('{account}/contacts')->controller(AccountContactController::class)->group(function () {
|
||||
Route::get('/', 'index')->name('index');
|
||||
Route::get('create', 'create')->name('create');
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue