Compare commits

...

7 commits

Author SHA1 Message Date
Timothée Jaussoin
749fe0586d Fix FLEXIAPI-242 Add stricter validation for the AccountCreationToken Push Notification endpoint 2025-07-21 16:29:30 +02:00
Timothée Jaussoin
bb58cd7347 Management Update the CHANGELOG with the 1.4 release 2024-10-21 09:08:14 +02:00
Timothée Jaussoin
b00b0523f1 Fix FLEXIAPI-209 Release the 1.5 version, introduce the RELEASE file 2024-08-29 13:59:41 +00:00
Timothée Jaussoin
84f71d8e7a Fix FLEXIAPI-208 Add SMS templates documentation 2024-08-27 16:24:02 +02:00
Timothée Jaussoin
5cc6034702 Fix/206 wording delete account on 1.5 2024-08-21 13:55:15 +00:00
Timothée Jaussoin
8c900e7f28 Fix FLEXIAPI-202 Add account parameter to the redirection in the destroy admin route 2024-08-05 15:07:54 +02:00
Timothée Jaussoin
0acdb9a200 Branch the 1.5 2024-07-03 10:14:51 +02:00
16 changed files with 192 additions and 38 deletions

View file

@ -14,13 +14,13 @@ rocky9-deploy:
- rocky9-package
- rocky9-test
debian11-deploy:
extends: .deploy
script:
- ./deploy_packages.sh debian bullseye
needs:
- debian11-package
- debian11-test
#debian11-deploy:
# extends: .deploy
# script:
# - ./deploy_packages.sh debian bullseye
# needs:
# - debian11-package
# - debian11-test
debian12-deploy:
extends: .deploy

View file

@ -16,9 +16,9 @@ rocky9-package:
script:
- make rpm-el9
debian11-package:
extends: .debian_package
image: gitlab.linphone.org:4567/bc/public/docker/debian11-php:$DEBIAN_11_IMAGE_VERSION
#debian11-package:
# extends: .debian_package
# image: gitlab.linphone.org:4567/bc/public/docker/debian11-php:$DEBIAN_11_IMAGE_VERSION
debian12-package:
extends: .debian_package

View file

@ -21,11 +21,11 @@ rocky9-test:
- php artisan key:generate
- vendor/bin/phpunit --log-junit $CI_PROJECT_DIR/flexiapi_phpunit.log
debian11-test:
extends: .debian-test
image: gitlab.linphone.org:4567/bc/public/docker/debian11-php:$DEBIAN_11_IMAGE_VERSION
needs:
- debian11-package
#debian11-test:
# extends: .debian-test
# image: gitlab.linphone.org:4567/bc/public/docker/debian11-php:$DEBIAN_11_IMAGE_VERSION
# needs:
# - debian11-package
debian12-test:
extends: .debian-test

View file

@ -2,6 +2,7 @@
v1.5
---
- Fix FLEXIAPI-202 Add account parameter to the redirection in the destroy admin route
- Fix FLEXIAPI-195 Fix LiblinphoneTesterAccoutSeeder to fit with the latest Account related changes
- Fix FLEXIAPI-193 Typo
- Fix FLEXIAPI-192 Clear and upgrade properly the account dictionary entries if the entries are already existing
@ -62,6 +63,29 @@ v1.5
- Fix #133 Make the MySQL connection unstrict
- Fix #132 Move the provisioning_tokens and recovery_codes to dedicated table
- Fix #130 Drop the group column in the Accounts table
- Fix FLEXIAPI-242 Add stricter validation for the AccountCreationToken Push Notification endpoint
v1.4.9
------
- Complete the missing changelog
v1.4.8
------
- Fix FLEXIAPI-166 Reimplement the deprecated email validation URL
- Fix FLEXIAPI-140 Select the display_name attribute from the database to inject...
v1.4.7
------
- Fix FLEXIAPI-175 and FLEXISIP-231 Rewrite the Redis contacts parser to handle properly SIP uris (thanks @thibault.lemaire !)
v1.4.6
------
- Fix FLEXIAPI-142 PUT /accounts endpoint doesn't allow overiding values anymore
- Fix typos and dependencies
v1.4.5
------
- Fix FLEXIAPI-132 Refactor the Provisioning to remove proxy_default_values
v1.4.4
------

View file

