diff --git a/CHANGELOG.md b/CHANGELOG.md index f1f87e5..1659202 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ v1.7 - Fix GH-15 Add password import from CSV - Fix FLEXIAPI-242 Add stricter validation for the AccountCreationToken Push Notification endpoint - Fix FLEXIAPI-241 Add a /push-notification endpoint to send custom push notifications to the Flexisip Pusher +- Fix FLEXIAPI-250 Allow Spaces to be declared without a subdomain v1.6 ---- diff --git a/RELEASE.md b/RELEASE.md index 248841d..6e693d8 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -5,19 +5,54 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/). +## [1.7] + +### Added + +- **Spaces:** A new way to manage your SIP domains and hosts. A Space is defined by a unique SIP Domain and Host pair. + - **New mandatory DotEnv variable** `APP_ROOT_HOST`, replaces `APP_URL` and `APP_SIP_DOMAIN` that are now configured using the new dedicated Artisan script. It defines the root hostname where all the Spaces will be configured. All the Spaces will be as subdomains of `APP_ROOT_HOST` except one that can be equal to `APP_ROOT_HOST`. Example: if `APP_ROOT_HOST=myhost.com` the Spaces hosts will be `myhost.com`, `alpha.myhost.com` , `beta.myhost.com`... + - **New Artisan script** `php artisan spaces:create-update {sip_domain} {host} {--super}`, replaces `php artisan sip_domains:create-update {sip_domain} {--super}`. Can create a Space or update a Space Host base on its Space SIP Domain. + +#### Migrate from [1.6] + +1. Deploy the new version and migrate the database. + +``` + php artisan migrate +``` + +2. Set `APP_ROOT_HOST` in `.env` or as an environnement variable. And remove `APP_URL` and `APP_SIP_DOMAIN` + +``` + APP_ROOT_HOST=myhost.com +``` + +3. The migration script will automatically copy the `sip_domain` into `host` in the `spaces` table. You then have to "fix" the hosts and set them to equal or be subdomains of `APP_ROOT_HOST`. + +``` + php artisan spaces:create-update my.sip myhost.com --super # You can set some Spaces as SuperSpaces, the admin will be able to manage the other spaces + php artisan spaces:create-update alpha.sip alpha.myhost.com + php artisan spaces:create-update beta.sip beta.myhost.com + ... +``` + +4. Configure your web server to point the `APP_ROOT_HOST` and subdomains to the app. + +5. Configure the upcoming Spaces + ## [1.5] - 2024-08-29 ### Added - **Account activity view:** new panel, available behind the Activity tab, will allow any admin to follow the activity of the accounts they manage. - **Detect and block abusive accounts:** This activity tracking is coming with a related tool that is measuring the accounts activity and automatically block them if it detects some unusual behaviors on the service. An account can also directly be blocked and unblocked from the setting panel. Two new setting variables will allow you to fine tune those behaviors triggers. - - **New DotEnv variable:** `BLOCKING_TIME_PERIOD_CHECK=30` # Time span on which the blocking service will proceed, in minutes - - **New DotEnv variable:** `BLOCKING_AMOUNT_EVENTS_AUTHORIZED_DURING_PERIOD=5` # Amount of account events authorized during this period + - **New DotEnv variable:** `BLOCKING_TIME_PERIOD_CHECK=30` Time span on which the blocking service will proceed, in minutes + - **New DotEnv variable:** `BLOCKING_AMOUNT_EVENTS_AUTHORIZED_DURING_PERIOD=5` Amount of account events authorized during this period - **OAuth JWT Authentication:** OAuth support with the handling of JWE tokens issues by a third party service such as Keycloack. - **New DotEnv variable:** `JWT_RSA_PUBLIC_KEY_PEM=` - **New DotEnv variable:** `JWT_SIP_IDENTIFIER=sip_identifier` - **Super-domains and super-admins support:** Introduce SIP domains management. The app accounts are now divided by their domains with their own respective administrators that can only see and manage their own domain accounts and settings. On top of that it is possible to configure a SIP domain as a "super-domain" and then allow its admins to become "super-admins". Those super-admins will then be able to manage all the accounts handled by the instance and create/edit/delete the other SIP domains. Add new endpoints and a new super-admin role in the API to manage the SIP domains. SIP domains can also be created and updated directly from the console using a new artisan script (documented in the README); - - **New Artisan script:** `php artisan spaces:create-update {domain} {--super}` + - **New Artisan script:** `php artisan sip_domains:create-update {domain} {--super}` - **Account Dictionary:** Each account can now handle a specific dictionary, configurable by the API or directly the web panel. This dictionary allows developers to store arbitrary `key -> value pairs` on each accounts. - **Vcard storage:** Attach custom vCards on a dedicated account using new endpoints in the API. The published vCard are validated before being stored. diff --git a/flexiapi/.env.example b/flexiapi/.env.example index eb45339..7e45146 100644 --- a/flexiapi/.env.example +++ b/flexiapi/.env.example @@ -2,7 +2,7 @@ APP_NAME=FlexiAPI APP_ENV=local APP_KEY= APP_DEBUG=false -APP_ROOT_DOMAIN= +APP_ROOT_HOST= APP_LINPHONE_DAEMON_UNIX_PATH= APP_FLEXISIP_PUSHER_PATH= diff --git a/flexiapi/app/Console/Commands/Spaces/CreateUpdate.php b/flexiapi/app/Console/Commands/Spaces/CreateUpdate.php index 564dc6c..a11af8f 100644 --- a/flexiapi/app/Console/Commands/Spaces/CreateUpdate.php +++ b/flexiapi/app/Console/Commands/Spaces/CreateUpdate.php @@ -31,6 +31,10 @@ class CreateUpdate extends Command { $this->info('Your will create or update a Space in the database'); + if (empty(config('app.root_host'))) { + $this->error('The environnement variable APP_ROOT_HOST doesn\'t seems to be set'); + } + $space = Space::where('domain', $this->argument('sip_domain'))->firstOrNew(); $space->host = $this->argument('host'); $space->domain = $this->argument('sip_domain'); diff --git a/flexiapi/app/Http/Controllers/Admin/SpaceController.php b/flexiapi/app/Http/Controllers/Admin/SpaceController.php index 9f0346b..1102a38 100644 --- a/flexiapi/app/Http/Controllers/Admin/SpaceController.php +++ b/flexiapi/app/Http/Controllers/Admin/SpaceController.php @@ -29,7 +29,7 @@ class SpaceController extends Controller { public function index() { - return view('admin.space.index', ['spaces' => Space::withCount('accounts')->get()]); + return view('admin.space.index', ['spaces' => Space::withCount('accounts')->orderBy('host')->get()]); } public function me(Request $request) @@ -55,10 +55,14 @@ class SpaceController extends Controller public function store(Request $request) { - $request->merge(['full_host' => $request->get('host') . '.' . config('app.root_domain')]); + $fullHost = empty($request->get('host')) + ? config('app.root_host') + : $request->get('host') . '.' . config('app.root_host'); + + $request->merge(['full_host' => $fullHost]); $request->validate([ 'domain' => 'required|unique:spaces|regex:/'. Space::DOMAIN_REGEX . '/', - 'host' => 'required|regex:/'. Space::HOST_REGEX . '/', + 'host' => 'nullable|regex:/'. Space::HOST_REGEX . '/', 'full_host' => 'required|unique:spaces,host', ]); diff --git a/flexiapi/app/Http/Middleware/IsSpaceExpired.php b/flexiapi/app/Http/Middleware/IsSpaceExpired.php index 9fae621..aef07a4 100644 --- a/flexiapi/app/Http/Middleware/IsSpaceExpired.php +++ b/flexiapi/app/Http/Middleware/IsSpaceExpired.php @@ -11,15 +11,15 @@ class IsSpaceExpired { public function handle(Request $request, Closure $next): Response { - if (empty(config('app.root_domain'))) { - return abort(503, 'APP_ROOT_DOMAIN is not configured'); + if (empty(config('app.root_host'))) { + return abort(503, 'APP_ROOT_HOST is not configured'); } $space = \App\Space::where('host', $request->header('host'))->first(); if ($space) { - if (!str_ends_with($space->host, config('app.root_domain'))) { - return abort(503, 'The APP_ROOT_DOMAIN configured does not match with the current root domain'); + if (!str_ends_with($space->host, config('app.root_host'))) { + return abort(503, 'The APP_ROOT_HOST configured does not match with the current root domain'); } Config::set('app.url', '://' . $space->host); diff --git a/flexiapi/app/Services/AccountService.php b/flexiapi/app/Services/AccountService.php index e55aceb..8b88f19 100644 --- a/flexiapi/app/Services/AccountService.php +++ b/flexiapi/app/Services/AccountService.php @@ -73,6 +73,10 @@ class AccountService $account->domain = resolveDomain($request); $account->user_agent = $request->header('User-Agent') ?? config('app.name'); $account->admin = $request->has('admin') && (bool)$request->get('admin'); + + if (!$request->api && $request->has('role')) { + $account->setRole($request->get('role')); + } } if ($account->activated == false) { diff --git a/flexiapi/app/Space.php b/flexiapi/app/Space.php index 5837177..3069a82 100644 --- a/flexiapi/app/Space.php +++ b/flexiapi/app/Space.php @@ -65,6 +65,11 @@ class Space extends Model return $this->expire_at && $this->expire_at->isPast(); } + public function isRoot(): bool + { + return $this->host == config('app.root_host'); + } + public function getAccountsPercentageClassAttribute(): string { if ($this->getAccountsPercentageAttribute() >= 80) { diff --git a/flexiapi/config/app.php b/flexiapi/config/app.php index 4a79f0e..59adbfa 100644 --- a/flexiapi/config/app.php +++ b/flexiapi/config/app.php @@ -14,7 +14,7 @@ return [ */ 'name' => env('APP_NAME', 'Account Manager'), - 'sip_domain' => env('APP_SIP_DOMAIN', 'sip.domain.com'), + //'sip_domain' => 'sip.domain.com', 'project_url' => env('APP_PROJECT_URL', ''), 'terms_of_use_url' => env('TERMS_OF_USE_URL', ''), @@ -128,7 +128,7 @@ return [ */ 'url' => env('APP_URL', 'http://localhost'), - 'root_domain' => env('APP_ROOT_DOMAIN', null), + 'root_host' => env('APP_ROOT_HOST', null), 'asset_url' => env('ASSET_URL', null), /* diff --git a/flexiapi/resources/views/admin/space/create.blade.php b/flexiapi/resources/views/admin/space/create.blade.php index 750041c..8105583 100644 --- a/flexiapi/resources/views/admin/space/create.blade.php +++ b/flexiapi/resources/views/admin/space/create.blade.php @@ -20,13 +20,13 @@ @method('post')
- - + + @include('parts.errors', ['name' => 'host']) @include('parts.errors', ['name' => 'full_host']) - Cannot be changed once created + Cannot be changed once created, leave empty to create a root Space
diff --git a/flexiapi/tests/Feature/ApiSpaceWithMiddlewareTest.php b/flexiapi/tests/Feature/ApiSpaceWithMiddlewareTest.php index 271397e..7eeb550 100644 --- a/flexiapi/tests/Feature/ApiSpaceWithMiddlewareTest.php +++ b/flexiapi/tests/Feature/ApiSpaceWithMiddlewareTest.php @@ -42,7 +42,7 @@ class ApiSpaceWithMiddlewareTest extends TestCaseWithSpaceMiddleware // Try to create a new user as an admin $admin->generateApiKey(); - config()->set('app.root_domain', $admin->domain); + config()->set('app.root_host', $admin->domain); $this->keyAuthenticated($admin) ->json($this->method, 'http://' . $admin->domain . $this->accountRoute, [ diff --git a/flexiapi/tests/TestCase.php b/flexiapi/tests/TestCase.php index e7cc0c2..2facd7d 100644 --- a/flexiapi/tests/TestCase.php +++ b/flexiapi/tests/TestCase.php @@ -39,6 +39,8 @@ abstract class TestCase extends BaseTestCase $this->withoutMiddleware([IsSpaceExpired::class]); + config()->set('app.sip_domain', 'sip.example.com'); + PhoneCountry::truncate(); PhoneCountry::factory()->france()->activated()->create(); PhoneCountry::factory()->netherlands()->create(); diff --git a/flexiapi/tests/TestCaseWithSpaceMiddleware.php b/flexiapi/tests/TestCaseWithSpaceMiddleware.php index 10ac440..2696f26 100644 --- a/flexiapi/tests/TestCaseWithSpaceMiddleware.php +++ b/flexiapi/tests/TestCaseWithSpaceMiddleware.php @@ -27,4 +27,11 @@ abstract class TestCaseWithSpaceMiddleware extends BaseTestCase use CreatesApplication; use RefreshDatabase; use TestUtilsTrait; + + public function setUp(): void + { + parent::setUp(); + + config()->set('app.sip_domain', 'sip.example.com'); + } }