diff --git a/cron/flexiapi.cron b/cron/flexiapi.cron new file mode 100644 index 0000000..a11ed25 --- /dev/null +++ b/cron/flexiapi.cron @@ -0,0 +1 @@ +* * * * * apache /opt/belledonne-communications/share/flexisip-account-manager/flexiapi/artisan schedule:run >> /dev/null 2>&1 \ No newline at end of file diff --git a/flexiapi/app/Account.php b/flexiapi/app/Account.php index 81bd739..4bfca3e 100644 --- a/flexiapi/app/Account.php +++ b/flexiapi/app/Account.php @@ -146,6 +146,11 @@ class Account extends Authenticatable ->latest(); } + public function uploadedVoicemails() + { + return $this->voicemails()->whereNotNull('name'); + } + public function vcardsStorage() { return $this->hasMany(VcardStorage::class); diff --git a/flexiapi/app/AccountFile.php b/flexiapi/app/AccountFile.php index 404f28f..e8c81a7 100644 --- a/flexiapi/app/AccountFile.php +++ b/flexiapi/app/AccountFile.php @@ -12,19 +12,22 @@ class AccountFile extends Model public const VOICEMAIL_CONTENTTYPES = ['audio/opus', 'audio/wav']; public const FILES_PATH = 'files'; - protected $hidden = ['account_id', 'updated_at']; + protected $hidden = ['account_id', 'updated_at', 'sending_by_mail_at', 'sent_by_mail_at', 'sending_by_mail_tryouts']; protected $appends = ['download_url']; + protected $casts = [ + 'uploaded_at' => 'datetime', + ]; protected static function booted() { - static::deleting(function ($category) { - Storage::delete($this->getPathAttribute()); + static::deleting(function (AccountFile $accountFile) { + Storage::delete($accountFile->getPathAttribute()); }); } public function account() { - return $this->belongsTo(Account::class); + return $this->belongsTo(Account::class)->withoutGlobalScopes(); } public function getMaxUploadSizeAttribute(): ?int @@ -42,11 +45,30 @@ class AccountFile extends Model return self::FILES_PATH . '/' . $this->attributes['name']; } + public function getUrlAttribute(): ?string + { + return !empty($this->attributes['name']) + && !empty($this->attributes['id']) + ? replaceHost( + route('file.show', ['uuid' => $this->attributes['id'], 'name' => $this->attributes['name']]), + $this->account->space->host + ) + : null; + } + public function getDownloadUrlAttribute(): ?string { return !empty($this->attributes['name']) && !empty($this->attributes['id']) - ? route('file.show', [$this->attributes['id'], $this->attributes['name']]) + ? replaceHost(route( + 'file.download', + ['uuid' => $this->attributes['id'], 'name' => $this->attributes['name']] + ), $this->account->space->host) : null; } + + public function isVoicemailAudio(): bool + { + return in_array($this->attributes['content_type'], self::VOICEMAIL_CONTENTTYPES); + } } diff --git a/flexiapi/app/Console/Commands/Accounts/SendVoicemailsEmails.php b/flexiapi/app/Console/Commands/Accounts/SendVoicemailsEmails.php new file mode 100644 index 0000000..a5ba5ad --- /dev/null +++ b/flexiapi/app/Console/Commands/Accounts/SendVoicemailsEmails.php @@ -0,0 +1,40 @@ +whereNull('sent_by_mail_at') + ->where('sending_by_mail_tryouts', '<', is_int($this->option('tryout')) + ? $this->option('tryout') + : 3) + ->get(); + + foreach ($voicemails as $voicemail) { + $voicemail->sending_by_mail_at = Carbon::now(); + $voicemail->save(); + + if (Mail::to(users: $voicemail->account)->send(new Voicemail($voicemail))) { + $voicemail->sent_by_mail_at = Carbon::now(); + $this->info('Voicemail sent to ' . $voicemail->account->identifier); + } else { + $voicemail->sending_by_mail_tryouts++; + $this->info('Error sending voicemail to ' . $voicemail->account->identifier); + } + + $voicemail->save(); + } + } +} diff --git a/flexiapi/app/Helpers/Utils.php b/flexiapi/app/Helpers/Utils.php index 8762f65..351cbef 100644 --- a/flexiapi/app/Helpers/Utils.php +++ b/flexiapi/app/Helpers/Utils.php @@ -162,17 +162,12 @@ function resolveDomain(Request $request): string : $request->space->domain; } -function maxUploadSize(): ?int +function maxUploadSize(): int { - $uploadMaxSizeInBytes = ini_parse_quantity(ini_get('upload_max_filesize')); - if ($uploadMaxSizeInBytes > 0) { - return $uploadMaxSizeInBytes / 1024; - } - - $postMaxSizeInBytes = ini_parse_quantity(ini_get('post_max_size')); - if ($postMaxSizeInBytes > 0) { - return $postMaxSizeInBytes / 1024; - } + return min( + ini_parse_quantity(ini_get('upload_max_filesize')), + ini_parse_quantity(ini_get('post_max_size')) + ); } function captchaConfigured(): bool diff --git a/flexiapi/app/Http/Controllers/Account/FileController.php b/flexiapi/app/Http/Controllers/Account/FileController.php new file mode 100644 index 0000000..a596887 --- /dev/null +++ b/flexiapi/app/Http/Controllers/Account/FileController.php @@ -0,0 +1,32 @@ +name != $name) { + abort(404); + } + + return Storage::get($file->path); + } + + public function download(string $uuid, string $name) + { + $file = AccountFile::findOrFail($uuid); + + if ($file->name != $name) { + abort(404); + } + + return Storage::download($file->path); + } +} diff --git a/flexiapi/app/Http/Controllers/Admin/Account/FileController.php b/flexiapi/app/Http/Controllers/Admin/Account/FileController.php new file mode 100644 index 0000000..26d55eb --- /dev/null +++ b/flexiapi/app/Http/Controllers/Admin/Account/FileController.php @@ -0,0 +1,32 @@ +files()->where('id', $fileId)->firstOrFail(); + + return view('admin.account.file.delete', [ + 'account' => $account, + 'file' => $file + ]); + } + + public function destroy(Request $request, int $accountId, string $fileId) + { + $account = Account::findOrFail($accountId); + $accountFile = $account->files() + ->where('id', $fileId) + ->firstOrFail(); + $accountFile->delete(); + + return redirect()->route('admin.account.show', $account)->withFragment('#files'); + } +} diff --git a/flexiapi/app/Http/Controllers/Api/Account/FileController.php b/flexiapi/app/Http/Controllers/Api/Account/FileController.php index 6c61b9f..bcab52d 100644 --- a/flexiapi/app/Http/Controllers/Api/Account/FileController.php +++ b/flexiapi/app/Http/Controllers/Api/Account/FileController.php @@ -4,24 +4,13 @@ namespace App\Http\Controllers\Api\Account; use App\AccountFile; use App\Http\Controllers\Controller; +use App\Rules\AudioMime; use Carbon\Carbon; use Illuminate\Http\Request; -use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; class FileController extends Controller { - public function show(string $uuid, string $name) - { - $file = AccountFile::findOrFail($uuid); - - if ($file->name != $name) { - abort(404); - } - - return Storage::download($file->path); - } - public function upload(Request $request, string $uuid) { $file = AccountFile::findOrFail($uuid); @@ -30,14 +19,16 @@ class FileController extends Controller abort(404); } - $request->validate([ - 'file' => 'required|file|mimetypes:' . $file->content_type - ]); + $request->validate(['file' => 'required|file']); + + if ($file->isVoicemailAudio()) { + $request->validate(['file' => [new AudioMime($file)]]); + } $uploadedFile = $request->file('file'); $name = Str::random(8) . '_' . $uploadedFile->getClientOriginalName(); - if ($uploadedFile->storeAs('files', $name)) { + if ($uploadedFile->storeAs(AccountFile::FILES_PATH, $name)) { $file->name = $name; $file->size = $uploadedFile->getSize(); $file->uploaded_at = Carbon::now(); diff --git a/flexiapi/app/Http/Controllers/Api/Admin/Account/VoicemailController.php b/flexiapi/app/Http/Controllers/Api/Admin/Account/VoicemailController.php index e2db717..42bf3b2 100644 --- a/flexiapi/app/Http/Controllers/Api/Admin/Account/VoicemailController.php +++ b/flexiapi/app/Http/Controllers/Api/Admin/Account/VoicemailController.php @@ -18,7 +18,6 @@ class VoicemailController extends Controller public function store(Request $request, int $accountId) { $account = Account::findOrFail($accountId); - $request->validate([ 'sip_from' => 'nullable|starts_with:sip', 'content_type' => [ diff --git a/flexiapi/app/Mail/ExpiringSpace.php b/flexiapi/app/Mail/ExpiringSpace.php index b540810..c315a54 100644 --- a/flexiapi/app/Mail/ExpiringSpace.php +++ b/flexiapi/app/Mail/ExpiringSpace.php @@ -5,7 +5,6 @@ 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; diff --git a/flexiapi/app/Mail/NewsletterRegistration.php b/flexiapi/app/Mail/NewsletterRegistration.php index bcd590d..b55c8d7 100644 --- a/flexiapi/app/Mail/NewsletterRegistration.php +++ b/flexiapi/app/Mail/NewsletterRegistration.php @@ -22,7 +22,6 @@ namespace App\Mail; use App\Account; use Illuminate\Bus\Queueable; -use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Mail\Mailable; use Illuminate\Mail\Mailables\Content; use Illuminate\Mail\Mailables\Envelope; diff --git a/flexiapi/app/Mail/Provisioning.php b/flexiapi/app/Mail/Provisioning.php index 097dd67..10995ef 100644 --- a/flexiapi/app/Mail/Provisioning.php +++ b/flexiapi/app/Mail/Provisioning.php @@ -22,7 +22,6 @@ namespace App\Mail; use App\Account; use Illuminate\Bus\Queueable; -use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Mail\Mailable; use Illuminate\Mail\Mailables\Content; use Illuminate\Mail\Mailables\Envelope; diff --git a/flexiapi/app/Mail/RecoverByCode.php b/flexiapi/app/Mail/RecoverByCode.php index 16f58ca..5aa0354 100644 --- a/flexiapi/app/Mail/RecoverByCode.php +++ b/flexiapi/app/Mail/RecoverByCode.php @@ -22,7 +22,6 @@ namespace App\Mail; use App\Account; use Illuminate\Bus\Queueable; -use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Mail\Mailable; use Illuminate\Mail\Mailables\Content; use Illuminate\Mail\Mailables\Envelope; diff --git a/flexiapi/app/Mail/ResetPassword.php b/flexiapi/app/Mail/ResetPassword.php index 4abc43a..e045bd7 100644 --- a/flexiapi/app/Mail/ResetPassword.php +++ b/flexiapi/app/Mail/ResetPassword.php @@ -20,10 +20,8 @@ namespace App\Mail; use App\Account; -use App\ResetPasswordEmailToken; use Illuminate\Bus\Queueable; -use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Mail\Mailable; use Illuminate\Mail\Mailables\Content; use Illuminate\Mail\Mailables\Envelope; diff --git a/flexiapi/app/Mail/Voicemail.php b/flexiapi/app/Mail/Voicemail.php new file mode 100644 index 0000000..56e217c --- /dev/null +++ b/flexiapi/app/Mail/Voicemail.php @@ -0,0 +1,44 @@ +accountFile->account->space->name . + ': ' . + __('New voice message from :sipfrom', ['sipfrom' => $this->accountFile->sip_from]), + ); + } + + public function content(): Content + { + return new Content( + markdown: 'mails.voicemail', + ); + } + + public function attachments(): array + { + return [ + Attachment::fromStorage($this->accountFile->path) + ->withMime($this->accountFile->content_type) + ]; + } +} diff --git a/flexiapi/app/Rules/AudioMime.php b/flexiapi/app/Rules/AudioMime.php new file mode 100644 index 0000000..b1d10da --- /dev/null +++ b/flexiapi/app/Rules/AudioMime.php @@ -0,0 +1,38 @@ +getMimeType()) { + case 'audio/opus': + $mimeType = 'audio/opus'; + break; + + case 'audio/vnd.wave': + case 'audio/wav': + case 'audio/wave': + case 'audio/x-wav': + case 'audio/x-pn-wav': + $mimeType = 'audio/wav'; + break; + } + + return $this->accountFile->content_type == $mimeType; + } + + public function message() + { + return __('The file should have the declared mime-type'); + } +} diff --git a/flexiapi/app/Rules/IsNotPhoneNumber.php b/flexiapi/app/Rules/IsNotPhoneNumber.php index cd27155..c06e1c8 100644 --- a/flexiapi/app/Rules/IsNotPhoneNumber.php +++ b/flexiapi/app/Rules/IsNotPhoneNumber.php @@ -3,7 +3,6 @@ namespace App\Rules; use Illuminate\Contracts\Validation\Rule; -use Respect\Validation\Validator; use Propaganistas\LaravelPhone\PhoneNumber; class IsNotPhoneNumber implements Rule diff --git a/flexiapi/database/migrations/2025_10_20_093414_create_account_files_table.php b/flexiapi/database/migrations/2025_10_20_093414_create_account_files_table.php index 6be05d2..cedde59 100644 --- a/flexiapi/database/migrations/2025_10_20_093414_create_account_files_table.php +++ b/flexiapi/database/migrations/2025_10_20_093414_create_account_files_table.php @@ -18,6 +18,9 @@ return new class extends Migration $table->string('content_type')->index(); $table->text('sip_from')->nullable(); $table->dateTime('uploaded_at')->nullable(); + $table->dateTime('sending_by_mail_at')->nullable(); + $table->integer('sending_by_mail_tryouts')->default(0); + $table->dateTime('sent_by_mail_at')->nullable(); $table->timestamps(); }); } diff --git a/flexiapi/lang/fr.json b/flexiapi/lang/fr.json index 47a70d5..ab99cfd 100644 --- a/flexiapi/lang/fr.json +++ b/flexiapi/lang/fr.json @@ -101,6 +101,7 @@ "Features": "Fonctionnalités", "Fill the related columns if you want to add an external account as well": "Remplissez également les colonnes suivantes si vous souhaitez ajouter un compte externe", "Fill to change": "Remplir pour changer", + "Files": "Fichiers", "From": "Depuis", "Hello":"Bonjour", "Host": "Hôte", @@ -145,6 +146,7 @@ "New newsletter subscription": "Nouvelle inscription à votre newsletter", "New Space": "Nouvel Espace", "New user": "Nouvel utilisateur", + "New voice message from :sipfrom": "Nouveau message vocal de :sipfrom", "Newsletter registration email address": "Addresse email d'inscription à la liste de diffusion", "Next": "Suivant", "No account yet?": "Pas encore de compte ?", @@ -170,6 +172,7 @@ "QR Code scanning": "Scan de QR Code", "Realm": "Royaume", "Recover your account using your email": "Récupérer votre compte avec votre email", + "Recorded at": "Enregistré le", "Register": "Inscription", "Registrar": "Registrar", "Registration confirmed": "Confirmation de l'inscription", @@ -246,6 +249,7 @@ "Verify": "Vérifier", "Via": "Via", "Visit our user guide" : "Consulter notre guide utilisateur", + "Voicemails": "Messages vocaux", "We are pleased to inform you that your account has been successfully created.":"Nous avons le plaisir de vous informer que votre compte a été créé avec succès.", "We inform you that this space will expire on :date, in accordance with the expiration date defined in your subscription.":"Nous vous informons que l'espace expira le :date, conformément à la date d’expiration définie dans votre abonnement.", "We received a request to recover your account on :space": "Nous avons reçu une demande de récupération de votre compte sur :space", diff --git a/flexiapi/phpmd.xml b/flexiapi/phpmd.xml index 953c29e..0b70f75 100644 --- a/flexiapi/phpmd.xml +++ b/flexiapi/phpmd.xml @@ -10,7 +10,6 @@ The Clean Code ruleset contains rules that enforce a clean code base. This includes rules from SOLID and object calisthenics. - diff --git a/flexiapi/public/css/style.css b/flexiapi/public/css/style.css index ac81b65..429ce8c 100644 --- a/flexiapi/public/css/style.css +++ b/flexiapi/public/css/style.css @@ -190,6 +190,11 @@ body.welcome content { } } +audio { + border-radius: 1rem; + max-width: 12rem; +} + hr { border-bottom: 1px solid var(--grey-3); margin: 2rem 0; diff --git a/flexiapi/resources/views/admin/account/show.blade.php b/flexiapi/resources/views/admin/account/show.blade.php index 6a3a36b..027e4ef 100644 --- a/flexiapi/resources/views/admin/account/show.blade.php +++ b/flexiapi/resources/views/admin/account/show.blade.php @@ -177,10 +177,9 @@ - @endif -
+

{{ __('Devices') }}

@@ -212,6 +211,53 @@
+
+

+ {{ __('Voicemails') }} +

+ + + + + + + + + @if ($account->uploadedVoicemails->isEmpty()) + + + + @endif + @foreach ($account->uploadedVoicemails as $voicemail) + + + + + @endforeach + +
{{ __('Created') }}
{{ __('Empty') }}
+ {{ $voicemail->created_at }} + @if ($voicemail->url) + + + + @endif + @if ($voicemail->sip_from) +
+ {{ $voicemail->sip_from }} + @endif +
+ @if ($voicemail->url) + + + + + @endif +
+
+
diff --git a/flexiapi/resources/views/mails/voicemail.blade.php b/flexiapi/resources/views/mails/voicemail.blade.php new file mode 100644 index 0000000..3bd7487 --- /dev/null +++ b/flexiapi/resources/views/mails/voicemail.blade.php @@ -0,0 +1,14 @@ +@extends('mails.layout') + +@section('content') +# {{ __('New voice message from :sipfrom', ['sipfrom' => $accountFile->sip_from]) }} + +{{ __('New voice message') }} + +{{ __('From') }}: {{ $accountFile->sip_from }} + +{{ __('To') }}: {{ $accountFile->account->identifier }} + +{{ __('Recorded at') }}: {{ $accountFile->created_at->toDateTimeString() }} (UTC) + +@endsection diff --git a/flexiapi/routes/api.php b/flexiapi/routes/api.php index 80ded70..5ed31f0 100644 --- a/flexiapi/routes/api.php +++ b/flexiapi/routes/api.php @@ -79,9 +79,10 @@ Route::get('accounts/me/api_key/{auth_token}', [ApiKeyController::class, 'genera Route::get('phone_countries', [PhoneCountryController::class, 'index']); Route::group(['middleware' => ['auth.jwt', 'auth.digest_or_key', 'auth.check_blocked']], function () { + Route::post('files/{uuid}', [FileController::class, 'upload'])->name('file.upload'); + Route::get('accounts/auth_token/{auth_token}/attach', [AuthTokenController::class, 'attach']); Route::post('account_creation_tokens/consume', [CreationTokenController::class, 'consume']); - Route::post('files/{uuid}', 'Api\Account\FileController@upload')->name('file.upload'); Route::post('push_notification', [PushNotificationController::class, 'push']); diff --git a/flexiapi/routes/console.php b/flexiapi/routes/console.php index def2870..e91e885 100644 --- a/flexiapi/routes/console.php +++ b/flexiapi/routes/console.php @@ -1,4 +1,8 @@ daily(); +Schedule::command(SendVoicemailsEmails::class)->everyMinute(); diff --git a/flexiapi/routes/web.php b/flexiapi/routes/web.php index a843982..a2af9ad 100644 --- a/flexiapi/routes/web.php +++ b/flexiapi/routes/web.php @@ -26,6 +26,7 @@ use App\Http\Controllers\Account\ContactVcardController; use App\Http\Controllers\Account\CreationRequestTokenController; use App\Http\Controllers\Account\DeviceController; use App\Http\Controllers\Account\EmailController; +use App\Http\Controllers\Account\FileController; use App\Http\Controllers\Account\PasswordController; use App\Http\Controllers\Account\PhoneController; use App\Http\Controllers\Account\ProvisioningController; @@ -39,6 +40,7 @@ use App\Http\Controllers\Admin\Account\CardDavCredentialsController; use App\Http\Controllers\Admin\Account\ContactController; use App\Http\Controllers\Admin\Account\DeviceController as AdminAccountDeviceController; use App\Http\Controllers\Admin\Account\DictionaryController; +use App\Http\Controllers\Admin\Account\FileController as AdminFileController; use App\Http\Controllers\Admin\Account\ImportController; use App\Http\Controllers\Admin\Account\StatisticsController as AdminAccountStatisticsController; use App\Http\Controllers\Admin\Account\TypeController; @@ -54,7 +56,6 @@ use App\Http\Controllers\Admin\Space\ContactsListController; use App\Http\Controllers\Admin\Space\EmailServerController; use App\Http\Controllers\Admin\SpaceController; use App\Http\Controllers\Admin\StatisticsController; -use App\Http\Controllers\Api\Account\FileController; use Illuminate\Support\Facades\Route; Route::redirect('/', 'login')->name('account.home'); @@ -77,8 +78,12 @@ Route::middleware(['feature.web_panel_enabled'])->group(function () { }); }); +Route::name('file.')->prefix('files')->controller(FileController::class)->group(function () { + Route::get('{uuid}/{name}', 'show')->name('show'); + Route::get('{uuid}/{name}/download', 'download')->name('download'); +}); + Route::group(['middleware' => ['auth.jwt', 'auth.digest_or_key']], function () { - Route::get('files/{uuid}/{name}', [FileController::class, 'show'])->name('file.show'); Route::get('provisioning/me', [ProvisioningController::class, 'me'])->name('provisioning.me'); @@ -341,6 +346,11 @@ Route::middleware(['feature.web_panel_enabled'])->group(function () { Route::get('call_logs', 'showCallLogs')->name('show_call_logs'); Route::post('/', 'edit')->name('edit'); }); + + Route::name('file.')->prefix('{account}/files')->controller(AdminFileController::class)->group(function () { + Route::get('{file_id}/delete', 'delete')->name('delete'); + Route::delete('{file_id}', 'destroy')->name('destroy'); + }); }); }); }); diff --git a/flexiapi/tests/Feature/ApiVoicemailTest.php b/flexiapi/tests/Feature/ApiVoicemailTest.php index 829426d..6723372 100644 --- a/flexiapi/tests/Feature/ApiVoicemailTest.php +++ b/flexiapi/tests/Feature/ApiVoicemailTest.php @@ -145,7 +145,7 @@ class ApiVoicemailTest extends TestCase 'file' => UploadedFile::fake()->create('audio.opus', 500, 'audio/opus') ])->assertNotFound(); - $this->head($file->json()['download_url'])->assertOk(); + $this->head($file->json()['download_url'])->dump()->assertOk(); // Delete the file $this->keyAuthenticated($account) @@ -153,5 +153,23 @@ class ApiVoicemailTest extends TestCase ->assertOk(); $this->head($file->json()['download_url'])->assertNotFound(); + + /* To try out with a real file + $accountFile = $this->keyAuthenticated($account) + ->json('POST', $this->route, [ + 'content_type' => 'audio/wav' + ])->assertCreated(); + + $uuid = $accountFile->json()['id']; + + $this->keyAuthenticated($account) + ->json('POST', $this->uploadRoute . $uuid, data: [ + 'file' => new UploadedFile( + storage_path("audio.wav"), + 'audio.wav', + test: true, + ) + ])->assertOk(); + */ } } diff --git a/flexisip-account-manager.spec b/flexisip-account-manager.spec index b3ae4fa..4df2d0e 100644 --- a/flexisip-account-manager.spec +++ b/flexisip-account-manager.spec @@ -54,6 +54,7 @@ cp flexiapi/composer.json "$RPM_BUILD_ROOT%{opt_dir}/flexiapi" cp README* "$RPM_BUILD_ROOT%{opt_dir}/" cp INSTALL* "$RPM_BUILD_ROOT%{opt_dir}/" mkdir -p $RPM_BUILD_ROOT/etc/cron.daily +mkdir -p $RPM_BUILD_ROOT/etc/cron.d mkdir -p $RPM_BUILD_ROOT%{apache_conf_path} cp httpd/flexisip-account-manager.conf "$RPM_BUILD_ROOT%{apache_conf_path}/" @@ -66,6 +67,13 @@ cp httpd/flexisip-account-manager.conf "$RPM_BUILD_ROOT%{apache_conf_path}/" chmod +x "$RPM_BUILD_ROOT/etc/cron.daily/flexiapi.redhat" %endif +cp cron/flexiapi.cron "$RPM_BUILD_ROOT/etc/cron.d/flexiapi" +chmod +x "$RPM_BUILD_ROOT/etc/cron.d/flexiapi" + +%if %{with deb} + sed 's/apache/www-data/g' "$RPM_BUILD_ROOT/etc/cron.d/flexiapi" +%endif + # POST INSTALLATION %posttrans @@ -161,6 +169,7 @@ fi %exclude %{opt_dir}/flexiapi/storage/ +%config /etc/cron.d/flexiapi %config(noreplace) %{apache_conf_path}/flexisip-account-manager.conf %if %{with deb} %config(noreplace) /etc/cron.daily/flexiapi.debian