@ -204,6 +204,15 @@ You can also seed the tables with test accounts for the liblinphone test suite w
php artisan accounts:seed /path/to/accounts.json
## SMS templates
To send SMS to the USA some providers need to validate their templates before transfering them, see [Sending SMS messages to the USA - OVH](https://help.ovhcloud.com/csm/en-ie-sms-sending-sms-to-usa?id=kb_article_view&sysparm_article=KB0051359).
Here are the currently used SMS templates in the app to declare in your provider panel:
- Creation code: `Your #APP_NAME# creation code is #CODE#`. Sent to confirm the creation of the account by SMS.
- Recovery code: `Your #APP_NAME# recovery code is #CODE#`. Sent to recover the account by SMS.
## Custom email templaces
Some email templates can be customized.

35
RELEASE.md Normal file
View file

@ -0,0 +1,35 @@
# Releases
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/).
## [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
- **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 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.
### Changed
- **User management of their own devices:** Allowing users will be able to manage its own devices. Specific API endpoints were also added to manage them directly from the clients.
- **Migration to hCaptcha:** Migrate from Google Recaptcha to hCaptcha in this release.
- **New DotEnv variable:** HCAPTCHA_SECRET=secret-key
- **New DotEnv variable:** HCAPTCHA_SITEKEY=site-key
- **Localization support:** The API is now accepting the `Accept-Language` header and adapt its internal localization to the client/browser one. For the moment only French and English are supported but more languages could be added in the future.
### Deprecated
- **Last major version supporting the deprecated endpoints of the API**

View file

@ -19,6 +19,7 @@
namespace App;
use Illuminate\Validation\Rule;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class AccountCreationToken extends Consommable

View file

@ -58,8 +58,10 @@ class AccountDeviceController extends Controller
public function destroy(Request $request, int $accountId)
{
$connector = new FlexisipConnector;
$connector->deleteDevice(Account::findOrFail($accountId)->identifier, $request->get('uuid'));
$account = Account::findOrFail($accountId);
return redirect()->route('admin.account.device.index');
$connector->deleteDevice($account->identifier, $request->get('uuid'));
return redirect()->route('admin.account.device.index', $account);
}
}

View file

