diff --git a/flexiapi/README.md b/flexiapi/README.md index 45c7f0e..aa99cb5 100644 --- a/flexiapi/README.md +++ b/flexiapi/README.md @@ -80,7 +80,7 @@ We advise you to copy the `style.css` file and rename it to make your custom CSS #### Flexisip Push notifications pusher -The API endpoint `POST /tokens` uses the `flexisip_pusher` binary delivered by the [Flexisip](https://gitlab.linphone.org/BC/public/flexisip) project (and related package). You must configure the `APP_FLEXISIP_PUSHER_PATH` environement variable to point to the correct binary. +The API endpoint `POST /account_creation_tokens/send-by-push` uses the `flexisip_pusher` binary delivered by the [Flexisip](https://gitlab.linphone.org/BC/public/flexisip) project (and related package). You must configure the `APP_FLEXISIP_PUSHER_PATH` environement variable to point to the correct binary. APP_FLEXISIP_PUSHER_PATH=/opt/belledonne-communications/bin/flexisip_pusher diff --git a/flexiapi/app/Account.php b/flexiapi/app/Account.php index 0f5dea7..85f4e13 100644 --- a/flexiapi/app/Account.php +++ b/flexiapi/app/Account.php @@ -38,7 +38,7 @@ class Account extends Authenticatable use HasFactory; protected $with = ['passwords', 'admin', 'emailChanged', 'alias', 'activationExpiration', 'types', 'actions']; - protected $hidden = ['alias', 'expire_time', 'confirmation_key', 'pivot']; + protected $hidden = ['alias', 'expire_time', 'confirmation_key', 'provisioning_token', 'pivot']; protected $dateTimes = ['creation_time']; protected $appends = ['realm', 'phone', 'confirmation_key_expires']; protected $casts = [ diff --git a/flexiapi/app/Token.php b/flexiapi/app/AccountCreationToken.php similarity index 95% rename from flexiapi/app/Token.php rename to flexiapi/app/AccountCreationToken.php index e4b0166..3f3d458 100644 --- a/flexiapi/app/Token.php +++ b/flexiapi/app/AccountCreationToken.php @@ -22,7 +22,7 @@ namespace App; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; -class Token extends Model +class AccountCreationToken extends Model { use HasFactory; } diff --git a/flexiapi/app/Http/Controllers/Account/ProvisioningController.php b/flexiapi/app/Http/Controllers/Account/ProvisioningController.php index e06fc42..b69864e 100644 --- a/flexiapi/app/Http/Controllers/Account/ProvisioningController.php +++ b/flexiapi/app/Http/Controllers/Account/ProvisioningController.php @@ -31,17 +31,17 @@ use Endroid\QrCode\Writer\PngWriter; class ProvisioningController extends Controller { - public function qrcode(Request $request, $confirmationKey) + public function qrcode(Request $request, $provisioningToken) { $account = Account::withoutGlobalScopes() - ->where('confirmation_key', $confirmationKey) + ->where('provisioning_token', $provisioningToken) ->firstOrFail(); if ($account->activationExpired()) abort(404); $result = Builder::create() ->writer(new PngWriter()) - ->data(route('provisioning.show', ['confirmation' => $confirmationKey])) + ->data(route('provisioning.show', ['provisioning_token' => $provisioningToken])) ->encoding(new Encoding('UTF-8')) ->errorCorrectionLevel(new ErrorCorrectionLevelHigh()) ->size(300) @@ -59,7 +59,7 @@ class ProvisioningController extends Controller return $this->show($request, null, $request->user()); } - public function show(Request $request, $confirmationKey = null, Account $requestAccount = null) + public function show(Request $request, $provisioningToken = null, Account $requestAccount = null) { // Load the hooks if they exists $provisioningHooks = config_path('provisioning_hooks.php'); @@ -109,9 +109,9 @@ class ProvisioningController extends Controller // Account handling if ($requestAccount) { $account = $requestAccount; - } else if ($confirmationKey) { + } else if ($provisioningToken) { $account = Account::withoutGlobalScopes() - ->where('confirmation_key', $confirmationKey) + ->where('provisioning_token', $provisioningToken) ->first(); } @@ -184,14 +184,14 @@ class ProvisioningController extends Controller } - if ($confirmationKey) { + if ($provisioningToken) { // Activate the account if ($account->activated == false - && $confirmationKey == $account->confirmation_key) { + && $provisioningToken == $account->provisioning_token) { $account->activated = true; } - $account->confirmation_key = null; + $account->provisioning_token = null; $account->save(); } } diff --git a/flexiapi/app/Http/Controllers/Admin/AccountController.php b/flexiapi/app/Http/Controllers/Admin/AccountController.php index a3d40bf..f2ee354 100644 --- a/flexiapi/app/Http/Controllers/Admin/AccountController.php +++ b/flexiapi/app/Http/Controllers/Admin/AccountController.php @@ -141,7 +141,7 @@ class AccountController extends Controller public function provision(int $id) { $account = Account::findOrFail($id); - $account->confirmation_key = Str::random(WebAuthenticateController::$emailCodeSize); + $account->provisioning_token = Str::random(WebAuthenticateController::$emailCodeSize); $account->save(); Log::channel('events')->info('Web Admin: Account provisioned', ['id' => $account->identifier]); diff --git a/flexiapi/app/Http/Controllers/Api/AccountController.php b/flexiapi/app/Http/Controllers/Api/AccountController.php index 8eb38d6..ad19bf6 100644 --- a/flexiapi/app/Http/Controllers/Api/AccountController.php +++ b/flexiapi/app/Http/Controllers/Api/AccountController.php @@ -29,7 +29,7 @@ use Carbon\Carbon; use App\Account; use App\AccountTombstone; -use App\Token; +use App\AccountCreationToken; use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController; use App\Rules\IsNotPhoneNumber; use App\Rules\NoUppercase; @@ -72,16 +72,16 @@ class AccountController extends Controller 'password' => 'required|filled', 'dtmf_protocol' => 'nullable|in:' . Account::dtmfProtocolsRule(), 'domain' => 'min:3', - 'token' => [ + 'account_creation_token' => [ 'required', - Rule::exists('tokens', 'token')->where(function ($query) { + Rule::exists('account_creation_tokens', 'token')->where(function ($query) { $query->where('used', false); }), 'size:'.WebAuthenticateController::$emailCodeSize ] ]); - $token = Token::where('token', $request->get('token'))->first(); + $token = AccountCreationToken::where('token', $request->get('account_creation_token'))->first(); $token->used = true; $token->save(); @@ -96,7 +96,7 @@ class AccountController extends Controller $account->creation_time = Carbon::now(); $account->user_agent = config('app.name'); $account->dtmf_protocol = $request->get('dtmf_protocol'); - $account->confirmation_key = Str::random(WebAuthenticateController::$emailCodeSize); + $account->provisioning_token = Str::random(WebAuthenticateController::$emailCodeSize); $account->save(); $account->updatePassword($request->get('password'), $request->get('algorithm')); diff --git a/flexiapi/app/Http/Controllers/Api/TokenController.php b/flexiapi/app/Http/Controllers/Api/AccountCreationTokenController.php similarity index 87% rename from flexiapi/app/Http/Controllers/Api/TokenController.php rename to flexiapi/app/Http/Controllers/Api/AccountCreationTokenController.php index 6139e5e..69f004a 100644 --- a/flexiapi/app/Http/Controllers/Api/TokenController.php +++ b/flexiapi/app/Http/Controllers/Api/AccountCreationTokenController.php @@ -24,13 +24,13 @@ use Illuminate\Http\Request; use Illuminate\Support\Str; use Illuminate\Support\Facades\Log; -use App\Token; +use App\AccountCreationToken; use App\Libraries\FlexisipPusherConnector; use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController; -class TokenController extends Controller +class AccountCreationTokenController extends Controller { - public function create(Request $request) + public function sendByPush(Request $request) { $request->validate([ 'pn_provider' => 'required', @@ -38,7 +38,7 @@ class TokenController extends Controller 'pn_prid' => 'required', ]); - if (Token::where('pn_provider', $request->get('pn_provider')) + if (AccountCreationToken::where('pn_provider', $request->get('pn_provider')) ->where('pn_param', $request->get('pn_param')) ->where('pn_prid', $request->get('pn_prid')) ->where('used', false) @@ -46,14 +46,14 @@ class TokenController extends Controller abort(403, 'A similar token was already used'); } - if (Token::where('pn_provider', $request->get('pn_provider')) + if (AccountCreationToken::where('pn_provider', $request->get('pn_provider')) ->where('pn_param', $request->get('pn_param')) ->where('pn_prid', $request->get('pn_prid')) ->count() > 3) { abort(403, 'The limit of tokens generated for this device has been reached'); } - $token = new Token; + $token = new AccountCreationToken; $token->token = Str::random(WebAuthenticateController::$emailCodeSize); $token->pn_provider = $request->get('pn_provider'); $token->pn_param = $request->get('pn_param'); diff --git a/flexiapi/app/Http/Controllers/Api/Admin/AccountController.php b/flexiapi/app/Http/Controllers/Api/Admin/AccountController.php index a13127e..9f210d5 100644 --- a/flexiapi/app/Http/Controllers/Api/Admin/AccountController.php +++ b/flexiapi/app/Http/Controllers/Api/Admin/AccountController.php @@ -46,7 +46,7 @@ class AccountController extends Controller public function show($id) { - return Account::without(['passwords', 'admin'])->findOrFail($id)->makeVisible(['confirmation_key']); + return Account::without(['passwords', 'admin'])->findOrFail($id)->makeVisible(['confirmation_key', 'provisioning_token']); } public function search(string $sip) @@ -95,12 +95,12 @@ class AccountController extends Controller public function provision(int $id) { $account = Account::findOrFail($id); - $account->confirmation_key = Str::random(WebAuthenticateController::$emailCodeSize); + $account->provisioning_token = Str::random(WebAuthenticateController::$emailCodeSize); $account->save(); Log::channel('events')->info('API Admin: Account provisioned', ['id' => $account->identifier]); - return $account->makeVisible(['confirmation_key']); + return $account->makeVisible(['provisioning_token']); } public function store(Request $request) @@ -152,6 +152,7 @@ class AccountController extends Controller if (!$request->has('activated') || !(bool)$request->get('activated')) { $account->confirmation_key = Str::random(WebAuthenticateController::$emailCodeSize); + $account->provisioning_token = Str::random(WebAuthenticateController::$emailCodeSize); } $account->save(); @@ -185,7 +186,7 @@ class AccountController extends Controller Log::channel('events')->info('API: Admin: Account created', ['id' => $account->identifier]); - return response()->json($account->makeVisible(['confirmation_key'])); + return response()->json($account->makeVisible(['confirmation_key', 'provisioning_token'])); } public function typeAdd(int $id, int $typeId) diff --git a/flexiapi/app/Http/Controllers/Api/Admin/AccountCreationTokenController.php b/flexiapi/app/Http/Controllers/Api/Admin/AccountCreationTokenController.php new file mode 100644 index 0000000..16e7d95 --- /dev/null +++ b/flexiapi/app/Http/Controllers/Api/Admin/AccountCreationTokenController.php @@ -0,0 +1,39 @@ +. +*/ + +namespace App\Http\Controllers\Api; + +use App\Http\Controllers\Controller; +use Illuminate\Http\Request; +use Illuminate\Support\Str; + +use App\AccountCreationToken; +use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController; + +class AccountCreationTokenController extends Controller +{ + public function create(Request $request) + { + $token = new AccountCreationToken; + $token->token = Str::random(WebAuthenticateController::$emailCodeSize); + $token->save(); + + return $token; + } +} diff --git a/flexiapi/composer.lock b/flexiapi/composer.lock index 8276255..b8e49bf 100644 --- a/flexiapi/composer.lock +++ b/flexiapi/composer.lock @@ -233,16 +233,16 @@ }, { "name": "doctrine/cache", - "version": "2.1.1", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce" + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/331b4d5dbaeab3827976273e9356b3b453c300ce", - "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce", + "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", "shasum": "" }, "require": { @@ -252,18 +252,12 @@ "doctrine/common": ">2.2,<2.4" }, "require-dev": { - "alcaeus/mongo-php-adapter": "^1.1", "cache/integration-tests": "dev-master", - "doctrine/coding-standard": "^8.0", - "mongodb/mongodb": "^1.1", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", - "predis/predis": "~1.0", + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", "psr/cache": "^1.0 || ^2.0 || ^3.0", - "symfony/cache": "^4.4 || ^5.2 || ^6.0@dev", - "symfony/var-exporter": "^4.4 || ^5.2 || ^6.0@dev" - }, - "suggest": { - "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" + "symfony/cache": "^4.4 || ^5.4 || ^6", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6" }, "type": "library", "autoload": { @@ -312,7 +306,7 @@ ], "support": { "issues": "https://github.com/doctrine/cache/issues", - "source": "https://github.com/doctrine/cache/tree/2.1.1" + "source": "https://github.com/doctrine/cache/tree/2.2.0" }, "funding": [ { @@ -328,20 +322,20 @@ "type": "tidelift" } ], - "time": "2021-07-17T14:49:29+00:00" + "time": "2022-05-20T20:07:39+00:00" }, { "name": "doctrine/dbal", - "version": "3.3.6", + "version": "3.3.7", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "9e7f76dd1cde81c62574fdffa5a9c655c847ad21" + "reference": "9f79d4650430b582f4598fe0954ef4d52fbc0a8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/9e7f76dd1cde81c62574fdffa5a9c655c847ad21", - "reference": "9e7f76dd1cde81c62574fdffa5a9c655c847ad21", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/9f79d4650430b582f4598fe0954ef4d52fbc0a8a", + "reference": "9f79d4650430b582f4598fe0954ef4d52fbc0a8a", "shasum": "" }, "require": { @@ -356,11 +350,11 @@ "require-dev": { "doctrine/coding-standard": "9.0.0", "jetbrains/phpstorm-stubs": "2022.1", - "phpstan/phpstan": "1.6.3", + "phpstan/phpstan": "1.7.13", "phpstan/phpstan-strict-rules": "^1.2", "phpunit/phpunit": "9.5.20", "psalm/plugin-phpunit": "0.16.1", - "squizlabs/php_codesniffer": "3.6.2", + "squizlabs/php_codesniffer": "3.7.0", "symfony/cache": "^5.2|^6.0", "symfony/console": "^2.7|^3.0|^4.0|^5.0|^6.0", "vimeo/psalm": "4.23.0" @@ -423,7 +417,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.3.6" + "source": "https://github.com/doctrine/dbal/tree/3.3.7" }, "funding": [ { @@ -439,7 +433,7 @@ "type": "tidelift" } ], - "time": "2022-05-02T17:21:01+00:00" + "time": "2022-06-13T21:43:03+00:00" }, { "name": "doctrine/deprecations", @@ -1165,24 +1159,24 @@ }, { "name": "guzzlehttp/guzzle", - "version": "6.5.5", + "version": "6.5.8", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e" + "reference": "a52f0440530b54fa079ce76e8c5d196a42cad981" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", - "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/a52f0440530b54fa079ce76e8c5d196a42cad981", + "reference": "a52f0440530b54fa079ce76e8c5d196a42cad981", "shasum": "" }, "require": { "ext-json": "*", "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.6.1", + "guzzlehttp/psr7": "^1.9", "php": ">=5.5", - "symfony/polyfill-intl-idn": "^1.17.0" + "symfony/polyfill-intl-idn": "^1.17" }, "require-dev": { "ext-curl": "*", @@ -1211,10 +1205,40 @@ "MIT" ], "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, { "name": "Michael Dowling", "email": "mtdowling@gmail.com", "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" } ], "description": "Guzzle is a PHP HTTP client library", @@ -1230,9 +1254,23 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/6.5" + "source": "https://github.com/guzzle/guzzle/tree/6.5.8" }, - "time": "2020-06-16T21:01:06+00:00" + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2022-06-20T22:16:07+00:00" }, { "name": "guzzlehttp/promises", @@ -1320,16 +1358,16 @@ }, { "name": "guzzlehttp/psr7", - "version": "1.8.5", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "337e3ad8e5716c15f9657bd214d16cc5e69df268" + "reference": "e98e3e6d4f86621a9b75f623996e6bbdeb4b9318" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/337e3ad8e5716c15f9657bd214d16cc5e69df268", - "reference": "337e3ad8e5716c15f9657bd214d16cc5e69df268", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/e98e3e6d4f86621a9b75f623996e6bbdeb4b9318", + "reference": "e98e3e6d4f86621a9b75f623996e6bbdeb4b9318", "shasum": "" }, "require": { @@ -1350,7 +1388,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7-dev" + "dev-master": "1.9-dev" } }, "autoload": { @@ -1410,7 +1448,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/1.8.5" + "source": "https://github.com/guzzle/psr7/tree/1.9.0" }, "funding": [ { @@ -1426,20 +1464,20 @@ "type": "tidelift" } ], - "time": "2022-03-20T21:51:18+00:00" + "time": "2022-06-20T21:43:03+00:00" }, { "name": "laravel/framework", - "version": "v8.83.12", + "version": "v8.83.16", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "2af2314989845db68dfbb65a54b8748ffaf26204" + "reference": "6be5abd144faf517879af7298e9d79f06f250f75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/2af2314989845db68dfbb65a54b8748ffaf26204", - "reference": "2af2314989845db68dfbb65a54b8748ffaf26204", + "url": "https://api.github.com/repos/laravel/framework/zipball/6be5abd144faf517879af7298e9d79f06f250f75", + "reference": "6be5abd144faf517879af7298e9d79f06f250f75", "shasum": "" }, "require": { @@ -1599,20 +1637,20 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-05-10T13:57:07+00:00" + "time": "2022-06-07T15:09:06+00:00" }, { "name": "laravel/serializable-closure", - "version": "v1.1.1", + "version": "v1.2.0", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "9e4b005daa20b0c161f3845040046dc9ddc1d74e" + "reference": "09f0e9fb61829f628205b7c94906c28740ff9540" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/9e4b005daa20b0c161f3845040046dc9ddc1d74e", - "reference": "9e4b005daa20b0c161f3845040046dc9ddc1d74e", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/09f0e9fb61829f628205b7c94906c28740ff9540", + "reference": "09f0e9fb61829f628205b7c94906c28740ff9540", "shasum": "" }, "require": { @@ -1658,7 +1696,7 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2022-02-11T19:23:53+00:00" + "time": "2022-05-16T17:09:47+00:00" }, { "name": "laravel/tinker", @@ -2045,16 +2083,16 @@ }, { "name": "monolog/monolog", - "version": "2.6.0", + "version": "2.7.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "247918972acd74356b0a91dfaa5adcaec069b6c0" + "reference": "5579edf28aee1190a798bfa5be8bc16c563bd524" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/247918972acd74356b0a91dfaa5adcaec069b6c0", - "reference": "247918972acd74356b0a91dfaa5adcaec069b6c0", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/5579edf28aee1190a798bfa5be8bc16c563bd524", + "reference": "5579edf28aee1190a798bfa5be8bc16c563bd524", "shasum": "" }, "require": { @@ -2133,7 +2171,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/2.6.0" + "source": "https://github.com/Seldaek/monolog/tree/2.7.0" }, "funding": [ { @@ -2145,7 +2183,7 @@ "type": "tidelift" } ], - "time": "2022-05-10T09:36:00+00:00" + "time": "2022-06-09T08:59:12+00:00" }, { "name": "nesbot/carbon", @@ -2246,16 +2284,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.13.2", + "version": "v4.14.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077" + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", "shasum": "" }, "require": { @@ -2296,9 +2334,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" }, - "time": "2021-11-30T19:35:32+00:00" + "time": "2022-05-31T20:59:12+00:00" }, { "name": "opis/closure", @@ -2840,16 +2878,16 @@ }, { "name": "psy/psysh", - "version": "v0.11.4", + "version": "v0.11.5", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "05c544b339b112226ad14803e1e5b09a61957454" + "reference": "c23686f9c48ca202710dbb967df8385a952a2daf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/05c544b339b112226ad14803e1e5b09a61957454", - "reference": "05c544b339b112226ad14803e1e5b09a61957454", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/c23686f9c48ca202710dbb967df8385a952a2daf", + "reference": "c23686f9c48ca202710dbb967df8385a952a2daf", "shasum": "" }, "require": { @@ -2910,9 +2948,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.11.4" + "source": "https://github.com/bobthecow/psysh/tree/v0.11.5" }, - "time": "2022-05-06T12:49:14+00:00" + "time": "2022-05-27T18:03:49+00:00" }, { "name": "ralouphie/getallheaders", @@ -3447,16 +3485,16 @@ }, { "name": "react/promise-timer", - "version": "v1.8.0", + "version": "v1.9.0", "source": { "type": "git", "url": "https://github.com/reactphp/promise-timer.git", - "reference": "0bbbcc79589e5bfdddba68a287f1cb805581a479" + "reference": "aa7a73c74b8d8c0f622f5982ff7b0351bc29e495" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise-timer/zipball/0bbbcc79589e5bfdddba68a287f1cb805581a479", - "reference": "0bbbcc79589e5bfdddba68a287f1cb805581a479", + "url": "https://api.github.com/repos/reactphp/promise-timer/zipball/aa7a73c74b8d8c0f622f5982ff7b0351bc29e495", + "reference": "aa7a73c74b8d8c0f622f5982ff7b0351bc29e495", "shasum": "" }, "require": { @@ -3514,7 +3552,7 @@ ], "support": { "issues": "https://github.com/reactphp/promise-timer/issues", - "source": "https://github.com/reactphp/promise-timer/tree/v1.8.0" + "source": "https://github.com/reactphp/promise-timer/tree/v1.9.0" }, "funding": [ { @@ -3526,7 +3564,7 @@ "type": "github" } ], - "time": "2021-12-06T11:08:48+00:00" + "time": "2022-06-13T13:41:03+00:00" }, { "name": "react/socket", @@ -3896,16 +3934,16 @@ }, { "name": "symfony/console", - "version": "v5.4.8", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "ffe3aed36c4d60da2cf1b0a1cee6b8f2e5fa881b" + "reference": "829d5d1bf60b2efeb0887b7436873becc71a45eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/ffe3aed36c4d60da2cf1b0a1cee6b8f2e5fa881b", - "reference": "ffe3aed36c4d60da2cf1b0a1cee6b8f2e5fa881b", + "url": "https://api.github.com/repos/symfony/console/zipball/829d5d1bf60b2efeb0887b7436873becc71a45eb", + "reference": "829d5d1bf60b2efeb0887b7436873becc71a45eb", "shasum": "" }, "require": { @@ -3975,7 +4013,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.8" + "source": "https://github.com/symfony/console/tree/v5.4.9" }, "funding": [ { @@ -3991,7 +4029,7 @@ "type": "tidelift" } ], - "time": "2022-04-12T16:02:29+00:00" + "time": "2022-05-18T06:17:34+00:00" }, { "name": "symfony/css-selector", @@ -4128,16 +4166,16 @@ }, { "name": "symfony/error-handler", - "version": "v5.4.8", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "c1fcde614dfe99d62a83b796a53b8bad358b266a" + "reference": "c116cda1f51c678782768dce89a45f13c949455d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/c1fcde614dfe99d62a83b796a53b8bad358b266a", - "reference": "c1fcde614dfe99d62a83b796a53b8bad358b266a", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/c116cda1f51c678782768dce89a45f13c949455d", + "reference": "c116cda1f51c678782768dce89a45f13c949455d", "shasum": "" }, "require": { @@ -4179,7 +4217,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v5.4.8" + "source": "https://github.com/symfony/error-handler/tree/v5.4.9" }, "funding": [ { @@ -4195,20 +4233,20 @@ "type": "tidelift" } ], - "time": "2022-04-12T15:48:08+00:00" + "time": "2022-05-21T13:57:48+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v5.4.3", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "dec8a9f58d20df252b9cd89f1c6c1530f747685d" + "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/dec8a9f58d20df252b9cd89f1c6c1530f747685d", - "reference": "dec8a9f58d20df252b9cd89f1c6c1530f747685d", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", + "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", "shasum": "" }, "require": { @@ -4264,7 +4302,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.3" + "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.9" }, "funding": [ { @@ -4280,7 +4318,7 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2022-05-05T16:45:39+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -4426,16 +4464,16 @@ }, { "name": "symfony/http-foundation", - "version": "v5.4.8", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "ff2818d1c3d49860bcae1f2cbb5eb00fcd3bf9e2" + "reference": "6b0d0e4aca38d57605dcd11e2416994b38774522" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ff2818d1c3d49860bcae1f2cbb5eb00fcd3bf9e2", - "reference": "ff2818d1c3d49860bcae1f2cbb5eb00fcd3bf9e2", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6b0d0e4aca38d57605dcd11e2416994b38774522", + "reference": "6b0d0e4aca38d57605dcd11e2416994b38774522", "shasum": "" }, "require": { @@ -4479,7 +4517,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.4.8" + "source": "https://github.com/symfony/http-foundation/tree/v5.4.9" }, "funding": [ { @@ -4495,20 +4533,20 @@ "type": "tidelift" } ], - "time": "2022-04-22T08:14:12+00:00" + "time": "2022-05-17T15:07:29+00:00" }, { "name": "symfony/http-kernel", - "version": "v5.4.8", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "cf7e61106abfc19b305ca0aedc41724ced89a02a" + "reference": "34b121ad3dc761f35fe1346d2f15618f8cbf77f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/cf7e61106abfc19b305ca0aedc41724ced89a02a", - "reference": "cf7e61106abfc19b305ca0aedc41724ced89a02a", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/34b121ad3dc761f35fe1346d2f15618f8cbf77f8", + "reference": "34b121ad3dc761f35fe1346d2f15618f8cbf77f8", "shasum": "" }, "require": { @@ -4591,7 +4629,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v5.4.8" + "source": "https://github.com/symfony/http-kernel/tree/v5.4.9" }, "funding": [ { @@ -4607,20 +4645,20 @@ "type": "tidelift" } ], - "time": "2022-04-27T17:22:21+00:00" + "time": "2022-05-27T07:09:08+00:00" }, { "name": "symfony/mime", - "version": "v5.4.8", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "af49bc163ec3272f677bde3bc44c0d766c1fd662" + "reference": "2b3802a24e48d0cfccf885173d2aac91e73df92e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/af49bc163ec3272f677bde3bc44c0d766c1fd662", - "reference": "af49bc163ec3272f677bde3bc44c0d766c1fd662", + "url": "https://api.github.com/repos/symfony/mime/zipball/2b3802a24e48d0cfccf885173d2aac91e73df92e", + "reference": "2b3802a24e48d0cfccf885173d2aac91e73df92e", "shasum": "" }, "require": { @@ -4674,7 +4712,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v5.4.8" + "source": "https://github.com/symfony/mime/tree/v5.4.9" }, "funding": [ { @@ -4690,20 +4728,20 @@ "type": "tidelift" } ], - "time": "2022-04-12T15:48:08+00:00" + "time": "2022-05-21T10:24:18+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "30885182c981ab175d4d034db0f6f469898070ab" + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", - "reference": "30885182c981ab175d4d034db0f6f469898070ab", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", "shasum": "" }, "require": { @@ -4718,7 +4756,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4756,7 +4794,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" }, "funding": [ { @@ -4772,20 +4810,20 @@ "type": "tidelift" } ], - "time": "2021-10-20T20:35:02+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-iconv", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "f1aed619e28cb077fc83fac8c4c0383578356e40" + "reference": "143f1881e655bebca1312722af8068de235ae5dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/f1aed619e28cb077fc83fac8c4c0383578356e40", - "reference": "f1aed619e28cb077fc83fac8c4c0383578356e40", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/143f1881e655bebca1312722af8068de235ae5dc", + "reference": "143f1881e655bebca1312722af8068de235ae5dc", "shasum": "" }, "require": { @@ -4800,7 +4838,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4839,7 +4877,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-iconv/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-iconv/tree/v1.26.0" }, "funding": [ { @@ -4855,20 +4893,20 @@ "type": "tidelift" } ], - "time": "2022-01-04T09:04:05+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" + "reference": "433d05519ce6990bf3530fba6957499d327395c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", + "reference": "433d05519ce6990bf3530fba6957499d327395c2", "shasum": "" }, "require": { @@ -4880,7 +4918,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4920,7 +4958,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" }, "funding": [ { @@ -4936,20 +4974,20 @@ "type": "tidelift" } ], - "time": "2021-11-23T21:10:46+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "749045c69efb97c70d25d7463abba812e91f3a44" + "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/749045c69efb97c70d25d7463abba812e91f3a44", - "reference": "749045c69efb97c70d25d7463abba812e91f3a44", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/59a8d271f00dd0e4c2e518104cc7963f655a1aa8", + "reference": "59a8d271f00dd0e4c2e518104cc7963f655a1aa8", "shasum": "" }, "require": { @@ -4963,7 +5001,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5007,7 +5045,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.26.0" }, "funding": [ { @@ -5023,20 +5061,20 @@ "type": "tidelift" } ], - "time": "2021-09-14T14:02:44+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + "reference": "219aa369ceff116e673852dce47c3a41794c14bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", + "reference": "219aa369ceff116e673852dce47c3a41794c14bd", "shasum": "" }, "require": { @@ -5048,7 +5086,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5091,7 +5129,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" }, "funding": [ { @@ -5107,20 +5145,20 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", "shasum": "" }, "require": { @@ -5135,7 +5173,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5174,7 +5212,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" }, "funding": [ { @@ -5190,20 +5228,20 @@ "type": "tidelift" } ], - "time": "2021-11-30T18:21:41+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "9a142215a36a3888e30d0a9eeea9766764e96976" + "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", - "reference": "9a142215a36a3888e30d0a9eeea9766764e96976", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2", + "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2", "shasum": "" }, "require": { @@ -5212,7 +5250,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5250,7 +5288,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0" }, "funding": [ { @@ -5266,20 +5304,20 @@ "type": "tidelift" } ], - "time": "2021-05-27T09:17:38+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" + "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85", + "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85", "shasum": "" }, "require": { @@ -5288,7 +5326,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5329,7 +5367,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0" }, "funding": [ { @@ -5345,20 +5383,20 @@ "type": "tidelift" } ], - "time": "2021-06-05T21:20:04+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c" + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c", - "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", "shasum": "" }, "require": { @@ -5367,7 +5405,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5412,7 +5450,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" }, "funding": [ { @@ -5428,20 +5466,20 @@ "type": "tidelift" } ], - "time": "2022-03-04T08:16:47+00:00" + "time": "2022-05-10T07:21:04+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.25.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f" + "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", - "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1", + "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1", "shasum": "" }, "require": { @@ -5450,7 +5488,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -5491,7 +5529,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0" }, "funding": [ { @@ -5507,7 +5545,7 @@ "type": "tidelift" } ], - "time": "2021-09-13T13:58:11+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/process", @@ -5746,16 +5784,16 @@ }, { "name": "symfony/string", - "version": "v5.4.8", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "3c061a76bff6d6ea427d85e12ad1bb8ed8cd43e8" + "reference": "985e6a9703ef5ce32ba617c9c7d97873bb7b2a99" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/3c061a76bff6d6ea427d85e12ad1bb8ed8cd43e8", - "reference": "3c061a76bff6d6ea427d85e12ad1bb8ed8cd43e8", + "url": "https://api.github.com/repos/symfony/string/zipball/985e6a9703ef5ce32ba617c9c7d97873bb7b2a99", + "reference": "985e6a9703ef5ce32ba617c9c7d97873bb7b2a99", "shasum": "" }, "require": { @@ -5812,7 +5850,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.8" + "source": "https://github.com/symfony/string/tree/v5.4.9" }, "funding": [ { @@ -5832,16 +5870,16 @@ }, { "name": "symfony/translation", - "version": "v5.4.8", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "f5c0f6d1f20993b2606f3a5f36b1dc8c1899170b" + "reference": "1639abc1177d26bcd4320e535e664cef067ab0ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/f5c0f6d1f20993b2606f3a5f36b1dc8c1899170b", - "reference": "f5c0f6d1f20993b2606f3a5f36b1dc8c1899170b", + "url": "https://api.github.com/repos/symfony/translation/zipball/1639abc1177d26bcd4320e535e664cef067ab0ca", + "reference": "1639abc1177d26bcd4320e535e664cef067ab0ca", "shasum": "" }, "require": { @@ -5909,7 +5947,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v5.4.8" + "source": "https://github.com/symfony/translation/tree/v5.4.9" }, "funding": [ { @@ -5925,7 +5963,7 @@ "type": "tidelift" } ], - "time": "2022-04-22T08:14:12+00:00" + "time": "2022-05-06T12:33:37+00:00" }, { "name": "symfony/translation-contracts", @@ -6007,16 +6045,16 @@ }, { "name": "symfony/var-dumper", - "version": "v5.4.8", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "cdcadd343d31ad16fc5e006b0de81ea307435053" + "reference": "af52239a330fafd192c773795520dc2dd62b5657" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/cdcadd343d31ad16fc5e006b0de81ea307435053", - "reference": "cdcadd343d31ad16fc5e006b0de81ea307435053", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/af52239a330fafd192c773795520dc2dd62b5657", + "reference": "af52239a330fafd192c773795520dc2dd62b5657", "shasum": "" }, "require": { @@ -6076,7 +6114,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.4.8" + "source": "https://github.com/symfony/var-dumper/tree/v5.4.9" }, "funding": [ { @@ -6092,7 +6130,7 @@ "type": "tidelift" } ], - "time": "2022-04-26T13:19:20+00:00" + "time": "2022-05-21T10:24:18+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -6303,21 +6341,21 @@ }, { "name": "webmozart/assert", - "version": "1.10.0", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "symfony/polyfill-ctype": "^1.8" + "ext-ctype": "*", + "php": "^7.2 || ^8.0" }, "conflict": { "phpstan/phpstan": "<0.12.20", @@ -6355,9 +6393,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.10.0" + "source": "https://github.com/webmozarts/assert/tree/1.11.0" }, - "time": "2021-03-09T10:59:23+00:00" + "time": "2022-06-03T18:03:27+00:00" } ], "packages-dev": [ @@ -7831,16 +7869,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.20", + "version": "9.5.21", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" + "reference": "0e32b76be457de00e83213528f6bb37e2a38fcb1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0e32b76be457de00e83213528f6bb37e2a38fcb1", + "reference": "0e32b76be457de00e83213528f6bb37e2a38fcb1", "shasum": "" }, "require": { @@ -7874,7 +7912,6 @@ "sebastian/version": "^3.0.2" }, "require-dev": { - "ext-pdo": "*", "phpspec/prophecy-phpunit": "^2.0.1" }, "suggest": { @@ -7918,7 +7955,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.21" }, "funding": [ { @@ -7930,7 +7967,7 @@ "type": "github" } ], - "time": "2022-04-01T12:37:26+00:00" + "time": "2022-06-19T12:14:25+00:00" }, { "name": "sebastian/cli-parser", @@ -8962,6 +8999,7 @@ "type": "tidelift" } ], + "abandoned": "symfony/error-handler", "time": "2022-04-12T15:19:55+00:00" }, { diff --git a/flexiapi/database/factories/TokenFactory.php b/flexiapi/database/factories/AccountCreationTokenFactory.php similarity index 91% rename from flexiapi/database/factories/TokenFactory.php rename to flexiapi/database/factories/AccountCreationTokenFactory.php index c1745cb..d02f5ff 100644 --- a/flexiapi/database/factories/TokenFactory.php +++ b/flexiapi/database/factories/AccountCreationTokenFactory.php @@ -22,12 +22,12 @@ namespace Database\Factories; use Illuminate\Database\Eloquent\Factories\Factory; use Illuminate\Support\Str; -use App\Token; +use App\AccountCreationToken; use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController; -class TokenFactory extends Factory +class AccountCreationTokenFactory extends Factory { - protected $model = Token::class; + protected $model = AccountCreationToken::class; public function definition() { diff --git a/flexiapi/database/factories/AccountFactory.php b/flexiapi/database/factories/AccountFactory.php index 493d850..be547ee 100644 --- a/flexiapi/database/factories/AccountFactory.php +++ b/flexiapi/database/factories/AccountFactory.php @@ -36,6 +36,7 @@ class AccountFactory extends Factory 'email' => $this->faker->email, 'user_agent' => $this->faker->userAgent, 'confirmation_key' => Str::random(WebAuthenticateController::$emailCodeSize), + 'provisioning_token' => Str::random(WebAuthenticateController::$emailCodeSize), 'ip_address' => $this->faker->ipv4, 'creation_time' => $this->faker->dateTime, 'dtmf_protocol' => array_rand(Account::$dtmfProtocols), diff --git a/flexiapi/database/migrations/2022_06_21_124721_rename_tokens_to_account_creation_tokens.php b/flexiapi/database/migrations/2022_06_21_124721_rename_tokens_to_account_creation_tokens.php new file mode 100644 index 0000000..a76c0e8 --- /dev/null +++ b/flexiapi/database/migrations/2022_06_21_124721_rename_tokens_to_account_creation_tokens.php @@ -0,0 +1,33 @@ +integer('account_id')->unsigned()->nullable(); + $table->foreign('account_id')->references('id') + ->on('accounts')->onDelete('cascade'); + }); + } + + public function down() + { + Schema::disableForeignKeyConstraints(); + + Schema::table('account_creation_tokens', function (Blueprint $table) { + $table->dropForeign(['account_id']); + $table->dropColumn('account_id'); + }); + + Schema::rename('account_creation_tokens', 'tokens'); + + Schema::enableForeignKeyConstraints(); + } +} diff --git a/flexiapi/database/migrations/2022_06_23_125740_add_provisioning_token_to_accounts_table.php b/flexiapi/database/migrations/2022_06_23_125740_add_provisioning_token_to_accounts_table.php new file mode 100644 index 0000000..13aebaa --- /dev/null +++ b/flexiapi/database/migrations/2022_06_23_125740_add_provisioning_token_to_accounts_table.php @@ -0,0 +1,22 @@ +string('provisioning_token')->nullable(); + }); + } + + public function down() + { + Schema::table('accounts', function (Blueprint $table) { + $table->dropColumn('provisioning_token'); + }); + } +} diff --git a/flexiapi/public/css/style.css b/flexiapi/public/css/style.css index 39e16df..947a89d 100644 --- a/flexiapi/public/css/style.css +++ b/flexiapi/public/css/style.css @@ -76,7 +76,7 @@ input.form-control { @media screen and (min-width: 1025px) { .table-of-contents { - width: 50%; + width: 40%; } } diff --git a/flexiapi/resources/views/admin/account/show.blade.php b/flexiapi/resources/views/admin/account/show.blade.php index 5751f17..2fa1763 100644 --- a/flexiapi/resources/views/admin/account/show.blade.php +++ b/flexiapi/resources/views/admin/account/show.blade.php @@ -108,14 +108,14 @@
Share the following picture with the user or the one-time-use link bellow.
-The following link can only be visited once
- +Renew the provision link The current one will be unavailable diff --git a/flexiapi/resources/views/api/documentation_markdown.blade.php b/flexiapi/resources/views/api/documentation_markdown.blade.php index d96ba0b..51cd6f6 100644 --- a/flexiapi/resources/views/api/documentation_markdown.blade.php +++ b/flexiapi/resources/views/api/documentation_markdown.blade.php @@ -17,6 +17,14 @@ A `from` (consisting of the user SIP address, prefixed with `sip:`), `content-ty Restricted endpoints are protected using a DIGEST authentication or an API Key mechanisms. +## Access model + +The endpoints are accessible using three different models: + +- Public publicly accessible +- User the endpoint can only be accessed by an authenticated user +- Admin the endpoint can be only be accessed by an authenticated admin user + ## Using the API Key You can retrieve an API Key from @if (config('app.web_panel')) [your account panel]({{ route('account.login') }}) @else your account panel @endif or using the dedicated API endpoint. @@ -59,17 +67,19 @@ You can find more documentation on the related [IETF RFC-7616](https://tools.iet # Endpoints -## Public endpoints +## Ping -### General - -#### `GET /ping` +### `GET /ping` +Public Returns `pong` -### Accounts +## Account Creation Tokens -#### `POST /tokens` -Send a token using a push notification to the device. +An account creation token is a unique token that allow the creation of a unique account. + +### `POST /account_creation_tokens/send-by-push` +Public +Create and send an `account_creation_token` using a push notification to the device. Return `403` if a token was already sent, or if the tokens limit is reached for this device. Return `503` if the token was not successfully sent. @@ -79,8 +89,16 @@ JSON parameters: * `pn_param` the push notification parameter * `pn_prid` the push notification unique id -#### `POST /accounts/with-token` -Create an account using a token. +### `POST /account_creation_tokens` +Admin + +Create and return an `account_creation_token`. + +## Accounts + +### `POST /accounts/with-account-creation-token` +Public +Create an account using an `account_creation_token`. Return `422` if the parameters are invalid or if the token is expired. JSON parameters: @@ -89,49 +107,52 @@ JSON parameters: * `password` required minimum 6 characters * `algorithm` required, values can be `SHA-256` or `MD5` * `domain` **not configurable except during test deployments** the value is enforced to the default registration domain set in the global configuration -* `token` the unique token +* `account_creation_token` the unique `account_creation_token` * `dtmf_protocol` optional, values must be `sipinfo` or `rfc2833` -#### `GET /accounts/{sip}/info` +### `GET /accounts/{sip}/info` +Public Retrieve public information about the account. Return `404` if the account doesn't exists. -#### `POST /accounts/{sip}/activate/email` +### `POST /accounts/{sip}/activate/email` +Public Activate an account using a secret code received by email. Return `404` if the account doesn't exists or if the code is incorrect, the validated account otherwise. JSON parameters: * `code` the code -#### `POST /accounts/{sip}/activate/phone` +### `POST /accounts/{sip}/activate/phone` +Public Activate an account using a pin code received by phone. Return `404` if the account doesn't exists or if the code is incorrect, the validated account otherwise. JSON parameters: * `code` the PIN code -## User authenticated endpoints -Those endpoints are authenticated and requires an activated account. - -### Accounts - -#### `GET /accounts/me/api_key` +### `GET /accounts/me/api_key` +User Generate and retrieve a fresh API Key. This endpoint is also setting the API Key as a Cookie. -#### `GET /accounts/me` +### `GET /accounts/me` +User Retrieve the account information. -#### `DELETE /accounts/me` +### `DELETE /accounts/me` +User Delete the account. -#### `POST /accounts/me/email/request` +### `POST /accounts/me/email/request` +User Change the account email. An email will be sent to the new email address to confirm the operation. JSON parameters: * `email` the new email address -#### `POST /accounts/me/password` +### `POST /accounts/me/password` +User Change the account password. JSON parameters: @@ -139,47 +160,10 @@ JSON parameters: * `old_password` required if the password is already set, the old password * `password` required, the new password -### Accounts phone number - -#### `POST /accounts/me/phone/request` -Request a specific code by SMS -JSON parameters: - -* `phone` the phone number to send the SMS - -#### `POST /accounts/me/phone` -Confirm the code received and change the phone number -JSON parameters: - -* `code` the received SMS code - -Return the updated account - -### Accounts devices - -#### `GET /accounts/me/devices` -Return the user registered devices. - -#### `DELETE /accounts/me/devices/{uuid}` -Remove one of the user registered devices. - -### Accounts contacts - -#### `GET /accounts/me/contacts` -Return the user contacts. - -#### `GET /accounts/me/contacts/{sip}` -Return a user contact. - -## Admin endpoints - -Those endpoints are authenticated and requires an admin account. - -### Accounts - -#### `POST /accounts` +### `POST /accounts` +Admin To create an account directly from the API. -If `activated` is set to `false` a random generated `confirmation_key` will be returned to allow further activation using the public endpoints. Check `confirmation_key_expires` to also set an expiration date on that `confirmation_key`. +If `activated` is set to `false` a random generated `confirmation_key` and `provisioning_token` will be returned to allow further activation using the public endpoints and provision the account. Check `confirmation_key_expires` to also set an expiration date on that `confirmation_key`. JSON parameters: @@ -195,49 +179,100 @@ The `domain` field is taken into account ONLY when `app.admins_manage_multi_doma * `dtmf_protocol` optional, values must be `sipinfo` or `rfc2833` * `confirmation_key_expires` optional, a datetime of this format: Y-m-d H:i:s. Only used when `activated` is not used or `false`. Enforces an expiration date on the returned `confirmation_key`. After that datetime public email or phone activation endpoints will return `403`. -#### `GET /accounts` +### `GET /accounts` +Admin Retrieve all the accounts, paginated. -#### `GET /accounts/{id}` +### `GET /accounts/{id}` +Admin Retrieve a specific account. -#### `GET /accounts/{sip}/search` +### `GET /accounts/{sip}/search` +Admin Search for a specific account by sip address. -#### `DELETE /accounts/{id}` +### `DELETE /accounts/{id}` +Admin Delete a specific account and its related information. -#### `GET /accounts/{id}/activate` +### `GET /accounts/{id}/activate` +Admin Activate an account. -#### `GET /accounts/{id}/deactivate` +### `GET /accounts/{id}/deactivate` +Admin Deactivate an account. -#### `GET /accounts/{id}/provision` -Re-provision an account by generating a fresh `confirmation_key`. +### `GET /accounts/{id}/provision` +Admin +Re-provision an account by generating a fresh `provisioning_token`. -### Contacts +## Accounts phone number -#### `GET /accounts/{id}/contacts/` +### `POST /accounts/me/phone/request` +User +Request a specific code by SMS +JSON parameters: + +* `phone` the phone number to send the SMS + +### `POST /accounts/me/phone` +User +Confirm the code received and change the phone number +JSON parameters: + +* `code` the received SMS code + +Return the updated account + +## Accounts devices + +### `GET /accounts/me/devices` +User +Return the user registered devices. + +### `DELETE /accounts/me/devices/{uuid}` +User +Remove one of the user registered devices. + +## Accounts contacts + +### `GET /accounts/me/contacts` +User +Return the user contacts. + +### `GET /accounts/me/contacts/{sip}` +User +Return a user contact. + +## Contacts + +### `GET /accounts/{id}/contacts/` +Admin Get all the account contacts. -#### `POST /accounts/{id}/contacts/{contact_id}` +### `POST /accounts/{id}/contacts/{contact_id}` +Admin Add a contact to the list. -#### `DELETE /accounts/{id}/contacts/{contact_id}` +### `DELETE /accounts/{id}/contacts/{contact_id}` +Admin Remove a contact from the list. -### Account Actions +## Account Actions The following endpoints will return `403 Forbidden` if the requested account doesn't have a DTMF protocol configured. -#### `GET /accounts/{id}/actions/` +### `GET /accounts/{id}/actions/` +Admin Show an account related actions. -#### `GET /accounts/{id}/actions/{action_id}` +### `GET /accounts/{id}/actions/{action_id}` +Admin Show an account related action. -#### `POST /accounts/{id}/actions/` +### `POST /accounts/{id}/actions/` +Admin Create an account action. JSON parameters: @@ -245,7 +280,8 @@ JSON parameters: * `key` required, alpha numeric with dashes, lowercase * `code` required, alpha numeric, lowercase -#### `PUT /accounts/{id}/actions/{action_id}` +### `PUT /accounts/{id}/actions/{action_id}` +Admin Create an account action. JSON parameters: @@ -253,43 +289,52 @@ JSON parameters: * `key` required, alpha numeric with dashes, lowercase * `code` required, alpha numeric, lowercase -#### `DELETE /accounts/{id}/actions/{action_id}` +### `DELETE /accounts/{id}/actions/{action_id}` +Admin Delete an account related action. -### Account Types +## Account Types -#### `GET /account_types/` +### `GET /account_types/` +Admin Show all the account types. -#### `GET /account_types/{id}` +### `GET /account_types/{id}` +Admin Show an account type. -#### `POST /account_types/` +### `POST /account_types/` +Admin Create an account type. JSON parameters: * `key` required, alpha numeric with dashes, lowercase -#### `PUT /account_types/{id}` +### `PUT /account_types/{id}` +Admin Update an account type. JSON parameters: * `key` required, alpha numeric with dashes, lowercase -#### `DELETE /account_types/{id}` +### `DELETE /account_types/{id}` +Admin Delete an account type. -#### `POST /accounts/{id}/types/{type_id}` +### `POST /accounts/{id}/types/{type_id}` +Admin Add a type to the account. -#### `DELETE /accounts/{id}/contacts/{type_id}` +### `DELETE /accounts/{id}/contacts/{type_id}` +Admin Remove a a type from the account. -### Messages +## Messages -#### `POST /messages` +### `POST /messages` +Admin Send a message over SIP. JSON parameters: @@ -297,15 +342,18 @@ JSON parameters: * `to` required, SIP address of the receiver * `body` required, content of the message -### Statistics +## Statistics -#### `GET /statistics/day` +### `GET /statistics/day` +Admin Retrieve registrations statistics for 24 hours. -#### `GET /statistics/week` +### `GET /statistics/week` +Admin Retrieve registrations statistics for a week. -#### `GET /statistics/month` +### `GET /statistics/month` +Admin Retrieve registrations statistics for a month. # Non-API Endpoints @@ -314,28 +362,31 @@ The following URLs are **not API endpoints** they are not returning `JSON` conte ## Provisioning -When an account is having an available `confirmation_key` it can be provisioned using the two following URL. +When an account is having an available `provisioning_token` it can be provisioned using the two following URL. ### `GET /provisioning/` +Public Return the provisioning information available in the liblinphone configuration file (if correctly configured). -### `GET /provisioning/{confirmation_key}` +### `GET /provisioning/{provisioning_token}` +Public Return the provisioning information available in the liblinphone configuration file. -If the `confirmation_key` is valid the related account information are added to the returned XML. The account is then considered as "provisioned" and those account related information will be removed in the upcoming requests (the content will be the same as the previous url). +If the `provisioning_token` is valid the related account information are added to the returned XML. The account is then considered as "provisioned" and those account related information will be removed in the upcoming requests (the content will be the same as the previous url). -If the account is not activated and the `confirmation_key` is valid. The account will be activated. +If the account is not activated and the `provisioning_token` is valid. The account will be activated. -### `GET /provisioning/qrcode/{confirmation_key}` +### `GET /provisioning/qrcode/{provisioning_token}` +Public Return a QRCode that points to the provisioning URL. -## Authenticated provisioning - ### `GET /provisioning/me` -Return the same base content as the previous URL and the account related information, similar to the `confirmation_key` endpoint. However this endpoint will always return those information. +User +Return the same base content as the previous URL and the account related information, similar to the `provisioning_token` endpoint. However this endpoint will always return those information. -## Authenticated contact list +## Contacts list ### `GET /contacts/vcard` +User Return the authenticated user contacts list, in [vCard 4.0 format](https://datatracker.ietf.org/doc/html/rfc6350). Here is the format of the vCard list returned by the endpoint: @@ -360,4 +411,5 @@ Here is the format of the vCard list returned by the endpoint: ``` ### `GET /contacts/vcard/{sip}` +User Return a specific user authenticated contact, in [vCard 4.0 format](https://datatracker.ietf.org/doc/html/rfc6350). \ No newline at end of file diff --git a/flexiapi/routes/api.php b/flexiapi/routes/api.php index 7016edd..8251e2e 100644 --- a/flexiapi/routes/api.php +++ b/flexiapi/routes/api.php @@ -26,9 +26,9 @@ Route::middleware('auth:api')->get('/user', function (Request $request) { }); Route::get('ping', 'Api\PingController@ping'); -Route::post('tokens', 'Api\TokenController@create'); +Route::post('account_creation_tokens/send-by-push', 'Api\AccountCreationTokenController@sendByPush'); Route::get('accounts/{sip}/info', 'Api\AccountController@info'); -Route::post('accounts/with-token', 'Api\AccountController@store'); +Route::post('accounts/with-account-creation-token', 'Api\AccountController@store'); Route::post('accounts/{sip}/activate/email', 'Api\AccountController@activateEmail'); Route::post('accounts/{sip}/activate/phone', 'Api\AccountController@activatePhone'); diff --git a/flexiapi/routes/web.php b/flexiapi/routes/web.php index 9a59f02..1ab68db 100644 --- a/flexiapi/routes/web.php +++ b/flexiapi/routes/web.php @@ -42,8 +42,8 @@ Route::group(['middleware' => 'auth.digest_or_key'], function () { Route::get('contacts/vcard', 'Account\ContactVcardController@index')->name('account.contacts.vcard.index'); }); -Route::get('provisioning/qrcode/{confirmation}', 'Account\ProvisioningController@qrcode')->name('provisioning.qrcode'); -Route::get('provisioning/{confirmation?}', 'Account\ProvisioningController@show')->name('provisioning.show'); +Route::get('provisioning/qrcode/{provisioning_token}', 'Account\ProvisioningController@qrcode')->name('provisioning.qrcode'); +Route::get('provisioning/{provisioning_token?}', 'Account\ProvisioningController@show')->name('provisioning.show'); if (config('app.public_registration')) { if (config('app.phone_authentication')) { diff --git a/flexiapi/tests/Feature/AccountApiTest.php b/flexiapi/tests/Feature/AccountApiTest.php index d778769..d305313 100644 --- a/flexiapi/tests/Feature/AccountApiTest.php +++ b/flexiapi/tests/Feature/AccountApiTest.php @@ -140,6 +140,7 @@ class AccountApiTest extends TestCase ]); $this->assertFalse(empty($response1['confirmation_key'])); + $this->assertFalse(empty($response1['provisioning_token'])); } public function testAdminMultiDomains() @@ -235,6 +236,7 @@ class AccountApiTest extends TestCase ]); $this->assertFalse(empty($response1['confirmation_key'])); + $this->assertFalse(empty($response1['provisioning_token'])); } public function testUsernameNoDomain() @@ -305,6 +307,7 @@ class AccountApiTest extends TestCase ]); $this->assertTrue(!empty($response1['confirmation_key'])); + $this->assertFalse(empty($response1['provisioning_token'])); } public function testActivated() @@ -334,6 +337,7 @@ class AccountApiTest extends TestCase ]); $this->assertTrue(empty($response1['confirmation_key'])); + $this->assertTrue(empty($response1['provisioning_token'])); } public function testNotActivated() @@ -362,6 +366,7 @@ class AccountApiTest extends TestCase ]); $this->assertFalse(empty($response1['confirmation_key'])); + $this->assertFalse(empty($response1['provisioning_token'])); } public function testSimpleAccount() diff --git a/flexiapi/tests/Feature/AccountTokenTest.php b/flexiapi/tests/Feature/AccountCreationTokenTest.php similarity index 83% rename from flexiapi/tests/Feature/AccountTokenTest.php rename to flexiapi/tests/Feature/AccountCreationTokenTest.php index bfb16ea..909075b 100644 --- a/flexiapi/tests/Feature/AccountTokenTest.php +++ b/flexiapi/tests/Feature/AccountCreationTokenTest.php @@ -22,14 +22,14 @@ namespace Tests\Feature; use Illuminate\Foundation\Testing\RefreshDatabase; use Tests\TestCase; -use App\Token; +use App\AccountCreationToken; -class AccountTokenTest extends TestCase +class AccountCreationTokenTest extends TestCase { use RefreshDatabase; - protected $tokenRoute = '/api/tokens'; - protected $accountRoute = '/api/accounts/with-token'; + protected $tokenRoute = '/api/account_creation_tokens/send-by-push'; + protected $accountRoute = '/api/accounts/with-account-creation-token'; protected $method = 'POST'; protected $pnProvider = 'provider'; @@ -54,7 +54,7 @@ class AccountTokenTest extends TestCase public function testLimit() { - $token = Token::factory()->create(); + $token = AccountCreationToken::factory()->create(); $response = $this->json($this->method, $this->tokenRoute, [ 'pn_provider' => $token->pn_provider, @@ -66,14 +66,14 @@ class AccountTokenTest extends TestCase public function testInvalidToken() { - $token = Token::factory()->create(); + $token = AccountCreationToken::factory()->create(); // Invalid token $response = $this->json($this->method, $this->accountRoute, [ 'username' => 'username', 'algorithm' => 'SHA-256', 'password' => '2', - 'token' => '0123456789abc' + 'account_creation_token' => '0123456789abc' ]); $response->assertStatus(422); @@ -82,7 +82,7 @@ class AccountTokenTest extends TestCase 'username' => 'username', 'algorithm' => 'SHA-256', 'password' => '2', - 'token' => $token->token + 'account_creation_token' => $token->token ]); $response->assertStatus(200); @@ -91,7 +91,7 @@ class AccountTokenTest extends TestCase 'username' => 'username2', 'algorithm' => 'SHA-256', 'password' => '2', - 'token' => $token->token + 'account_creation_token' => $token->token ]); $response->assertStatus(422); } diff --git a/flexiapi/tests/Feature/AccountProvisioningTest.php b/flexiapi/tests/Feature/AccountProvisioningTest.php index 043f0d7..a8f5688 100644 --- a/flexiapi/tests/Feature/AccountProvisioningTest.php +++ b/flexiapi/tests/Feature/AccountProvisioningTest.php @@ -83,7 +83,7 @@ class AccountProvisioningTest extends TestCase $password->account->save(); // Ensure that we get the authentication password once - $response = $this->get($this->route.'/'.$password->account->confirmation_key) + $response = $this->get($this->route.'/'.$password->account->provisioning_token) ->assertStatus(200) ->assertHeader('Content-Type', 'application/xml') ->assertSee('ha1'); @@ -92,31 +92,31 @@ class AccountProvisioningTest extends TestCase $this->assertEquals(true, DBAccount::where('id', $password->account->id)->first()->activated); // And then twice - $response = $this->get($this->route.'/'.$password->account->confirmation_key) + $response = $this->get($this->route.'/'.$password->account->provisioning_token) ->assertStatus(200) ->assertHeader('Content-Type', 'application/xml') ->assertDontSee('ha1'); $password->account->refresh(); - $confirmationKey = $password->account->confirmation_key; + $provisioningToken = $password->account->provisioning_token; - // Refresh the confirmation_key + // Refresh the provisioning_token $admin = Admin::factory()->create(); $admin->account->generateApiKey(); $this->keyAuthenticated($admin->account) ->json($this->method, '/api/accounts/'.$password->account->id.'/provision') ->assertStatus(200) - ->assertSee('confirmation_key') - ->assertDontSee($confirmationKey); + ->assertSee('provisioning_token') + ->assertDontSee($provisioningToken); $password->account->refresh(); - $this->assertNotEquals($confirmationKey, $password->account->confirmation_key); + $this->assertNotEquals($provisioningToken, $password->account->provisioning_token); // And then provision one last time - $this->get($this->route.'/'.$password->account->confirmation_key) + $this->get($this->route.'/'.$password->account->provisioning_token) ->assertStatus(200) ->assertHeader('Content-Type', 'application/xml') ->assertSee('ha1'); diff --git a/flexisip-account-manager.spec b/flexisip-account-manager.spec index 0df9f8c..ddacd82 100644 --- a/flexisip-account-manager.spec +++ b/flexisip-account-manager.spec @@ -8,7 +8,7 @@ #%define _datadir %{_datarootdir} #%define _docdir %{_datadir}/doc -%define build_number 137 +%define build_number 138 %define var_dir /var/opt/belledonne-communications %define opt_dir /opt/belledonne-communications/share/flexisip-account-manager