@ -26,6 +26,9 @@ use Carbon\Carbon;
use App\AccountCreationToken;
use App\AccountCreationRequestToken;
use App\Rules\PnParam;
use App\Rules\PnPrid;
use App\Rules\PnProvider;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController;
use App\Libraries\FlexisipPusherConnector;
@ -36,9 +39,9 @@ class CreationTokenController extends Controller
public function sendByPush(Request $request)
{
$request->validate([
'pn_provider' => 'required',
'pn_param' => 'required',
'pn_prid' => 'required',
'pn_provider' => ['required', new PnProvider],
'pn_param' => [new PnParam],
'pn_prid' => [new PnPrid],
]);
$last = AccountCreationToken::where('pn_provider', $request->get('pn_provider'))

View file

@ -0,0 +1,19 @@
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use Respect\Validation\Validator;
class PnParam implements Rule
{
public function passes($attribute, $value)
{
return $value == null || Validator::regex('/^\w+$/')->validate($value);
}
public function message()
{
return 'The :attribute should be null or contain only alphanumeric and underscore characters';
}
}

View file

@ -0,0 +1,19 @@
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use Respect\Validation\Validator;
class PnPrid implements Rule
{
public function passes($attribute, $value)
{
return $value == null || Validator::regex('/^[\w\-\:]+$/')->validate($value);
}
public function message()
{
return 'The :attribute should be null or contain only alphanumeric, dashes and colon characters';
}
}

View file

@ -0,0 +1,21 @@
<?php
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use Respect\Validation\Validator;
class PnProvider implements Rule
{
private $values = ['apns.dev', 'apns', 'fcm'];
public function passes($attribute, $value)
{
return in_array($value, $this->values);
}
public function message()
{
return 'The :attribute should be in ' . implode(', ', $this->values);
}
}

24
flexiapi/composer.lock generated
View file

@ -3177,16 +3177,16 @@
},
{
"name": "nikic/php-parser",
"version": "v5.0.2",
"version": "v5.1.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13"
"reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13",
"reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/683130c2ff8c2739f4822ff7ac5c873ec529abd1",
"reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1",
"shasum": ""
},
"require": {
@ -3197,7 +3197,7 @@
},
"require-dev": {
"ircmaxell/php-yacc": "^0.0.7",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
"phpunit/phpunit": "^9.0"
},
"bin": [
"bin/php-parse"
@ -3229,9 +3229,9 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v5.0.2"
"source": "https://github.com/nikic/PHP-Parser/tree/v5.1.0"
},
"time": "2024-03-05T20:51:40+00:00"
"time": "2024-07-01T20:03:41+00:00"
},
{
"name": "nunomaduro/termwind",
@ -5446,16 +5446,16 @@
},
{
"name": "sabre/vobject",
"version": "4.5.4",
"version": "4.5.5",
"source": {
"type": "git",
"url": "https://github.com/sabre-io/vobject.git",
"reference": "a6d53a3e5bec85ed3dd78868b7de0f5b4e12f772"
"reference": "7148cf57d25aaba0a49f6656d37c35e8175b3087"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sabre-io/vobject/zipball/a6d53a3e5bec85ed3dd78868b7de0f5b4e12f772",
"reference": "a6d53a3e5bec85ed3dd78868b7de0f5b4e12f772",
"url": "https://api.github.com/repos/sabre-io/vobject/zipball/7148cf57d25aaba0a49f6656d37c35e8175b3087",
"reference": "7148cf57d25aaba0a49f6656d37c35e8175b3087",
"shasum": ""
},
"require": {
@ -5546,7 +5546,7 @@
"issues": "https://github.com/sabre-io/vobject/issues",
"source": "https://github.com/fruux/sabre-vobject"
},
"time": "2023-11-09T12:54:37+00:00"
"time": "2024-07-02T08:48:52+00:00"
},
{
"name": "sabre/xml",

View file

@ -18,12 +18,12 @@
<div class="large">
<p>You are going to permanently delete your account.</p>
<p>Please enter your complete username to confirm: <b>{{ $account->identifier }}</b>.</p>
<p>Please enter your complete SIP address to confirm: <b>{{ $account->identifier }}</b>.</p>
</div>
<div>
<input placeholder="bob@example.net" name="identifier" type="text" value="{{ old('identifier') }}">
<label for="identifier">Username</label>
<label for="identifier">SIP address</label>
</div>
<div class="on_desktop"></div>

View file

@ -179,9 +179,9 @@ Return `503` if the token was not successfully sent.
JSON parameters:
* `pn_provider` the push notification provider
* `pn_param` the push notification parameter
* `pn_prid` the push notification unique id
* `pn_provider` **required**, the push notification provider, must be in apns.dev, apns or fcm
* `pn_param` the push notification parameter, can be null or contain only alphanumeric and underscore characters
* `pn_prid` the push notification unique id, can be null or contain only alphanumeric, dashes and colon characters
### `POST /account_creation_tokens/using-account-creation-request-token`
<span class="badge badge-success">Public</span>

View file

@ -35,12 +35,33 @@ class ApiAccountCreationTokenTest extends TestCase
protected $adminRoute = '/api/account_creation_tokens';
protected $method = 'POST';
protected $pnProvider = 'provider';
protected $pnProvider = 'fcm';
protected $pnParam = 'param';
protected $pnPrid = 'id';
public function testCorrectParameters()
{
$this->assertSame(AccountCreationToken::count(), 0);
$this->json($this->method, $this->tokenRoute, [
'pn_provider' => 'wrong',
'pn_param' => $this->pnParam,
'pn_prid' => $this->pnPrid,
])->assertJsonValidationErrors(['pn_provider']);
$this->assertSame(AccountCreationToken::count(), 0);
$this->json($this->method, $this->tokenRoute, [
'pn_provider' => $this->pnProvider,
'pn_param' => '@wrong',
'pn_prid' => $this->pnPrid,
])->assertJsonValidationErrors(['pn_param']);
$this->assertSame(AccountCreationToken::count(), 0);
$this->json($this->method, $this->tokenRoute, [
'pn_provider' => $this->pnProvider,
'pn_param' => $this->pnParam,
'pn_prid' => '@wrong',
])->assertJsonValidationErrors(['pn_prid']);
$this->assertSame(AccountCreationToken::count(), 0);
$this->json($this->method, $this->tokenRoute, [
'pn_provider' => $this->pnProvider,